Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

N21-1491 Provisioning of birthday from SchulConneX #4564

Merged
merged 4 commits into from
Nov 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions apps/server/src/modules/provisioning/dto/external-user.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,14 @@ export class ExternalUserDto {

roles?: RoleName[];

birthday?: Date;

constructor(props: ExternalUserDto) {
this.externalId = props.externalId;
this.firstName = props.firstName;
this.lastName = props.lastName;
this.email = props.email;
this.roles = props.roles;
this.birthday = props.birthday;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -518,13 +518,15 @@ describe('OidcProvisioningService', () => {
const setupUser = () => {
const systemId = 'systemId';
const schoolId = 'schoolId';
const birthday = new Date('2023-11-17');
const existingUser: UserDO = userDoFactory.withRoles([{ id: 'existingRoleId', name: RoleName.USER }]).buildWithId(
{
firstName: 'existingFirstName',
lastName: 'existingLastName',
email: 'existingEmail',
schoolId: 'existingSchoolId',
externalId: 'externalUserId',
birthday: new Date('2023-11-16'),
},
'userId'
);
Expand All @@ -535,6 +537,7 @@ describe('OidcProvisioningService', () => {
email: 'email',
schoolId,
externalId: 'externalUserId',
birthday,
},
'userId'
);
Expand All @@ -544,6 +547,7 @@ describe('OidcProvisioningService', () => {
lastName: 'lastName',
email: 'email',
roles: [RoleName.USER],
birthday,
});
const userRole: RoleDto = new RoleDto({
id: 'roleId',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ export class OidcProvisioningService {
user.email = externalUser.email ?? existingUser.email;
user.roles = roleRefs ?? existingUser.roles;
user.schoolId = schoolId ?? existingUser.schoolId;
user.birthday = externalUser.birthday ?? existingUser.birthday;
} else {
createNewAccount = true;

Expand All @@ -108,6 +109,7 @@ export class OidcProvisioningService {
email: externalUser.email ?? '',
roles: roleRefs ?? [],
schoolId,
birthday: externalUser.birthday,
});
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export interface SanisGeburtResponse {
datum?: string;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an extra object because from sanis we also can get geburtsort for example

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export interface SanisNameResponse {
familienname: string;
familienname?: string;

vorname: string;
vorname?: string;
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import { SanisGeburtResponse } from './sanis-geburt-response';
import { SanisNameResponse } from './sanis-name-response';

export interface SanisPersonResponse {
name: SanisNameResponse;
name?: SanisNameResponse;

geschlecht: string;
geburt?: SanisGeburtResponse;

lokalisierung: string;
geschlecht?: string;

vertrauensstufe: string;
lokalisierung?: string;

vertrauensstufe?: string;
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,17 @@ describe('SanisResponseMapper', () => {
const setupSanisResponse = () => {
const externalUserId = 'aef1f4fd-c323-466e-962b-a84354c0e713';
const externalSchoolId = 'df66c8e6-cfac-40f7-b35b-0da5d8ee680e';

const sanisResponse: SanisResponse = {
pid: externalUserId,
person: {
name: {
vorname: 'firstName',
familienname: 'lastName',
},
geburt: {
datum: '2023-11-17',
},
geschlecht: 'x',
lokalisierung: 'de-de',
vertrauensstufe: '',
Expand Down Expand Up @@ -124,6 +128,7 @@ describe('SanisResponseMapper', () => {
firstName: 'firstName',
lastName: 'lastName',
roles: [RoleName.STUDENT],
birthday: new Date('2023-11-17'),
});
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,11 @@ export class SanisResponseMapper {

mapToExternalUserDto(source: SanisResponse): ExternalUserDto {
const mapped = new ExternalUserDto({
firstName: source.person.name.vorname,
lastName: source.person.name.familienname,
firstName: source.person.name?.vorname,
lastName: source.person.name?.familienname,
roles: [this.mapSanisRoleToRoleName(source)],
externalId: source.pid,
birthday: source.person.geburt?.datum ? new Date(source.person.geburt?.datum) : undefined,
});

return mapped;
Expand Down
3 changes: 3 additions & 0 deletions apps/server/src/shared/domain/domainobject/user.do.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ export class UserDO extends BaseDO {

previousExternalId?: string;

birthday?: Date;

constructor(domainObject: UserDO) {
super(domainObject.id);

Expand All @@ -64,5 +66,6 @@ export class UserDO extends BaseDO {
this.lastLoginSystemChange = domainObject.lastLoginSystemChange;
this.outdatedSince = domainObject.outdatedSince;
this.previousExternalId = domainObject.previousExternalId;
this.birthday = domainObject.birthday;
}
}
5 changes: 5 additions & 0 deletions apps/server/src/shared/domain/entity/user.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export interface IUserProperties {
lastLoginSystemChange?: Date;
outdatedSince?: Date;
previousExternalId?: string;
birthday?: Date;
}

@Entity({ tableName: 'users' })
Expand Down Expand Up @@ -96,6 +97,9 @@ export class User extends BaseEntityWithTimestamps implements IEntityWithSchool
@Property({ nullable: true })
outdatedSince?: Date;

@Property({ nullable: true })
birthday?: Date;

constructor(props: IUserProperties) {
super();
this.firstName = props.firstName;
Expand All @@ -112,6 +116,7 @@ export class User extends BaseEntityWithTimestamps implements IEntityWithSchool
this.lastLoginSystemChange = props.lastLoginSystemChange;
this.outdatedSince = props.outdatedSince;
this.previousExternalId = props.previousExternalId;
this.birthday = props.birthday;
}

public resolvePermissions(): string[] {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { createMock } from '@golevelup/ts-jest';
import { MongoMemoryDatabaseModule } from '@infra/database';
import { FindOptions, NotFoundError, QueryOrderMap } from '@mikro-orm/core';
import { EntityManager, ObjectId } from '@mikro-orm/mongodb';
import { UserQuery } from '@modules/user/service/user-query.type';
import { Test, TestingModule } from '@nestjs/testing';
import { EntityNotFoundError } from '@shared/common';
import {
Expand All @@ -16,7 +18,6 @@ import {
} from '@shared/domain';
import { Page } from '@shared/domain/domainobject/page';
import { UserDO } from '@shared/domain/domainobject/user.do';
import { MongoMemoryDatabaseModule } from '@infra/database';
import { UserDORepo } from '@shared/repo/user/user-do.repo';
import {
cleanupCollections,
Expand All @@ -27,7 +28,6 @@ import {
userFactory,
} from '@shared/testing';
import { LegacyLogger } from '@src/core/logger';
import { UserQuery } from '@modules/user/service/user-query.type';

describe('UserRepo', () => {
let module: TestingModule;
Expand Down Expand Up @@ -234,6 +234,7 @@ describe('UserRepo', () => {
language: LanguageType.DE,
forcePasswordChange: false,
preferences: { firstLogin: true },
birthday: new Date(),
},
id.toHexString()
);
Expand Down Expand Up @@ -276,6 +277,7 @@ describe('UserRepo', () => {
outdatedSince: testEntity.outdatedSince,
lastLoginSystemChange: testEntity.lastLoginSystemChange,
previousExternalId: testEntity.previousExternalId,
birthday: testEntity.birthday,
})
);
});
Expand All @@ -299,6 +301,7 @@ describe('UserRepo', () => {
outdatedSince: new Date(),
lastLoginSystemChange: new Date(),
previousExternalId: 'someId',
birthday: new Date(),
},
'testId'
);
Expand All @@ -321,6 +324,7 @@ describe('UserRepo', () => {
outdatedSince: testDO.outdatedSince,
lastLoginSystemChange: testDO.lastLoginSystemChange,
previousExternalId: testDO.previousExternalId,
birthday: testDO.birthday,
});
});
});
Expand Down
4 changes: 3 additions & 1 deletion apps/server/src/shared/repo/user/user-do.repo.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { EntityName, FilterQuery, QueryOrderMap } from '@mikro-orm/core';
import { UserQuery } from '@modules/user/service/user-query.type';
import { Injectable } from '@nestjs/common';
import { EntityNotFoundError } from '@shared/common';
import {
Expand All @@ -17,7 +18,6 @@ import { RoleReference } from '@shared/domain/domainobject';
import { Page } from '@shared/domain/domainobject/page';
import { UserDO } from '@shared/domain/domainobject/user.do';
import { BaseDORepo, Scope } from '@shared/repo';
import { UserQuery } from '@modules/user/service/user-query.type';
import { UserScope } from './user.scope';

@Injectable()
Expand Down Expand Up @@ -109,6 +109,7 @@ export class UserDORepo extends BaseDORepo<UserDO, User, IUserProperties> {
lastLoginSystemChange: entity.lastLoginSystemChange,
outdatedSince: entity.outdatedSince,
previousExternalId: entity.previousExternalId,
birthday: entity.birthday,
});

if (entity.roles.isInitialized()) {
Expand All @@ -135,6 +136,7 @@ export class UserDORepo extends BaseDORepo<UserDO, User, IUserProperties> {
lastLoginSystemChange: entityDO.lastLoginSystemChange,
outdatedSince: entityDO.outdatedSince,
previousExternalId: entityDO.previousExternalId,
birthday: entityDO.birthday,
};
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { MongoMemoryDatabaseModule } from '@infra/database';
import { NotFoundError } from '@mikro-orm/core';
import { EntityManager, ObjectId } from '@mikro-orm/mongodb';
import { Test, TestingModule } from '@nestjs/testing';
import { MatchCreator, SortOrder, SystemEntity, User } from '@shared/domain';
import { MongoMemoryDatabaseModule } from '@infra/database';
import { cleanupCollections, importUserFactory, roleFactory, schoolFactory, userFactory } from '@shared/testing';
import { systemFactory } from '@shared/testing/factory/system.factory';
import { UserRepo } from './user.repo';
Expand Down Expand Up @@ -70,6 +70,7 @@ describe('user repo', () => {
'lastLoginSystemChange',
'outdatedSince',
'previousExternalId',
'birthday',
].sort()
);
});
Expand Down Expand Up @@ -133,6 +134,7 @@ describe('user repo', () => {
await em.persistAndFlush([userA, userB]);
em.clear();
});

it('should return right keys', async () => {
const result = await repo.findByExternalIdOrFail(userA.externalId as string, sys.id);
expect(Object.keys(result).sort()).toEqual(
Expand All @@ -158,6 +160,7 @@ describe('user repo', () => {
'lastLoginSystemChange',
'outdatedSince',
'previousExternalId',
'birthday',
].sort()
);
});
Expand Down
Loading