mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-05-24 08:27:27 -04:00
Implement LDAP backend for CreateSchool
This commit is contained in:
committed by
Ralf Haferkamp
parent
b302af88f6
commit
ad1355d032
@@ -2,12 +2,16 @@ package identity
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
|
||||
"github.com/go-ldap/ldap/v3"
|
||||
"github.com/gofrs/uuid"
|
||||
libregraph "github.com/owncloud/libre-graph-api-go"
|
||||
oldap "github.com/owncloud/ocis/v2/ocis-pkg/ldap"
|
||||
"github.com/owncloud/ocis/v2/services/graph/pkg/config"
|
||||
"github.com/owncloud/ocis/v2/services/graph/pkg/service/v0/errorcode"
|
||||
)
|
||||
|
||||
type educationConfig struct {
|
||||
@@ -57,7 +61,43 @@ func newSchoolAttributeMap() schoolAttributeMap {
|
||||
|
||||
// CreateSchool creates the supplied school in the identity backend.
|
||||
func (i *LDAP) CreateSchool(ctx context.Context, school libregraph.EducationSchool) (*libregraph.EducationSchool, error) {
|
||||
return nil, errNotImplemented
|
||||
logger := i.logger.SubloggerWithRequestID(ctx)
|
||||
logger.Debug().Str("backend", "ldap").Msg("CreateSchool")
|
||||
if !i.writeEnabled {
|
||||
return nil, errReadOnly
|
||||
}
|
||||
|
||||
dn := fmt.Sprintf("%s=%s,%s",
|
||||
i.educationConfig.schoolAttributeMap.displayName,
|
||||
oldap.EscapeDNAttributeValue(school.GetDisplayName()),
|
||||
i.educationConfig.schoolBaseDN,
|
||||
)
|
||||
ar := ldap.NewAddRequest(dn, nil)
|
||||
ar.Attribute(i.educationConfig.schoolAttributeMap.displayName, []string{school.GetDisplayName()})
|
||||
ar.Attribute(i.educationConfig.schoolAttributeMap.schoolNumber, []string{school.GetSchoolNumber()})
|
||||
if !i.useServerUUID {
|
||||
ar.Attribute(i.educationConfig.schoolAttributeMap.id, []string{uuid.Must(uuid.NewV4()).String()})
|
||||
}
|
||||
objectClasses := []string{"organizationalUnit", i.educationConfig.schoolObjectClass, "top"}
|
||||
ar.Attribute("objectClass", objectClasses)
|
||||
|
||||
if err := i.conn.Add(ar); err != nil {
|
||||
var lerr *ldap.Error
|
||||
logger.Debug().Err(err).Msg("error adding school")
|
||||
if errors.As(err, &lerr) {
|
||||
if lerr.ResultCode == ldap.LDAPResultEntryAlreadyExists {
|
||||
err = errorcode.New(errorcode.NameAlreadyExists, lerr.Error())
|
||||
}
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Read back school from LDAP to get the generated UUID
|
||||
e, err := i.getSchoolByDN(ar.DN)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return i.createSchoolModelFromLDAP(e), nil
|
||||
}
|
||||
|
||||
// DeleteSchool deletes a given school, identified by id
|
||||
@@ -89,3 +129,37 @@ func (i *LDAP) AddMembersToSchool(ctx context.Context, schoolID string, memberID
|
||||
func (i *LDAP) RemoveMemberFromSchool(ctx context.Context, schoolID string, memberID string) error {
|
||||
return errNotImplemented
|
||||
}
|
||||
|
||||
func (i *LDAP) getSchoolByDN(dn string) (*ldap.Entry, error) {
|
||||
attrs := []string{
|
||||
i.educationConfig.schoolAttributeMap.displayName,
|
||||
i.educationConfig.schoolAttributeMap.id,
|
||||
i.educationConfig.schoolAttributeMap.schoolNumber,
|
||||
}
|
||||
filter := fmt.Sprintf("(objectClass=%s)", i.educationConfig.schoolObjectClass)
|
||||
|
||||
if i.educationConfig.schoolFilter != "" {
|
||||
filter = fmt.Sprintf("(&%s(%s))", filter, i.educationConfig.schoolFilter)
|
||||
}
|
||||
return i.getEntryByDN(dn, attrs, filter)
|
||||
}
|
||||
|
||||
func (i *LDAP) createSchoolModelFromLDAP(e *ldap.Entry) *libregraph.EducationSchool {
|
||||
if e == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
displayName := e.GetEqualFoldAttributeValue(i.educationConfig.schoolAttributeMap.displayName)
|
||||
id := e.GetEqualFoldAttributeValue(i.educationConfig.schoolAttributeMap.id)
|
||||
schoolNumber := e.GetEqualFoldAttributeValue(i.educationConfig.schoolAttributeMap.schoolNumber)
|
||||
|
||||
if id != "" && displayName != "" && schoolNumber != "" {
|
||||
school := libregraph.NewEducationSchool()
|
||||
school.SetDisplayName(displayName)
|
||||
school.SetSchoolNumber(schoolNumber)
|
||||
school.SetId(id)
|
||||
return school
|
||||
}
|
||||
i.logger.Warn().Str("dn", e.DN).Str("id", id).Str("displayName", displayName).Str("schoolNumber", schoolNumber).Msg("Invalid School. Missing required attribute")
|
||||
return nil
|
||||
}
|
||||
|
||||
70
services/graph/pkg/identity/ldap_school_test.go
Normal file
70
services/graph/pkg/identity/ldap_school_test.go
Normal file
@@ -0,0 +1,70 @@
|
||||
package identity
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/go-ldap/ldap/v3"
|
||||
libregraph "github.com/owncloud/libre-graph-api-go"
|
||||
"github.com/owncloud/ocis/v2/services/graph/mocks"
|
||||
"github.com/owncloud/ocis/v2/services/graph/pkg/config"
|
||||
"github.com/test-go/testify/assert"
|
||||
"github.com/test-go/testify/mock"
|
||||
)
|
||||
|
||||
var eduConfig = config.LDAP{
|
||||
UserBaseDN: "ou=people,dc=test",
|
||||
UserObjectClass: "inetOrgPerson",
|
||||
UserSearchScope: "sub",
|
||||
UserFilter: "",
|
||||
UserDisplayNameAttribute: "displayname",
|
||||
UserIDAttribute: "entryUUID",
|
||||
UserEmailAttribute: "mail",
|
||||
UserNameAttribute: "uid",
|
||||
|
||||
GroupBaseDN: "ou=groups,dc=test",
|
||||
GroupObjectClass: "groupOfNames",
|
||||
GroupSearchScope: "sub",
|
||||
GroupFilter: "",
|
||||
GroupNameAttribute: "cn",
|
||||
GroupIDAttribute: "entryUUID",
|
||||
|
||||
WriteEnabled: true,
|
||||
EducationResourcesEnabled: true,
|
||||
}
|
||||
|
||||
var schoolEntry = ldap.NewEntry("ou=Test School",
|
||||
map[string][]string{
|
||||
"ou": {"Test School"},
|
||||
"ocEducationSchoolNumber": {"0123"},
|
||||
"owncloudUUID": {"abcd-defg"},
|
||||
})
|
||||
|
||||
func TestCreateSchool(t *testing.T) {
|
||||
lm := &mocks.Client{}
|
||||
lm.On("Add", mock.Anything).
|
||||
Return(nil)
|
||||
|
||||
lm.On("Search", mock.Anything).
|
||||
Return(
|
||||
&ldap.SearchResult{
|
||||
Entries: []*ldap.Entry{schoolEntry},
|
||||
},
|
||||
nil)
|
||||
|
||||
b, err := getMockedBackend(lm, eduConfig, &logger)
|
||||
assert.Nil(t, err)
|
||||
assert.NotEqual(t, "", b.educationConfig.schoolObjectClass)
|
||||
school := libregraph.NewEducationSchool()
|
||||
school.SetDisplayName("Test School")
|
||||
school.SetSchoolNumber("0123")
|
||||
school.SetId("abcd-defg")
|
||||
res_school, err := b.CreateSchool(context.Background(), *school)
|
||||
lm.AssertNumberOfCalls(t, "Add", 1)
|
||||
lm.AssertNumberOfCalls(t, "Search", 1)
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, res_school)
|
||||
assert.Equal(t, res_school.GetDisplayName(), school.GetDisplayName())
|
||||
assert.Equal(t, res_school.GetId(), school.GetId())
|
||||
assert.Equal(t, res_school.GetSchoolNumber(), school.GetSchoolNumber())
|
||||
}
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
)
|
||||
|
||||
func getMockedBackend(l ldap.Client, lc config.LDAP, logger *log.Logger) (*LDAP, error) {
|
||||
return NewLDAPBackend(l, lconfig, logger)
|
||||
return NewLDAPBackend(l, lc, logger)
|
||||
}
|
||||
|
||||
var lconfig = config.LDAP{
|
||||
@@ -33,6 +33,8 @@ var lconfig = config.LDAP{
|
||||
GroupFilter: "",
|
||||
GroupNameAttribute: "cn",
|
||||
GroupIDAttribute: "entryUUID",
|
||||
|
||||
WriteEnabled: true,
|
||||
}
|
||||
|
||||
var userEntry = ldap.NewEntry("uid=user",
|
||||
|
||||
Reference in New Issue
Block a user