From a51393e5bf08bec2f154dac2acab857b052a6165 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20Franke?= Date: Fri, 3 Feb 2023 13:34:08 +0100 Subject: [PATCH] Add username changing functionality. This is an incomplete implementation of username changing code. The things still needed to be finished: * The method that changes the member attribute has to be filled in. * The functionality needs to be tested. * Unit tests need to be added. --- services/graph/pkg/identity/ldap.go | 41 ++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/services/graph/pkg/identity/ldap.go b/services/graph/pkg/identity/ldap.go index 867750e5a7..7f5b2f4650 100644 --- a/services/graph/pkg/identity/ldap.go +++ b/services/graph/pkg/identity/ldap.go @@ -216,7 +216,10 @@ func (i *LDAP) UpdateUser(ctx context.Context, nameOrID string, user libregraph. // want to allow changing the user name?). For now just disallow it. if user.OnPremisesSamAccountName != nil && *user.OnPremisesSamAccountName != "" { if e.GetEqualFoldAttributeValue(i.userAttributeMap.userName) != *user.OnPremisesSamAccountName { - return nil, errorcode.New(errorcode.NotSupported, "changing the user name is currently not supported") + e, err = i.changeUserName(ctx, e.DN, user.GetOnPremisesSamAccountName()) + if err != nil { + return nil, err + } } } @@ -470,6 +473,42 @@ func (i *LDAP) GetUsers(ctx context.Context, oreq *godata.GoDataRequest) ([]*lib return users, nil } +func (i *LDAP) changeUserName(ctx context.Context, dn, originalUserName, newUserName string) (*ldap.Entry, error) { + groups, err := i.getGroupsForUser(dn) + if err != nil { + return nil, err + } + + newDN := fmt.Sprintf("%s=%s", i.userAttributeMap.userName, newUserName) + for _, g := range groups { + err = i.renameMemberInGroup(ctx, g, dn, newDN) + // This could leave the groups in an inconsistent state, might be a good idea to + // add a defer that changes everything back on error. Ideally, this entire function + // should be atomic, but LDAP doesn't support that. + if err != nil { + return nil, err + } + } + + mrdn := ldap.NewModifyDNRequest(dn, newDN, true, "") + + if err := i.conn.ModifyDN(mrdn); err != nil { + var lerr *ldap.Error + if errors.As(err, &lerr) { + if lerr.ResultCode == ldap.LDAPResultEntryAlreadyExists { + err = errorcode.New(errorcode.NameAlreadyExists, lerr.Error()) + } + } + return nil, err + } + + return i.getUserByDN(newDN) +} + +// TODO: Fill this in. +func (i *LDAP) renameMemberInGroup(ctx context.Context, group *ldap.Entry, oldMember, newMember) error { +} + func (i *LDAP) updateUserPassowrd(ctx context.Context, dn, password string) error { logger := i.logger.SubloggerWithRequestID(ctx) logger.Debug().Str("backend", "ldap").Msg("updateUserPassowrd")