Skip to content

Commit

Permalink
linter and refactor UC
Browse files Browse the repository at this point in the history
  • Loading branch information
virgilchiriac committed Oct 13, 2023
1 parent 43e97b7 commit 89555a8
Show file tree
Hide file tree
Showing 8 changed files with 83 additions and 124 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ApiProperty } from '@nestjs/swagger';
import { TimestampsResponse } from '../timestamps.response';
import { FileElementResponse, RichTextElementResponse } from '..';
import { FileElementResponse, RichTextElementResponse } from '../element';

export class SubmissionItemResponse {
constructor({ id, timestamps, completed, userId, elements }: SubmissionItemResponse) {
Expand Down
1 change: 0 additions & 1 deletion apps/server/src/modules/board/controller/mapper/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,5 @@ export * from './external-tool-element-response.mapper';
export * from './file-element-response.mapper';
export * from './link-element-response.mapper';
export * from './rich-text-element-response.mapper';
export * from './file-element-response.mapper';
export * from './submission-container-element-response.mapper';
export * from './submission-item-response.mapper';
7 changes: 3 additions & 4 deletions apps/server/src/modules/board/repo/recursive-save.visitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { Utils } from '@mikro-orm/core';
import { EntityManager } from '@mikro-orm/mongodb';
import {
AnyBoardDo,
AnyBoardNode,
BoardCompositeVisitor,
BoardNode,
Card,
Expand Down Expand Up @@ -194,9 +193,9 @@ export class RecursiveSaveVisitor implements BoardCompositeVisitor {
this.parentsMap.set(child.id, { boardNode: parentNode, position });
}

private saveRecursive(anyBoardNode: AnyBoardNode, anyBoardDo: AnyBoardDo): void {
this.createOrUpdateBoardNode(anyBoardNode);
this.visitChildren(anyBoardDo, anyBoardNode);
private saveRecursive(boardNode: BoardNode, anyBoardDo: AnyBoardDo): void {
this.createOrUpdateBoardNode(boardNode);
this.visitChildren(anyBoardDo, boardNode);
}

// TODO make private
Expand Down
51 changes: 51 additions & 0 deletions apps/server/src/modules/board/uc/base.uc.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { AnyBoardDo, EntityId, SubmissionItem, UserRoleEnum } from '@shared/domain';
import { ForbiddenException, forwardRef, Inject } from '@nestjs/common';
import { Action, AuthorizationService } from '../../authorization';
import { BoardDoAuthorizableService } from '../service';

export abstract class BaseUc {
constructor(
@Inject(forwardRef(() => AuthorizationService))
protected readonly authorizationService: AuthorizationService,
protected readonly boardDoAuthorizableService: BoardDoAuthorizableService
) {}

protected async checkPermission(
userId: EntityId,
boardDo: AnyBoardDo,
action: Action,
requiredUserRole?: UserRoleEnum
): Promise<void> {
const user = await this.authorizationService.getUserWithPermissions(userId);
const boardDoAuthorizable = await this.boardDoAuthorizableService.getBoardAuthorizable(boardDo);
if (requiredUserRole) {
boardDoAuthorizable.requiredUserRole = requiredUserRole;
}
const context = { action, requiredPermissions: [] };

return this.authorizationService.checkPermission(user, boardDoAuthorizable, context);
}

protected async isAuthorizedStudent(userId: EntityId, boardDo: AnyBoardDo): Promise<boolean> {
const boardDoAuthorizable = await this.boardDoAuthorizableService.getBoardAuthorizable(boardDo);
const userRoleEnum = boardDoAuthorizable.users.find((u) => u.userId === userId)?.userRoleEnum;

if (!userRoleEnum) {
throw new ForbiddenException('User not part of this board');
}

// TODO do this with permission instead of role and using authorizable rules
if (userRoleEnum === UserRoleEnum.STUDENT) {
return true;
}

return false;
}

protected async checkSubmissionItemEditPermission(userId: EntityId, submissionItem: SubmissionItem) {
if (submissionItem.userId !== userId) {
throw new ForbiddenException();
}
await this.checkPermission(userId, submissionItem, Action.read, UserRoleEnum.STUDENT);
}
}
26 changes: 6 additions & 20 deletions apps/server/src/modules/board/uc/board.uc.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,23 @@
import { Injectable } from '@nestjs/common';
import {
AnyBoardDo,
BoardExternalReference,
Card,
Column,
ColumnBoard,
ContentElementType,
EntityId,
} from '@shared/domain';
import { BoardExternalReference, Card, Column, ColumnBoard, ContentElementType, EntityId } from '@shared/domain';
import { LegacyLogger } from '@src/core/logger';
import { AuthorizationService } from '@src/modules/authorization/authorization.service';
import { Action } from '@src/modules/authorization/types/action.enum';
import { CardService, ColumnBoardService, ColumnService } from '../service';
import { BoardDoAuthorizableService } from '../service/board-do-authorizable.service';
import { BaseUc } from './base.uc';

@Injectable()
export class BoardUc {
export class BoardUc extends BaseUc {
constructor(
private readonly authorizationService: AuthorizationService,
private readonly boardDoAuthorizableService: BoardDoAuthorizableService,
protected readonly authorizationService: AuthorizationService,
protected readonly boardDoAuthorizableService: BoardDoAuthorizableService,
private readonly cardService: CardService,
private readonly columnBoardService: ColumnBoardService,
private readonly columnService: ColumnService,
private readonly logger: LegacyLogger
) {
super(authorizationService, boardDoAuthorizableService);
this.logger.setContext(BoardUc.name);
}

Expand Down Expand Up @@ -157,12 +151,4 @@ export class BoardUc {

await this.cardService.delete(card);
}

private async checkPermission(userId: EntityId, boardDo: AnyBoardDo, action: Action): Promise<void> {
const user = await this.authorizationService.getUserWithPermissions(userId);
const boardDoAuthorizable = await this.boardDoAuthorizableService.getBoardAuthorizable(boardDo);
const context = { action, requiredPermissions: [] };

return this.authorizationService.checkPermission(user, boardDoAuthorizable, context);
}
}
16 changes: 5 additions & 11 deletions apps/server/src/modules/board/uc/card.uc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,18 @@ import { LegacyLogger } from '@src/core/logger';
import { AuthorizationService } from '@src/modules/authorization/authorization.service';
import { Action } from '@src/modules/authorization/types/action.enum';
import { BoardDoAuthorizableService, CardService, ContentElementService } from '../service';
import { BaseUc } from './base.uc';

@Injectable()
export class CardUc {
export class CardUc extends BaseUc {
constructor(
private readonly authorizationService: AuthorizationService,
private readonly boardDoAuthorizableService: BoardDoAuthorizableService,
protected readonly authorizationService: AuthorizationService,
protected readonly boardDoAuthorizableService: BoardDoAuthorizableService,
private readonly cardService: CardService,
private readonly elementService: ContentElementService,
private readonly logger: LegacyLogger
) {
super(authorizationService, boardDoAuthorizableService);
this.logger.setContext(CardUc.name);
}

Expand Down Expand Up @@ -73,14 +75,6 @@ export class CardUc {
await this.elementService.move(element, targetCard, targetPosition);
}

private async checkPermission(userId: EntityId, boardDo: AnyBoardDo, action: Action): Promise<void> {
const user = await this.authorizationService.getUserWithPermissions(userId);
const boardDoAuthorizable = await this.boardDoAuthorizableService.getBoardAuthorizable(boardDo);
const context = { action, requiredPermissions: [] };

return this.authorizationService.checkPermission(user, boardDoAuthorizable, context);
}

private async filterAllowed<T extends AnyBoardDo>(userId: EntityId, boardDos: T[], action: Action): Promise<T[]> {
const user = await this.authorizationService.getUserWithPermissions(userId);

Expand Down
33 changes: 7 additions & 26 deletions apps/server/src/modules/board/uc/element.uc.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { ForbiddenException, forwardRef, Inject, Injectable, UnprocessableEntityException } from '@nestjs/common';
import {
AnyBoardDo,
AnyContentElementDo,
EntityId,
isSubmissionContainerElement,
Expand All @@ -13,17 +12,19 @@ import { Action, AuthorizationService } from '@src/modules/authorization';
import { AnyElementContentBody } from '../controller/dto';
import { BoardDoAuthorizableService, ContentElementService } from '../service';
import { SubmissionItemService } from '../service/submission-item.service';
import { BaseUc } from './base.uc';

@Injectable()
export class ElementUc {
export class ElementUc extends BaseUc {
constructor(
@Inject(forwardRef(() => AuthorizationService))
private readonly authorizationService: AuthorizationService,
private readonly boardDoAuthorizableService: BoardDoAuthorizableService,
protected readonly authorizationService: AuthorizationService,
protected readonly boardDoAuthorizableService: BoardDoAuthorizableService,
private readonly elementService: ContentElementService,
private readonly submissionItemService: SubmissionItemService,
private readonly logger: Logger
) {
super(authorizationService, boardDoAuthorizableService);
this.logger.setContext(ElementUc.name);
}

Expand All @@ -36,8 +37,9 @@ export class ElementUc {

const parent = await this.elementService.findParentOfId(elementId);

// TODO refactor
if (isSubmissionItem(parent)) {
await this.checkSubmissionPermission(userId, element, parent);
await this.checkSubmissionItemEditPermission(userId, parent);
} else {
await this.checkPermission(userId, element, Action.write);
}
Expand Down Expand Up @@ -78,25 +80,4 @@ export class ElementUc {

return submissionItem;
}

private async checkPermission(
userId: EntityId,
boardDo: AnyBoardDo,
action: Action,
requiredUserRole?: UserRoleEnum
): Promise<void> {
const user = await this.authorizationService.getUserWithPermissions(userId);
const boardDoAuthorizable = await this.boardDoAuthorizableService.getBoardAuthorizable(boardDo);
if (requiredUserRole) boardDoAuthorizable.requiredUserRole = requiredUserRole;
const context = { action, requiredPermissions: [] };

return this.authorizationService.checkPermission(user, boardDoAuthorizable, context);
}

private async checkSubmissionPermission(userId: EntityId, element: AnyBoardDo, parent: SubmissionItem) {
if (parent.userId !== userId) {
throw new ForbiddenException();
}
await this.checkPermission(userId, parent, Action.read, UserRoleEnum.STUDENT);
}
}
71 changes: 10 additions & 61 deletions apps/server/src/modules/board/uc/submission-item.uc.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,5 @@
import { BadRequestException, forwardRef, Inject, Injectable, UnprocessableEntityException } from '@nestjs/common';
import {
BadRequestException,
ForbiddenException,
forwardRef,
HttpException,
HttpStatus,
Inject,
Injectable,
UnprocessableEntityException,
} from '@nestjs/common';
import {
AnyBoardDo,
ContentElementType,
EntityId,
FileElement,
Expand All @@ -22,22 +12,21 @@ import {
UserBoardRoles,
UserRoleEnum,
} from '@shared/domain';
import { Logger } from '@src/core/logger';
import { AuthorizationService } from '@src/modules/authorization';
import { Action } from '@src/modules/authorization/types/action.enum';
import { BoardDoAuthorizableService, ContentElementService, SubmissionItemService } from '../service';
import { BaseUc } from './base.uc';

@Injectable()
export class SubmissionItemUc {
export class SubmissionItemUc extends BaseUc {
constructor(
@Inject(forwardRef(() => AuthorizationService))
private readonly authorizationService: AuthorizationService,
private readonly boardDoAuthorizableService: BoardDoAuthorizableService,
private readonly elementService: ContentElementService,
private readonly submissionItemService: SubmissionItemService,
private readonly logger: Logger
protected readonly authorizationService: AuthorizationService,
protected readonly boardDoAuthorizableService: BoardDoAuthorizableService,
protected readonly elementService: ContentElementService,
protected readonly submissionItemService: SubmissionItemService
) {
this.logger.setContext(SubmissionItemUc.name);
super(authorizationService, boardDoAuthorizableService);
}

async findSubmissionItems(
Expand Down Expand Up @@ -72,7 +61,7 @@ export class SubmissionItemUc {
completed: boolean
): Promise<SubmissionItem> {
const submissionItem = await this.submissionItemService.findById(submissionItemId);
await this.checkSubmissionItemPermission(userId, submissionItem);
await this.checkSubmissionItemEditPermission(userId, submissionItem);
await this.submissionItemService.update(submissionItem, completed);

return submissionItem;
Expand All @@ -89,8 +78,7 @@ export class SubmissionItemUc {

const submissionItem = await this.submissionItemService.findById(submissionItemId);

// TODO
// await this.checkPermission(userId, submissionItem, Action.write);
await this.checkSubmissionItemEditPermission(userId, submissionItem);

const element = await this.elementService.create(submissionItem, type);

Expand All @@ -100,43 +88,4 @@ export class SubmissionItemUc {

return element;
}

private async isAuthorizedStudent(userId: EntityId, boardDo: AnyBoardDo): Promise<boolean> {
const boardDoAuthorizable = await this.boardDoAuthorizableService.getBoardAuthorizable(boardDo);
const userRoleEnum = boardDoAuthorizable.users.find((u) => u.userId === userId)?.userRoleEnum;

if (!userRoleEnum) {
throw new ForbiddenException('User not part of this board');
}

// TODO do this with permission instead of role and using authorizable rules
if (userRoleEnum === UserRoleEnum.STUDENT) {
return true;
}

return false;
}

private async checkSubmissionItemPermission(userId: EntityId, submissionItem: SubmissionItem) {
await this.checkPermission(userId, submissionItem, Action.read, UserRoleEnum.STUDENT);
if (submissionItem.userId !== userId) {
throw new ForbiddenException();
}
}

private async checkPermission(
userId: EntityId,
boardDo: AnyBoardDo,
action: Action,
requiredUserRole?: UserRoleEnum
): Promise<void> {
const user = await this.authorizationService.getUserWithPermissions(userId);
const boardDoAuthorizable = await this.boardDoAuthorizableService.getBoardAuthorizable(boardDo);
if (requiredUserRole) {
boardDoAuthorizable.requiredUserRole = requiredUserRole;
}
const context = { action, requiredPermissions: [] };

return this.authorizationService.checkPermission(user, boardDoAuthorizable, context);
}
}

0 comments on commit 89555a8

Please sign in to comment.