diff --git a/src/api/public/notes/notes.controller.ts b/src/api/public/notes/notes.controller.ts index 8addb3de7..2046915ab 100644 --- a/src/api/public/notes/notes.controller.ts +++ b/src/api/public/notes/notes.controller.ts @@ -4,6 +4,7 @@ * SPDX-License-Identifier: AGPL-3.0-only */ import { + BadRequestException, Body, Controller, Delete, @@ -17,6 +18,8 @@ import { import { ApiSecurity, ApiTags } from '@nestjs/swagger'; import { TokenAuthGuard } from '../../../auth/token.strategy'; +import { NotInDBError } from '../../../errors/errors'; +import { GroupsService } from '../../../groups/groups.service'; import { HistoryService } from '../../../history/history.service'; import { ConsoleLoggerService } from '../../../logger/console-logger.service'; import { MediaUploadDto } from '../../../media/media-upload.dto'; @@ -35,6 +38,7 @@ import { RevisionMetadataDto } from '../../../revisions/revision-metadata.dto'; import { RevisionDto } from '../../../revisions/revision.dto'; import { RevisionsService } from '../../../revisions/revisions.service'; import { User } from '../../../users/user.entity'; +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'; @@ -52,6 +56,8 @@ export class NotesController { constructor( private readonly logger: ConsoleLoggerService, private noteService: NotesService, + private userService: UsersService, + private groupService: GroupsService, private revisionsService: RevisionsService, private historyService: HistoryService, private mediaService: MediaService, @@ -222,6 +228,200 @@ export class NotesController { ); } + @UseInterceptors(GetNoteInterceptor) + @Permissions(Permission.READ) + @UseGuards(TokenAuthGuard, PermissionsGuard) + @Get(':noteIdOrAlias/metadata/permissions') + @OpenApi( + { + code: 200, + description: 'Get the permissions for a note', + dto: NotePermissionsDto, + }, + 403, + 404, + ) + async getPermissions( + @RequestUser() user: User, + @RequestNote() note: Note, + ): Promise { + return await this.noteService.toNotePermissionsDto(note); + } + + @UseInterceptors(GetNoteInterceptor) + @Permissions(Permission.OWNER) + @UseGuards(TokenAuthGuard, PermissionsGuard) + @OpenApi( + { + code: 200, + description: 'Set the permissions for a user on a note', + dto: NotePermissionsDto, + }, + 403, + 404, + ) + async setUserPermission( + @RequestUser() user: User, + @RequestNote() note: Note, + @Param('userName') username: string, + @Body() canEdit: boolean, + ): Promise { + try { + const permissionUser = await this.userService.getUserByUsername(username); + const returnedNote = await this.noteService.setUserPermission( + note, + permissionUser, + canEdit, + ); + return await this.noteService.toNotePermissionsDto(returnedNote); + } catch (e) { + if (e instanceof NotInDBError) { + throw new BadRequestException( + "Can't add user to permissions. User not known.", + ); + } + throw e; + } + } + + @UseInterceptors(GetNoteInterceptor) + @Permissions(Permission.OWNER) + @UseGuards(TokenAuthGuard, PermissionsGuard) + @Delete(':noteIdOrAlias/metadata/permissions/users/:userName') + @OpenApi( + { + code: 200, + description: 'Remove the permission for a user on a note', + dto: NotePermissionsDto, + }, + 403, + 404, + ) + async removeUserPermission( + @RequestUser() user: User, + @RequestNote() note: Note, + @Param('userName') username: string, + ): Promise { + try { + const permissionUser = await this.userService.getUserByUsername(username); + const returnedNote = await this.noteService.removeUserPermission( + note, + permissionUser, + ); + return await this.noteService.toNotePermissionsDto(returnedNote); + } catch (e) { + if (e instanceof NotInDBError) { + throw new BadRequestException( + "Can't remove user from permissions. User not known.", + ); + } + throw e; + } + } + + @UseInterceptors(GetNoteInterceptor) + @Permissions(Permission.OWNER) + @UseGuards(TokenAuthGuard, PermissionsGuard) + @Put(':noteIdOrAlias/metadata/permissions/groups/:groupName') + @OpenApi( + { + code: 200, + description: 'Set the permissions for a user on a note', + dto: NotePermissionsDto, + }, + 403, + 404, + ) + async setGroupPermission( + @RequestUser() user: User, + @RequestNote() note: Note, + @Param('groupName') groupName: string, + @Body() canEdit: boolean, + ): Promise { + try { + const permissionGroup = await this.groupService.getGroupByName(groupName); + const returnedNote = await this.noteService.setGroupPermission( + note, + permissionGroup, + canEdit, + ); + return await this.noteService.toNotePermissionsDto(returnedNote); + } catch (e) { + if (e instanceof NotInDBError) { + throw new BadRequestException( + "Can't add group to permissions. Group not known.", + ); + } + throw e; + } + } + + @UseInterceptors(GetNoteInterceptor) + @Permissions(Permission.OWNER) + @UseGuards(TokenAuthGuard, PermissionsGuard) + @Delete(':noteIdOrAlias/metadata/permissions/groups/:groupName') + @OpenApi( + { + code: 200, + description: 'Remove the permission for a group on a note', + dto: NotePermissionsDto, + }, + 403, + 404, + ) + async removeGroupPermission( + @RequestUser() user: User, + @RequestNote() note: Note, + @Param('groupName') groupName: string, + ): Promise { + try { + const permissionGroup = await this.groupService.getGroupByName(groupName); + const returnedNote = await this.noteService.removeGroupPermission( + note, + permissionGroup, + ); + return await this.noteService.toNotePermissionsDto(returnedNote); + } catch (e) { + if (e instanceof NotInDBError) { + throw new BadRequestException( + "Can't remove group from permissions. Group not known.", + ); + } + throw e; + } + } + + @UseInterceptors(GetNoteInterceptor) + @Permissions(Permission.OWNER) + @UseGuards(TokenAuthGuard, PermissionsGuard) + @Put(':noteIdOrAlias/metadata/permissions/owner') + @OpenApi( + { + code: 200, + description: 'Changes the owner of the note', + dto: NoteDto, + }, + 403, + 404, + ) + async changeOwner( + @RequestUser() user: User, + @RequestNote() note: Note, + @Body() newOwner: string, + ): Promise { + try { + const owner = await this.userService.getUserByUsername(newOwner); + return await this.noteService.toNoteDto( + await this.noteService.changeOwner(note, owner), + ); + } catch (e) { + if (e instanceof NotInDBError) { + throw new BadRequestException("Can't set new owner. User not known."); + } + throw e; + } + } + @UseInterceptors(GetNoteInterceptor) @Permissions(Permission.READ) @Get(':noteIdOrAlias/revisions')