Skip to content

Commit

Permalink
SPSH-1354 IDOX in Keycloakattributes (#761)
Browse files Browse the repository at this point in the history
  • Loading branch information
casparneumann-cap authored Nov 15, 2024
1 parent 37742b4 commit 8d24e28
Show file tree
Hide file tree
Showing 4 changed files with 168 additions and 1 deletion.
9 changes: 9 additions & 0 deletions seeding/dev/01/04_rolle.json
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,15 @@
"systemrechte": [],
"serviceProviderIds": [3]
},
{
"id": 17,
"administeredBySchulstrukturknoten": 0,
"name": "itslearning-Schulbegleitung",
"rollenart": "LERN",
"merkmale": [],
"systemrechte": [],
"serviceProviderIds": [3]
},
{
"id": 100,
"administeredBySchulstrukturknoten": 0,
Expand Down
9 changes: 9 additions & 0 deletions seeding/prod/01/04_rolle.json
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,15 @@
"systemrechte": [],
"serviceProviderIds": [3]
},
{
"id": 17,
"administeredBySchulstrukturknoten": 0,
"name": "itslearning-Schulbegleitung",
"rollenart": "LERN",
"merkmale": [],
"systemrechte": [],
"serviceProviderIds": [3]
},
{
"id": 100,
"administeredBySchulstrukturknoten": 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ import { PersonID } from '../../../shared/types/aggregate-ids.types.js';
import { EventService } from '../../../core/eventbus/services/event.service.js';
import { OxUserChangedEvent } from '../../../shared/events/ox-user-changed.event.js';
import { KeycloakClientError } from '../../../shared/error/keycloak-client.error.js';
import { PersonenkontextMigrationRuntype } from '../../personenkontext/domain/personenkontext.enums.js';
import { Personenkontext } from '../../personenkontext/domain/personenkontext.js';
import { Person } from '../../person/domain/person.js';
import { Rolle } from '../../rolle/domain/rolle.js';
import { Organisation } from '../../organisation/domain/organisation.js';
import { PersonenkontextCreatedMigrationEvent } from '../../../shared/events/personenkontext-created-migration.event.js';
import { RollenArt } from '../../rolle/domain/rolle.enums.js';

describe('KeycloakEventHandler', () => {
let module: TestingModule;
Expand Down Expand Up @@ -44,6 +51,97 @@ describe('KeycloakEventHandler', () => {
jest.resetAllMocks();
});

describe('handlePersonenkontextCreatedMigrationEvent', () => {
const migrationType: PersonenkontextMigrationRuntype = PersonenkontextMigrationRuntype.STANDARD;

let personenkontext: Personenkontext<true>;
let person: Person<true>;
let rolle: Rolle<true>;
let orga: Organisation<true>;

beforeEach(() => {
personenkontext = createMock<Personenkontext<true>>();
person = createMock<Person<true>>();
rolle = createMock<Rolle<true>>();
orga = createMock<Organisation<true>>();
});

it('should do nothing', async () => {
const event: PersonenkontextCreatedMigrationEvent = new PersonenkontextCreatedMigrationEvent(
migrationType,
personenkontext,
person,
rolle,
orga,
'[email protected]',
);

await sut.handlePersonenkontextCreatedMigrationEvent(event);
expect(loggerMock.info).toHaveBeenCalledWith(
expect.stringContaining('UpdateOXUserAttributes criteria not fulfilled, no action taken'),
);
expect(keycloakUserServiceMock.updateOXUserAttributes).not.toHaveBeenCalled();
});

it('should successfully call updateOXUserAttributes', async () => {
person.email = faker.internet.email();
person.referrer = faker.internet.userName();
rolle.rollenart = RollenArt.LEHR;

const event: PersonenkontextCreatedMigrationEvent = new PersonenkontextCreatedMigrationEvent(
migrationType,
personenkontext,
person,
rolle,
orga,
'[email protected]',
);

keycloakUserServiceMock.updateOXUserAttributes.mockResolvedValueOnce({
ok: true,
value: undefined,
});

await sut.handlePersonenkontextCreatedMigrationEvent(event);
expect(loggerMock.info).toHaveBeenCalledWith(
expect.stringContaining('UpdateOXUserAttributes criteria fulfilled, trying to updateOXUserAttributes'),
);
expect(loggerMock.error).not.toHaveBeenCalledWith(
expect.stringContaining('Updating user in keycloak failed for OxUserChangedEvent'),
);
expect(keycloakUserServiceMock.updateOXUserAttributes).toHaveBeenCalledTimes(1);
});

it('should log error if updateOXUserAttributes fails', async () => {
person.email = faker.internet.email();
person.referrer = faker.internet.userName();
rolle.rollenart = RollenArt.LEHR;

const event: PersonenkontextCreatedMigrationEvent = new PersonenkontextCreatedMigrationEvent(
migrationType,
personenkontext,
person,
rolle,
orga,
'[email protected]',
);

keycloakUserServiceMock.updateOXUserAttributes.mockResolvedValueOnce({
ok: false,
error: new KeycloakClientError('Could not update user-attributes'),
});

await sut.handlePersonenkontextCreatedMigrationEvent(event);
expect(loggerMock.info).toHaveBeenCalledWith(
expect.stringContaining('UpdateOXUserAttributes criteria fulfilled, trying to updateOXUserAttributes'),
);
expect(loggerMock.error).toHaveBeenCalledWith(
expect.stringContaining('Updating user in keycloak failed for OxUserChangedEvent'),
);
expect(keycloakUserServiceMock.updateOXUserAttributes).toHaveBeenCalledTimes(1);
});
});

describe('handleOxUserCreatedEvent', () => {
let fakePersonID: PersonID;
let fakeOXUserID: OXUserID;
Expand All @@ -61,6 +159,10 @@ describe('KeycloakEventHandler', () => {
fakeEmail = faker.internet.email();
});
it('should log info and call KeycloakUserService', async () => {
keycloakUserServiceMock.updateOXUserAttributes.mockResolvedValueOnce({
ok: true,
value: undefined,
});
await sut.handleOxUserChangedEvent(
new OxUserChangedEvent(
fakePersonID,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,61 @@ import { KeycloakUserService } from '../domain/keycloak-user.service.js';
import { OxMetadataInKeycloakChangedEvent } from '../../../shared/events/ox-metadata-in-keycloak-changed.event.js';
import { EventService } from '../../../core/eventbus/services/event.service.js';
import { OxUserChangedEvent } from '../../../shared/events/ox-user-changed.event.js';
import { PersonenkontextCreatedMigrationEvent } from '../../../shared/events/personenkontext-created-migration.event.js';
import { RollenArt } from '../../rolle/domain/rolle.enums.js';
import { PersonenkontextMigrationRuntype } from '../../personenkontext/domain/personenkontext.enums.js';
import { OxConfig } from '../../../shared/config/ox.config.js';
import { ConfigService } from '@nestjs/config';
import { ServerConfig } from '../../../shared/config/server.config.js';
import { OXContextName } from '../../../shared/types/ox-ids.types.js';

@Injectable()
export class KeycloakEventHandler {
private readonly contextName: OXContextName;

public constructor(
private readonly logger: ClassLogger,
private readonly kcUserService: KeycloakUserService,
private readonly eventService: EventService,
) {}
configService: ConfigService<ServerConfig>,
) {
const oxConfig: OxConfig = configService.getOrThrow<OxConfig>('OX');
this.contextName = oxConfig.CONTEXT_NAME;
}

@EventHandler(PersonenkontextCreatedMigrationEvent)
public async handlePersonenkontextCreatedMigrationEvent(
event: PersonenkontextCreatedMigrationEvent,
): Promise<void> {
this.logger.info(
`MIGRATION: Create Kontext Operation / personId: ${event.createdKontextPerson.id} ; orgaId: ${event.createdKontextOrga.id} ; rolleId: ${event.createdKontextRolle.id} / Received PersonenkontextCreatedMigrationEvent`,
);
if (
event.email &&
event.createdKontextPerson.referrer &&
event.createdKontextRolle.rollenart == RollenArt.LEHR &&
event.migrationRunType === PersonenkontextMigrationRuntype.STANDARD
) {
this.logger.info(
`MIGRATION: Create Kontext Operation / personId: ${event.createdKontextPerson.id} ; orgaId: ${event.createdKontextOrga.id} ; rolleId: ${event.createdKontextRolle.id} / UpdateOXUserAttributes criteria fulfilled, trying to updateOXUserAttributes`,
);

const updateResult: Result<void> = await this.kcUserService.updateOXUserAttributes(
event.createdKontextPerson.referrer,
event.createdKontextPerson.referrer,
this.contextName,
);
if (!updateResult.ok) {
this.logger.error(
`MIGRATION: Create Kontext Operation / personId: ${event.createdKontextPerson.id} ; orgaId: ${event.createdKontextOrga.id} ; rolleId: ${event.createdKontextRolle.id} / Updating user in keycloak failed for OxUserChangedEvent`,
);
}
} else {
this.logger.info(
`MIGRATION: Create Kontext Operation / personId: ${event.createdKontextPerson.id} ; orgaId: ${event.createdKontextOrga.id} ; rolleId: ${event.createdKontextRolle.id} / UpdateOXUserAttributes criteria not fulfilled, no action taken`,
);
}
}

@EventHandler(OxUserChangedEvent)
public async handleOxUserChangedEvent(event: OxUserChangedEvent): Promise<void> {
Expand Down

0 comments on commit 8d24e28

Please sign in to comment.