diff --git a/services/graph/pkg/identity/ldap_school.go b/services/graph/pkg/identity/ldap_school.go index c14a535bbc..d8d8df5464 100644 --- a/services/graph/pkg/identity/ldap_school.go +++ b/services/graph/pkg/identity/ldap_school.go @@ -133,7 +133,47 @@ func (i *LDAP) GetSchool(ctx context.Context, nameOrID string, queryParam url.Va // GetSchools implements the EducationBackend interface for the LDAP backend. func (i *LDAP) GetSchools(ctx context.Context, queryParam url.Values) ([]*libregraph.EducationSchool, error) { - return nil, errNotImplemented + var filter string + filter = fmt.Sprintf("(objectClass=%s)", i.educationConfig.schoolObjectClass) + + if i.educationConfig.schoolFilter != "" { + filter = fmt.Sprintf("(&%s%s)", i.educationConfig.schoolFilter, filter) + } + + searchRequest := ldap.NewSearchRequest( + i.educationConfig.schoolBaseDN, + i.educationConfig.schoolScope, + ldap.NeverDerefAliases, 0, 0, false, + filter, + []string{ + i.educationConfig.schoolAttributeMap.displayName, + i.educationConfig.schoolAttributeMap.id, + i.educationConfig.schoolAttributeMap.schoolNumber, + }, + nil, + ) + i.logger.Debug().Str("backend", "ldap"). + Str("base", searchRequest.BaseDN). + Str("filter", searchRequest.Filter). + Int("scope", searchRequest.Scope). + Int("sizelimit", searchRequest.SizeLimit). + Interface("attributes", searchRequest.Attributes). + Msg("GetSchools") + res, err := i.conn.Search(searchRequest) + if err != nil { + return nil, errorcode.New(errorcode.ItemNotFound, err.Error()) + } + + schools := make([]*libregraph.EducationSchool, 0, len(res.Entries)) + for _, e := range res.Entries { + school := i.createSchoolModelFromLDAP(e) + // Skip invalid LDAP entries + if school == nil { + continue + } + schools = append(schools, school) + } + return schools, nil } // GetSchoolMembers implements the EducationBackend interface for the LDAP backend. diff --git a/services/graph/pkg/identity/ldap_school_test.go b/services/graph/pkg/identity/ldap_school_test.go index d83cc68fe7..a4efbf30fa 100644 --- a/services/graph/pkg/identity/ldap_school_test.go +++ b/services/graph/pkg/identity/ldap_school_test.go @@ -39,6 +39,12 @@ var schoolEntry = ldap.NewEntry("ou=Test School", "ocEducationSchoolNumber": {"0123"}, "owncloudUUID": {"abcd-defg"}, }) +var schoolEntry1 = ldap.NewEntry("ou=Test School1", + map[string][]string{ + "ou": {"Test School1"}, + "ocEducationSchoolNumber": {"0042"}, + "owncloudUUID": {"hijk-defg"}, + }) func TestCreateSchool(t *testing.T) { lm := &mocks.Client{} @@ -142,3 +148,22 @@ func TestGetSchool(t *testing.T) { assert.NotNil(t, err) assert.Equal(t, "itemNotFound", err.Error()) } + +func TestGetSchools(t *testing.T) { + lm := &mocks.Client{} + sr1 := &ldap.SearchRequest{ + BaseDN: "", + Scope: 2, + SizeLimit: 0, + Filter: "(objectClass=ocEducationSchool)", + Attributes: []string{"ou", "owncloudUUID", "ocEducationSchoolNumber"}, + 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{}}, nil) + b, err := getMockedBackend(lm, eduConfig, &logger) + assert.Nil(t, err) + _, err = b.GetSchools(context.Background(), nil) + lm.AssertNumberOfCalls(t, "Search", 1) + assert.Nil(t, err) +}