Просмотр исходного кода

Merge pull request #11178 from growilabs/fix/183471-183550-bookmark-folder-authorization

fix(bookmark): Add owner authorization checks to bookmark folder api
mergify[bot] 2 недель назад
Родитель
Сommit
ad2de3a05e

+ 15 - 1
apps/app/src/server/models/bookmark-folder.ts

@@ -10,7 +10,11 @@ import type {
 
 import loggerFactory from '../../utils/logger';
 import { getOrCreateModel } from '../util/mongoose-utils';
-import { InvalidParentBookmarkFolderError } from './errors';
+import {
+  BookmarkFolderForbiddenError,
+  BookmarkFolderNotFoundError,
+  InvalidParentBookmarkFolderError,
+} from './errors';
 
 const logger = loggerFactory('growi:models:bookmark-folder');
 const Bookmark = monggoose.model('Bookmark');
@@ -28,6 +32,7 @@ export interface BookmarkFolderModel extends Model<BookmarkFolderDocument> {
   createByParameters(params: IBookmarkFolder): Promise<BookmarkFolderDocument>;
   deleteFolderAndChildren(
     bookmarkFolderId: Types.ObjectId | string,
+    ownerId?: Types.ObjectId | string,
   ): Promise<{ deletedCount: number }>;
   updateBookmarkFolder(
     bookmarkFolderId: string,
@@ -115,8 +120,17 @@ bookmarkFolderSchema.statics.createByParameters = async function (
 
 bookmarkFolderSchema.statics.deleteFolderAndChildren = async function (
   bookmarkFolderId: Types.ObjectId | string,
+  ownerId?: Types.ObjectId | string,
 ): Promise<{ deletedCount: number }> {
   const bookmarkFolder = await this.findById(bookmarkFolderId);
+  if (ownerId != null) {
+    if (bookmarkFolder == null) {
+      throw new BookmarkFolderNotFoundError('Bookmark folder not found');
+    }
+    if (bookmarkFolder.owner.toString() !== ownerId.toString()) {
+      throw new BookmarkFolderForbiddenError('Forbidden');
+    }
+  }
   // Delete parent and all children folder
   let deletedCount = 0;
   if (bookmarkFolder != null) {

+ 3 - 0
apps/app/src/server/models/errors.ts

@@ -16,3 +16,6 @@ export class NullUsernameToBeRegisteredError extends ExtensibleCustomError {}
 
 // Invalid Parent bookmark folder error
 export class InvalidParentBookmarkFolderError extends ExtensibleCustomError {}
+
+export class BookmarkFolderNotFoundError extends ExtensibleCustomError {}
+export class BookmarkFolderForbiddenError extends ExtensibleCustomError {}

+ 15 - 2
apps/app/src/server/routes/apiv3/bookmark-folder.ts

@@ -8,7 +8,11 @@ import type Crowi from '~/server/crowi';
 import { accessTokenParser } from '~/server/middlewares/access-token-parser';
 import { apiV3FormValidator } from '~/server/middlewares/apiv3-form-validator';
 import loginRequiredFactory from '~/server/middlewares/login-required';
-import { InvalidParentBookmarkFolderError } from '~/server/models/errors';
+import {
+  BookmarkFolderForbiddenError,
+  BookmarkFolderNotFoundError,
+  InvalidParentBookmarkFolderError,
+} from '~/server/models/errors';
 import { serializeBookmarkSecurely } from '~/server/models/serializers/bookmark-serializer';
 import loggerFactory from '~/utils/logger';
 
@@ -340,10 +344,19 @@ module.exports = (crowi: Crowi) => {
     async (req, res) => {
       const { id } = req.params;
       try {
-        const result = await BookmarkFolder.deleteFolderAndChildren(id);
+        const result = await BookmarkFolder.deleteFolderAndChildren(
+          id,
+          req.user._id,
+        );
         const { deletedCount } = result;
         return res.apiv3({ deletedCount });
       } catch (err) {
+        if (err instanceof BookmarkFolderNotFoundError) {
+          return res.apiv3Err('bookmark_folder_not_found', 404);
+        }
+        if (err instanceof BookmarkFolderForbiddenError) {
+          return res.apiv3Err('forbidden', 403);
+        }
         logger.error(err);
         return res.apiv3Err(err, 500);
       }