Add support for removing users from schools

This commit is contained in:
Ralf Haferkamp
2022-12-15 21:02:35 +01:00
committed by Ralf Haferkamp
parent 5095b35822
commit 77ea95535e
4 changed files with 97 additions and 37 deletions
@@ -249,6 +249,7 @@ func (i *LDAP) getEducationUserAttrTypes() []string {
i.userAttributeMap.userName,
i.educationConfig.userAttributeMap.identities,
i.educationConfig.userAttributeMap.primaryRole,
i.educationConfig.memberOfSchoolAttribute,
}
}
@@ -23,13 +23,26 @@ var eduUserEntry = ldap.NewEntry("uid=user,ou=people,dc=test",
"xxx $ http://idpnew $ xxxxx-xxxxx-xxxxx",
},
})
var eduUserEntryWithSchool = ldap.NewEntry("uid=user,ou=people,dc=test",
map[string][]string{
"uid": {"testuser"},
"displayname": {"Test User"},
"mail": {"user@example"},
"entryuuid": {"abcd-defg"},
"userClass": {"student"},
"ocMemberOfSchool": {"abcd-defg"},
"oCExternalIdentity": {
"$ http://idp $ testuser",
"xxx $ http://idpnew $ xxxxx-xxxxx-xxxxx",
},
})
var sr1 *ldap.SearchRequest = &ldap.SearchRequest{
BaseDN: "ou=people,dc=test",
Scope: 2,
SizeLimit: 1,
Filter: "(&(objectClass=ocEducationUser)(|(uid=abcd-defg)(entryUUID=abcd-defg)))",
Attributes: []string{"displayname", "entryUUID", "mail", "uid", "oCExternalIdentity", "userClass"},
Attributes: []string{"displayname", "entryUUID", "mail", "uid", "oCExternalIdentity", "userClass", "ocMemberOfSchool"},
Controls: []ldap.Control(nil),
}
var sr2 *ldap.SearchRequest = &ldap.SearchRequest{
@@ -37,7 +50,7 @@ var sr2 *ldap.SearchRequest = &ldap.SearchRequest{
Scope: 2,
SizeLimit: 1,
Filter: "(&(objectClass=ocEducationUser)(|(uid=xxxx-xxxx)(entryUUID=xxxx-xxxx)))",
Attributes: []string{"displayname", "entryUUID", "mail", "uid", "oCExternalIdentity", "userClass"},
Attributes: []string{"displayname", "entryUUID", "mail", "uid", "oCExternalIdentity", "userClass", "ocMemberOfSchool"},
Controls: []ldap.Control(nil),
}
@@ -120,7 +133,7 @@ func TestGetEducationUsers(t *testing.T) {
Scope: 2,
SizeLimit: 0,
Filter: "(objectClass=ocEducationUser)",
Attributes: []string{"displayname", "entryUUID", "mail", "uid", "oCExternalIdentity", "userClass"},
Attributes: []string{"displayname", "entryUUID", "mail", "uid", "oCExternalIdentity", "userClass", "ocMemberOfSchool"},
Controls: []ldap.Control(nil),
}
lm.On("Search", sr).Return(&ldap.SearchResult{Entries: []*ldap.Entry{eduUserEntry}}, nil)
+30 -3
View File
@@ -256,9 +256,36 @@ func (i *LDAP) AddUsersToEducationSchool(ctx context.Context, schoolID string, m
return nil
}
// RemoveMemberFromEducationSchool removes a single member (by ID) from a school
func (i *LDAP) RemoveMemberFromEducationSchool(ctx context.Context, schoolID string, memberID string) error {
return errNotImplemented
// RemoveUserFromEducationSchool removes a single member (by ID) from a school
func (i *LDAP) RemoveUserFromEducationSchool(ctx context.Context, schoolID string, memberID string) error {
logger := i.logger.SubloggerWithRequestID(ctx)
logger.Debug().Str("backend", "ldap").Msg("RemoveUserFromEducationSchool")
schoolEntry, err := i.getSchoolByID(schoolID)
if err != nil {
return err
}
if schoolEntry == nil {
return errNotFound
}
user, err := i.getEducationUserByNameOrID(memberID)
if err != nil {
i.logger.Warn().Str("userid", memberID).Msg("User does not exist")
return err
}
currentSchools := user.GetEqualFoldAttributeValues(i.educationConfig.memberOfSchoolAttribute)
for _, currentSchool := range currentSchools {
if currentSchool == schoolID {
mr := ldap.ModifyRequest{DN: user.DN}
mr.Delete(i.educationConfig.memberOfSchoolAttribute, []string{schoolID})
if err := i.conn.Modify(&mr); err != nil {
return err
}
break
}
}
return nil
}
func (i *LDAP) getSchoolByDN(dn string) (*ldap.Entry, error) {
+50 -31
View File
@@ -168,45 +168,64 @@ func TestGetEducationSchools(t *testing.T) {
assert.Nil(t, err)
}
func TestAddMembersToEducationSchool(t *testing.T) {
var schoolByIDSearch1 *ldap.SearchRequest = &ldap.SearchRequest{
BaseDN: "",
Scope: 2,
SizeLimit: 1,
Filter: "(&(objectClass=ocEducationSchool)(owncloudUUID=abcd-defg))",
Attributes: []string{"ou", "owncloudUUID", "ocEducationSchoolNumber"},
Controls: []ldap.Control(nil),
}
var userByIDSearch1 *ldap.SearchRequest = &ldap.SearchRequest{
BaseDN: "ou=people,dc=test",
Scope: 2,
SizeLimit: 1,
Filter: "(&(objectClass=ocEducationUser)(|(uid=abcd-defg)(entryUUID=abcd-defg)))",
Attributes: []string{"displayname", "entryUUID", "mail", "uid", "oCExternalIdentity", "userClass", "ocMemberOfSchool"},
Controls: []ldap.Control(nil),
}
var userByIDSearch2 *ldap.SearchRequest = &ldap.SearchRequest{
BaseDN: "ou=people,dc=test",
Scope: 2,
SizeLimit: 1,
Filter: "(&(objectClass=ocEducationUser)(|(uid=does-not-exist)(entryUUID=does-not-exist)))",
Attributes: []string{"displayname", "entryUUID", "mail", "uid", "oCExternalIdentity", "userClass", "ocMemberOfSchool"},
Controls: []ldap.Control(nil),
}
func TestAddUsersToEducationSchool(t *testing.T) {
lm := &mocks.Client{}
sr1 := &ldap.SearchRequest{
BaseDN: "",
Scope: 2,
SizeLimit: 1,
Filter: "(&(objectClass=ocEducationSchool)(owncloudUUID=abcd-defg))",
Attributes: []string{"ou", "owncloudUUID", "ocEducationSchoolNumber"},
Controls: []ldap.Control(nil),
}
sr2 := &ldap.SearchRequest{
BaseDN: "ou=people,dc=test",
Scope: 2,
SizeLimit: 1,
Filter: "(&(objectClass=ocEducationUser)(|(uid=abcd-defg)(entryUUID=abcd-defg)))",
Attributes: []string{"displayname", "entryUUID", "mail", "uid", "oCExternalIdentity", "userClass"},
Controls: []ldap.Control(nil),
}
sr3 := &ldap.SearchRequest{
BaseDN: "ou=people,dc=test",
Scope: 2,
SizeLimit: 1,
Filter: "(&(objectClass=ocEducationUser)(|(uid=does-not-exist)(entryUUID=does-not-exist)))",
Attributes: []string{"displayname", "entryUUID", "mail", "uid", "oCExternalIdentity", "userClass"},
Controls: []ldap.Control(nil),
}
lm.On("Search", sr1).Return(&ldap.SearchResult{Entries: []*ldap.Entry{schoolEntry, schoolEntry1}}, nil)
lm.On("Search", sr2).Return(&ldap.SearchResult{Entries: []*ldap.Entry{eduUserEntry}}, nil)
lm.On("Search", sr3).Return(&ldap.SearchResult{Entries: []*ldap.Entry{}}, nil)
lm.On("Search", schoolByIDSearch1).Return(&ldap.SearchResult{Entries: []*ldap.Entry{schoolEntry, schoolEntry1}}, nil)
lm.On("Search", userByIDSearch1).Return(&ldap.SearchResult{Entries: []*ldap.Entry{eduUserEntry}}, nil)
lm.On("Search", userByIDSearch2).Return(&ldap.SearchResult{Entries: []*ldap.Entry{}}, nil)
lm.On("Modify", mock.Anything).Return(nil)
b, err := getMockedBackend(lm, eduConfig, &logger)
assert.Nil(t, err)
err = b.AddMembersToEducationSchool(context.Background(), "abcd-defg", []string{"does-not-exist"})
err = b.AddUsersToEducationSchool(context.Background(), "abcd-defg", []string{"does-not-exist"})
lm.AssertNumberOfCalls(t, "Search", 2)
assert.NotNil(t, err)
err = b.AddMembersToEducationSchool(context.Background(), "abcd-defg", []string{"abcd-defg", "does-not-exist"})
err = b.AddUsersToEducationSchool(context.Background(), "abcd-defg", []string{"abcd-defg", "does-not-exist"})
lm.AssertNumberOfCalls(t, "Search", 5)
assert.NotNil(t, err)
err = b.AddMembersToEducationSchool(context.Background(), "abcd-defg", []string{"abcd-defg"})
err = b.AddUsersToEducationSchool(context.Background(), "abcd-defg", []string{"abcd-defg"})
lm.AssertNumberOfCalls(t, "Search", 7)
assert.Nil(t, err)
}
func TestRemoveMemberFromEducationSchoo(t *testing.T) {
lm := &mocks.Client{}
lm.On("Search", schoolByIDSearch1).Return(&ldap.SearchResult{Entries: []*ldap.Entry{schoolEntry, schoolEntry1}}, nil)
lm.On("Search", userByIDSearch1).Return(&ldap.SearchResult{Entries: []*ldap.Entry{eduUserEntryWithSchool}}, nil)
lm.On("Search", userByIDSearch2).Return(&ldap.SearchResult{Entries: []*ldap.Entry{}}, nil)
lm.On("Modify", mock.Anything).Return(nil)
b, err := getMockedBackend(lm, eduConfig, &logger)
assert.Nil(t, err)
err = b.RemoveUserFromEducationSchool(context.Background(), "abcd-defg", "does-not-exist")
lm.AssertNumberOfCalls(t, "Search", 2)
assert.NotNil(t, err)
assert.Equal(t, "itemNotFound", err.Error())
err = b.RemoveUserFromEducationSchool(context.Background(), "abcd-defg", "abcd-defg")
lm.AssertNumberOfCalls(t, "Search", 4)
lm.AssertNumberOfCalls(t, "Modify", 1)
assert.Nil(t, err)
}