LDAP Support for Delete School

This commit is contained in:
Ralf Haferkamp
2022-12-14 14:51:20 +01:00
committed by Ralf Haferkamp
parent ad1355d032
commit bc9f81cc23
2 changed files with 105 additions and 1 deletions
+66 -1
View File
@@ -102,7 +102,21 @@ func (i *LDAP) CreateSchool(ctx context.Context, school libregraph.EducationScho
// DeleteSchool deletes a given school, identified by id
func (i *LDAP) DeleteSchool(ctx context.Context, id string) error {
return errNotImplemented
logger := i.logger.SubloggerWithRequestID(ctx)
logger.Debug().Str("backend", "ldap").Msg("DeleteSchool")
if !i.writeEnabled {
return errReadOnly
}
e, err := i.getSchoolByID(id)
if err != nil {
return err
}
dr := ldap.DelRequest{DN: e.DN}
if err = i.conn.Del(&dr); err != nil {
return err
}
return nil
}
// GetSchool implements the EducationBackend interface for the LDAP backend.
@@ -144,6 +158,57 @@ func (i *LDAP) getSchoolByDN(dn string) (*ldap.Entry, error) {
return i.getEntryByDN(dn, attrs, filter)
}
func (i *LDAP) getSchoolByID(id string) (*ldap.Entry, error) {
id = ldap.EscapeFilter(id)
filter := fmt.Sprintf("(%s=%s)", i.educationConfig.schoolAttributeMap.id, id)
return i.getSchoolByFilter(filter)
}
func (i *LDAP) getSchoolByFilter(filter string) (*ldap.Entry, error) {
filter = fmt.Sprintf("(&%s(objectClass=%s)%s)",
i.educationConfig.schoolFilter,
i.educationConfig.schoolObjectClass,
filter,
)
searchRequest := ldap.NewSearchRequest(
i.educationConfig.schoolBaseDN,
i.educationConfig.schoolScope,
ldap.NeverDerefAliases, 1, 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("getSchoolByFilter")
res, err := i.conn.Search(searchRequest)
if err != nil {
var errmsg string
if lerr, ok := err.(*ldap.Error); ok {
if lerr.ResultCode == ldap.LDAPResultSizeLimitExceeded {
errmsg = fmt.Sprintf("too many results searching for school '%s'", filter)
i.logger.Debug().Str("backend", "ldap").Err(lerr).
Str("schoolfilter", filter).Msg("too many results searching for school")
}
}
return nil, errorcode.New(errorcode.ItemNotFound, errmsg)
}
if len(res.Entries) == 0 {
return nil, errNotFound
}
return res.Entries[0], nil
}
func (i *LDAP) createSchoolModelFromLDAP(e *ldap.Entry) *libregraph.EducationSchool {
if e == nil {
return nil
@@ -68,3 +68,42 @@ func TestCreateSchool(t *testing.T) {
assert.Equal(t, res_school.GetId(), school.GetId())
assert.Equal(t, res_school.GetSchoolNumber(), school.GetSchoolNumber())
}
func TestDeleteSchool(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: "",
Scope: 2,
SizeLimit: 1,
Filter: "(&(objectClass=ocEducationSchool)(owncloudUUID=xxxx-xxxx))",
Attributes: []string{"ou", "owncloudUUID", "ocEducationSchoolNumber"},
Controls: []ldap.Control(nil),
}
lm.On("Search", sr1).Return(&ldap.SearchResult{Entries: []*ldap.Entry{schoolEntry}}, nil)
lm.On("Search", sr2).Return(&ldap.SearchResult{Entries: []*ldap.Entry{}}, nil)
dr1 := &ldap.DelRequest{
DN: "ou=Test School",
}
lm.On("Del", dr1).Return(nil)
b, err := getMockedBackend(lm, eduConfig, &logger)
assert.Nil(t, err)
err = b.DeleteSchool(context.Background(), "abcd-defg")
lm.AssertNumberOfCalls(t, "Search", 1)
lm.AssertNumberOfCalls(t, "Del", 1)
assert.Nil(t, err)
err = b.DeleteSchool(context.Background(), "xxxx-xxxx")
lm.AssertNumberOfCalls(t, "Search", 2)
lm.AssertNumberOfCalls(t, "Del", 1)
assert.NotNil(t, err)
assert.Equal(t, "itemNotFound", err.Error())
}