feat: checkNoteIdOrAlias in more alias service methods

This should prevent any interaction by a forbidden id

Signed-off-by: Philip Molares <philip.molares@udo.edu>
This commit is contained in:
Philip Molares 2022-02-06 22:09:22 +01:00
parent 6269c7f7bc
commit c891a95588
4 changed files with 17 additions and 17 deletions

View file

@ -21,7 +21,6 @@ import {
ApiNotFoundResponse, ApiNotFoundResponse,
ApiTags, ApiTags,
ApiUnauthorizedResponse, ApiUnauthorizedResponse,
ApiUnprocessableEntityResponse,
} from '@nestjs/swagger'; } from '@nestjs/swagger';
import { SessionGuard } from '../../../identity/session.guard'; import { SessionGuard } from '../../../identity/session.guard';
@ -39,7 +38,6 @@ import {
conflictDescription, conflictDescription,
notFoundDescription, notFoundDescription,
unauthorizedDescription, unauthorizedDescription,
unprocessableEntityDescription,
} from '../../utils/descriptions'; } from '../../utils/descriptions';
import { RequestUser } from '../../utils/request-user.decorator'; import { RequestUser } from '../../utils/request-user.decorator';
@ -58,6 +56,7 @@ export class AliasController {
} }
@Post() @Post()
@ApiBadRequestResponse({ description: badRequestDescription })
@ApiConflictResponse({ description: conflictDescription }) @ApiConflictResponse({ description: conflictDescription })
@ApiUnauthorizedResponse({ description: unauthorizedDescription }) @ApiUnauthorizedResponse({ description: unauthorizedDescription })
@ApiNotFoundResponse({ description: notFoundDescription }) @ApiNotFoundResponse({ description: notFoundDescription })
@ -104,8 +103,8 @@ export class AliasController {
@HttpCode(204) @HttpCode(204)
@ApiUnauthorizedResponse({ description: unauthorizedDescription }) @ApiUnauthorizedResponse({ description: unauthorizedDescription })
@ApiNotFoundResponse({ description: notFoundDescription }) @ApiNotFoundResponse({ description: notFoundDescription })
@ApiUnprocessableEntityResponse({ @ApiBadRequestResponse({
description: unprocessableEntityDescription, description: badRequestDescription,
}) })
async removeAlias( async removeAlias(
@RequestUser() user: User, @RequestUser() user: User,

View file

@ -16,11 +16,11 @@ import {
UseGuards, UseGuards,
} from '@nestjs/common'; } from '@nestjs/common';
import { import {
ApiBadRequestResponse,
ApiNoContentResponse, ApiNoContentResponse,
ApiOkResponse, ApiOkResponse,
ApiSecurity, ApiSecurity,
ApiTags, ApiTags,
ApiUnprocessableEntityResponse,
} from '@nestjs/swagger'; } from '@nestjs/swagger';
import { TokenAuthGuard } from '../../../auth/token.strategy'; import { TokenAuthGuard } from '../../../auth/token.strategy';
@ -32,7 +32,7 @@ import { AliasService } from '../../../notes/alias.service';
import { NotesService } from '../../../notes/notes.service'; import { NotesService } from '../../../notes/notes.service';
import { PermissionsService } from '../../../permissions/permissions.service'; import { PermissionsService } from '../../../permissions/permissions.service';
import { User } from '../../../users/user.entity'; import { User } from '../../../users/user.entity';
import { unprocessableEntityDescription } from '../../utils/descriptions'; import { badRequestDescription } from '../../utils/descriptions';
import { FullApi } from '../../utils/fullapi-decorator'; import { FullApi } from '../../utils/fullapi-decorator';
import { RequestUser } from '../../utils/request-user.decorator'; import { RequestUser } from '../../utils/request-user.decorator';
@ -103,8 +103,8 @@ export class AliasController {
description: 'The alias was deleted', description: 'The alias was deleted',
}) })
@FullApi @FullApi
@ApiUnprocessableEntityResponse({ @ApiBadRequestResponse({
description: unprocessableEntityDescription, description: badRequestDescription,
}) })
async removeAlias( async removeAlias(
@RequestUser() user: User, @RequestUser() user: User,

View file

@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file) * SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
* *
* SPDX-License-Identifier: AGPL-3.0-only * SPDX-License-Identifier: AGPL-3.0-only
*/ */
@ -36,6 +36,7 @@ export class AliasService {
* @param {Note} note - the note to add the alias to * @param {Note} note - the note to add the alias to
* @param {string} alias - the alias to add to the note * @param {string} alias - the alias to add to the note
* @throws {AlreadyInDBError} the alias is already in use. * @throws {AlreadyInDBError} the alias is already in use.
* @throws {ForbiddenIdError} the requested id or alias is forbidden
* @return {Alias} the new alias * @return {Alias} the new alias
*/ */
async addAlias(note: Note, alias: string): Promise<Alias> { async addAlias(note: Note, alias: string): Promise<Alias> {
@ -79,6 +80,7 @@ export class AliasService {
* Set the specified alias as the primary alias of the note. * Set the specified alias as the primary alias of the note.
* @param {Note} note - the note to change the primary alias * @param {Note} note - the note to change the primary alias
* @param {string} alias - the alias to be the new primary alias of the note * @param {string} alias - the alias to be the new primary alias of the note
* @throws {ForbiddenIdError} the requested id or alias is forbidden
* @throws {NotInDBError} the alias is not part of this note. * @throws {NotInDBError} the alias is not part of this note.
* @return {Alias} the new primary alias * @return {Alias} the new primary alias
*/ */
@ -87,6 +89,8 @@ export class AliasService {
let oldPrimaryId = ''; let oldPrimaryId = '';
let newPrimaryId = ''; let newPrimaryId = '';
this.notesService.checkNoteIdOrAlias(alias);
for (const anAlias of await note.aliases) { for (const anAlias of await note.aliases) {
// found old primary // found old primary
if (anAlias.primary) { if (anAlias.primary) {
@ -130,10 +134,12 @@ export class AliasService {
* Remove the specified alias from the note. * Remove the specified alias from the note.
* @param {Note} note - the note to remove the alias from * @param {Note} note - the note to remove the alias from
* @param {string} alias - the alias to remove from the note * @param {string} alias - the alias to remove from the note
* @throws {ForbiddenIdError} the requested id or alias is forbidden
* @throws {NotInDBError} the alias is not part of this note. * @throws {NotInDBError} the alias is not part of this note.
* @throws {PrimaryAliasDeletionForbiddenError} the primary alias can only be deleted if it's the only alias * @throws {PrimaryAliasDeletionForbiddenError} the primary alias can only be deleted if it's the only alias
*/ */
async removeAlias(note: Note, alias: string): Promise<Note> { async removeAlias(note: Note, alias: string): Promise<Note> {
this.notesService.checkNoteIdOrAlias(alias);
const primaryAlias = await getPrimaryAlias(note); const primaryAlias = await getPrimaryAlias(note);
if (primaryAlias === alias && (await note.aliases).length !== 1) { if (primaryAlias === alias && (await note.aliases).length !== 1) {

View file

@ -157,20 +157,15 @@ export class NotesService {
* @param {string} noteIdOrAlias - the notes id or alias * @param {string} noteIdOrAlias - the notes id or alias
* @return {Note} the note * @return {Note} the note
* @throws {NotInDBError} there is no note with this id or alias * @throws {NotInDBError} there is no note with this id or alias
* @throws {ForbiddenIdError} the requested id or alias is forbidden
*/ */
async getNoteByIdOrAlias(noteIdOrAlias: string): Promise<Note> { async getNoteByIdOrAlias(noteIdOrAlias: string): Promise<Note> {
this.logger.debug( this.logger.debug(
`Trying to find note '${noteIdOrAlias}'`, `Trying to find note '${noteIdOrAlias}'`,
'getNoteByIdOrAlias', 'getNoteByIdOrAlias',
); );
try {
this.checkNoteIdOrAlias(noteIdOrAlias); this.checkNoteIdOrAlias(noteIdOrAlias);
} catch (e) {
if (e instanceof ForbiddenIdError) {
throw new NotInDBError(e.message);
}
throw e;
}
/** /**
* This query gets the note's aliases, owner, groupPermissions (and the groups), userPermissions (and the users) and tags and * This query gets the note's aliases, owner, groupPermissions (and the groups), userPermissions (and the users) and tags and