Skip to content

Commit

Permalink
Merge branch 'refs/heads/main' into N21-2191-fix-lti-encryption
Browse files Browse the repository at this point in the history
  • Loading branch information
mrikallab committed Oct 9, 2024
2 parents 4e3f00b + ac4f35d commit 7be01c6
Show file tree
Hide file tree
Showing 24 changed files with 295 additions and 24 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Embedded, Entity, Property, Unique } from '@mikro-orm/core';

import { BaseEntityWithTimestamps } from '@shared/domain/entity/base.entity';
import { EntityId } from '@shared/domain/types';
import { ToolContextType } from '../../common/enum';
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { AuthorizableObject, DomainObject } from '@shared/domain/domain-object';
import { EntityId } from '@shared/domain/types';
import { MediaSourceAuthMethod } from '../enum';

export interface MediaSourceOauthConfigProps extends AuthorizableObject {
id: EntityId;

clientId: string;

clientSecret: string;

authEndpoint: string;

method: MediaSourceAuthMethod;
}

export class MediaSourceOauthConfig extends DomainObject<MediaSourceOauthConfigProps> {}
18 changes: 16 additions & 2 deletions apps/server/src/modules/user-license/domain/media-source.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
import { DomainObject } from '@shared/domain/domain-object';
import { AuthorizableObject, DomainObject } from '@shared/domain/domain-object';
import { MediaSourceOauthConfig } from './media-source-oauth-config';
import { MediaSourceDataFormat } from '../enum';

export interface MediaSourceProps {
export interface MediaSourceProps extends AuthorizableObject {
id: string;

name?: string;

sourceId: string;

format?: MediaSourceDataFormat;

config?: MediaSourceOauthConfig;
}

export class MediaSource extends DomainObject<MediaSourceProps> {
Expand All @@ -16,4 +22,12 @@ export class MediaSource extends DomainObject<MediaSourceProps> {
get sourceId(): string {
return this.props.sourceId;
}

get format(): MediaSourceDataFormat | undefined {
return this.props.format;
}

get config(): MediaSourceOauthConfig | undefined {
return this.props.config;
}
}
4 changes: 3 additions & 1 deletion apps/server/src/modules/user-license/entity/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export { UserLicenseType } from './user-license-type';
export { UserLicenseType } from '../enum/user-license-type';
export { MediaUserLicenseEntity, MediaUserLicenseEntityProps } from './media-user-license.entity';
export { UserLicenseEntity } from './user-license.entity';
export { MediaSourceEntity, MediaSourceEntityProps } from './media-source.entity';
export { MediaSourceDataFormat } from '../enum/media-source-data-format.enum';
export { MediaSourceAuthMethod } from '../enum/media-source-auth-method.enum';
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { Embeddable, Enum, Property } from '@mikro-orm/core';
import { ObjectId } from '@mikro-orm/mongodb';
import { MediaSourceAuthMethod } from '../enum/media-source-auth-method.enum';

export interface MediaSourceConfigEmbeddableProps {
_id: ObjectId;

clientId: string;

clientSecret: string;

authEndpoint: string;

method: MediaSourceAuthMethod;
}

@Embeddable()
export class MediaSourceConfigEmbeddable {
@Property()
_id: ObjectId;

@Property()
clientId: string;

@Property()
clientSecret: string;

@Property()
authEndpoint: string;

@Enum({ nullable: false })
method: MediaSourceAuthMethod;

constructor(props: MediaSourceConfigEmbeddableProps) {
this._id = props._id;
this.clientId = props.clientId;
this.clientSecret = props.clientSecret;
this.authEndpoint = props.authEndpoint;
this.method = props.method;
}
}
26 changes: 20 additions & 6 deletions apps/server/src/modules/user-license/entity/media-source.entity.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,44 @@
import { Entity, Index, Property } from '@mikro-orm/core';
import { Embedded, Entity, Index, Property } from '@mikro-orm/core';
import { BaseEntityWithTimestamps } from '@shared/domain/entity/base.entity';
import { EntityId } from '@shared/domain/types';
import { MediaSourceDataFormat } from '../enum/media-source-data-format.enum';
import { MediaSourceConfigEmbeddable } from './media-source-oauth-config.embeddable';

export interface MediaSourceEntityProps {
id?: EntityId;

name?: string;

sourceId: string;

config?: MediaSourceConfigEmbeddable;

format?: MediaSourceDataFormat;
}

@Entity({ tableName: 'media-sources' })
export class MediaSourceEntity extends BaseEntityWithTimestamps {
constructor(props: MediaSourceEntityProps) {
super();
if (props.id != null) {
if (props.id) {
this.id = props.id;
}
this.name = props.name;
this.sourceId = props.sourceId;
this.name = props.name;
this.format = props.format;
this.config = props.config;
}

@Property({ nullable: true })
name?: string;

@Index()
@Property()
sourceId: string;

@Property({ nullable: true })
name?: string;

@Property({ nullable: true })
format?: MediaSourceDataFormat;

@Embedded(() => MediaSourceConfigEmbeddable, { object: true, nullable: true })
config?: MediaSourceConfigEmbeddable;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Entity, ManyToOne, Property } from '@mikro-orm/core';
import { MediaSourceEntity } from './media-source.entity';
import { UserLicenseType } from './user-license-type';
import { UserLicenseType } from '../enum/user-license-type';
import { UserLicenseEntity, UserLicenseProps } from './user-license.entity';

export interface MediaUserLicenseEntityProps extends UserLicenseProps {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Entity, Enum, Index, ManyToOne } from '@mikro-orm/core';
import { BaseEntityWithTimestamps } from '@shared/domain/entity/base.entity';
import { User as UserEntity } from '@shared/domain/entity/user.entity';
import { EntityId } from '@shared/domain/types';
import { UserLicenseType } from './user-license-type';
import { UserLicenseType } from '../enum/user-license-type';

export interface UserLicenseProps {
id?: EntityId;
Expand Down
3 changes: 3 additions & 0 deletions apps/server/src/modules/user-license/enum/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export { UserLicenseType } from './user-license-type';
export { MediaSourceDataFormat } from './media-source-data-format.enum';
export { MediaSourceAuthMethod } from './media-source-auth-method.enum';
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export enum MediaSourceAuthMethod {
CLIENT_CREDENTIALS = 'CLIENT_CREDENTIALS',
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export enum MediaSourceDataFormat {
BILDUNGSLOGIN = 'BILDUNGSLOGIN',
}
13 changes: 7 additions & 6 deletions apps/server/src/modules/user-license/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
export { UserLicenseModule } from './user-license.module';
export { MediaUserLicenseService, MediaSourceService } from './service';
export { MediaUserLicense, MediaSource, MediaUserLicenseProps, MediaSourceProps, AnyUserLicense } from './domain';
export { UserLicenseType } from './entity/user-license-type';
export { AnyUserLicense, MediaSource, MediaSourceProps, MediaUserLicense, MediaUserLicenseProps } from './domain';
export { MediaSourceEntity } from './entity';
export { UserLicenseType } from './enum/user-license-type';
export { MediaSourceService, MediaUserLicenseService } from './service';
export {
mediaUserLicenseFactory,
mediaSourceFactory,
mediaSourceEntityFactory,
mediaSourceFactory,
mediaUserLicenseEntityFactory,
mediaUserLicenseFactory,
} from './testing';
export { UserLicenseModule } from './user-license.module';
3 changes: 2 additions & 1 deletion apps/server/src/modules/user-license/repo/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export { MediaSourceConfigMapper } from './media-source-config.mapper';
export { MediaSourceRepo } from './media-source.repo';
export { MediaUserLicenseRepo } from './media-user-license.repo';
export { UserLicenseQuery } from './user-license-query';
export { MediaSourceRepo } from './media-source.repo';
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { ObjectId } from '@mikro-orm/mongodb';
import { setupEntities } from '@shared/testing';
import { MediaSourceOauthConfig } from '../domain/media-source-oauth-config';
import { MediaSourceConfigEmbeddable } from '../entity/media-source-oauth-config.embeddable';
import { mediaSourceConfigEmbeddableFactory } from '../testing/media-source-config.embeddable.factory';
import { mediaSourceConfigFactory } from '../testing/media-source-config.factory';
import { MediaSourceConfigMapper } from './media-source-config.mapper';

describe('MediaSourceConfigMapper', () => {
describe('mapToDo', () => {
describe('when entity is passed', () => {
const setup = async () => {
await setupEntities();

const entity = mediaSourceConfigEmbeddableFactory.build();
const expected = new MediaSourceOauthConfig({
id: entity._id.toHexString(),
clientId: entity.clientId,
clientSecret: entity.clientSecret,
authEndpoint: entity.authEndpoint,
method: entity.method,
});

return { entity, expected };
};

it('should return an instance of config', async () => {
const { entity } = await setup();

const result = MediaSourceConfigMapper.mapToDo(entity);

expect(result).toBeInstanceOf(MediaSourceOauthConfig);
});

it('should return a do with all properties', async () => {
const { entity, expected } = await setup();

const result = MediaSourceConfigMapper.mapToDo(entity);

expect(result).toEqual(expected);
});
});
});

describe('mapToEntity', () => {
describe('when config do is passed', () => {
const setup = async () => {
await setupEntities();

const configDo = mediaSourceConfigFactory.build();
const expected = new MediaSourceConfigEmbeddable({
_id: new ObjectId(configDo.id),
clientId: configDo.getProps().clientId,
clientSecret: configDo.getProps().clientSecret,
authEndpoint: configDo.getProps().authEndpoint,
method: configDo.getProps().method,
});

return { configDo, expected };
};

it('should return an instance of config embeddable', async () => {
const { configDo } = await setup();

const result = MediaSourceConfigMapper.mapToEntity(configDo);

expect(result).toBeInstanceOf(MediaSourceConfigEmbeddable);
});

it('should return an embeddable with all properties', async () => {
const { configDo, expected } = await setup();

const result = MediaSourceConfigMapper.mapToEntity(configDo);

expect(result).toEqual(expected);
});
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { ObjectId } from '@mikro-orm/mongodb';
import { MediaSourceOauthConfig } from '../domain/media-source-oauth-config';
import { MediaSourceConfigEmbeddable } from '../entity/media-source-oauth-config.embeddable';

export class MediaSourceConfigMapper {
static mapToEntity(config: MediaSourceOauthConfig): MediaSourceConfigEmbeddable {
const configProps = config.getProps();

const configEmbeddable = new MediaSourceConfigEmbeddable({ ...configProps, _id: new ObjectId(configProps.id) });

return configEmbeddable;
}

static mapToDo(embeddable: MediaSourceConfigEmbeddable): MediaSourceOauthConfig {
const config = new MediaSourceOauthConfig({
id: embeddable._id.toHexString(),
clientId: embeddable.clientId,
clientSecret: embeddable.clientSecret,
method: embeddable.method,
authEndpoint: embeddable.authEndpoint,
});

return config;
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import { EntityData } from '@mikro-orm/core';
import { MediaSource } from '../domain';
import { MediaSourceEntity } from '../entity';
import { MediaSourceConfigMapper } from './media-source-config.mapper';

export class MediaSourceMapper {
public static mapToEntityProperties(entityDO: MediaSource): EntityData<MediaSourceEntity> {
const entityProps: EntityData<MediaSourceEntity> = {
name: entityDO.name,
sourceId: entityDO.sourceId,
config: entityDO.config ? MediaSourceConfigMapper.mapToEntity(entityDO.config) : undefined,
format: entityDO.format,
};

return entityProps;
Expand All @@ -17,6 +20,8 @@ export class MediaSourceMapper {
id: entity.id,
name: entity.name,
sourceId: entity.sourceId,
config: entity.config ? MediaSourceConfigMapper.mapToDo(entity.config) : undefined,
format: entity.format,
});

return domainObject;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import { MediaSource } from '../domain';
import { MediaSourceEntity } from '../entity';
import { mediaSourceEntityFactory, mediaSourceFactory } from '../testing';
import { MediaSourceRepo } from './media-source.repo';
import { MediaSourceConfigEmbeddable } from '../entity/media-source-oauth-config.embeddable';
import { mediaSourceConfigEmbeddableFactory } from '../testing/media-source-config.embeddable.factory';
import { MediaSourceConfigMapper } from './media-source-config.mapper';

describe(MediaSourceRepo.name, () => {
let module: TestingModule;
Expand Down Expand Up @@ -33,19 +36,22 @@ describe(MediaSourceRepo.name, () => {
describe('findBySourceId', () => {
describe('when a media source exists', () => {
const setup = async () => {
const mediaSource: MediaSourceEntity = mediaSourceEntityFactory.build();
const config: MediaSourceConfigEmbeddable = mediaSourceConfigEmbeddableFactory.build();

const mediaSource: MediaSourceEntity = mediaSourceEntityFactory.build({ config });

await em.persistAndFlush([mediaSource]);

em.clear();

return {
mediaSource,
config,
};
};

it('should return user licenses for user', async () => {
const { mediaSource } = await setup();
const { mediaSource, config } = await setup();

const result = await repo.findBySourceId(mediaSource.sourceId);

Expand All @@ -54,6 +60,8 @@ describe(MediaSourceRepo.name, () => {
id: mediaSource.id,
name: mediaSource.name,
sourceId: mediaSource.sourceId,
format: mediaSource.format,
config: MediaSourceConfigMapper.mapToDo(config),
})
);
});
Expand Down
Loading

0 comments on commit 7be01c6

Please sign in to comment.