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",
|
"type": "local",
|
||||||
"id": "foo",
|
"id": "foo",
|
||||||
"passwordInfos": []map[string]string{
|
"passwordInfos": []map[string]string{
|
||||||
{"userId": "abc", "passwordHash": "PING"},
|
{"userId": "abc", "passwordHash": "UElORw=="}, // []byte is base64 encoded when using json.Marshasl
|
||||||
{"userId": "271", "passwordPlaintext": "pong"},
|
{"userId": "271", "passwordPlaintext": "pong"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -53,9 +53,9 @@ func NewPasswordFromPlaintext(plaintext string) (Password, error) {
|
||||||
type PasswordInfo struct {
|
type PasswordInfo struct {
|
||||||
UserID string
|
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) {
|
func (p PasswordInfo) Authenticate(plaintext string) (*oidc.Identity, error) {
|
||||||
|
@ -86,7 +86,7 @@ type PasswordInfoRepo interface {
|
||||||
func (u *PasswordInfo) UnmarshalJSON(data []byte) error {
|
func (u *PasswordInfo) UnmarshalJSON(data []byte) error {
|
||||||
var dec struct {
|
var dec struct {
|
||||||
UserID string `json:"userId"`
|
UserID string `json:"userId"`
|
||||||
PasswordHash string `json:"passwordHash"`
|
PasswordHash []byte `json:"passwordHash"`
|
||||||
PasswordPlaintext string `json:"passwordPlaintext"`
|
PasswordPlaintext string `json:"passwordPlaintext"`
|
||||||
PasswordExpires time.Time `json:"passwordExpires"`
|
PasswordExpires time.Time `json:"passwordExpires"`
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,9 @@ func (u *PasswordInfo) UnmarshalJSON(data []byte) error {
|
||||||
|
|
||||||
u.UserID = dec.UserID
|
u.UserID = dec.UserID
|
||||||
|
|
||||||
u.PasswordExpires = dec.PasswordExpires
|
if !dec.PasswordExpires.IsZero() {
|
||||||
|
u.PasswordExpires = dec.PasswordExpires
|
||||||
|
}
|
||||||
|
|
||||||
if len(dec.PasswordHash) != 0 {
|
if len(dec.PasswordHash) != 0 {
|
||||||
if dec.PasswordPlaintext != "" {
|
if dec.PasswordPlaintext != "" {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package user
|
package user
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"net/url"
|
"net/url"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
@ -13,6 +14,44 @@ import (
|
||||||
"github.com/coreos/go-oidc/key"
|
"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) {
|
func TestNewPasswordFromHash(t *testing.T) {
|
||||||
tests := []string{
|
tests := []string{
|
||||||
"test",
|
"test",
|
||||||
|
|
Reference in a new issue