package identity import ( "context" "testing" "github.com/go-ldap/ldap/v3" libregraph "github.com/opencloud-eu/libre-graph-api-go" "github.com/qsfera/server/services/graph/pkg/identity/mocks" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" ) const peopleBaseDN = "ou=people,dc=test" var eduUserAttrs = []string{ "displayname", "entryUUID", "mail", "uid", "sn", "givenname", "userEnabledAttribute", "userTypeAttribute", "qsferaExternalIdentity", "userClass", "qsferaEducationExternalId", "qsferaMemberOfSchool", } var eduUserEntry = ldap.NewEntry("uid=user,ou=people,dc=test", map[string][]string{ "uid": {"testuser"}, "displayname": {"Test User"}, "mail": {"user@example"}, "entryuuid": {"abcd-defg"}, "userClass": {"student"}, "qsferaExternalIdentity": { "$ http://idp $ testuser", "xxx $ http://idpnew $ xxxxx-xxxxx-xxxxx", }, "userTypeAttribute": {"Member"}, "userEnabledAttribute": {"FALSE"}, }) var renamedEduUserEntry = ldap.NewEntry("uid=newtestuser,ou=people,dc=test", map[string][]string{ "uid": {"newtestuser"}, "displayname": {"Test User"}, "mail": {"user@example"}, "entryuuid": {"abcd-defg"}, "userClass": {"student"}, "qsferaExternalIdentity": { "$ http://idp $ testuser", "xxx $ http://idpnew $ xxxxx-xxxxx-xxxxx", }, "userTypeAttribute": {"Guest"}, "userEnabledAttribute": {"TRUE"}, }) 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"}, "qsferaMemberOfSchool": {"abcd-defg"}, "qsferaExternalIdentity": { "$ http://idp $ testuser", "xxx $ http://idpnew $ xxxxx-xxxxx-xxxxx", }, }) var sr1 *ldap.SearchRequest = &ldap.SearchRequest{ BaseDN: peopleBaseDN, Scope: 2, SizeLimit: 1, Filter: "(&(objectClass=qsferaEducationUser)(|(uid=abcd-defg)(entryUUID=abcd-defg)))", Attributes: eduUserAttrs, Controls: []ldap.Control(nil), } var sr2 *ldap.SearchRequest = &ldap.SearchRequest{ BaseDN: peopleBaseDN, Scope: 2, SizeLimit: 1, Filter: "(&(objectClass=qsferaEducationUser)(|(uid=xxxx-xxxx)(entryUUID=xxxx-xxxx)))", Attributes: eduUserAttrs, Controls: []ldap.Control(nil), } func TestCreateEducationUser(t *testing.T) { lm := &mocks.Client{} b, err := getMockedBackend(lm, eduConfig, &logger) assert.Nil(t, err) //assert.NotEqual(t, "", b.educationConfig.schoolObjectClass) lm.On("Add", mock.Anything).Return(nil) lm.On("Search", mock.Anything). Return( &ldap.SearchResult{ Entries: []*ldap.Entry{ eduUserEntry, }, }, nil) user := libregraph.NewEducationUser() user.SetDisplayName("Test User") user.SetOnPremisesSamAccountName("testuser") user.SetMail("testuser@example.org") user.SetPrimaryRole("student") user.SetUserType(("Member")) user.SetAccountEnabled(false) eduUser, err := b.CreateEducationUser(context.Background(), *user) lm.AssertNumberOfCalls(t, "Add", 1) lm.AssertNumberOfCalls(t, "Search", 1) assert.NotNil(t, eduUser) assert.Nil(t, err) assert.Equal(t, eduUser.GetDisplayName(), user.GetDisplayName()) 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()) assert.Equal(t, eduUser.GetAccountEnabled(), false) } func TestDeleteEducationUser(t *testing.T) { lm := &mocks.Client{} lm.On("Search", sr1).Return(&ldap.SearchResult{Entries: []*ldap.Entry{eduUserEntry}}, nil) lm.On("Search", sr2).Return(&ldap.SearchResult{Entries: []*ldap.Entry{}}, nil) dr1 := &ldap.DelRequest{ DN: "uid=user,ou=people,dc=test", } lm.On("Del", dr1).Return(nil) b, err := getMockedBackend(lm, eduConfig, &logger) assert.Nil(t, err) err = b.DeleteEducationUser(context.Background(), "abcd-defg") lm.AssertNumberOfCalls(t, "Search", 1) lm.AssertNumberOfCalls(t, "Del", 1) assert.Nil(t, err) err = b.DeleteEducationUser(context.Background(), "xxxx-xxxx") lm.AssertNumberOfCalls(t, "Search", 2) lm.AssertNumberOfCalls(t, "Del", 1) assert.NotNil(t, err) assert.Equal(t, "itemNotFound: not found", err.Error()) } func TestGetEducationUser(t *testing.T) { lm := &mocks.Client{} lm.On("Search", sr1).Return(&ldap.SearchResult{Entries: []*ldap.Entry{eduUserEntry}}, nil) lm.On("Search", sr2).Return(&ldap.SearchResult{Entries: []*ldap.Entry{}}, nil) b, err := getMockedBackend(lm, eduConfig, &logger) assert.Nil(t, err) user, err := b.GetEducationUser(context.Background(), "abcd-defg") lm.AssertNumberOfCalls(t, "Search", 1) assert.Nil(t, err) assert.Equal(t, "Test User", user.GetDisplayName()) assert.Equal(t, "abcd-defg", user.GetId()) _, err = b.GetEducationUser(context.Background(), "xxxx-xxxx") lm.AssertNumberOfCalls(t, "Search", 2) assert.NotNil(t, err) assert.Equal(t, "itemNotFound: not found", err.Error()) } func TestGetEducationUsers(t *testing.T) { lm := &mocks.Client{} sr := &ldap.SearchRequest{ BaseDN: peopleBaseDN, Scope: 2, SizeLimit: 0, Filter: "(objectClass=qsferaEducationUser)", Attributes: eduUserAttrs, Controls: []ldap.Control(nil), } lm.On("Search", sr).Return(&ldap.SearchResult{Entries: []*ldap.Entry{eduUserEntry}}, nil) b, err := getMockedBackend(lm, eduConfig, &logger) assert.Nil(t, err) _, err = b.GetEducationUsers(context.Background()) lm.AssertNumberOfCalls(t, "Search", 1) assert.Nil(t, err) } func TestFilterEducationUsersByAttr(t *testing.T) { lm := &mocks.Client{} sr := &ldap.SearchRequest{ BaseDN: peopleBaseDN, Scope: 2, SizeLimit: 0, Filter: "(&(objectClass=qsferaEducationUser)(qsferaEducationExternalId=id1234))", Attributes: eduUserAttrs, Controls: []ldap.Control(nil), } lm.On("Search", sr).Return(&ldap.SearchResult{Entries: []*ldap.Entry{eduUserEntry}}, nil) b, err := getMockedBackend(lm, eduConfig, &logger) assert.Nil(t, err) _, err = b.FilterEducationUsersByAttribute(context.Background(), "externalId", "id1234") lm.AssertNumberOfCalls(t, "Search", 1) assert.Nil(t, err) } func TestUpdateEducationUser(t *testing.T) { lm := &mocks.Client{} b, err := getMockedBackend(lm, eduConfig, &logger) assert.Nil(t, err) userSearchReq := &ldap.SearchRequest{ BaseDN: peopleBaseDN, Scope: 2, SizeLimit: 1, Filter: "(&(objectClass=qsferaEducationUser)(|(uid=testuser)(entryUUID=testuser)))", Attributes: eduUserAttrs, } userLookupReq := &ldap.SearchRequest{ BaseDN: "uid=newtestuser,ou=people,dc=test", Scope: 0, SizeLimit: 1, Filter: "(objectClass=inetOrgPerson)", Attributes: ldapUserAttributes, } eduUserLookupReq := &ldap.SearchRequest{ BaseDN: "uid=newtestuser,ou=people,dc=test", Scope: 0, SizeLimit: 1, Filter: "(objectClass=qsferaEducationUser)", Attributes: eduUserAttrs, } groupSearchReq := &ldap.SearchRequest{ BaseDN: "ou=groups,dc=test", Scope: 2, Filter: "(&(objectClass=groupOfNames)(member=uid=user,ou=people,dc=test))", Attributes: []string{ "cn", "entryUUID", }, } lm.On("Search", userLookupReq). Return( &ldap.SearchResult{ Entries: []*ldap.Entry{ renamedEduUserEntry, }, }, nil) lm.On("Search", eduUserLookupReq). Return( &ldap.SearchResult{ Entries: []*ldap.Entry{ renamedEduUserEntry, }, }, nil) lm.On("Search", userSearchReq). Return( &ldap.SearchResult{ Entries: []*ldap.Entry{ eduUserEntry, }, }, nil) lm.On("Search", groupSearchReq). Return( &ldap.SearchResult{ Entries: []*ldap.Entry{}, }, nil) modReq := ldap.ModifyRequest{ DN: "uid=newtestuser,ou=people,dc=test", Changes: []ldap.Change{ { Operation: ldap.ReplaceAttribute, Modification: ldap.PartialAttribute{ Type: "mail", Vals: []string{"new@mail.org"}, }, }, { Operation: ldap.ReplaceAttribute, Modification: ldap.PartialAttribute{ Type: "userEnabledAttribute", Vals: []string{"TRUE"}, }, }, }, } modDNReq := ldap.ModifyDNRequest{ DN: "uid=user,ou=people,dc=test", NewRDN: "uid=newtestuser", DeleteOldRDN: true, } lm.On("ModifyDN", &modDNReq).Return(nil) lm.On("Modify", &modReq).Return(nil) user := libregraph.NewEducationUser() user.SetOnPremisesSamAccountName("newtestuser") user.SetMail("new@mail.org") user.SetAccountEnabled(true) eduUser, err := b.UpdateEducationUser(context.Background(), "testuser", *user) assert.NotNil(t, eduUser) assert.Nil(t, err) assert.Equal(t, eduUser.GetOnPremisesSamAccountName(), "newtestuser") assert.Equal(t, "abcd-defg", eduUser.GetId()) assert.Equal(t, "Guest", eduUser.GetUserType()) assert.Equal(t, eduUser.GetAccountEnabled(), true) }