mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-01-04 11:19:39 -06:00
graph: Use userType property to distinguish between Member and Guest accounts
Fixes 5603 - Calling POST /graph/v1.0/users with userType not set will create a user as "Member" - Calling POST /graph/v1.0/users with userType set as "Member" or "Guest" will create a user as "Member" or "Guest" - Calling POST /graph/v1.0/users with userType set as anything but "Member" or "Guest" returns error - Calling POST /graph/v1.0/education/users with userType not set will create a user as "Member" - Calling POST /graph/v1.0/education/users with userType set as "Member" will create a user as "Member" and primary role as parameter specifies - Calling POST /graph/v1.0/education/users with userType set as "Guest" will create a user as "Guest" and primary role as parameter specifies - Calling POST /graph/v1.0/education/users with userType not set as anything but "Member" or "Guest" returns error - Calling PATCH on /users or /education/users will update attribute in the same way as for POST
This commit is contained in:
committed by
Ralf Haferkamp
parent
36d0c8c939
commit
23ba180e8a
@@ -61,6 +61,7 @@ type LDAP struct {
|
||||
UserDisplayNameAttribute string `yaml:"user_displayname_attribute" env:"LDAP_USER_SCHEMA_DISPLAY_NAME;GRAPH_LDAP_USER_DISPLAYNAME_ATTRIBUTE" desc:"LDAP Attribute to use for the displayname of users."`
|
||||
UserNameAttribute string `yaml:"user_name_attribute" env:"LDAP_USER_SCHEMA_USERNAME;GRAPH_LDAP_USER_NAME_ATTRIBUTE" desc:"LDAP Attribute to use for username of users."`
|
||||
UserIDAttribute string `yaml:"user_id_attribute" env:"LDAP_USER_SCHEMA_ID;GRAPH_LDAP_USER_UID_ATTRIBUTE" desc:"LDAP Attribute to use as the unique ID for users. This should be a stable globally unique ID like a UUID."`
|
||||
UserTypeAttribute string `yaml:"user_type_attribute" env:"LDAP_USER_SCHEMA_USER_TYPE;GRAPH_LDAP_USER_TYPE_ATTRIBUTE" desc:"LDAP Attribute to distinguish between 'Member' and 'Guest' users."`
|
||||
UserEnabledAttribute string `yaml:"user_enabled_attribute" env:"LDAP_USER_ENABLED_ATTRIBUTE;GRAPH_USER_ENABLED_ATTRIBUTE" desc:"LDAP Attribute to use as a flag telling if the user is enabled or disabled."`
|
||||
DisableUserMechanism string `yaml:"disable_user_mechanism" env:"LDAP_DISABLE_USER_MECHANISM;GRAPH_DISABLE_USER_MECHANISM" desc:"An option to control the behavior for disabling users. Supported options are 'none', 'attribute' and 'group'. If set to 'group', disabling a user via API will add the user to the configured group for disabled users, if set to 'attribute' this will be done in the ldap user entry, if set to 'none' the disable request is not processed. Default is 'attribute'."`
|
||||
LdapDisabledUsersGroupDN string `yaml:"ldap_disabled_users_group_dn" env:"LDAP_DISABLED_USERS_GROUP_DN;GRAPH_DISABLED_USERS_GROUP_DN" desc:"The distinguished name of the group to which added users will be classified as disabled when 'disable_user_mechanism' is set to 'group'."`
|
||||
|
||||
@@ -71,6 +71,7 @@ func DefaultConfig() *config.Config {
|
||||
// FIXME: switch this to some more widely available attribute by default
|
||||
// ideally this needs to be constant for the lifetime of a users
|
||||
UserIDAttribute: "owncloudUUID",
|
||||
UserTypeAttribute: "ownCloudUserType",
|
||||
UserEnabledAttribute: "ownCloudUserEnabled",
|
||||
DisableUserMechanism: "attribute",
|
||||
LdapDisabledUsersGroupDN: "cn=DisabledUsersGroup,ou=groups,o=libregraph-idm",
|
||||
|
||||
@@ -77,6 +77,7 @@ type userAttributeMap struct {
|
||||
givenName string
|
||||
surname string
|
||||
accountEnabled string
|
||||
userType string
|
||||
}
|
||||
|
||||
type ldapAttributeValues map[string][]string
|
||||
@@ -105,6 +106,7 @@ func NewLDAPBackend(lc ldap.Client, config config.LDAP, logger *log.Logger) (*LD
|
||||
accountEnabled: config.UserEnabledAttribute,
|
||||
givenName: _givenNameAttribute,
|
||||
surname: _surNameAttribute,
|
||||
userType: config.UserTypeAttribute,
|
||||
}
|
||||
|
||||
if config.GroupNameAttribute == "" || config.GroupIDAttribute == "" {
|
||||
@@ -296,6 +298,12 @@ func (i *LDAP) UpdateUser(ctx context.Context, nameOrID string, user libregraph.
|
||||
updateNeeded = true
|
||||
}
|
||||
}
|
||||
if user.GetUserType() != "" {
|
||||
if e.GetEqualFoldAttributeValue(i.userAttributeMap.userType) != user.GetUserType() {
|
||||
mr.Replace(i.userAttributeMap.userType, []string{user.GetUserType()})
|
||||
updateNeeded = true
|
||||
}
|
||||
}
|
||||
if user.PasswordProfile != nil && user.PasswordProfile.GetPassword() != "" {
|
||||
if i.usePwModifyExOp {
|
||||
if err := i.updateUserPassowrd(ctx, e.DN, user.PasswordProfile.GetPassword()); err != nil {
|
||||
@@ -372,6 +380,7 @@ func (i *LDAP) getUserByDN(dn string) (*ldap.Entry, error) {
|
||||
i.userAttributeMap.surname,
|
||||
i.userAttributeMap.givenName,
|
||||
i.userAttributeMap.accountEnabled,
|
||||
i.userAttributeMap.userType,
|
||||
}
|
||||
|
||||
filter := fmt.Sprintf("(objectClass=%s)", i.userObjectClass)
|
||||
@@ -469,6 +478,7 @@ func (i *LDAP) getLDAPUserByFilter(filter string) (*ldap.Entry, error) {
|
||||
i.userAttributeMap.surname,
|
||||
i.userAttributeMap.givenName,
|
||||
i.userAttributeMap.accountEnabled,
|
||||
i.userAttributeMap.userType,
|
||||
}
|
||||
return i.searchLDAPEntryByFilter(i.userBaseDN, attrs, filter)
|
||||
}
|
||||
@@ -707,6 +717,7 @@ func (i *LDAP) createUserModelFromLDAP(e *ldap.Entry) *libregraph.User {
|
||||
id := e.GetEqualFoldAttributeValue(i.userAttributeMap.id)
|
||||
givenName := e.GetEqualFoldAttributeValue(i.userAttributeMap.givenName)
|
||||
surname := e.GetEqualFoldAttributeValue(i.userAttributeMap.surname)
|
||||
userType := e.GetEqualFoldAttributeValue(i.userAttributeMap.userType)
|
||||
|
||||
if id != "" && opsan != "" {
|
||||
return &libregraph.User{
|
||||
@@ -716,6 +727,7 @@ func (i *LDAP) createUserModelFromLDAP(e *ldap.Entry) *libregraph.User {
|
||||
Id: &id,
|
||||
GivenName: &givenName,
|
||||
Surname: &surname,
|
||||
UserType: &userType,
|
||||
AccountEnabled: booleanOrNil(e.GetEqualFoldAttributeValue(i.userAttributeMap.accountEnabled)),
|
||||
}
|
||||
}
|
||||
@@ -730,6 +742,7 @@ func (i *LDAP) userToLDAPAttrValues(user libregraph.User) (map[string][]string,
|
||||
i.userAttributeMap.mail: {user.GetMail()},
|
||||
"objectClass": {"inetOrgPerson", "organizationalPerson", "person", "top", "ownCloudUser"},
|
||||
"cn": {user.GetOnPremisesSamAccountName()},
|
||||
i.userAttributeMap.userType: {user.GetUserType()},
|
||||
}
|
||||
|
||||
if !i.useServerUUID {
|
||||
@@ -778,6 +791,7 @@ func (i *LDAP) getUserAttrTypes() []string {
|
||||
"owncloudUUID",
|
||||
"userPassword",
|
||||
i.userAttributeMap.accountEnabled,
|
||||
i.userAttributeMap.userType,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -275,7 +275,7 @@ func TestGetEducationClassMembers(t *testing.T) {
|
||||
Scope: 0,
|
||||
SizeLimit: 1,
|
||||
Filter: "(objectClass=inetOrgPerson)",
|
||||
Attributes: []string{"displayname", "entryUUID", "mail", "uid", "sn", "givenname", "userEnabledAttribute"},
|
||||
Attributes: []string{"displayname", "entryUUID", "mail", "uid", "sn", "givenname", "userEnabledAttribute", "userTypeAttribute"},
|
||||
Controls: []ldap.Control(nil),
|
||||
}
|
||||
lm.On("Search", user_sr).Return(&ldap.SearchResult{Entries: []*ldap.Entry{userEntry}}, nil)
|
||||
|
||||
@@ -22,6 +22,7 @@ var eduConfig = config.LDAP{
|
||||
UserEmailAttribute: "mail",
|
||||
UserNameAttribute: "uid",
|
||||
UserEnabledAttribute: "userEnabledAttribute",
|
||||
UserTypeAttribute: "userTypeAttribute",
|
||||
|
||||
GroupBaseDN: "ou=groups,dc=test",
|
||||
GroupObjectClass: "groupOfNames",
|
||||
|
||||
@@ -133,6 +133,12 @@ func (i *LDAP) UpdateEducationUser(ctx context.Context, nameOrID string, user li
|
||||
updateNeeded = true
|
||||
}
|
||||
}
|
||||
if user.GetUserType() != "" {
|
||||
if e.GetEqualFoldAttributeValue(i.userAttributeMap.userType) != user.GetUserType() {
|
||||
mr.Replace(i.userAttributeMap.userType, []string{user.GetUserType()})
|
||||
updateNeeded = true
|
||||
}
|
||||
}
|
||||
if user.PasswordProfile != nil && user.PasswordProfile.GetPassword() != "" {
|
||||
if i.usePwModifyExOp {
|
||||
if err := i.updateUserPassowrd(ctx, e.DN, user.PasswordProfile.GetPassword()); err != nil {
|
||||
@@ -250,6 +256,8 @@ func (i *LDAP) educationUserToUser(eduUser libregraph.EducationUser) *libregraph
|
||||
user.GivenName = eduUser.GivenName
|
||||
user.DisplayName = eduUser.DisplayName
|
||||
user.Mail = eduUser.Mail
|
||||
user.UserType = eduUser.UserType
|
||||
|
||||
return user
|
||||
}
|
||||
|
||||
@@ -262,6 +270,7 @@ func (i *LDAP) userToEducationUser(user libregraph.User, e *ldap.Entry) *libregr
|
||||
eduUser.GivenName = user.GivenName
|
||||
eduUser.DisplayName = user.DisplayName
|
||||
eduUser.Mail = user.Mail
|
||||
eduUser.UserType = user.UserType
|
||||
|
||||
if e != nil {
|
||||
// Set the education User specific Attributes from the supplied LDAP Entry
|
||||
@@ -345,6 +354,7 @@ func (i *LDAP) getEducationUserAttrTypes() []string {
|
||||
i.userAttributeMap.surname,
|
||||
i.userAttributeMap.givenName,
|
||||
i.userAttributeMap.accountEnabled,
|
||||
i.userAttributeMap.userType,
|
||||
i.educationConfig.userAttributeMap.identities,
|
||||
i.educationConfig.userAttributeMap.primaryRole,
|
||||
i.educationConfig.memberOfSchoolAttribute,
|
||||
|
||||
@@ -11,7 +11,19 @@ import (
|
||||
"github.com/test-go/testify/mock"
|
||||
)
|
||||
|
||||
var eduUserAttrs = []string{"displayname", "entryUUID", "mail", "uid", "sn", "givenname", "userEnabledAttribute", "oCExternalIdentity", "userClass", "ocMemberOfSchool"}
|
||||
var eduUserAttrs = []string{
|
||||
"displayname",
|
||||
"entryUUID",
|
||||
"mail",
|
||||
"uid",
|
||||
"sn",
|
||||
"givenname",
|
||||
"userEnabledAttribute",
|
||||
"userTypeAttribute",
|
||||
"oCExternalIdentity",
|
||||
"userClass",
|
||||
"ocMemberOfSchool",
|
||||
}
|
||||
|
||||
var eduUserEntry = ldap.NewEntry("uid=user,ou=people,dc=test",
|
||||
map[string][]string{
|
||||
@@ -24,6 +36,7 @@ var eduUserEntry = ldap.NewEntry("uid=user,ou=people,dc=test",
|
||||
"$ http://idp $ testuser",
|
||||
"xxx $ http://idpnew $ xxxxx-xxxxx-xxxxx",
|
||||
},
|
||||
"userTypeAttribute": {"Member"},
|
||||
})
|
||||
var renamedEduUserEntry = ldap.NewEntry("uid=newtestuser,ou=people,dc=test",
|
||||
map[string][]string{
|
||||
@@ -36,6 +49,7 @@ var renamedEduUserEntry = ldap.NewEntry("uid=newtestuser,ou=people,dc=test",
|
||||
"$ http://idp $ testuser",
|
||||
"xxx $ http://idpnew $ xxxxx-xxxxx-xxxxx",
|
||||
},
|
||||
"userTypeAttribute": {"Guest"},
|
||||
})
|
||||
var eduUserEntryWithSchool = ldap.NewEntry("uid=user,ou=people,dc=test",
|
||||
map[string][]string{
|
||||
@@ -88,6 +102,7 @@ func TestCreateEducationUser(t *testing.T) {
|
||||
user.SetOnPremisesSamAccountName("testuser")
|
||||
user.SetMail("testuser@example.org")
|
||||
user.SetPrimaryRole("student")
|
||||
user.SetUserType(("Member"))
|
||||
eduUser, err := b.CreateEducationUser(context.Background(), *user)
|
||||
lm.AssertNumberOfCalls(t, "Add", 1)
|
||||
lm.AssertNumberOfCalls(t, "Search", 1)
|
||||
@@ -97,6 +112,7 @@ func TestCreateEducationUser(t *testing.T) {
|
||||
assert.Equal(t, eduUser.GetOnPremisesSamAccountName(), user.GetOnPremisesSamAccountName())
|
||||
assert.Equal(t, "abcd-defg", eduUser.GetId())
|
||||
assert.Equal(t, eduUser.GetPrimaryRole(), user.GetPrimaryRole())
|
||||
assert.Equal(t, eduUser.GetUserType(), user.GetUserType())
|
||||
}
|
||||
|
||||
func TestDeleteEducationUser(t *testing.T) {
|
||||
@@ -174,7 +190,7 @@ func TestUpdateEducationUser(t *testing.T) {
|
||||
Scope: 0,
|
||||
SizeLimit: 1,
|
||||
Filter: "(objectClass=inetOrgPerson)",
|
||||
Attributes: []string{"displayname", "entryUUID", "mail", "uid", "sn", "givenname", "userEnabledAttribute"},
|
||||
Attributes: []string{"displayname", "entryUUID", "mail", "uid", "sn", "givenname", "userEnabledAttribute", "userTypeAttribute"},
|
||||
}
|
||||
eduUserLookupReq := &ldap.SearchRequest{
|
||||
BaseDN: "uid=newtestuser,ou=people,dc=test",
|
||||
@@ -249,4 +265,5 @@ func TestUpdateEducationUser(t *testing.T) {
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, eduUser.GetOnPremisesSamAccountName(), "newtestuser")
|
||||
assert.Equal(t, "abcd-defg", eduUser.GetId())
|
||||
assert.Equal(t, "Guest", eduUser.GetUserType())
|
||||
}
|
||||
|
||||
@@ -100,14 +100,14 @@ func TestGetGroup(t *testing.T) {
|
||||
BaseDN: "uid=user,ou=people,dc=test",
|
||||
SizeLimit: 1,
|
||||
Filter: "(objectClass=inetOrgPerson)",
|
||||
Attributes: []string{"displayname", "entryUUID", "mail", "uid", "sn", "givenname", "userEnabledAttribute"},
|
||||
Attributes: []string{"displayname", "entryUUID", "mail", "uid", "sn", "givenname", "userEnabledAttribute", "userTypeAttribute"},
|
||||
Controls: []ldap.Control(nil),
|
||||
}
|
||||
sr3 := &ldap.SearchRequest{
|
||||
BaseDN: "uid=invalid,ou=people,dc=test",
|
||||
SizeLimit: 1,
|
||||
Filter: "(objectClass=inetOrgPerson)",
|
||||
Attributes: []string{"displayname", "entryUUID", "mail", "uid", "sn", "givenname", "userEnabledAttribute"},
|
||||
Attributes: []string{"displayname", "entryUUID", "mail", "uid", "sn", "givenname", "userEnabledAttribute", "userTypeAttribute"},
|
||||
Controls: []ldap.Control(nil),
|
||||
}
|
||||
|
||||
@@ -195,14 +195,14 @@ func TestGetGroups(t *testing.T) {
|
||||
BaseDN: "uid=user,ou=people,dc=test",
|
||||
SizeLimit: 1,
|
||||
Filter: "(objectClass=inetOrgPerson)",
|
||||
Attributes: []string{"displayname", "entryUUID", "mail", "uid", "sn", "givenname", "userEnabledAttribute"},
|
||||
Attributes: []string{"displayname", "entryUUID", "mail", "uid", "sn", "givenname", "userEnabledAttribute", "userTypeAttribute"},
|
||||
Controls: []ldap.Control(nil),
|
||||
}
|
||||
sr3 := &ldap.SearchRequest{
|
||||
BaseDN: "uid=invalid,ou=people,dc=test",
|
||||
SizeLimit: 1,
|
||||
Filter: "(objectClass=inetOrgPerson)",
|
||||
Attributes: []string{"displayname", "entryUUID", "mail", "uid", "sn", "givenname", "userEnabledAttribute"},
|
||||
Attributes: []string{"displayname", "entryUUID", "mail", "uid", "sn", "givenname", "userEnabledAttribute", "userTypeAttribute"},
|
||||
Controls: []ldap.Control(nil),
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ var lconfig = config.LDAP{
|
||||
UserEmailAttribute: "mail",
|
||||
UserNameAttribute: "uid",
|
||||
UserEnabledAttribute: "userEnabledAttribute",
|
||||
UserTypeAttribute: "userTypeAttribute",
|
||||
LdapDisabledUsersGroupDN: disableUsersGroup,
|
||||
DisableUserMechanism: "attribute",
|
||||
|
||||
@@ -58,6 +59,7 @@ var userEntry = ldap.NewEntry("uid=user",
|
||||
"sn": {"surname"},
|
||||
"givenname": {"givenName"},
|
||||
"userenabledattribute": {"TRUE"},
|
||||
"usertypeattribute": {"Member"},
|
||||
})
|
||||
|
||||
var invalidUserEntry = ldap.NewEntry("uid=user",
|
||||
@@ -107,6 +109,7 @@ func TestCreateUser(t *testing.T) {
|
||||
userName := "user"
|
||||
surname := "surname"
|
||||
givenName := "givenName"
|
||||
userType := "Member"
|
||||
|
||||
ar := ldap.NewAddRequest(fmt.Sprintf("uid=user,%s", lconfig.UserBaseDN), nil)
|
||||
ar.Attribute(lconfig.UserDisplayNameAttribute, []string{displayName})
|
||||
@@ -117,6 +120,7 @@ func TestCreateUser(t *testing.T) {
|
||||
ar.Attribute("objectClass", []string{"inetOrgPerson", "organizationalPerson", "person", "top", "ownCloudUser"})
|
||||
ar.Attribute("cn", []string{userName})
|
||||
ar.Attribute(lconfig.UserEnabledAttribute, []string{"TRUE"})
|
||||
ar.Attribute(lconfig.UserTypeAttribute, []string{"Member"})
|
||||
|
||||
l := &mocks.Client{}
|
||||
l.On("Search", mock.Anything).
|
||||
@@ -135,6 +139,7 @@ func TestCreateUser(t *testing.T) {
|
||||
user.SetSurname(surname)
|
||||
user.SetGivenName(givenName)
|
||||
user.SetAccountEnabled(true)
|
||||
user.SetUserType(userType)
|
||||
|
||||
c := lconfig
|
||||
c.UseServerUUID = true
|
||||
@@ -148,6 +153,7 @@ func TestCreateUser(t *testing.T) {
|
||||
assert.Equal(t, givenName, newUser.GetGivenName())
|
||||
assert.Equal(t, surname, newUser.GetSurname())
|
||||
assert.True(t, newUser.GetAccountEnabled())
|
||||
assert.Equal(t, userType, newUser.GetUserType())
|
||||
}
|
||||
|
||||
func TestCreateUserModelFromLDAP(t *testing.T) {
|
||||
@@ -301,6 +307,7 @@ func TestUpdateUser(t *testing.T) {
|
||||
displayName string
|
||||
onPremisesSamAccountName string
|
||||
accountEnabled *bool
|
||||
userType string
|
||||
}
|
||||
type args struct {
|
||||
nameOrID string
|
||||
@@ -340,7 +347,7 @@ func TestUpdateUser(t *testing.T) {
|
||||
ldap.ScopeWholeSubtree,
|
||||
ldap.NeverDerefAliases, 1, 0, false,
|
||||
"(&(objectClass=inetOrgPerson)(|(uid=testUser)(entryUUID=testUser)))",
|
||||
[]string{"displayname", "entryUUID", "mail", "uid", "sn", "givenname", "userEnabledAttribute"},
|
||||
[]string{"displayname", "entryUUID", "mail", "uid", "sn", "givenname", "userEnabledAttribute", "userTypeAttribute"},
|
||||
nil,
|
||||
),
|
||||
},
|
||||
@@ -384,7 +391,7 @@ func TestUpdateUser(t *testing.T) {
|
||||
ldap.ScopeWholeSubtree,
|
||||
ldap.NeverDerefAliases, 1, 0, false,
|
||||
"(&(objectClass=inetOrgPerson)(|(uid=testUser)(entryUUID=testUser)))",
|
||||
[]string{"displayname", "entryUUID", "mail", "uid", "sn", "givenname", "userEnabledAttribute"},
|
||||
[]string{"displayname", "entryUUID", "mail", "uid", "sn", "givenname", "userEnabledAttribute", "userTypeAttribute"},
|
||||
nil,
|
||||
),
|
||||
},
|
||||
@@ -428,7 +435,7 @@ func TestUpdateUser(t *testing.T) {
|
||||
TimeLimit: 0,
|
||||
TypesOnly: false,
|
||||
Filter: "(objectClass=inetOrgPerson)",
|
||||
Attributes: []string{"displayname", "entryUUID", "mail", "uid", "sn", "givenname", "userEnabledAttribute"},
|
||||
Attributes: []string{"displayname", "entryUUID", "mail", "uid", "sn", "givenname", "userEnabledAttribute", "userTypeAttribute"},
|
||||
Controls: []ldap.Control(nil),
|
||||
},
|
||||
},
|
||||
@@ -513,7 +520,7 @@ func TestUpdateUser(t *testing.T) {
|
||||
ldap.ScopeWholeSubtree,
|
||||
ldap.NeverDerefAliases, 1, 0, false,
|
||||
"(&(objectClass=inetOrgPerson)(|(uid=testUser)(entryUUID=testUser)))",
|
||||
[]string{"displayname", "entryUUID", "mail", "uid", "sn", "givenname", "userEnabledAttribute"},
|
||||
[]string{"displayname", "entryUUID", "mail", "uid", "sn", "givenname", "userEnabledAttribute", "userTypeAttribute"},
|
||||
nil,
|
||||
),
|
||||
},
|
||||
@@ -557,7 +564,7 @@ func TestUpdateUser(t *testing.T) {
|
||||
TimeLimit: 0,
|
||||
TypesOnly: false,
|
||||
Filter: "(objectClass=inetOrgPerson)",
|
||||
Attributes: []string{"displayname", "entryUUID", "mail", "uid", "sn", "givenname", "userEnabledAttribute"},
|
||||
Attributes: []string{"displayname", "entryUUID", "mail", "uid", "sn", "givenname", "userEnabledAttribute", "userTypeAttribute"},
|
||||
Controls: []ldap.Control(nil),
|
||||
},
|
||||
},
|
||||
@@ -642,7 +649,7 @@ func TestUpdateUser(t *testing.T) {
|
||||
ldap.ScopeWholeSubtree,
|
||||
ldap.NeverDerefAliases, 1, 0, false,
|
||||
"(&(objectClass=inetOrgPerson)(|(uid=testUser)(entryUUID=testUser)))",
|
||||
[]string{"displayname", "entryUUID", "mail", "uid", "sn", "givenname", "userEnabledAttribute"},
|
||||
[]string{"displayname", "entryUUID", "mail", "uid", "sn", "givenname", "userEnabledAttribute", "userTypeAttribute"},
|
||||
nil,
|
||||
),
|
||||
},
|
||||
@@ -738,7 +745,7 @@ func TestUpdateUser(t *testing.T) {
|
||||
TimeLimit: 0,
|
||||
TypesOnly: false,
|
||||
Filter: "(objectClass=inetOrgPerson)",
|
||||
Attributes: []string{"displayname", "entryUUID", "mail", "uid", "sn", "givenname", "userEnabledAttribute"},
|
||||
Attributes: []string{"displayname", "entryUUID", "mail", "uid", "sn", "givenname", "userEnabledAttribute", "userTypeAttribute"},
|
||||
Controls: []ldap.Control(nil),
|
||||
},
|
||||
},
|
||||
@@ -831,7 +838,7 @@ func TestUpdateUser(t *testing.T) {
|
||||
ldap.ScopeWholeSubtree,
|
||||
ldap.NeverDerefAliases, 1, 0, false,
|
||||
"(&(objectClass=inetOrgPerson)(|(uid=testUser)(entryUUID=testUser)))",
|
||||
[]string{"displayname", "entryUUID", "mail", "uid", "sn", "givenname", "userEnabledAttribute"},
|
||||
[]string{"displayname", "entryUUID", "mail", "uid", "sn", "givenname", "userEnabledAttribute", "userTypeAttribute"},
|
||||
nil,
|
||||
),
|
||||
},
|
||||
@@ -875,7 +882,7 @@ func TestUpdateUser(t *testing.T) {
|
||||
TimeLimit: 0,
|
||||
TypesOnly: false,
|
||||
Filter: "(objectClass=inetOrgPerson)",
|
||||
Attributes: []string{"displayname", "entryUUID", "mail", "uid", "sn", "givenname", "userEnabledAttribute"},
|
||||
Attributes: []string{"displayname", "entryUUID", "mail", "uid", "sn", "givenname", "userEnabledAttribute", "userTypeAttribute"},
|
||||
Controls: []ldap.Control(nil),
|
||||
},
|
||||
},
|
||||
@@ -961,7 +968,7 @@ func TestUpdateUser(t *testing.T) {
|
||||
ldap.ScopeWholeSubtree,
|
||||
ldap.NeverDerefAliases, 1, 0, false,
|
||||
"(&(objectClass=inetOrgPerson)(|(uid=testUser)(entryUUID=testUser)))",
|
||||
[]string{"displayname", "entryUUID", "mail", "uid", "sn", "givenname", "userEnabledAttribute"},
|
||||
[]string{"displayname", "entryUUID", "mail", "uid", "sn", "givenname", "userEnabledAttribute", "userTypeAttribute"},
|
||||
nil,
|
||||
),
|
||||
},
|
||||
@@ -1064,7 +1071,7 @@ func TestUpdateUser(t *testing.T) {
|
||||
ldap.ScopeBaseObject,
|
||||
ldap.NeverDerefAliases, 1, 0, false,
|
||||
"(objectClass=inetOrgPerson)",
|
||||
[]string{"displayname", "entryUUID", "mail", "uid", "sn", "givenname", "userEnabledAttribute"},
|
||||
[]string{"displayname", "entryUUID", "mail", "uid", "sn", "givenname", "userEnabledAttribute", "userTypeAttribute"},
|
||||
[]ldap.Control(nil),
|
||||
),
|
||||
},
|
||||
@@ -1127,7 +1134,7 @@ func TestUpdateUser(t *testing.T) {
|
||||
ldap.ScopeWholeSubtree,
|
||||
ldap.NeverDerefAliases, 1, 0, false,
|
||||
"(&(objectClass=inetOrgPerson)(|(uid=testUser)(entryUUID=testUser)))",
|
||||
[]string{"displayname", "entryUUID", "mail", "uid", "sn", "givenname", "userEnabledAttribute"},
|
||||
[]string{"displayname", "entryUUID", "mail", "uid", "sn", "givenname", "userEnabledAttribute", "userTypeAttribute"},
|
||||
nil,
|
||||
),
|
||||
},
|
||||
@@ -1230,7 +1237,7 @@ func TestUpdateUser(t *testing.T) {
|
||||
ldap.ScopeBaseObject,
|
||||
ldap.NeverDerefAliases, 1, 0, false,
|
||||
"(objectClass=inetOrgPerson)",
|
||||
[]string{"displayname", "entryUUID", "mail", "uid", "sn", "givenname", "userEnabledAttribute"},
|
||||
[]string{"displayname", "entryUUID", "mail", "uid", "sn", "givenname", "userEnabledAttribute", "userTypeAttribute"},
|
||||
[]ldap.Control(nil),
|
||||
),
|
||||
},
|
||||
@@ -1265,6 +1272,144 @@ func TestUpdateUser(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Test changing userType",
|
||||
args: args{
|
||||
nameOrID: "testUser",
|
||||
userProps: userProps{
|
||||
userType: "Member",
|
||||
},
|
||||
disableUserMechanism: "group",
|
||||
},
|
||||
want: &userProps{
|
||||
id: "testUser",
|
||||
mail: "testuser@example.org",
|
||||
displayName: "testUser",
|
||||
onPremisesSamAccountName: "testUser",
|
||||
userType: "Member",
|
||||
},
|
||||
assertion: func(t assert.TestingT, err error, args ...interface{}) bool {
|
||||
return assert.Nil(t, err, args...)
|
||||
},
|
||||
ldapMocks: []mockInputs{
|
||||
{
|
||||
funcName: "Search",
|
||||
args: []interface{}{
|
||||
ldap.NewSearchRequest(
|
||||
"ou=people,dc=test",
|
||||
ldap.ScopeWholeSubtree,
|
||||
ldap.NeverDerefAliases, 1, 0, false,
|
||||
"(&(objectClass=inetOrgPerson)(|(uid=testUser)(entryUUID=testUser)))",
|
||||
[]string{"displayname", "entryUUID", "mail", "uid", "sn", "givenname", "userEnabledAttribute", "userTypeAttribute"},
|
||||
nil,
|
||||
),
|
||||
},
|
||||
returns: []interface{}{
|
||||
&ldap.SearchResult{
|
||||
Entries: []*ldap.Entry{
|
||||
{
|
||||
DN: "uid=name",
|
||||
Attributes: []*ldap.EntryAttribute{
|
||||
{
|
||||
Name: "displayname",
|
||||
Values: []string{"testuser@example.org"},
|
||||
},
|
||||
{
|
||||
Name: "entryUUID",
|
||||
Values: []string{"testUser"},
|
||||
},
|
||||
{
|
||||
Name: "mail",
|
||||
Values: []string{"testuser@example.org"},
|
||||
},
|
||||
{
|
||||
Name: lconfig.UserTypeAttribute,
|
||||
Values: []string{"Guest"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
nil,
|
||||
},
|
||||
},
|
||||
{
|
||||
funcName: "Modify",
|
||||
args: []interface{}{
|
||||
&ldap.ModifyRequest{
|
||||
DN: "uid=name",
|
||||
Changes: []ldap.Change{
|
||||
{
|
||||
Operation: ldap.ReplaceAttribute,
|
||||
Modification: ldap.PartialAttribute{
|
||||
Type: "userTypeAttribute",
|
||||
Vals: []string{"Member"},
|
||||
},
|
||||
},
|
||||
},
|
||||
Controls: []ldap.Control(nil),
|
||||
},
|
||||
},
|
||||
returns: []interface{}{nil},
|
||||
},
|
||||
{
|
||||
funcName: "Modify",
|
||||
args: []interface{}{
|
||||
&ldap.ModifyRequest{
|
||||
DN: "uid=name",
|
||||
Changes: []ldap.Change(nil),
|
||||
Controls: []ldap.Control(nil),
|
||||
},
|
||||
},
|
||||
returns: []interface{}{nil},
|
||||
},
|
||||
{
|
||||
funcName: "Search",
|
||||
args: []interface{}{
|
||||
ldap.NewSearchRequest(
|
||||
"uid=name",
|
||||
ldap.ScopeBaseObject,
|
||||
ldap.NeverDerefAliases, 1, 0, false,
|
||||
"(objectClass=inetOrgPerson)",
|
||||
[]string{"displayname", "entryUUID", "mail", "uid", "sn", "givenname", "userEnabledAttribute", "userTypeAttribute"},
|
||||
[]ldap.Control(nil),
|
||||
),
|
||||
},
|
||||
returns: []interface{}{
|
||||
&ldap.SearchResult{
|
||||
Entries: []*ldap.Entry{
|
||||
{
|
||||
DN: "uid=name",
|
||||
Attributes: []*ldap.EntryAttribute{
|
||||
{
|
||||
Name: "uid",
|
||||
Values: []string{"testUser"},
|
||||
},
|
||||
{
|
||||
Name: "displayname",
|
||||
Values: []string{"testUser"},
|
||||
},
|
||||
{
|
||||
Name: "entryUUID",
|
||||
Values: []string{"testUser"},
|
||||
},
|
||||
{
|
||||
Name: "mail",
|
||||
Values: []string{"testuser@example.org"},
|
||||
},
|
||||
{
|
||||
Name: lconfig.UserTypeAttribute,
|
||||
Values: []string{"Member"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
nil,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
@@ -1283,6 +1428,7 @@ func TestUpdateUser(t *testing.T) {
|
||||
DisplayName: &tt.args.userProps.displayName,
|
||||
OnPremisesSamAccountName: &tt.args.userProps.onPremisesSamAccountName,
|
||||
AccountEnabled: tt.args.userProps.accountEnabled,
|
||||
UserType: &tt.args.userProps.userType,
|
||||
}
|
||||
|
||||
emptyString := ""
|
||||
@@ -1295,6 +1441,7 @@ func TestUpdateUser(t *testing.T) {
|
||||
OnPremisesSamAccountName: &tt.want.onPremisesSamAccountName,
|
||||
Surname: &emptyString,
|
||||
GivenName: &emptyString,
|
||||
UserType: &tt.want.userType,
|
||||
}
|
||||
|
||||
if tt.want.accountEnabled != nil {
|
||||
|
||||
@@ -132,6 +132,16 @@ func (g Graph) PostEducationUser(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if u.HasUserType() {
|
||||
if !isValidUserType(*u.UserType) {
|
||||
logger.Debug().Interface("user", u).Msg("invalid userType attribute")
|
||||
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "invalid userType attribute, valid options are 'Member' or 'Guest'")
|
||||
return
|
||||
}
|
||||
} else {
|
||||
u.SetUserType("Member")
|
||||
}
|
||||
|
||||
if _, ok := u.GetPrimaryRoleOk(); !ok {
|
||||
logger.Debug().Err(err).Interface("user", u).Msg("could not create education user: missing required Attribute: 'primaryRole'")
|
||||
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "missing required Attribute: 'primaryRole'")
|
||||
@@ -368,6 +378,14 @@ func (g Graph) PatchEducationUser(w http.ResponseWriter, r *http.Request) {
|
||||
features = append(features, events.UserFeature{Name: "displayname", Value: *name})
|
||||
}
|
||||
|
||||
if changes.HasUserType() {
|
||||
if !isValidUserType(*changes.UserType) {
|
||||
logger.Debug().Interface("user", changes).Msg("invalid userType attribute")
|
||||
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "invalid userType attribute, valid options are 'Member' or 'Guest'")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
logger.Debug().Str("nameid", nameOrID).Interface("changes", *changes).Msg("calling update education user on backend")
|
||||
u, err := g.identityEducationBackend.UpdateEducationUser(r.Context(), nameOrID, *changes)
|
||||
if err != nil {
|
||||
|
||||
@@ -297,7 +297,65 @@ var _ = Describe("EducationUsers", func() {
|
||||
svc.PostEducationUser(rr, r)
|
||||
|
||||
Expect(rr.Code).To(Equal(http.StatusOK))
|
||||
data, err := io.ReadAll(rr.Body)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
createdUser := libregraph.EducationUser{}
|
||||
err = json.Unmarshal(data, &createdUser)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(createdUser.GetUserType()).To(Equal("Member"))
|
||||
})
|
||||
|
||||
It("creates a guest user", func() {
|
||||
roleService.On("AssignRoleToUser", mock.Anything, mock.Anything).Return(&settingssvc.AssignRoleToUserResponse{}, nil)
|
||||
identityEducationBackend.On("CreateEducationUser", mock.Anything, mock.Anything).Return(func(ctx context.Context, user libregraph.EducationUser) *libregraph.EducationUser {
|
||||
user.SetId("/users/user")
|
||||
return &user
|
||||
}, nil)
|
||||
|
||||
user.SetUserType("Guest")
|
||||
userJson, err := json.Marshal(user)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
r := httptest.NewRequest(http.MethodPost, "/graph/v1.0/education/users", bytes.NewBuffer(userJson))
|
||||
r = r.WithContext(revactx.ContextSetUser(ctx, currentUser))
|
||||
svc.PostEducationUser(rr, r)
|
||||
|
||||
Expect(rr.Code).To(Equal(http.StatusOK))
|
||||
data, err := io.ReadAll(rr.Body)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
createdUser := libregraph.EducationUser{}
|
||||
err = json.Unmarshal(data, &createdUser)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(createdUser.GetUserType()).To(Equal("Guest"))
|
||||
})
|
||||
|
||||
It("creates a member user", func() {
|
||||
roleService.On("AssignRoleToUser", mock.Anything, mock.Anything).Return(&settingssvc.AssignRoleToUserResponse{}, nil)
|
||||
identityEducationBackend.On("CreateEducationUser", mock.Anything, mock.Anything).Return(func(ctx context.Context, user libregraph.EducationUser) *libregraph.EducationUser {
|
||||
user.SetId("/users/user")
|
||||
return &user
|
||||
}, nil)
|
||||
|
||||
user.SetUserType("Member")
|
||||
userJson, err := json.Marshal(user)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
r := httptest.NewRequest(http.MethodPost, "/graph/v1.0/education/users", bytes.NewBuffer(userJson))
|
||||
r = r.WithContext(revactx.ContextSetUser(ctx, currentUser))
|
||||
svc.PostEducationUser(rr, r)
|
||||
|
||||
Expect(rr.Code).To(Equal(http.StatusOK))
|
||||
data, err := io.ReadAll(rr.Body)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
createdUser := libregraph.EducationUser{}
|
||||
err = json.Unmarshal(data, &createdUser)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(createdUser.GetUserType()).To(Equal("Member"))
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
Describe("DeleteEducationUser", func() {
|
||||
@@ -406,6 +464,20 @@ var _ = Describe("EducationUsers", func() {
|
||||
Expect(rr.Code).To(Equal(http.StatusBadRequest))
|
||||
})
|
||||
|
||||
It("handles invalid userType", func() {
|
||||
user.SetUserType("Clown")
|
||||
data, err := json.Marshal(user)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
r := httptest.NewRequest(http.MethodPost, "/graph/v1.0/education/users?$invalid=true", bytes.NewBuffer(data))
|
||||
rctx := chi.NewRouteContext()
|
||||
rctx.URLParams.Add("userID", user.GetId())
|
||||
r = r.WithContext(context.WithValue(revactx.ContextSetUser(ctx, currentUser), chi.RouteCtxKey, rctx))
|
||||
svc.PatchEducationUser(rr, r)
|
||||
|
||||
Expect(rr.Code).To(Equal(http.StatusBadRequest))
|
||||
})
|
||||
|
||||
It("updates attributes", func() {
|
||||
identityEducationBackend.On("UpdateEducationUser", mock.Anything, user.GetId(), mock.Anything).Return(user, nil)
|
||||
|
||||
|
||||
@@ -305,6 +305,16 @@ func (g Graph) PostUser(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if u.HasUserType() {
|
||||
if !isValidUserType(*u.UserType) {
|
||||
logger.Debug().Interface("user", u).Msg("invalid userType attribute")
|
||||
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "invalid userType attribute, valid options are 'Member' or 'Guest'")
|
||||
return
|
||||
}
|
||||
} else {
|
||||
u.SetUserType("Member")
|
||||
}
|
||||
|
||||
logger.Debug().Interface("user", u).Msg("calling create user on backend")
|
||||
if u, err = g.identityBackend.CreateUser(r.Context(), *u); err != nil {
|
||||
logger.Debug().Err(err).Msg("could not create user: backend error")
|
||||
@@ -652,6 +662,14 @@ func (g Graph) PatchUser(w http.ResponseWriter, r *http.Request) {
|
||||
features = append(features, events.UserFeature{Name: "displayname", Value: *name})
|
||||
}
|
||||
|
||||
if changes.HasUserType() {
|
||||
if !isValidUserType(*changes.UserType) {
|
||||
logger.Debug().Interface("user", changes).Msg("invalid userType attribute")
|
||||
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "invalid userType attribute, valid options are 'Member' or 'Guest'")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
logger.Debug().Str("nameid", nameOrID).Interface("changes", *changes).Msg("calling update user on backend")
|
||||
u, err := g.identityBackend.UpdateUser(r.Context(), nameOrID, *changes)
|
||||
if err != nil {
|
||||
@@ -743,3 +761,15 @@ func sortUsers(req *godata.GoDataRequest, users []*libregraph.User) ([]*libregra
|
||||
}
|
||||
return users, nil
|
||||
}
|
||||
|
||||
func isValidUserType(userType string) bool {
|
||||
userType = strings.ToLower(userType)
|
||||
|
||||
for _, value := range []string{"member", "guest"} {
|
||||
if userType == value {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -588,6 +588,11 @@ var _ = Describe("Users", func() {
|
||||
assertHandleBadAttributes(user)
|
||||
})
|
||||
|
||||
It("handles invalid userType", func() {
|
||||
user.SetUserType("Clown")
|
||||
assertHandleBadAttributes(user)
|
||||
})
|
||||
|
||||
It("creates a user", func() {
|
||||
roleService.On("AssignRoleToUser", mock.Anything, mock.Anything).Return(&settings.AssignRoleToUserResponse{}, nil)
|
||||
identityBackend.On("CreateUser", mock.Anything, mock.Anything).Return(func(ctx context.Context, user libregraph.User) *libregraph.User {
|
||||
@@ -602,6 +607,63 @@ var _ = Describe("Users", func() {
|
||||
svc.PostUser(rr, r)
|
||||
|
||||
Expect(rr.Code).To(Equal(http.StatusOK))
|
||||
data, err := io.ReadAll(rr.Body)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
createdUser := libregraph.User{}
|
||||
err = json.Unmarshal(data, &createdUser)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(createdUser.GetUserType()).To(Equal("Member"))
|
||||
})
|
||||
|
||||
It("creates a guest user", func() {
|
||||
roleService.On("AssignRoleToUser", mock.Anything, mock.Anything).Return(&settings.AssignRoleToUserResponse{}, nil)
|
||||
identityBackend.On("CreateUser", mock.Anything, mock.Anything).Return(func(ctx context.Context, user libregraph.User) *libregraph.User {
|
||||
user.SetId("/users/user")
|
||||
return &user
|
||||
}, nil)
|
||||
|
||||
user.SetUserType("Guest")
|
||||
userJson, err := json.Marshal(user)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
r := httptest.NewRequest(http.MethodPost, "/graph/v1.0/users", bytes.NewBuffer(userJson))
|
||||
r = r.WithContext(revactx.ContextSetUser(ctx, currentUser))
|
||||
svc.PostUser(rr, r)
|
||||
|
||||
Expect(rr.Code).To(Equal(http.StatusOK))
|
||||
data, err := io.ReadAll(rr.Body)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
createdUser := libregraph.User{}
|
||||
err = json.Unmarshal(data, &createdUser)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(createdUser.GetUserType()).To(Equal("Guest"))
|
||||
})
|
||||
|
||||
It("creates a member user", func() {
|
||||
roleService.On("AssignRoleToUser", mock.Anything, mock.Anything).Return(&settings.AssignRoleToUserResponse{}, nil)
|
||||
identityBackend.On("CreateUser", mock.Anything, mock.Anything).Return(func(ctx context.Context, user libregraph.User) *libregraph.User {
|
||||
user.SetId("/users/user")
|
||||
return &user
|
||||
}, nil)
|
||||
|
||||
user.SetUserType("Member")
|
||||
userJson, err := json.Marshal(user)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
r := httptest.NewRequest(http.MethodPost, "/graph/v1.0/users", bytes.NewBuffer(userJson))
|
||||
r = r.WithContext(revactx.ContextSetUser(ctx, currentUser))
|
||||
svc.PostUser(rr, r)
|
||||
|
||||
Expect(rr.Code).To(Equal(http.StatusOK))
|
||||
data, err := io.ReadAll(rr.Body)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
createdUser := libregraph.User{}
|
||||
err = json.Unmarshal(data, &createdUser)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(createdUser.GetUserType()).To(Equal("Member"))
|
||||
})
|
||||
|
||||
Describe("Handling usernames with spaces", func() {
|
||||
@@ -768,9 +830,25 @@ var _ = Describe("Users", func() {
|
||||
Expect(rr.Code).To(Equal(http.StatusBadRequest))
|
||||
})
|
||||
|
||||
It("handles invalid userType", func() {
|
||||
user.SetUserType("Clown")
|
||||
data, err := json.Marshal(user)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
r := httptest.NewRequest(http.MethodPost, "/graph/v1.0/users?$invalid=true", bytes.NewBuffer(data))
|
||||
rctx := chi.NewRouteContext()
|
||||
rctx.URLParams.Add("userID", user.GetId())
|
||||
r = r.WithContext(context.WithValue(revactx.ContextSetUser(ctx, currentUser), chi.RouteCtxKey, rctx))
|
||||
svc.PatchUser(rr, r)
|
||||
|
||||
Expect(rr.Code).To(Equal(http.StatusBadRequest))
|
||||
})
|
||||
|
||||
It("updates attributes", func() {
|
||||
user.SetUserType("Member")
|
||||
identityBackend.On("UpdateUser", mock.Anything, user.GetId(), mock.Anything).Return(user, nil)
|
||||
|
||||
user.SetUserType(("Member"))
|
||||
user.SetDisplayName("New Display Name")
|
||||
data, err := json.Marshal(user)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
@@ -788,6 +866,7 @@ var _ = Describe("Users", func() {
|
||||
updatedUser := libregraph.User{}
|
||||
err = json.Unmarshal(data, &updatedUser)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(updatedUser.GetUserType()).To(Equal("Member"))
|
||||
Expect(updatedUser.GetDisplayName()).To(Equal("New Display Name"))
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user