diff --git a/src/core/ldap/domain/ldap-client.service.spec.ts b/src/core/ldap/domain/ldap-client.service.spec.ts index 2da975229..67f862787 100644 --- a/src/core/ldap/domain/ldap-client.service.spec.ts +++ b/src/core/ldap/domain/ldap-client.service.spec.ts @@ -248,8 +248,9 @@ describe('LDAP Client Service', () => { }); describe('addPersonToGroup', () => { - const fakePersonUid: string = 'test-user'; + const fakeReferrer: string = 'test-user'; const fakeSchoolReferrer: string = '123'; + const fakeLehrerUid: string = `uid=${fakeReferrer},ou=oeffentlicheSchulen,${mockLdapInstanceConfig.BASE_DN}`; const fakeGroupId: string = `lehrer-${fakeSchoolReferrer}`; const fakeGroupDn: string = `cn=${fakeGroupId},cn=groups,ou=${fakeSchoolReferrer},${mockLdapInstanceConfig.BASE_DN}`; @@ -271,7 +272,11 @@ describe('LDAP Client Service', () => { return clientMock; }); - const result: Result = await ldapClientService.addPersonToGroup(fakePersonUid, fakeSchoolReferrer); + const result: Result = await ldapClientService.addPersonToGroup( + fakeReferrer, + fakeSchoolReferrer, + fakeLehrerUid, + ); expect(result.ok).toBeTruthy(); expect(clientMock.modify).toHaveBeenCalledWith(fakeGroupDn, [ @@ -279,12 +284,12 @@ describe('LDAP Client Service', () => { operation: 'add', modification: new Attribute({ type: 'member', - values: [ldapClientService.getLehrerUid(fakePersonUid, 'users')], + values: [fakeLehrerUid], }), }), ]); expect(loggerMock.info).toHaveBeenCalledWith( - `LDAP: Successfully added person ${fakePersonUid} to group ${fakeGroupId}`, + `LDAP: Successfully added person ${fakeReferrer} to group ${fakeGroupId}`, ); }); @@ -307,7 +312,11 @@ describe('LDAP Client Service', () => { return clientMock; }); - const result: Result = await ldapClientService.addPersonToGroup(fakePersonUid, fakeSchoolReferrer); + const result: Result = await ldapClientService.addPersonToGroup( + fakeReferrer, + fakeSchoolReferrer, + fakeLehrerUid, + ); expect(result.ok).toBeTruthy(); expect(clientMock.add).toHaveBeenCalledWith( @@ -335,16 +344,20 @@ describe('LDAP Client Service', () => { return clientMock; }); - const result: Result = await ldapClientService.addPersonToGroup(fakePersonUid, fakeSchoolReferrer); + const result: Result = await ldapClientService.addPersonToGroup( + fakeReferrer, + fakeSchoolReferrer, + fakeLehrerUid, + ); expect(result.ok).toBeTruthy(); expect(clientMock.add).toHaveBeenCalledWith(fakeGroupDn, { cn: fakeGroupId, objectclass: ['groupOfNames'], - member: [ldapClientService.getLehrerUid(fakePersonUid, 'users')], + member: [fakeLehrerUid], }); expect(loggerMock.info).toHaveBeenCalledWith( - `LDAP: Successfully created group ${fakeGroupId} and added person ${fakePersonUid}`, + `LDAP: Successfully created group ${fakeGroupId} and added person ${fakeReferrer}`, ); }); @@ -366,7 +379,11 @@ describe('LDAP Client Service', () => { return clientMock; }); - const result: Result = await ldapClientService.addPersonToGroup(fakePersonUid, fakeSchoolReferrer); + const result: Result = await ldapClientService.addPersonToGroup( + fakeReferrer, + fakeSchoolReferrer, + fakeLehrerUid, + ); expect(result.ok).toBeFalsy(); if (result.ok) throw Error(); @@ -394,7 +411,11 @@ describe('LDAP Client Service', () => { return clientMock; }); - const result: Result = await ldapClientService.addPersonToGroup(fakePersonUid, fakeSchoolReferrer); + const result: Result = await ldapClientService.addPersonToGroup( + fakeReferrer, + fakeSchoolReferrer, + fakeLehrerUid, + ); expect(result.ok).toBeFalsy(); if (result.ok) throw Error(); @@ -410,7 +431,11 @@ describe('LDAP Client Service', () => { return clientMock; }); - const result: Result = await ldapClientService.addPersonToGroup(fakePersonUid, fakeSchoolReferrer); + const result: Result = await ldapClientService.addPersonToGroup( + fakeReferrer, + fakeSchoolReferrer, + fakeLehrerUid, + ); expect(result.ok).toBeFalsy(); if (result.ok) throw Error(); @@ -428,7 +453,7 @@ describe('LDAP Client Service', () => { searchEntries: [ createMock({ dn: fakeGroupDn, - member: [ldapClientService.getLehrerUid(fakePersonUid, 'users')], + member: [fakeLehrerUid], }), ], }), @@ -437,14 +462,18 @@ describe('LDAP Client Service', () => { return clientMock; }); - const result: Result = await ldapClientService.addPersonToGroup(fakePersonUid, fakeSchoolReferrer); + const result: Result = await ldapClientService.addPersonToGroup( + fakeReferrer, + fakeSchoolReferrer, + fakeLehrerUid, + ); expect(result.ok).toBeTruthy(); if (!result.ok) throw Error(); expect(result.value).toBe(false); expect(clientMock.modify).not.toHaveBeenCalled(); expect(loggerMock.info).toHaveBeenCalledWith( - `LDAP: Person ${fakePersonUid} is already in group ${fakeGroupId}`, + `LDAP: Person ${fakeReferrer} is already in group ${fakeGroupId}`, ); }); }); @@ -1225,6 +1254,7 @@ describe('LDAP Client Service', () => { const result: Result = await ldapClientService.removePersonFromGroup( fakePersonUid, fakeDienstStellenNummer, + fakeLehrerUid, ); expect(result.ok).toBeTruthy(); @@ -1263,6 +1293,7 @@ describe('LDAP Client Service', () => { const result: Result = await ldapClientService.removePersonFromGroup( fakePersonUid, fakeDienstStellenNummer, + fakeLehrerUid, ); expect(result.ok).toBeTruthy(); @@ -1288,6 +1319,7 @@ describe('LDAP Client Service', () => { const result: Result = await ldapClientService.removePersonFromGroup( fakePersonUid, fakeDienstStellenNummer, + fakeLehrerUid, ); expect(result.ok).toBeFalsy(); @@ -1304,6 +1336,7 @@ describe('LDAP Client Service', () => { const result: Result = await ldapClientService.removePersonFromGroup( fakePersonUid, fakeDienstStellenNummer, + fakeLehrerUid, ); expect(result.ok).toBeFalsy(); @@ -1335,6 +1368,7 @@ describe('LDAP Client Service', () => { const result: Result = await ldapClientService.removePersonFromGroup( fakePersonUid, fakeDienstStellenNummer, + fakeLehrerUid, ); expect(result.ok).toBeFalsy(); @@ -1363,6 +1397,7 @@ describe('LDAP Client Service', () => { const result: Result = await ldapClientService.removePersonFromGroup( fakePersonUid, fakeDienstStellenNummer, + fakeLehrerUid, ); expect(result.ok).toBeFalsy(); @@ -1393,6 +1428,7 @@ describe('LDAP Client Service', () => { const result: Result = await ldapClientService.removePersonFromGroup( fakePersonUid, fakeDienstStellenNummer, + fakeLehrerUid, ); expect(result.ok).toBeTruthy(); @@ -1416,6 +1452,7 @@ describe('LDAP Client Service', () => { const result: Result = await ldapClientService.removePersonFromGroup( fakePersonUid, fakeDienstStellenNummer, + fakeLehrerUid, ); expect(result.ok).toBeFalsy(); @@ -1449,6 +1486,7 @@ describe('LDAP Client Service', () => { const result: Result = await ldapClientService.removePersonFromGroup( fakePersonUid, fakeDienstStellenNummer, + fakeLehrerUid, ); expect(result.ok).toBeTruthy(); @@ -1487,6 +1525,7 @@ describe('LDAP Client Service', () => { const result: Result = await ldapClientService.updateMemberDnInGroups( fakeOldReferrer, fakeNewReferrer, + fakeOldReferrerUid, clientMock2, ); expect(result.ok).toBeTruthy(); @@ -1517,6 +1556,7 @@ describe('LDAP Client Service', () => { const result: Result = await ldapClientService.updateMemberDnInGroups( fakeOldReferrer, fakeNewReferrer, + fakeOldReferrerUid, clientMock3, ); @@ -1543,6 +1583,7 @@ describe('LDAP Client Service', () => { const result: Result = await ldapClientService.updateMemberDnInGroups( fakeOldReferrer, fakeNewReferrer, + fakeOldReferrerUid, clientMock5, ); @@ -1564,6 +1605,7 @@ describe('LDAP Client Service', () => { const result: Result = await ldapClientService.updateMemberDnInGroups( fakeOldReferrer, fakeNewReferrer, + fakeOldReferrerUid, clientMock4, ); @@ -1594,6 +1636,7 @@ describe('LDAP Client Service', () => { const result: Result = await ldapClientService.updateMemberDnInGroups( fakeOldReferrer, fakeNewReferrer, + fakeOldReferrerUid, clientMock, ); @@ -1627,6 +1670,7 @@ describe('LDAP Client Service', () => { const result: Result = await ldapClientService.updateMemberDnInGroups( fakeOldReferrer, fakeNewReferrer, + fakeOldReferrerUid, clientMock, ); @@ -1665,6 +1709,7 @@ describe('LDAP Client Service', () => { const result: Result = await ldapClientService.updateMemberDnInGroups( fakeOldReferrer, fakeNewReferrer, + fakeOldReferrerUid, clientMock, ); @@ -1801,4 +1846,32 @@ describe('LDAP Client Service', () => { }); }); }); + describe('createNewLehrerUidFromOldUid', () => { + it('should replace the old uid with the new referrer and join the DN parts with commas', () => { + const oldUid: string = 'uid=oldUser,ou=users,dc=example,dc=com'; + const newReferrer: string = 'newUser'; + + const result: string = ldapClientService.createNewLehrerUidFromOldUid(oldUid, newReferrer); + + expect(result).toBe('uid=newUser,ou=users,dc=example,dc=com'); + }); + + it('should handle a DN with only a uid component', () => { + const oldUid: string = 'uid=oldUser'; + const newReferrer: string = 'newUser'; + + const result: string = ldapClientService.createNewLehrerUidFromOldUid(oldUid, newReferrer); + + expect(result).toBe('uid=newUser'); + }); + + it('should handle an empty DN string', () => { + const oldUid: string = ''; + const newReferrer: string = 'newUser'; + + const result: string = ldapClientService.createNewLehrerUidFromOldUid(oldUid, newReferrer); + + expect(result).toBe('uid=newUser'); + }); + }); }); diff --git a/src/core/ldap/domain/ldap-client.service.ts b/src/core/ldap/domain/ldap-client.service.ts index fb848f696..3d6b10bb4 100644 --- a/src/core/ldap/domain/ldap-client.service.ts +++ b/src/core/ldap/domain/ldap-client.service.ts @@ -147,7 +147,7 @@ export class LdapClientService { const bindResult: Result = await this.bind(); if (!bindResult.ok) return bindResult; - const groupResult: Result = await this.addPersonToGroup(referrer, schulId); + const groupResult: Result = await this.addPersonToGroup(referrer, schulId, lehrerUid); if (!groupResult.ok) { this.logger.error(`LDAP: Failed to add lehrer ${referrer} to group lehrer-${schulId}`); return groupResult; @@ -223,7 +223,7 @@ export class LdapClientService { oldReferrer: string, newGivenName?: string, newSn?: string, - newUid?: string, + newReferrer?: string, ): Promise> { return this.mutex.runExclusive(async () => { this.logger.info('LDAP: modifyPersonAttributes'); @@ -234,7 +234,7 @@ export class LdapClientService { const searchResult: SearchResult = await client.search(`${this.ldapInstanceConfig.BASE_DN}`, { scope: 'sub', filter: `(uid=${oldReferrer})`, - attributes: ['givenName', 'sn', 'uid'], + attributes: ['givenName', 'sn', 'uid', 'dn'], returnAttributeValues: true, }); if (!searchResult.searchEntries[0]) { @@ -248,13 +248,13 @@ export class LdapClientService { const entryDn: string = searchResult.searchEntries[0].dn; const modifications: Change[] = []; - if (newUid) { + if (newReferrer) { modifications.push( new Change({ operation: 'replace', modification: new Attribute({ type: 'cn', - values: [newUid], + values: [newReferrer], }), }), ); @@ -288,16 +288,17 @@ export class LdapClientService { this.logger.info(`No givenName/sn attributes provided to modify for person:${oldReferrer}`); } - if (newUid && searchResult.searchEntries[0]['uid'] !== newUid) { - const newDn: string = `uid=${newUid}`; + if (newReferrer && searchResult.searchEntries[0]['uid'] !== newReferrer) { + const newDn: string = `uid=${newReferrer}`; await client.modifyDN(entryDn, newDn); - this.logger.info(`LDAP: Successfully updated uid for person:${oldReferrer} to ${newUid}`); + this.logger.info(`LDAP: Successfully updated uid for person:${oldReferrer} to ${newReferrer}`); } - if (newUid) { + if (newReferrer) { const groupUpdateResult: Result = await this.updateMemberDnInGroups( oldReferrer, - newUid, + newReferrer, + entryDn, client, ); if (!groupUpdateResult.ok) { @@ -310,17 +311,24 @@ export class LdapClientService { }); } + public createNewLehrerUidFromOldUid(oldUid: string, newReferrer: string): string { + const splitted: string[] = oldUid.split(','); + splitted[0] = `uid=${newReferrer}`; + return splitted.join(','); + } + public async updateMemberDnInGroups( oldReferrer: string, newReferrer: string, + oldUid: string, client: Client, ): Promise> { - const oldReferrerUid: string = this.getLehrerUid(oldReferrer, LdapClientService.USERS_OU); - const newReferrerUid: string = this.getLehrerUid(newReferrer, LdapClientService.USERS_OU); + const oldLehrerUid: string = oldUid; + const newLehrerUid: string = this.createNewLehrerUidFromOldUid(oldUid, newReferrer); const searchResult: SearchResult = await client.search(`${this.ldapInstanceConfig.BASE_DN}`, { scope: 'sub', - filter: `(member=${oldReferrerUid})`, + filter: `(member=${oldLehrerUid})`, attributes: ['dn', 'member'], returnAttributeValues: true, }); @@ -361,7 +369,7 @@ export class LdapClientService { } const updatedMembers: (string | Buffer)[] = existingMembers.map((member: string | Buffer) => - member === oldReferrerUid ? newReferrerUid : member, + member === oldLehrerUid ? newLehrerUid : member, ); await client @@ -427,7 +435,7 @@ export class LdapClientService { }; } const lehrerUid: string = this.getLehrerUid(person.referrer, rootName.value); - await this.removePersonFromGroup(person.referrer, orgaKennung); + await this.removePersonFromGroup(person.referrer, orgaKennung, lehrerUid); await client.del(lehrerUid); this.logger.info(`LDAP: Successfully deleted lehrer ${lehrerUid}`); @@ -525,7 +533,11 @@ export class LdapClientService { }); } - public async addPersonToGroup(personUid: string, schoolReferrer: string): Promise> { + public async addPersonToGroup( + personUid: string, + schoolReferrer: string, + lehrerUid: string, + ): Promise> { const groupId: string = 'lehrer-' + schoolReferrer; this.logger.info(`LDAP: Adding person ${personUid} to group ${groupId}`); const client: Client = this.ldapClient.getClient(); @@ -567,7 +579,7 @@ export class LdapClientService { const newLehrerGroup: { cn: string; objectclass: string[]; member: string[] } = { cn: groupId, objectclass: ['groupOfNames'], - member: [this.getLehrerUid(personUid, LdapClientService.USERS_OU)], + member: [lehrerUid], }; try { await client.add(lehrerDn, newLehrerGroup); @@ -591,7 +603,7 @@ export class LdapClientService { operation: 'add', modification: new Attribute({ type: 'member', - values: [this.getLehrerUid(personUid, LdapClientService.USERS_OU)], + values: [lehrerUid], }), }), ]); @@ -604,9 +616,13 @@ export class LdapClientService { } } - public async removePersonFromGroup(personUid: string, schoolReferrer: string): Promise> { + public async removePersonFromGroup( + referrer: string, + schoolReferrer: string, + lehrerUid: string, + ): Promise> { const groupId: string = 'lehrer-' + schoolReferrer; - this.logger.info(`LDAP: Removing person ${personUid} from group ${groupId}`); + this.logger.info(`LDAP: Removing person ${referrer} from group ${groupId}`); const client: Client = this.ldapClient.getClient(); const bindResult: Result = await this.bind(); if (!bindResult.ok) return bindResult; @@ -623,15 +639,15 @@ export class LdapClientService { return { ok: false, error: new Error(errMsg) }; } - if (!this.isPersonInSearchResult(searchResultOrgUnit.searchEntries[0], personUid)) { - this.logger.info(`LDAP: Person ${personUid} is not in group ${groupId}`); - return { ok: false, error: new Error(`Person ${personUid} is not in group ${groupId}`) }; + if (!this.isPersonInSearchResult(searchResultOrgUnit.searchEntries[0], referrer)) { + this.logger.info(`LDAP: Person ${referrer} is not in group ${groupId}`); + return { ok: false, error: new Error(`Person ${referrer} is not in group ${groupId}`) }; } const groupDn: string = searchResultOrgUnit.searchEntries[0].dn; try { if (typeof searchResultOrgUnit.searchEntries[0]['member'] === 'string') { await client.del(groupDn); - this.logger.info(`LDAP: Successfully removed person ${personUid} from group ${groupId}`); + this.logger.info(`LDAP: Successfully removed person ${referrer} from group ${groupId}`); this.logger.info(`LDAP: Successfully deleted group ${groupId}`); return { ok: true, value: true }; } @@ -640,11 +656,11 @@ export class LdapClientService { operation: 'delete', modification: new Attribute({ type: 'member', - values: [this.getLehrerUid(personUid, LdapClientService.USERS_OU)], + values: [lehrerUid], }), }), ]); - this.logger.info(`LDAP: Successfully removed person ${personUid} from group ${groupId}`); + this.logger.info(`LDAP: Successfully removed person ${referrer} from group ${groupId}`); return { ok: true, value: true }; } catch (err) { const errMsg: string = `LDAP: Failed to remove person from group ${groupId}, errMsg: ${String(err)}`;