Bladeren bron

Add scopes to endpoints where AccessTokenParser has no scopes configured

Shun Miyazawa 10 maanden geleden
bovenliggende
commit
1a463ae23c

+ 4 - 2
apps/app/public/static/locales/en_US/commons.json

@@ -203,7 +203,8 @@
         "share_link": "Grants permission to view share link features.",
         "bookmark": "Grants permission to view bookmark features.",
         "questionnaire": "Grants permission to view questionnaire features.",
-        "attachment": "Grants permission to view attachment features."
+        "attachment": "Grants permission to view attachment features.",
+        "page_bulk_export": "Grants permission to view page bulk export features."
       }
     },
     "write": {
@@ -248,7 +249,8 @@
         "share_link": "Grants permission to edit share link features.",
         "bookmark": "Grants permission to edit bookmark features.",
         "questionnaire": "Grants permission to edit questionnaire features.",
-        "attachment": "Grants permission to edit attachment features."
+        "attachment": "Grants permission to edit attachment features.",
+        "page_bulk_export": "Grants permission to edit page bulk export features."
       }
     }
   }

+ 4 - 2
apps/app/public/static/locales/fr_FR/commons.json

@@ -189,7 +189,8 @@
         "share_link": "Accorde la permission de voir les fonctionnalités de lien de partage.",
         "bookmark": "Accorde la permission de voir les fonctionnalités de signet.",
         "questionnaire": "Accorde la permission de voir les fonctionnalités de questionnaire.",
-        "attachment": "Accorde la permission de voir les fonctionnalités de pièce jointe."
+        "attachment": "Accorde la permission de voir les fonctionnalités de pièce jointe.",
+        "page_bulk_export": "Accorde la permission de voir les fonctionnalités d'exportation en masse de pages."
       }
     },
     "write": {
@@ -234,7 +235,8 @@
         "share_link": "Accorde la permission de modifier les fonctionnalités de lien de partage.",
         "bookmark": "Accorde la permission de modifier les fonctionnalités de signet.",
         "questionnaire": "Accorde la permission de modifier les fonctionnalités de questionnaire.",
-        "attachment": "Accorde la permission de modifier les fonctionnalités de pièce jointe."
+        "attachment": "Accorde la permission de modifier les fonctionnalités de pièce jointe.",
+        "page_bulk_export": "Accorde la permission de modifier les fonctionnalités d'exportation en masse de pages."
       }
     }
   }

+ 4 - 2
apps/app/public/static/locales/ja_JP/commons.json

@@ -206,7 +206,8 @@
         "share_link": "共有リンク機能の閲覧権限を付与できます。",
         "bookmark": "ブックマーク機能の閲覧権限を付与できます。",
         "questionnaire": "アンケート機能の閲覧権限を付与できます。",
-        "attachment": "添付ファイル機能の閲覧権限を付与できます。"
+        "attachment": "添付ファイル機能の閲覧権限を付与できます。",
+        "page_bulk_export": "ページの一括エクスポート機能の閲覧権限を付与できます。"
       }
     },
     "write": {
@@ -251,7 +252,8 @@
         "share_link": "共有リンク機能の編集権限を付与できます。",
         "bookmark": "ブックマーク機能の編集権限を付与できます。",
         "questionnaire": "アンケート機能の編集権限を付与できます。",
-        "attachment": "添付ファイル機能の編集権限を付与できます。"
+        "attachment": "添付ファイル機能の編集権限を付与できます。",
+        "page_bulk_export": "ページの一括エクスポート機能の編集権限を付与できます。"
       }
     }
   }

+ 4 - 2
apps/app/public/static/locales/zh_CN/commons.json

@@ -206,7 +206,8 @@
         "share_link": "授予查看共享链接功能的权限。",
         "bookmark": "授予查看书签功能的权限。",
         "questionnaire": "授予查看问卷功能的权限。",
-        "attachment": "授予查看附件功能的权限。"
+        "attachment": "授予查看附件功能的权限。",
+        "page_bulk_export": "授予查看页面批量导出功能的权限。"
       }
     },
     "write": {
@@ -251,7 +252,8 @@
         "share_link": "授予编辑共享链接功能的权限。",
         "bookmark": "授予编辑书签功能的权限。",
         "questionnaire": "授予编辑问卷功能的权限。",
-        "attachment": "授予编辑附件功能的权限。"
+        "attachment": "授予编辑附件功能的权限。",
+        "page_bulk_export": "授予编辑页面批量导出功能的权限。"
       }
     }
   }

+ 26 - 24
apps/app/src/features/page-bulk-export/server/routes/apiv3/page-bulk-export.ts

@@ -1,3 +1,4 @@
+import { SCOPE } from '@growi/core/dist/interfaces';
 import { ErrorV3 } from '@growi/core/dist/models';
 import type { Request } from 'express';
 import { Router } from 'express';
@@ -18,6 +19,7 @@ interface AuthorizedRequest extends Request {
 }
 
 module.exports = (crowi: Crowi): Router => {
+  const accessTokenParser = crowi.accessTokenParser;
   const loginRequiredStrictly = require('~/server/middlewares/login-required')(crowi);
 
   const validators = {
@@ -28,31 +30,31 @@ module.exports = (crowi: Crowi): Router => {
     ],
   };
 
-  // TODO: https://redmine.weseek.co.jp/issues/166911
-  router.post('/', loginRequiredStrictly, validators.pageBulkExport, async(req: AuthorizedRequest, res: ApiV3Response) => {
-    const errors = validationResult(req);
-    if (!errors.isEmpty()) {
-      return res.status(400).json({ errors: errors.array() });
-    }
-
-    const { path, format, restartJob } = req.body;
-
-    try {
-      await pageBulkExportService?.createOrResetBulkExportJob(path, format, req.user, restartJob);
-      return res.apiv3({}, 204);
-    }
-    catch (err) {
-      logger.error(err);
-      if (err instanceof DuplicateBulkExportJobError) {
-        return res.apiv3Err(new ErrorV3(
-          'Duplicate bulk export job is in progress',
-          'page_export.duplicate_bulk_export_job_error', undefined,
-          { duplicateJob: { createdAt: err.duplicateJob.createdAt } },
-        ), 409);
+  router.post('/', accessTokenParser([SCOPE.WRITE.FEATURES.PAGE_BULK_EXPORT]),
+    loginRequiredStrictly, validators.pageBulkExport, async(req: AuthorizedRequest, res: ApiV3Response) => {
+      const errors = validationResult(req);
+      if (!errors.isEmpty()) {
+        return res.status(400).json({ errors: errors.array() });
       }
-      return res.apiv3Err(new ErrorV3('Failed to start bulk export', 'page_export.failed_to_export'));
-    }
-  });
+
+      const { path, format, restartJob } = req.body;
+
+      try {
+        await pageBulkExportService?.createOrResetBulkExportJob(path, format, req.user, restartJob);
+        return res.apiv3({}, 204);
+      }
+      catch (err) {
+        logger.error(err);
+        if (err instanceof DuplicateBulkExportJobError) {
+          return res.apiv3Err(new ErrorV3(
+            'Duplicate bulk export job is in progress',
+            'page_export.duplicate_bulk_export_job_error', undefined,
+            { duplicateJob: { createdAt: err.duplicateJob.createdAt } },
+          ), 409);
+        }
+        return res.apiv3Err(new ErrorV3('Failed to start bulk export', 'page_export.failed_to_export'));
+      }
+    });
 
   return router;
 

+ 1 - 0
packages/core/src/interfaces/scope.ts

@@ -47,6 +47,7 @@ const SCOPE_SEED_USER = {
     bookmark: {},
     questionnaire: {},
     attachment: {},
+    page_bulk_export: {},
   },
 } as const;
 

+ 3 - 4
packages/remark-attachment-refs/src/server/routes/refs.ts

@@ -1,4 +1,5 @@
 import type { IPage, IUser, IAttachment } from '@growi/core';
+import { SCOPE } from '@growi/core/dist/interfaces';
 import { serializeAttachmentSecurely } from '@growi/core/dist/models/serializers';
 import { OptionParser } from '@growi/core/dist/remark-plugins';
 import type { Request } from 'express';
@@ -83,8 +84,7 @@ export const routesFactory = (crowi): any => {
   /**
    * return an Attachment model
    */
-  // TODO: https://redmine.weseek.co.jp/issues/166911
-  router.get('/ref', accessTokenParser(), loginRequired, async(req: RequestWithUser, res) => {
+  router.get('/ref', accessTokenParser([SCOPE.READ.FEATURES.PAGE], { acceptLegacy: true }), loginRequired, async(req: RequestWithUser, res) => {
     const user = req.user;
     const { pagePath, fileNameOrId } = req.query;
     const filterXSS = new FilterXSS();
@@ -139,8 +139,7 @@ export const routesFactory = (crowi): any => {
   /**
    * return a list of Attachment
    */
-  // TODO: https://redmine.weseek.co.jp/issues/166911
-  router.get('/refs', accessTokenParser(), loginRequired, async(req: RequestWithUser, res) => {
+  router.get('/refs', accessTokenParser([SCOPE.READ.FEATURES.PAGE], { acceptLegacy: true }), loginRequired, async(req: RequestWithUser, res) => {
     const user = req.user;
     const { prefix, pagePath } = req.query;
     const options: Record<string, string | undefined> = JSON.parse(req.query.options?.toString() ?? '');

+ 2 - 1
packages/remark-lsx/src/server/index.ts

@@ -4,6 +4,7 @@ import { FilterXSS } from 'xss';
 
 import type { LsxApiOptions } from '../interfaces/api';
 
+import { SCOPE } from '@growi/core/dist/interfaces';
 import { listPages } from './routes/list-pages';
 
 const loginRequiredFallback = (req: Request, res: Response) => {
@@ -59,7 +60,7 @@ const middleware = (crowi: any, app: any): void => {
 
   app.get(
     '/_api/lsx',
-    accessTokenParser(), // TODO: https://redmine.weseek.co.jp/issues/166911
+    accessTokenParser([SCOPE.READ.FEATURES.PAGE], { acceptLegacy: true }),
     loginRequired,
     lsxValidator,
     paramValidator,