Add permission checks for notes routes

Signed-off-by: Yannick Bungers <git@innay.de>
This commit is contained in:
Yannick Bungers 2021-02-16 09:33:42 +01:00
parent f40ed5db2a
commit a694d71fff
2 changed files with 52 additions and 14 deletions

View file

@ -15,6 +15,7 @@ import {
Post, Post,
Put, Put,
Request, Request,
UnauthorizedException,
UseGuards, UseGuards,
} from '@nestjs/common'; } from '@nestjs/common';
import { NotInDBError } from '../../../errors/errors'; import { NotInDBError } from '../../../errors/errors';
@ -33,6 +34,8 @@ import { NoteDto } from '../../../notes/note.dto';
import { NoteMetadataDto } from '../../../notes/note-metadata.dto'; import { NoteMetadataDto } from '../../../notes/note-metadata.dto';
import { RevisionMetadataDto } from '../../../revisions/revision-metadata.dto'; import { RevisionMetadataDto } from '../../../revisions/revision-metadata.dto';
import { RevisionDto } from '../../../revisions/revision.dto'; import { RevisionDto } from '../../../revisions/revision.dto';
import { PermissionsService } from '../../../permissions/permissions.service';
import { Note } from '../../../notes/note.entity';
@ApiTags('notes') @ApiTags('notes')
@ApiSecurity('token') @ApiSecurity('token')
@ -42,6 +45,7 @@ export class NotesController {
private readonly logger: ConsoleLoggerService, private readonly logger: ConsoleLoggerService,
private noteService: NotesService, private noteService: NotesService,
private revisionsService: RevisionsService, private revisionsService: RevisionsService,
private permissionsService: PermissionsService,
private historyService: HistoryService, private historyService: HistoryService,
) { ) {
this.logger.setContext(NotesController.name); this.logger.setContext(NotesController.name);
@ -54,7 +58,10 @@ export class NotesController {
@MarkdownBody() text: string, @MarkdownBody() text: string,
): Promise<NoteDto> { ): Promise<NoteDto> {
// ToDo: provide user for createNoteDto // ToDo: provide user for createNoteDto
this.logger.debug('Got raw markdown:\n' + text, 'createNote'); if (!this.permissionsService.mayCreate(req.user)) {
throw new UnauthorizedException('Creating note denied!');
}
this.logger.debug('Got raw markdown:\n' + text);
return this.noteService.toNoteDto( return this.noteService.toNoteDto(
await this.noteService.createNote(text, undefined, req.user), await this.noteService.createNote(text, undefined, req.user),
); );
@ -62,18 +69,24 @@ export class NotesController {
@UseGuards(TokenAuthGuard) @UseGuards(TokenAuthGuard)
@Get(':noteIdOrAlias') @Get(':noteIdOrAlias')
async getNote(@Request() req, @Param('noteIdOrAlias') noteIdOrAlias: string) { async getNote(
// ToDo: check if user is allowed to view this note @Request() req,
@Param('noteIdOrAlias') noteIdOrAlias: string,
): Promise<NoteDto> {
let note: Note;
try { try {
const note = await this.noteService.getNoteByIdOrAlias(noteIdOrAlias); note = await this.noteService.getNoteByIdOrAlias(noteIdOrAlias);
await this.historyService.createOrUpdateHistoryEntry(note, req.user);
return this.noteService.toNoteDto(note);
} catch (e) { } catch (e) {
if (e instanceof NotInDBError) { if (e instanceof NotInDBError) {
throw new NotFoundException(e.message); throw new NotFoundException(e.message);
} }
throw e; throw e;
} }
if (!this.permissionsService.mayRead(req.user, note)) {
throw new UnauthorizedException('Reading note denied!');
}
await this.historyService.createOrUpdateHistoryEntry(note, req.user);
return this.noteService.toNoteDto(note);
} }
@UseGuards(TokenAuthGuard) @UseGuards(TokenAuthGuard)
@ -83,7 +96,9 @@ export class NotesController {
@Param('noteAlias') noteAlias: string, @Param('noteAlias') noteAlias: string,
@MarkdownBody() text: string, @MarkdownBody() text: string,
): Promise<NoteDto> { ): Promise<NoteDto> {
// ToDo: check if user is allowed to view this note if (!this.permissionsService.mayCreate(req.user)) {
throw new UnauthorizedException('Creating note denied!');
}
this.logger.debug('Got raw markdown:\n' + text, 'createNamedNote'); this.logger.debug('Got raw markdown:\n' + text, 'createNamedNote');
return this.noteService.toNoteDto( return this.noteService.toNoteDto(
await this.noteService.createNote(text, noteAlias, req.user), await this.noteService.createNote(text, noteAlias, req.user),
@ -96,7 +111,10 @@ export class NotesController {
@Request() req, @Request() req,
@Param('noteIdOrAlias') noteIdOrAlias: string, @Param('noteIdOrAlias') noteIdOrAlias: string,
): Promise<void> { ): Promise<void> {
// ToDo: check if user is allowed to delete this note const note = await this.noteService.getNoteByIdOrAlias(noteIdOrAlias);
if (!this.permissionsService.isOwner(req.user, note)) {
throw new UnauthorizedException('Deleting note denied!');
}
this.logger.debug('Deleting note: ' + noteIdOrAlias, 'deleteNote'); this.logger.debug('Deleting note: ' + noteIdOrAlias, 'deleteNote');
try { try {
await this.noteService.deleteNoteByIdOrAlias(noteIdOrAlias); await this.noteService.deleteNoteByIdOrAlias(noteIdOrAlias);
@ -117,7 +135,10 @@ export class NotesController {
@Param('noteIdOrAlias') noteIdOrAlias: string, @Param('noteIdOrAlias') noteIdOrAlias: string,
@MarkdownBody() text: string, @MarkdownBody() text: string,
): Promise<NoteDto> { ): Promise<NoteDto> {
// ToDo: check if user is allowed to change this note const note = await this.noteService.getNoteByIdOrAlias(noteIdOrAlias);
if (!this.permissionsService.mayWrite(req.user, note)) {
throw new UnauthorizedException('Updating note denied!');
}
this.logger.debug('Got raw markdown:\n' + text, 'updateNote'); this.logger.debug('Got raw markdown:\n' + text, 'updateNote');
try { try {
return this.noteService.toNoteDto( return this.noteService.toNoteDto(
@ -138,7 +159,10 @@ export class NotesController {
@Request() req, @Request() req,
@Param('noteIdOrAlias') noteIdOrAlias: string, @Param('noteIdOrAlias') noteIdOrAlias: string,
): Promise<string> { ): Promise<string> {
// ToDo: check if user is allowed to view this notes content const note = await this.noteService.getNoteByIdOrAlias(noteIdOrAlias);
if (!this.permissionsService.mayRead(req.user, note)) {
throw new UnauthorizedException('Reading note denied!');
}
try { try {
return await this.noteService.getNoteContent(noteIdOrAlias); return await this.noteService.getNoteContent(noteIdOrAlias);
} catch (e) { } catch (e) {
@ -155,7 +179,10 @@ export class NotesController {
@Request() req, @Request() req,
@Param('noteIdOrAlias') noteIdOrAlias: string, @Param('noteIdOrAlias') noteIdOrAlias: string,
): Promise<NoteMetadataDto> { ): Promise<NoteMetadataDto> {
// ToDo: check if user is allowed to view this notes metadata const note = await this.noteService.getNoteByIdOrAlias(noteIdOrAlias);
if (!this.permissionsService.mayRead(req.user, note)) {
throw new UnauthorizedException('Reading note denied!');
}
try { try {
return this.noteService.toNoteMetadataDto( return this.noteService.toNoteMetadataDto(
await this.noteService.getNoteByIdOrAlias(noteIdOrAlias), await this.noteService.getNoteByIdOrAlias(noteIdOrAlias),
@ -175,7 +202,10 @@ export class NotesController {
@Param('noteIdOrAlias') noteIdOrAlias: string, @Param('noteIdOrAlias') noteIdOrAlias: string,
@Body() updateDto: NotePermissionsUpdateDto, @Body() updateDto: NotePermissionsUpdateDto,
): Promise<NotePermissionsDto> { ): Promise<NotePermissionsDto> {
// ToDo: check if user is allowed to view this notes permissions const note = await this.noteService.getNoteByIdOrAlias(noteIdOrAlias);
if (!this.permissionsService.isOwner(req.user, note)) {
throw new UnauthorizedException('Updating note denied!');
}
try { try {
return this.noteService.toNotePermissionsDto( return this.noteService.toNotePermissionsDto(
await this.noteService.updateNotePermissions(noteIdOrAlias, updateDto), await this.noteService.updateNotePermissions(noteIdOrAlias, updateDto),
@ -194,7 +224,10 @@ export class NotesController {
@Request() req, @Request() req,
@Param('noteIdOrAlias') noteIdOrAlias: string, @Param('noteIdOrAlias') noteIdOrAlias: string,
): Promise<RevisionMetadataDto[]> { ): Promise<RevisionMetadataDto[]> {
// ToDo: check if user is allowed to view this notes revisions const note = await this.noteService.getNoteByIdOrAlias(noteIdOrAlias);
if (!this.permissionsService.mayRead(req.user, note)) {
throw new UnauthorizedException('Reading note denied!');
}
try { try {
const revisions = await this.revisionsService.getAllRevisions( const revisions = await this.revisionsService.getAllRevisions(
noteIdOrAlias, noteIdOrAlias,
@ -219,7 +252,10 @@ export class NotesController {
@Param('noteIdOrAlias') noteIdOrAlias: string, @Param('noteIdOrAlias') noteIdOrAlias: string,
@Param('revisionId') revisionId: number, @Param('revisionId') revisionId: number,
): Promise<RevisionDto> { ): Promise<RevisionDto> {
// ToDo: check if user is allowed to view this notes revision const note = await this.noteService.getNoteByIdOrAlias(noteIdOrAlias);
if (!this.permissionsService.mayRead(req.user, note)) {
throw new UnauthorizedException('Reading note denied!');
}
try { try {
return this.revisionsService.toRevisionDto( return this.revisionsService.toRevisionDto(
await this.revisionsService.getRevision(noteIdOrAlias, revisionId), await this.revisionsService.getRevision(noteIdOrAlias, revisionId),

View file

@ -16,6 +16,7 @@ import { MeController } from './me/me.controller';
import { NotesController } from './notes/notes.controller'; import { NotesController } from './notes/notes.controller';
import { MediaController } from './media/media.controller'; import { MediaController } from './media/media.controller';
import { MonitoringController } from './monitoring/monitoring.controller'; import { MonitoringController } from './monitoring/monitoring.controller';
import { PermissionsModule } from '../../permissions/permissions.module';
@Module({ @Module({
imports: [ imports: [
@ -26,6 +27,7 @@ import { MonitoringController } from './monitoring/monitoring.controller';
MonitoringModule, MonitoringModule,
LoggerModule, LoggerModule,
MediaModule, MediaModule,
PermissionsModule,
], ],
controllers: [ controllers: [
MeController, MeController,