Allow patching of EducationClass properties.

As described in #5410: add support for updating educationClass properties.
This adds the `UpdateEducationClass` to the `EducationBackend` interface,
and implements it on the `ErrEducationBackend` and `LDAP` backends.

It also alters `PatchEducationClass` to call the `UpdateEducationClass` method.

Closes #5410
This commit is contained in:
Daniël Franke
2023-01-17 13:52:04 +01:00
committed by Ralf Haferkamp
parent 32cc9beb0b
commit 2ca35f0a2b
4 changed files with 90 additions and 2 deletions

View File

@@ -70,6 +70,8 @@ type EducationBackend interface {
DeleteEducationClass(ctx context.Context, nameOrID string) error
// GetEducationClassMembers returns the EducationUser members for an EducationClass
GetEducationClassMembers(ctx context.Context, nameOrID string) ([]*libregraph.EducationUser, error)
// UpdateEducationClass updates properties of the supplied class in the identity backend.
UpdateEducationClass(ctx context.Context, id string, class libregraph.EducationClass) (*libregraph.EducationClass, error)
// CreateEducationUser creates a given education user in the identity backend.
CreateEducationUser(ctx context.Context, user libregraph.EducationUser) (*libregraph.EducationUser, error)

View File

@@ -75,6 +75,10 @@ func (i *ErrEducationBackend) GetEducationClassMembers(ctx context.Context, name
return nil, errNotImplemented
}
func (i *ErrEducationBackend) UpdateEducationClass(ctx context.Context, id string, class libregraph.EducationClass) (*libregraph.EducationClass, error) {
return nil, errNotImplemented
}
// CreateEducationUser creates a given education user in the identity backend.
func (i *ErrEducationBackend) CreateEducationUser(ctx context.Context, user libregraph.EducationUser) (*libregraph.EducationUser, error) {
return nil, errNotImplemented

View File

@@ -139,6 +139,78 @@ func (i *LDAP) DeleteEducationClass(ctx context.Context, id string) error {
return nil
}
// UpdateEducationClass implements the EducationBackend interface for the LDAP backend.
// Only the displayName and externalID are supported to change at this point.
func (i *LDAP) UpdateEducationClass(ctx context.Context, id string, class libregraph.EducationClass) (*libregraph.EducationClass, error) {
logger := i.logger.SubloggerWithRequestID(ctx)
logger.Debug().Str("backend", "ldap").Msg("UpdateEducationClass")
if !i.writeEnabled {
return nil, ErrReadOnly
}
g, err := i.getLDAPGroupByID(id, false)
if err != nil {
return nil, err
}
var updateNeeded bool
if class.GetId() != "" {
if g.GetEqualFoldAttributeValue(i.groupAttributeMap.id) != class.GetId() {
return nil, errorcode.New(errorcode.NotAllowed, "changing the GroupID is not allowed")
}
}
if class.GetOnPremisesSamAccountName() != "" {
return nil, errorcode.New(errorcode.NotSupported, "changing the SAM account name is currently not supported")
}
if class.GetOnPremisesDomainName() != "" {
return nil, errorcode.New(errorcode.NotSupported, "changing the SAM account name is currently not supported")
}
if class.GetDescription() != "" {
return nil, errorcode.New(errorcode.NotSupported, "changing the description is currently not supported")
}
if len(class.GetMembers()) != 0 {
return nil, errorcode.New(errorcode.NotSupported, "changing the members is currently not supported")
}
if class.GetClassification() != "" {
return nil, errorcode.New(errorcode.NotSupported, "changing the classification is currently not supported")
}
mr := ldap.ModifyRequest{DN: g.DN}
if eID := class.GetExternalId(); eID != "" {
if g.GetEqualFoldAttributeValue(i.educationConfig.classAttributeMap.externalID) != eID {
mr.Replace(i.educationConfig.classAttributeMap.externalID, []string{eID})
updateNeeded = true
}
}
if dName := class.GetDisplayName(); dName != "" {
if g.GetEqualFoldAttributeValue(i.groupAttributeMap.name) != dName {
mr.Replace(i.groupAttributeMap.name, []string{dName})
updateNeeded = true
}
}
if updateNeeded {
if err := i.conn.Modify(&mr); err != nil {
return nil, err
}
}
g, err = i.getEducationClassByDN(g.DN)
if err != nil {
return nil, err
}
return i.createEducationClassModelFromLDAP(g), nil
}
// GetEducationClassMembers implements the EducationBackend interface for the LDAP backend.
func (i *LDAP) GetEducationClassMembers(ctx context.Context, id string) ([]*libregraph.EducationUser, error) {
logger := i.logger.SubloggerWithRequestID(ctx)

View File

@@ -120,6 +120,16 @@ func (g Graph) PatchEducationClass(w http.ResponseWriter, r *http.Request) {
return
}
class, err := g.identityEducationBackend.UpdateEducationClass(r.Context(), classID, *changes)
if err != nil {
logger.Error().
Err(err).
Str("classID", classID).
Msg("could not update class")
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, err.Error())
return
}
if memberRefs, ok := changes.GetMembersodataBindOk(); ok {
// The spec defines a limit of 20 members maxium per Request
if len(memberRefs) > g.config.API.GroupMembersPatchLimit {
@@ -166,8 +176,8 @@ func (g Graph) PatchEducationClass(w http.ResponseWriter, r *http.Request) {
}
return
}
render.Status(r, http.StatusNoContent) // TODO StatusNoContent when prefer=minimal is used, otherwise OK and the resource in the body
render.NoContent(w, r)
render.Status(r, http.StatusOK) // TODO StatusNoContent when prefer=minimal is used, otherwise OK and the resource in the body
render.JSON(w, r, class)
}
// GetEducationClass implements the Service interface.