refactor: move permissions decorator and guard into permissions directory

Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de>
This commit is contained in:
Tilman Vatteroth 2023-05-19 13:32:09 +02:00
parent 22f0abbfbe
commit 65fb110a1e
6 changed files with 17 additions and 17 deletions

View file

@ -23,13 +23,13 @@ import { MediaUploadDto } from '../../../media/media-upload.dto';
import { MediaService } from '../../../media/media.service';
import { MulterFile } from '../../../media/multer-file.interface';
import { Note } from '../../../notes/note.entity';
import { Permissions } from '../../../permissions/permissions.decorator';
import { Permission } from '../../../permissions/permissions.enum';
import { PermissionsGuard } from '../../../permissions/permissions.guard';
import { PermissionsService } from '../../../permissions/permissions.service';
import { User } from '../../../users/user.entity';
import { NoteHeaderInterceptor } from '../../utils/note-header.interceptor';
import { OpenApi } from '../../utils/openapi.decorator';
import { Permissions } from '../../utils/permissions.decorator';
import { PermissionsGuard } from '../../utils/permissions.guard';
import { RequestNote } from '../../utils/request-note.decorator';
import { RequestUser } from '../../utils/request-user.decorator';

View file

@ -30,7 +30,9 @@ import { NoteDto } from '../../../notes/note.dto';
import { Note } from '../../../notes/note.entity';
import { NoteMediaDeletionDto } from '../../../notes/note.media-deletion.dto';
import { NotesService } from '../../../notes/notes.service';
import { Permissions } from '../../../permissions/permissions.decorator';
import { Permission } from '../../../permissions/permissions.enum';
import { PermissionsGuard } from '../../../permissions/permissions.guard';
import { PermissionsService } from '../../../permissions/permissions.service';
import { RevisionMetadataDto } from '../../../revisions/revision-metadata.dto';
import { RevisionDto } from '../../../revisions/revision.dto';
@ -40,8 +42,6 @@ import { UsersService } from '../../../users/users.service';
import { GetNoteInterceptor } from '../../utils/get-note.interceptor';
import { MarkdownBody } from '../../utils/markdown-body.decorator';
import { OpenApi } from '../../utils/openapi.decorator';
import { Permissions } from '../../utils/permissions.decorator';
import { PermissionsGuard } from '../../utils/permissions.guard';
import { RequestNote } from '../../utils/request-note.decorator';
import { RequestUser } from '../../utils/request-user.decorator';

View file

@ -29,13 +29,13 @@ import { MediaUploadDto } from '../../../media/media-upload.dto';
import { MediaService } from '../../../media/media.service';
import { MulterFile } from '../../../media/multer-file.interface';
import { Note } from '../../../notes/note.entity';
import { Permissions } from '../../../permissions/permissions.decorator';
import { Permission } from '../../../permissions/permissions.enum';
import { PermissionsGuard } from '../../../permissions/permissions.guard';
import { PermissionsService } from '../../../permissions/permissions.service';
import { User } from '../../../users/user.entity';
import { NoteHeaderInterceptor } from '../../utils/note-header.interceptor';
import { OpenApi } from '../../utils/openapi.decorator';
import { Permissions } from '../../utils/permissions.decorator';
import { PermissionsGuard } from '../../utils/permissions.guard';
import { RequestNote } from '../../utils/request-note.decorator';
import { RequestUser } from '../../utils/request-user.decorator';

View file

@ -33,7 +33,9 @@ import { NoteDto } from '../../../notes/note.dto';
import { Note } from '../../../notes/note.entity';
import { NoteMediaDeletionDto } from '../../../notes/note.media-deletion.dto';
import { NotesService } from '../../../notes/notes.service';
import { Permissions } from '../../../permissions/permissions.decorator';
import { Permission } from '../../../permissions/permissions.enum';
import { PermissionsGuard } from '../../../permissions/permissions.guard';
import { PermissionsService } from '../../../permissions/permissions.service';
import { RevisionMetadataDto } from '../../../revisions/revision-metadata.dto';
import { RevisionDto } from '../../../revisions/revision.dto';
@ -43,8 +45,6 @@ import { UsersService } from '../../../users/users.service';
import { GetNoteInterceptor } from '../../utils/get-note.interceptor';
import { MarkdownBody } from '../../utils/markdown-body.decorator';
import { OpenApi } from '../../utils/openapi.decorator';
import { Permissions } from '../../utils/permissions.decorator';
import { PermissionsGuard } from '../../utils/permissions.guard';
import { RequestNote } from '../../utils/request-note.decorator';
import { RequestUser } from '../../utils/request-user.decorator';

View file

@ -1,17 +0,0 @@
/*
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { CustomDecorator, SetMetadata } from '@nestjs/common';
import { Permission } from '../../permissions/permissions.enum';
/**
* This decorator gathers the {@link Permission Permission} a user must hold for the {@link PermissionsGuard}
* @param permissions - an array of permissions. In practice this should always contain exactly one {@link Permission}
* @constructor
*/
// eslint-disable-next-line func-style,@typescript-eslint/naming-convention
export const Permissions = (...permissions: Permission[]): CustomDecorator =>
SetMetadata('permissions', permissions);

View file

@ -1,63 +0,0 @@
/*
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { ConsoleLoggerService } from '../../logger/console-logger.service';
import { NotesService } from '../../notes/notes.service';
import { Permission } from '../../permissions/permissions.enum';
import { PermissionsService } from '../../permissions/permissions.service';
import { getNote } from './get-note.interceptor';
import { CompleteRequest } from './request.type';
/**
* This guards controller methods from access, if the user has not the appropriate permissions.
* The permissions are set via the {@link Permissions} decorator in addition to this guard.
* If the check permission is not CREATE the method needs to extract the noteIdOrAlias from
* request.params['noteIdOrAlias'] or request.headers['hedgedoc-note'] to check if the user has the permission.
*/
@Injectable()
export class PermissionsGuard implements CanActivate {
constructor(
private readonly logger: ConsoleLoggerService,
private reflector: Reflector,
private permissionsService: PermissionsService,
private noteService: NotesService,
) {
this.logger.setContext(PermissionsGuard.name);
}
async canActivate(context: ExecutionContext): Promise<boolean> {
const permissions = this.reflector.get<Permission[]>(
'permissions',
context.getHandler(),
);
// If no permissions are set this is probably an error and this guard should not let the request pass
if (!permissions) {
this.logger.error(
'Could not find permission metadata. This should never happen. If you see this, please open an issue at https://github.com/hedgedoc/hedgedoc/issues',
);
return false;
}
const request: CompleteRequest = context.switchToHttp().getRequest();
const user = request.user ?? null;
// handle CREATE permissions, as this does not need any note
if (permissions[0] === Permission.CREATE) {
return this.permissionsService.mayCreate(user);
}
// Get the note from the parameter noteIdOrAlias or the http header hedgedoc-note
// Attention: This gets the note an additional time if used in conjunction with GetNoteInterceptor or NoteHeaderInterceptor
let noteIdOrAlias = request.params['noteIdOrAlias'];
if (noteIdOrAlias === undefined)
noteIdOrAlias = request.headers['hedgedoc-note'] as string;
const note = await getNote(this.noteService, noteIdOrAlias);
return await this.permissionsService.checkPermissionOnNote(
permissions[0],
user,
note,
);
}
}