forked from mystiq/dex
user: fix password info JSON encoding to survive round trips
PasswordInfos are marshaled when storing them in the database as part of the local connector. However, the custom unmarsheler defined could not unmarshal the standard marshling of this struct. Add a struct tag to the Password field to correct this. Closes #332
This commit is contained in:
parent
f51125f555
commit
221a1ad7a0
3 changed files with 46 additions and 5 deletions
|
@ -61,7 +61,7 @@ func TestNewConnectorConfigFromMap(t *testing.T) {
|
|||
"type": "local",
|
||||
"id": "foo",
|
||||
"passwordInfos": []map[string]string{
|
||||
{"userId": "abc", "passwordHash": "PING"},
|
||||
{"userId": "abc", "passwordHash": "UElORw=="}, // []byte is base64 encoded when using json.Marshasl
|
||||
{"userId": "271", "passwordPlaintext": "pong"},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -53,9 +53,9 @@ func NewPasswordFromPlaintext(plaintext string) (Password, error) {
|
|||
type PasswordInfo struct {
|
||||
UserID string
|
||||
|
||||
Password Password
|
||||
Password Password `json:"passwordHash"`
|
||||
|
||||
PasswordExpires time.Time
|
||||
PasswordExpires time.Time `json:"passwordExpires"`
|
||||
}
|
||||
|
||||
func (p PasswordInfo) Authenticate(plaintext string) (*oidc.Identity, error) {
|
||||
|
@ -86,7 +86,7 @@ type PasswordInfoRepo interface {
|
|||
func (u *PasswordInfo) UnmarshalJSON(data []byte) error {
|
||||
var dec struct {
|
||||
UserID string `json:"userId"`
|
||||
PasswordHash string `json:"passwordHash"`
|
||||
PasswordHash []byte `json:"passwordHash"`
|
||||
PasswordPlaintext string `json:"passwordPlaintext"`
|
||||
PasswordExpires time.Time `json:"passwordExpires"`
|
||||
}
|
||||
|
@ -98,7 +98,9 @@ func (u *PasswordInfo) UnmarshalJSON(data []byte) error {
|
|||
|
||||
u.UserID = dec.UserID
|
||||
|
||||
u.PasswordExpires = dec.PasswordExpires
|
||||
if !dec.PasswordExpires.IsZero() {
|
||||
u.PasswordExpires = dec.PasswordExpires
|
||||
}
|
||||
|
||||
if len(dec.PasswordHash) != 0 {
|
||||
if dec.PasswordPlaintext != "" {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package user
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
"testing"
|
||||
"time"
|
||||
|
@ -13,6 +14,44 @@ import (
|
|||
"github.com/coreos/go-oidc/key"
|
||||
)
|
||||
|
||||
func TestPasswordMarshaling(t *testing.T) {
|
||||
hashPassword := func(s string) []byte {
|
||||
data, err := DefaultPasswordHasher(s)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to hash password: %v", err)
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
tests := []PasswordInfo{
|
||||
{
|
||||
UserID: "mrpink",
|
||||
Password: hashPassword("mrpinks-password"),
|
||||
},
|
||||
{
|
||||
UserID: "mrorange",
|
||||
Password: hashPassword("mroranges-password"),
|
||||
PasswordExpires: time.Now().Add(time.Hour),
|
||||
},
|
||||
}
|
||||
for i, tt := range tests {
|
||||
data, err := json.Marshal(tt)
|
||||
if err != nil {
|
||||
t.Errorf("case %d: failed to marshal password info: %v", i, err)
|
||||
continue
|
||||
}
|
||||
var p PasswordInfo
|
||||
if err := json.Unmarshal(data, &p); err != nil {
|
||||
t.Errorf("case %d: failed to unmarshal password info: %v", i, err)
|
||||
continue
|
||||
}
|
||||
if diff := pretty.Compare(tt, p); diff != "" {
|
||||
t.Errorf("case %d: password info did not survive JSON marshal round trip: %s", i, diff)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestNewPasswordFromHash(t *testing.T) {
|
||||
tests := []string{
|
||||
"test",
|
||||
|
|
Loading…
Reference in a new issue