committed by
GitHub
5 changed files with 357 additions and 5 deletions
@ -0,0 +1,242 @@ |
|||||
|
package keycloak |
||||
|
|
||||
|
import ( |
||||
|
"strconv" |
||||
|
"time" |
||||
|
) |
||||
|
|
||||
|
// Get a given attribute
|
||||
|
func (a Attributes) Get(key AttributeKey) []string { |
||||
|
return a[key] |
||||
|
} |
||||
|
|
||||
|
// Set a given attribute
|
||||
|
func (a Attributes) Set(key AttributeKey, value []string) { |
||||
|
a[key] = value |
||||
|
} |
||||
|
|
||||
|
// GetString gets the first value of a given attribute
|
||||
|
func (a Attributes) GetString(key AttributeKey) *string { |
||||
|
var attrbs = a[key] |
||||
|
if len(attrbs) > 0 { |
||||
|
return &attrbs[0] |
||||
|
} |
||||
|
return nil |
||||
|
} |
||||
|
|
||||
|
// SetString sets the value of a given attribute
|
||||
|
func (a Attributes) SetString(key AttributeKey, value string) { |
||||
|
a.Set(key, []string{value}) |
||||
|
} |
||||
|
|
||||
|
// GetInt gets the first value of a given attribute
|
||||
|
func (a Attributes) GetInt(key AttributeKey) (*int, error) { |
||||
|
var attrbs = a[key] |
||||
|
if len(attrbs) > 0 { |
||||
|
var res64, err = strconv.ParseInt(attrbs[0], 0, 0) |
||||
|
var res = int(res64) |
||||
|
return &res, err |
||||
|
} |
||||
|
return nil, nil |
||||
|
} |
||||
|
|
||||
|
// SetInt sets the value of a given attribute
|
||||
|
func (a Attributes) SetInt(key AttributeKey, value int) { |
||||
|
a.Set(key, []string{strconv.FormatInt(int64(value), 10)}) |
||||
|
} |
||||
|
|
||||
|
// GetBool gets the first value of a given attribute
|
||||
|
func (a Attributes) GetBool(key AttributeKey) (*bool, error) { |
||||
|
var attrbs = a[key] |
||||
|
if len(attrbs) > 0 { |
||||
|
var res, err = strconv.ParseBool(attrbs[0]) |
||||
|
return &res, err |
||||
|
} |
||||
|
return nil, nil |
||||
|
} |
||||
|
|
||||
|
// SetBool sets the value of a given attribute
|
||||
|
func (a Attributes) SetBool(key AttributeKey, value bool) { |
||||
|
a.Set(key, []string{strconv.FormatBool(value)}) |
||||
|
} |
||||
|
|
||||
|
// GetDate returns an attribute which contains a date value
|
||||
|
func (a Attributes) GetDate(key AttributeKey, dateLayouts []string) *string { |
||||
|
var attrb = a.GetString(key) |
||||
|
var formatted = a.reformatDate(attrb, dateLayouts) |
||||
|
if formatted != nil { |
||||
|
a[key] = []string{*formatted} |
||||
|
return formatted |
||||
|
} |
||||
|
return attrb |
||||
|
} |
||||
|
|
||||
|
// SetDate sets a date
|
||||
|
func (a Attributes) SetDate(key AttributeKey, value string, dateLayouts []string) { |
||||
|
var formatted = a.reformatDate(&value, dateLayouts) |
||||
|
if formatted != nil { |
||||
|
value = *formatted |
||||
|
} |
||||
|
a.Set(key, []string{value}) |
||||
|
} |
||||
|
|
||||
|
// GetTime returns an attribute which contains a date value
|
||||
|
func (a Attributes) GetTime(key AttributeKey, dateLayouts []string) (*time.Time, error) { |
||||
|
return a.parseDate(a.GetString(key), dateLayouts) |
||||
|
} |
||||
|
|
||||
|
// SetTime sets a date
|
||||
|
func (a Attributes) SetTime(key AttributeKey, value time.Time, dateLayout string) { |
||||
|
a.Set(key, []string{value.Format(dateLayout)}) |
||||
|
} |
||||
|
|
||||
|
// SetStringWhenNotNil sets an attribute value if it is not nil
|
||||
|
func (a Attributes) SetStringWhenNotNil(key AttributeKey, value *string) { |
||||
|
if value != nil { |
||||
|
a.Set(key, []string{*value}) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// SetIntWhenNotNil sets an attribute value if it is not nil
|
||||
|
func (a Attributes) SetIntWhenNotNil(key AttributeKey, value *int) { |
||||
|
if value != nil { |
||||
|
a.Set(key, []string{strconv.FormatInt(int64(*value), 10)}) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// SetBoolWhenNotNil sets an attribute value if it is not nil
|
||||
|
func (a Attributes) SetBoolWhenNotNil(key AttributeKey, value *bool) { |
||||
|
if value != nil { |
||||
|
a.Set(key, []string{strconv.FormatBool(*value)}) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// SetDateWhenNotNil sets a date attribute if it is not nil
|
||||
|
func (a Attributes) SetDateWhenNotNil(key AttributeKey, value *string, dateLayouts []string) { |
||||
|
if value != nil { |
||||
|
a.SetDate(key, *value, dateLayouts) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// SetTimeWhenNotNil sets a date attribute if it is not nil
|
||||
|
func (a Attributes) SetTimeWhenNotNil(key AttributeKey, value *time.Time, dateLayout string) { |
||||
|
if value != nil { |
||||
|
a.SetTime(key, *value, dateLayout) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
func (a Attributes) parseDate(value *string, dateLayouts []string) (*time.Time, error) { |
||||
|
if value == nil || len(dateLayouts) == 0 { |
||||
|
return nil, nil |
||||
|
} |
||||
|
var date, firstErr = time.Parse(dateLayouts[0], *value) |
||||
|
if firstErr == nil { |
||||
|
return &date, nil |
||||
|
} |
||||
|
|
||||
|
// Date does not have the expected layout. Try to convert it from supported layouts
|
||||
|
var err error |
||||
|
for _, layout := range dateLayouts[1:] { |
||||
|
date, err = time.Parse(layout, *value) |
||||
|
if err == nil { |
||||
|
return &date, nil |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return nil, firstErr |
||||
|
} |
||||
|
|
||||
|
func (a Attributes) reformatDate(value *string, dateLayouts []string) *string { |
||||
|
var date, err = a.parseDate(value, dateLayouts) |
||||
|
if err != nil || date == nil { |
||||
|
return nil |
||||
|
} |
||||
|
var res = date.Format(dateLayouts[0]) |
||||
|
return &res |
||||
|
} |
||||
|
|
||||
|
// GetAttribute returns an attribute given its key
|
||||
|
func (u *UserRepresentation) GetAttribute(key AttributeKey) []string { |
||||
|
if u.Attributes != nil { |
||||
|
return u.Attributes.Get(key) |
||||
|
} |
||||
|
return nil |
||||
|
} |
||||
|
|
||||
|
// SetAttribute sets an attribute
|
||||
|
func (u *UserRepresentation) SetAttribute(key AttributeKey, value []string) { |
||||
|
if u.Attributes == nil { |
||||
|
var attrbs = make(Attributes) |
||||
|
u.Attributes = &attrbs |
||||
|
} |
||||
|
u.Attributes.Set(key, value) |
||||
|
} |
||||
|
|
||||
|
// GetAttributeString returns the first value of an attribute given its key
|
||||
|
func (u *UserRepresentation) GetAttributeString(key AttributeKey) *string { |
||||
|
if u.Attributes != nil { |
||||
|
return u.Attributes.GetString(key) |
||||
|
} |
||||
|
return nil |
||||
|
} |
||||
|
|
||||
|
// SetAttributeString sets an attribute with a single value
|
||||
|
func (u *UserRepresentation) SetAttributeString(key AttributeKey, value string) { |
||||
|
u.SetAttribute(key, []string{value}) |
||||
|
} |
||||
|
|
||||
|
// GetAttributeBool returns the first value of an attribute given its key
|
||||
|
func (u *UserRepresentation) GetAttributeBool(key AttributeKey) (*bool, error) { |
||||
|
if u.Attributes != nil { |
||||
|
return u.Attributes.GetBool(key) |
||||
|
} |
||||
|
return nil, nil |
||||
|
} |
||||
|
|
||||
|
// SetAttributeBool sets an attribute with a single value
|
||||
|
func (u *UserRepresentation) SetAttributeBool(key AttributeKey, value bool) { |
||||
|
u.SetAttribute(key, []string{strconv.FormatBool(value)}) |
||||
|
} |
||||
|
|
||||
|
// GetAttributeInt returns the first value of an attribute given its key
|
||||
|
func (u *UserRepresentation) GetAttributeInt(key AttributeKey) (*int, error) { |
||||
|
if u.Attributes != nil { |
||||
|
return u.Attributes.GetInt(key) |
||||
|
} |
||||
|
return nil, nil |
||||
|
} |
||||
|
|
||||
|
// SetAttributeInt sets an attribute with a single value
|
||||
|
func (u *UserRepresentation) SetAttributeInt(key AttributeKey, value int) { |
||||
|
u.SetAttribute(key, []string{strconv.FormatInt(int64(value), 10)}) |
||||
|
} |
||||
|
|
||||
|
// GetAttributeDate returns an attribute which contains a date value
|
||||
|
func (u *UserRepresentation) GetAttributeDate(key AttributeKey, dateLayouts []string) *string { |
||||
|
if u.Attributes != nil { |
||||
|
return u.Attributes.GetDate(key, dateLayouts) |
||||
|
} |
||||
|
return nil |
||||
|
} |
||||
|
|
||||
|
// SetAttributeDate sets a date attribute
|
||||
|
func (u *UserRepresentation) SetAttributeDate(key AttributeKey, date string, dateLayouts []string) { |
||||
|
if u.Attributes == nil { |
||||
|
var attrbs = make(Attributes) |
||||
|
u.Attributes = &attrbs |
||||
|
} |
||||
|
u.Attributes.SetDate(key, date, dateLayouts) |
||||
|
} |
||||
|
|
||||
|
// GetAttributeTime returns an attribute which contains a date value
|
||||
|
func (u *UserRepresentation) GetAttributeTime(key AttributeKey, dateLayouts []string) (*time.Time, error) { |
||||
|
if u.Attributes != nil { |
||||
|
return u.Attributes.GetTime(key, dateLayouts) |
||||
|
} |
||||
|
return nil, nil |
||||
|
} |
||||
|
|
||||
|
// SetAttributeTime sets a date attribute
|
||||
|
func (u *UserRepresentation) SetAttributeTime(key AttributeKey, date time.Time, dateLayout string) { |
||||
|
u.SetAttributeString(key, date.Format(dateLayout)) |
||||
|
} |
||||
@ -0,0 +1,104 @@ |
|||||
|
package keycloak |
||||
|
|
||||
|
import ( |
||||
|
"testing" |
||||
|
|
||||
|
"github.com/stretchr/testify/assert" |
||||
|
) |
||||
|
|
||||
|
var ( |
||||
|
supportedDateLayouts = []string{"02.01.2006", "2006/01/02"} |
||||
|
) |
||||
|
|
||||
|
func TestUserRepresentationAttributes(t *testing.T) { |
||||
|
var userRep UserRepresentation |
||||
|
|
||||
|
var ( |
||||
|
keyMissing = AttributeKey("missing") |
||||
|
keyDate = AttributeKey("date") |
||||
|
keyGender = AttributeKey("gender") |
||||
|
keyMultiple = AttributeKey("multiple") |
||||
|
) |
||||
|
|
||||
|
// Attributes are empty
|
||||
|
assert.Nil(t, userRep.GetAttribute(keyMissing), "Search with no attribute") |
||||
|
assert.Nil(t, userRep.GetAttributeString(keyMissing), "Search with no attribute") |
||||
|
assert.Nil(t, userRep.GetAttributeDate(keyDate, supportedDateLayouts), "Search with no attribute") |
||||
|
|
||||
|
// Sets some attributes
|
||||
|
userRep.SetAttributeString(keyDate, "2021/12/31") |
||||
|
userRep.SetAttributeString(keyGender, "M") |
||||
|
|
||||
|
// Search for a missing attribute
|
||||
|
assert.Nil(t, userRep.GetAttribute(keyMissing), "Missing attribute") |
||||
|
|
||||
|
t.Run("Check that a Set/Get cycle gives the correct values", func(t *testing.T) { |
||||
|
userRep.SetAttribute(AttributeKey("multiple"), []string{"3", "7", "21"}) |
||||
|
assert.Equal(t, []string{"3", "7", "21"}, userRep.GetAttribute(keyMultiple), "Gets a multiple-value attribute") |
||||
|
assert.Equal(t, []string{"2021/12/31"}, userRep.GetAttribute(keyDate), "Gets an array") |
||||
|
assert.Equal(t, "2021/12/31", *userRep.GetAttributeString(keyDate), "Gets a single attribute") |
||||
|
assert.Equal(t, "31.12.2021", *userRep.GetAttributeDate(keyDate, supportedDateLayouts), "Gets a birthdate") |
||||
|
}) |
||||
|
|
||||
|
t.Run("Attributes and dates", func(t *testing.T) { |
||||
|
// Set a date in a different format than the one which will be used to store the information
|
||||
|
userRep.SetAttributeDate(keyDate, "2021/12/31", supportedDateLayouts) |
||||
|
assert.Equal(t, "31.12.2021", *userRep.GetAttributeString(keyDate), "Gets a single attribute") |
||||
|
assert.Equal(t, "31.12.2021", *userRep.GetAttributeDate(keyDate, supportedDateLayouts), "Gets a birthdate") |
||||
|
|
||||
|
// Do not override a parameter with a nil value
|
||||
|
userRep.Attributes.SetDateWhenNotNil(keyDate, nil, supportedDateLayouts) |
||||
|
assert.Equal(t, "31.12.2021", *userRep.GetAttributeString(keyDate)) |
||||
|
var otherDate = "30.11.2022" |
||||
|
userRep.Attributes.SetDateWhenNotNil(keyDate, &otherDate, supportedDateLayouts) |
||||
|
assert.Equal(t, otherDate, *userRep.GetAttributeString(keyDate)) |
||||
|
}) |
||||
|
|
||||
|
t.Run("Int tests", func(t *testing.T) { |
||||
|
var keyInt = AttributeKey("numeric") |
||||
|
var res, err = userRep.Attributes.GetInt(keyInt) |
||||
|
var value = 5 |
||||
|
assert.Nil(t, err) |
||||
|
assert.Nil(t, res) |
||||
|
// Set int value
|
||||
|
userRep.Attributes.SetIntWhenNotNil(keyInt, &value) |
||||
|
res, err = userRep.Attributes.GetInt(keyInt) |
||||
|
assert.Nil(t, err) |
||||
|
assert.Equal(t, value, *res) |
||||
|
// Set when not nil : won't have any effect with nil
|
||||
|
userRep.Attributes.SetIntWhenNotNil(keyInt, nil) |
||||
|
res, err = userRep.Attributes.GetInt(keyInt) |
||||
|
assert.Nil(t, err) |
||||
|
assert.Equal(t, value, *res) |
||||
|
// Update to 10
|
||||
|
value = 10 |
||||
|
userRep.Attributes.SetIntWhenNotNil(keyInt, &value) |
||||
|
res, err = userRep.Attributes.GetInt(keyInt) |
||||
|
assert.Nil(t, err) |
||||
|
assert.Equal(t, value, *res) |
||||
|
}) |
||||
|
|
||||
|
t.Run("Boolean tests", func(t *testing.T) { |
||||
|
var keyBool = AttributeKey("boolean") |
||||
|
var res, err = userRep.Attributes.GetBool(keyBool) |
||||
|
var value = false |
||||
|
assert.Nil(t, err) |
||||
|
assert.Nil(t, res) |
||||
|
// Set boolean value
|
||||
|
userRep.Attributes.SetBoolWhenNotNil(keyBool, &value) |
||||
|
res, err = userRep.Attributes.GetBool(keyBool) |
||||
|
assert.Nil(t, err) |
||||
|
assert.False(t, *res) |
||||
|
// Set when not nil : won't have any effect with nil
|
||||
|
userRep.Attributes.SetBoolWhenNotNil(keyBool, nil) |
||||
|
res, err = userRep.Attributes.GetBool(keyBool) |
||||
|
assert.Nil(t, err) |
||||
|
assert.False(t, *res) |
||||
|
// Update to true
|
||||
|
value = true |
||||
|
userRep.Attributes.SetBoolWhenNotNil(keyBool, &value) |
||||
|
res, err = userRep.Attributes.GetBool(keyBool) |
||||
|
assert.Nil(t, err) |
||||
|
assert.True(t, *res) |
||||
|
}) |
||||
|
} |
||||
Loading…
Reference in new issue