From 24b861c5aa324a2448ed5d1dad451152fb0efa03 Mon Sep 17 00:00:00 2001 From: Yi Yi Date: Thu, 10 Jun 2021 15:33:44 +0800 Subject: [PATCH 1/8] update the permission check of add/delete item's tag & category --- rest_server/src/controllers/item_controller.js | 17 ++++++++++++++--- rest_server/src/models/marketplace_item.js | 8 ++++---- rest_server/src/router.js | 8 ++++---- 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/rest_server/src/controllers/item_controller.js b/rest_server/src/controllers/item_controller.js index 25cd540f..3735f40c 100644 --- a/rest_server/src/controllers/item_controller.js +++ b/rest_server/src/controllers/item_controller.js @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. const { isNil } = require('lodash'); -const { MarketplaceItem } = require('../models'); +const { MarketplaceItem, ItemCategory } = require('../models'); const asyncHandler = require('./async_handler'); const yaml = require('js-yaml'); const protocolValidator = require('../utils/protocol'); @@ -246,7 +246,18 @@ const listCategories = asyncHandler(async (req, res, next) => { const addCategory = asyncHandler(async (req, res, next) => { try { let result = await MarketplaceItem.get(req.params.itemId); - if (checkReadPermission(req.userInfo, result)) { + if (checkWritePermission(req.tokenInfo, result)) { + const category = await ItemCategory.get(req.params.categoryId); + if ( + category.name === 'official example' && + req.tokenInfo.admin !== true + ) { + return next( + error.createForbidden( + 'Only admin can set "official example" category.', + ), + ); + } result = await MarketplaceItem.addCategory(result, req.params.categoryId); if (isNil(result)) { return next(error.createNotFound()); @@ -268,7 +279,7 @@ const addCategory = asyncHandler(async (req, res, next) => { const deleteCategory = asyncHandler(async (req, res, next) => { try { let result = await MarketplaceItem.get(req.params.itemId); - if (checkReadPermission(req.userInfo, result)) { + if (checkWritePermission(req.tokenInfo, result)) { result = await MarketplaceItem.deleteCategory( result, req.params.categoryId, diff --git a/rest_server/src/models/marketplace_item.js b/rest_server/src/models/marketplace_item.js index 78af945f..3e0705e6 100644 --- a/rest_server/src/models/marketplace_item.js +++ b/rest_server/src/models/marketplace_item.js @@ -373,17 +373,17 @@ class MarketplaceItem { return await handler(item, this.models); } - async addCategory(item, tagId) { + async addCategory(item, categoryId) { const handler = modelSyncHandler(async item => { - return await item.addItemCategory(tagId); + return await item.addItemCategory(categoryId); }); return await handler(item, this.models); } - async deleteCategory(item, tagId) { + async deleteCategory(item, categoryId) { const handler = modelSyncHandler(async item => { - return await item.removeItemCategory(tagId); + return await item.removeItemCategory(categoryId); }); return await handler(item, this.models); diff --git a/rest_server/src/router.js b/rest_server/src/router.js index c8bc5fc8..852323c3 100644 --- a/rest_server/src/router.js +++ b/rest_server/src/router.js @@ -26,8 +26,8 @@ router router .route('/items/:itemId/tag/:tagId') - .post(token.checkAuthAndGetUserInfo, itemController.addTag) - .delete(token.checkAuthAndGetUserInfo, itemController.deleteTag); + .post(token.checkAuthAndGetTokenInfo, itemController.addTag) + .delete(token.checkAuthAndGetTokenInfo, itemController.deleteTag); router .route('/items/:itemId/category') @@ -35,8 +35,8 @@ router router .route('/items/:itemId/category/:categoryId') - .post(token.checkAuthAndGetUserInfo, itemController.addCategory) - .delete(token.checkAuthAndGetUserInfo, itemController.deleteCategory); + .post(token.checkAuthAndGetTokenInfo, itemController.addCategory) + .delete(token.checkAuthAndGetTokenInfo, itemController.deleteCategory); router .route('/tags') From cdbaa7bafb29db6d02dfef703584c4ba9b6b75e8 Mon Sep 17 00:00:00 2001 From: Yi Yi Date: Thu, 10 Jun 2021 15:33:54 +0800 Subject: [PATCH 2/8] update the permission check of add/delete item's tag & category --- rest_server/src/controllers/item_controller.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rest_server/src/controllers/item_controller.js b/rest_server/src/controllers/item_controller.js index 3735f40c..5957dbf6 100644 --- a/rest_server/src/controllers/item_controller.js +++ b/rest_server/src/controllers/item_controller.js @@ -180,7 +180,7 @@ const listTags = asyncHandler(async (req, res, next) => { const addTag = asyncHandler(async (req, res, next) => { try { let result = await MarketplaceItem.get(req.params.itemId); - if (checkReadPermission(req.userInfo, result)) { + if (checkWritePermission(req.tokenInfo, result)) { result = await MarketplaceItem.addTag(result, req.params.tagId); if (isNil(result)) { return next(error.createNotFound()); @@ -202,7 +202,7 @@ const addTag = asyncHandler(async (req, res, next) => { const deleteTag = asyncHandler(async (req, res, next) => { try { let result = await MarketplaceItem.get(req.params.itemId); - if (checkReadPermission(req.userInfo, result)) { + if (checkWritePermission(req.tokenInfo, result)) { result = await MarketplaceItem.deleteTag(result, req.params.tagId); if (isNil(result)) { return next(error.createNotFound()); From 5dfa0a3e1fb137c36136377938aba7d3d60c03b8 Mon Sep 17 00:00:00 2001 From: Yi Yi Date: Thu, 10 Jun 2021 16:00:57 +0800 Subject: [PATCH 3/8] update --- .../src/controllers/item_controller.js | 58 +++++++++++-------- 1 file changed, 34 insertions(+), 24 deletions(-) diff --git a/rest_server/src/controllers/item_controller.js b/rest_server/src/controllers/item_controller.js index 5957dbf6..57d245aa 100644 --- a/rest_server/src/controllers/item_controller.js +++ b/rest_server/src/controllers/item_controller.js @@ -7,11 +7,19 @@ const yaml = require('js-yaml'); const protocolValidator = require('../utils/protocol'); const error = require('../models/error'); -function checkReadPermission(userInfo, item) { +const OFFICIAL_EXAMPLE = 'official example'; + +async function checkReadPermission(userInfo, item, categories) { if (userInfo.admin === true) { return true; } - if (userInfo.username === item.author) { + if (categories === undefined) { + categories = await MarketplaceItem.getCategories(item); + } + if ( + !categories.includes(OFFICIAL_EXAMPLE) && + userInfo.username === item.author + ) { return true; } if (item.isPublic) { @@ -27,11 +35,17 @@ function checkReadPermission(userInfo, item) { return false; } -function checkWritePermission(tokenInfo, item) { +async function checkWritePermission(tokenInfo, item, categories) { if (tokenInfo.admin === true) { return true; } - if (tokenInfo.username === item.author) { + if (categories === undefined) { + categories = await MarketplaceItem.getCategories(item); + } + if ( + !categories.includes(OFFICIAL_EXAMPLE) && + tokenInfo.username === item.author + ) { return true; } return false; @@ -96,7 +110,7 @@ const get = asyncHandler(async (req, res, next) => { if (isNil(result)) { return next(error.createNotFound()); } else { - if (checkReadPermission(req.userInfo, result)) { + if (await checkReadPermission(req.userInfo, result)) { res.status(200).json(result); } else { return next( @@ -114,7 +128,7 @@ const get = asyncHandler(async (req, res, next) => { const update = asyncHandler(async (req, res, next) => { try { let result = await MarketplaceItem.get(req.params.itemId); - if (checkWritePermission(req.tokenInfo, result)) { + if (await checkWritePermission(req.tokenInfo, result)) { result = await MarketplaceItem.update(req.params.itemId, req.body); if (isNil(result)) { return next(error.createNotFound()); @@ -136,7 +150,7 @@ const update = asyncHandler(async (req, res, next) => { const del = asyncHandler(async (req, res, next) => { try { let result = await MarketplaceItem.get(req.params.itemId); - if (checkWritePermission(req.tokenInfo, result)) { + if (await checkWritePermission(req.tokenInfo, result)) { result = await MarketplaceItem.del(req.params.itemId); if (isNil(result)) { return next(error.createNotFound()); @@ -158,7 +172,7 @@ const del = asyncHandler(async (req, res, next) => { const listTags = asyncHandler(async (req, res, next) => { try { let result = await MarketplaceItem.get(req.params.itemId); - if (checkReadPermission(req.userInfo, result)) { + if (await checkReadPermission(req.userInfo, result)) { result = await MarketplaceItem.getTags(result); if (isNil(result)) { return next(error.createNotFound()); @@ -180,7 +194,7 @@ const listTags = asyncHandler(async (req, res, next) => { const addTag = asyncHandler(async (req, res, next) => { try { let result = await MarketplaceItem.get(req.params.itemId); - if (checkWritePermission(req.tokenInfo, result)) { + if (await checkWritePermission(req.tokenInfo, result)) { result = await MarketplaceItem.addTag(result, req.params.tagId); if (isNil(result)) { return next(error.createNotFound()); @@ -202,7 +216,7 @@ const addTag = asyncHandler(async (req, res, next) => { const deleteTag = asyncHandler(async (req, res, next) => { try { let result = await MarketplaceItem.get(req.params.itemId); - if (checkWritePermission(req.tokenInfo, result)) { + if (await checkWritePermission(req.tokenInfo, result)) { result = await MarketplaceItem.deleteTag(result, req.params.tagId); if (isNil(result)) { return next(error.createNotFound()); @@ -223,14 +237,13 @@ const deleteTag = asyncHandler(async (req, res, next) => { const listCategories = asyncHandler(async (req, res, next) => { try { - let result = await MarketplaceItem.get(req.params.itemId); - if (checkReadPermission(req.userInfo, result)) { - result = await MarketplaceItem.getCategories(result); - if (isNil(result)) { - return next(error.createNotFound()); - } else { - res.status(200).json(result); - } + const result = await MarketplaceItem.get(req.params.itemId); + const categories = await MarketplaceItem.getCategories(result); + if (isNil(result)) { + return next(error.createNotFound()); + } + if (await checkReadPermission(req.userInfo, result, categories)) { + res.status(200).json(categories); } else { return next( error.createForbidden( @@ -246,12 +259,9 @@ const listCategories = asyncHandler(async (req, res, next) => { const addCategory = asyncHandler(async (req, res, next) => { try { let result = await MarketplaceItem.get(req.params.itemId); - if (checkWritePermission(req.tokenInfo, result)) { + if (await checkWritePermission(req.tokenInfo, result)) { const category = await ItemCategory.get(req.params.categoryId); - if ( - category.name === 'official example' && - req.tokenInfo.admin !== true - ) { + if (category.name === OFFICIAL_EXAMPLE && req.tokenInfo.admin !== true) { return next( error.createForbidden( 'Only admin can set "official example" category.', @@ -279,7 +289,7 @@ const addCategory = asyncHandler(async (req, res, next) => { const deleteCategory = asyncHandler(async (req, res, next) => { try { let result = await MarketplaceItem.get(req.params.itemId); - if (checkWritePermission(req.tokenInfo, result)) { + if (await checkWritePermission(req.tokenInfo, result)) { result = await MarketplaceItem.deleteCategory( result, req.params.categoryId, From 5167afea30095323eac3a2193bb26fa1fd49b1b0 Mon Sep 17 00:00:00 2001 From: Yi Yi Date: Thu, 10 Jun 2021 17:26:34 +0800 Subject: [PATCH 4/8] update --- .../src/controllers/item_controller.js | 6 +- rest_server/src/models/marketplace_item.js | 99 ++++++++++++------- 2 files changed, 65 insertions(+), 40 deletions(-) diff --git a/rest_server/src/controllers/item_controller.js b/rest_server/src/controllers/item_controller.js index 57d245aa..4b810c01 100644 --- a/rest_server/src/controllers/item_controller.js +++ b/rest_server/src/controllers/item_controller.js @@ -16,8 +16,9 @@ async function checkReadPermission(userInfo, item, categories) { if (categories === undefined) { categories = await MarketplaceItem.getCategories(item); } + const categoriesArray = categories.map(category => category.name); if ( - !categories.includes(OFFICIAL_EXAMPLE) && + !categoriesArray.includes(OFFICIAL_EXAMPLE) && userInfo.username === item.author ) { return true; @@ -42,8 +43,9 @@ async function checkWritePermission(tokenInfo, item, categories) { if (categories === undefined) { categories = await MarketplaceItem.getCategories(item); } + const categoriesArray = categories.map(category => category.name); if ( - !categories.includes(OFFICIAL_EXAMPLE) && + !categoriesArray.includes(OFFICIAL_EXAMPLE) && tokenInfo.username === item.author ) { return true; diff --git a/rest_server/src/models/marketplace_item.js b/rest_server/src/models/marketplace_item.js index 3e0705e6..fe131666 100644 --- a/rest_server/src/models/marketplace_item.js +++ b/rest_server/src/models/marketplace_item.js @@ -4,6 +4,8 @@ const { isNil, toLower } = require('lodash'); const { Op, fn, col, where, cast } = require('sequelize'); const modelSyncHandler = require('./model_init_handler'); +const OFFICIAL_EXAMPLE = 'official example'; + class MarketplaceItem { constructor(sequelize, DataTypes) { this.orm = sequelize.define('MarketplaceItem', { @@ -123,44 +125,6 @@ class MarketplaceItem { }, ]; } - if (!userInfo.admin) { - filterStatement[Op.or] = [ - { - isPublic: { - [Op.eq]: true, - }, - }, - { - [Op.and]: [ - { - isPrivate: { - [Op.eq]: true, - }, - }, - { - author: { - [Op.eq]: userInfo.username, - }, - }, - ], - }, - { - [Op.and]: [ - { - isPublic: { - [Op.eq]: false, - }, - isPrivate: { - [Op.eq]: false, - }, - groupList: { - [Op.overlap]: userInfo.groupList, - }, - }, - ], - }, - ]; - } const havings = []; const havingArrayAgg = (queryParameter, colName) => { @@ -177,6 +141,65 @@ class MarketplaceItem { havingArrayAgg(tags, 'ItemTags.name'); havingArrayAgg(categories, 'ItemCategories.name'); + if (!userInfo.admin) { + if (filterStatement[Op.and] === undefined) { + filterStatement[Op.and] = []; + } + filterStatement[Op.and].push({ + [Op.or]: [ + { + isPublic: { + [Op.eq]: true, + }, + }, + { + [Op.and]: [ + { + isPrivate: { + [Op.eq]: true, + }, + }, + { + author: { + [Op.eq]: userInfo.username, + }, + }, + ], + }, + { + [Op.and]: [ + { + isPublic: { + [Op.eq]: false, + }, + isPrivate: { + [Op.eq]: false, + }, + groupList: { + [Op.overlap]: userInfo.groupList, + }, + }, + ], + }, + ], + }); + + havings.push({ + [Op.not]: { + [Op.and]: [ + { + isPrivate: true, + }, + where( + fn('array_agg', col('ItemCategories.name')), + Op.contains, + cast([OFFICIAL_EXAMPLE], 'varchar[]'), + ), + ], + }, + }); + } + const items = await this.orm.findAll({ where: filterStatement, having: havings, From a8ef12743f518def02925f568ef6e9863eb1d2d3 Mon Sep 17 00:00:00 2001 From: Yi Yi Date: Thu, 10 Jun 2021 18:03:50 +0800 Subject: [PATCH 5/8] use Array.prototype.some() instead of ...map().includes() --- rest_server/src/controllers/item_controller.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/rest_server/src/controllers/item_controller.js b/rest_server/src/controllers/item_controller.js index 4b810c01..3f8f8f9a 100644 --- a/rest_server/src/controllers/item_controller.js +++ b/rest_server/src/controllers/item_controller.js @@ -16,9 +16,8 @@ async function checkReadPermission(userInfo, item, categories) { if (categories === undefined) { categories = await MarketplaceItem.getCategories(item); } - const categoriesArray = categories.map(category => category.name); if ( - !categoriesArray.includes(OFFICIAL_EXAMPLE) && + !categories.some(category => category.name === OFFICIAL_EXAMPLE) && userInfo.username === item.author ) { return true; @@ -43,9 +42,8 @@ async function checkWritePermission(tokenInfo, item, categories) { if (categories === undefined) { categories = await MarketplaceItem.getCategories(item); } - const categoriesArray = categories.map(category => category.name); if ( - !categoriesArray.includes(OFFICIAL_EXAMPLE) && + !categories.some(category => category.name === OFFICIAL_EXAMPLE) && tokenInfo.username === item.author ) { return true; From 7ce86301eb04ff331af0698c7fa436f6f943b3f3 Mon Sep 17 00:00:00 2001 From: Yi Yi Date: Fri, 11 Jun 2021 15:08:27 +0800 Subject: [PATCH 6/8] move all OFFICIAL_EXAMPLE to a same place --- rest_server/.eslintrc.js | 1 + rest_server/package-lock.json | 210 ++++++++++++++++++ rest_server/package.json | 1 + .../src/controllers/item_controller.js | 10 +- rest_server/src/models/item_category.js | 2 + rest_server/src/models/marketplace_item.js | 5 +- 6 files changed, 220 insertions(+), 9 deletions(-) diff --git a/rest_server/.eslintrc.js b/rest_server/.eslintrc.js index 4731d993..290d6297 100644 --- a/rest_server/.eslintrc.js +++ b/rest_server/.eslintrc.js @@ -5,6 +5,7 @@ module.exports = { es6: true, }, extends: ['standard', 'plugin:prettier/recommended', 'prettier'], + parser: '@babel/eslint-parser', parserOptions: { sourceType: 'module', }, diff --git a/rest_server/package-lock.json b/rest_server/package-lock.json index 0baf6f18..708b9200 100644 --- a/rest_server/package-lock.json +++ b/rest_server/package-lock.json @@ -13,6 +13,55 @@ "@babel/highlight": "^7.10.4" } }, + "@babel/generator": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.5.tgz", + "integrity": "sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz", + "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.14.5", + "@babel/template": "^7.14.5", + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz", + "integrity": "sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.14.5.tgz", + "integrity": "sha512-R1PXiz31Uc0Vxy4OEOm07x0oSjKAdPPCh3tPivn/Eo8cvz6gveAeuyUUPB21Hoiif0uoPQSSdhIPS3352nvdyQ==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz", + "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5" + } + }, "@babel/helper-validator-identifier": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", @@ -30,6 +79,135 @@ "js-tokens": "^4.0.0" } }, + "@babel/parser": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.5.tgz", + "integrity": "sha512-TM8C+xtH/9n1qzX+JNHi7AN2zHMTiPUtspO0ZdHflW8KaskkALhMmuMHb4bCmNdv9VAPzJX3/bXqkVLnAvsPfg==", + "dev": true + }, + "@babel/template": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz", + "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/parser": "^7.14.5", + "@babel/types": "^7.14.5" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", + "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.14.5" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", + "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", + "dev": true + }, + "@babel/highlight": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", + "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + } + } + }, + "@babel/traverse": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.5.tgz", + "integrity": "sha512-G3BiS15vevepdmFqmUc9X+64y0viZYygubAMO8SvBmKARuF6CPSZtH4Ng9vi/lrWlZFGe3FWdXNy835akH8Glg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/generator": "^7.14.5", + "@babel/helper-function-name": "^7.14.5", + "@babel/helper-hoist-variables": "^7.14.5", + "@babel/helper-split-export-declaration": "^7.14.5", + "@babel/parser": "^7.14.5", + "@babel/types": "^7.14.5", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", + "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.14.5" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", + "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", + "dev": true + }, + "@babel/highlight": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", + "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "@babel/types": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", + "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "to-fast-properties": "^2.0.0" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", + "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", + "dev": true + } + } + }, "@types/color-name": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", @@ -173,6 +351,20 @@ "follow-redirects": "^1.10.0" } }, + "babel-eslint": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz", + "integrity": "sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.7.0", + "@babel/traverse": "^7.7.0", + "@babel/types": "^7.7.0", + "eslint-visitor-keys": "^1.0.0", + "resolve": "^1.12.0" + } + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -1562,6 +1754,12 @@ "esprima": "^4.0.0" } }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, "json-merge-patch": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-merge-patch/-/json-merge-patch-0.2.3.tgz", @@ -2487,6 +2685,12 @@ } } }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, "spdx-correct": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", @@ -2702,6 +2906,12 @@ "os-tmpdir": "~1.0.2" } }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, "toidentifier": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", diff --git a/rest_server/package.json b/rest_server/package.json index 3db0adf3..5acf5763 100644 --- a/rest_server/package.json +++ b/rest_server/package.json @@ -30,6 +30,7 @@ "url-join": "^4.0.1" }, "devDependencies": { + "babel-eslint": "^10.1.0", "eslint": "^6.8.0", "eslint-config-prettier": "^6.10.1", "eslint-config-standard": "^14.1.1", diff --git a/rest_server/src/controllers/item_controller.js b/rest_server/src/controllers/item_controller.js index 3f8f8f9a..86eadc37 100644 --- a/rest_server/src/controllers/item_controller.js +++ b/rest_server/src/controllers/item_controller.js @@ -7,8 +7,6 @@ const yaml = require('js-yaml'); const protocolValidator = require('../utils/protocol'); const error = require('../models/error'); -const OFFICIAL_EXAMPLE = 'official example'; - async function checkReadPermission(userInfo, item, categories) { if (userInfo.admin === true) { return true; @@ -17,7 +15,7 @@ async function checkReadPermission(userInfo, item, categories) { categories = await MarketplaceItem.getCategories(item); } if ( - !categories.some(category => category.name === OFFICIAL_EXAMPLE) && + !categories.some(category => category.name === ItemCategory.OFFICIAL_EXAMPLE) && userInfo.username === item.author ) { return true; @@ -43,7 +41,7 @@ async function checkWritePermission(tokenInfo, item, categories) { categories = await MarketplaceItem.getCategories(item); } if ( - !categories.some(category => category.name === OFFICIAL_EXAMPLE) && + !categories.some(category => category.name === ItemCategory.OFFICIAL_EXAMPLE) && tokenInfo.username === item.author ) { return true; @@ -261,10 +259,10 @@ const addCategory = asyncHandler(async (req, res, next) => { let result = await MarketplaceItem.get(req.params.itemId); if (await checkWritePermission(req.tokenInfo, result)) { const category = await ItemCategory.get(req.params.categoryId); - if (category.name === OFFICIAL_EXAMPLE && req.tokenInfo.admin !== true) { + if (category.name === ItemCategory.OFFICIAL_EXAMPLE && req.tokenInfo.admin !== true) { return next( error.createForbidden( - 'Only admin can set "official example" category.', + `Only admin can set "${ItemCategory.OFFICIAL_EXAMPLE}" category.`, ), ); } diff --git a/rest_server/src/models/item_category.js b/rest_server/src/models/item_category.js index 538c4489..4366a48d 100644 --- a/rest_server/src/models/item_category.js +++ b/rest_server/src/models/item_category.js @@ -4,6 +4,8 @@ const { isNil } = require('lodash'); const modelSyncHandler = require('./model_init_handler'); class ItemCategory { + static OFFICIAL_EXAMPLE = 'official example'; + constructor(sequelize, DataTypes) { this.orm = sequelize.define('ItemCategory', { id: { diff --git a/rest_server/src/models/marketplace_item.js b/rest_server/src/models/marketplace_item.js index fe131666..312653c1 100644 --- a/rest_server/src/models/marketplace_item.js +++ b/rest_server/src/models/marketplace_item.js @@ -3,8 +3,7 @@ const { isNil, toLower } = require('lodash'); const { Op, fn, col, where, cast } = require('sequelize'); const modelSyncHandler = require('./model_init_handler'); - -const OFFICIAL_EXAMPLE = 'official example'; +const ItemCategory = require('./item_category'); class MarketplaceItem { constructor(sequelize, DataTypes) { @@ -193,7 +192,7 @@ class MarketplaceItem { where( fn('array_agg', col('ItemCategories.name')), Op.contains, - cast([OFFICIAL_EXAMPLE], 'varchar[]'), + cast([ItemCategory.OFFICIAL_EXAMPLE], 'varchar[]'), ), ], }, From 61453a389afab5bdb7d1db84d621b555fedc8f18 Mon Sep 17 00:00:00 2001 From: Yi Yi Date: Fri, 11 Jun 2021 15:37:52 +0800 Subject: [PATCH 7/8] fix --- rest_server/.eslintrc.js | 1 - rest_server/package-lock.json | 210 ------------------ rest_server/package.json | 1 - .../src/controllers/item_controller.js | 13 +- rest_server/src/models/item_category.js | 4 +- 5 files changed, 12 insertions(+), 217 deletions(-) diff --git a/rest_server/.eslintrc.js b/rest_server/.eslintrc.js index 290d6297..4731d993 100644 --- a/rest_server/.eslintrc.js +++ b/rest_server/.eslintrc.js @@ -5,7 +5,6 @@ module.exports = { es6: true, }, extends: ['standard', 'plugin:prettier/recommended', 'prettier'], - parser: '@babel/eslint-parser', parserOptions: { sourceType: 'module', }, diff --git a/rest_server/package-lock.json b/rest_server/package-lock.json index 708b9200..0baf6f18 100644 --- a/rest_server/package-lock.json +++ b/rest_server/package-lock.json @@ -13,55 +13,6 @@ "@babel/highlight": "^7.10.4" } }, - "@babel/generator": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.5.tgz", - "integrity": "sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA==", - "dev": true, - "requires": { - "@babel/types": "^7.14.5", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" - } - }, - "@babel/helper-function-name": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz", - "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.14.5", - "@babel/template": "^7.14.5", - "@babel/types": "^7.14.5" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz", - "integrity": "sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==", - "dev": true, - "requires": { - "@babel/types": "^7.14.5" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.14.5.tgz", - "integrity": "sha512-R1PXiz31Uc0Vxy4OEOm07x0oSjKAdPPCh3tPivn/Eo8cvz6gveAeuyUUPB21Hoiif0uoPQSSdhIPS3352nvdyQ==", - "dev": true, - "requires": { - "@babel/types": "^7.14.5" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz", - "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==", - "dev": true, - "requires": { - "@babel/types": "^7.14.5" - } - }, "@babel/helper-validator-identifier": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", @@ -79,135 +30,6 @@ "js-tokens": "^4.0.0" } }, - "@babel/parser": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.5.tgz", - "integrity": "sha512-TM8C+xtH/9n1qzX+JNHi7AN2zHMTiPUtspO0ZdHflW8KaskkALhMmuMHb4bCmNdv9VAPzJX3/bXqkVLnAvsPfg==", - "dev": true - }, - "@babel/template": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz", - "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.14.5", - "@babel/parser": "^7.14.5", - "@babel/types": "^7.14.5" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", - "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", - "dev": true, - "requires": { - "@babel/highlight": "^7.14.5" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", - "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", - "dev": true - }, - "@babel/highlight": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", - "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.14.5", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - } - } - }, - "@babel/traverse": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.5.tgz", - "integrity": "sha512-G3BiS15vevepdmFqmUc9X+64y0viZYygubAMO8SvBmKARuF6CPSZtH4Ng9vi/lrWlZFGe3FWdXNy835akH8Glg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.14.5", - "@babel/generator": "^7.14.5", - "@babel/helper-function-name": "^7.14.5", - "@babel/helper-hoist-variables": "^7.14.5", - "@babel/helper-split-export-declaration": "^7.14.5", - "@babel/parser": "^7.14.5", - "@babel/types": "^7.14.5", - "debug": "^4.1.0", - "globals": "^11.1.0" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", - "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", - "dev": true, - "requires": { - "@babel/highlight": "^7.14.5" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", - "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", - "dev": true - }, - "@babel/highlight": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", - "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.14.5", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "@babel/types": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", - "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.14.5", - "to-fast-properties": "^2.0.0" - }, - "dependencies": { - "@babel/helper-validator-identifier": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", - "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", - "dev": true - } - } - }, "@types/color-name": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", @@ -351,20 +173,6 @@ "follow-redirects": "^1.10.0" } }, - "babel-eslint": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz", - "integrity": "sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.7.0", - "@babel/traverse": "^7.7.0", - "@babel/types": "^7.7.0", - "eslint-visitor-keys": "^1.0.0", - "resolve": "^1.12.0" - } - }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -1754,12 +1562,6 @@ "esprima": "^4.0.0" } }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true - }, "json-merge-patch": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-merge-patch/-/json-merge-patch-0.2.3.tgz", @@ -2685,12 +2487,6 @@ } } }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - }, "spdx-correct": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", @@ -2906,12 +2702,6 @@ "os-tmpdir": "~1.0.2" } }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true - }, "toidentifier": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", diff --git a/rest_server/package.json b/rest_server/package.json index 5acf5763..3db0adf3 100644 --- a/rest_server/package.json +++ b/rest_server/package.json @@ -30,7 +30,6 @@ "url-join": "^4.0.1" }, "devDependencies": { - "babel-eslint": "^10.1.0", "eslint": "^6.8.0", "eslint-config-prettier": "^6.10.1", "eslint-config-standard": "^14.1.1", diff --git a/rest_server/src/controllers/item_controller.js b/rest_server/src/controllers/item_controller.js index 86eadc37..694f3958 100644 --- a/rest_server/src/controllers/item_controller.js +++ b/rest_server/src/controllers/item_controller.js @@ -15,7 +15,9 @@ async function checkReadPermission(userInfo, item, categories) { categories = await MarketplaceItem.getCategories(item); } if ( - !categories.some(category => category.name === ItemCategory.OFFICIAL_EXAMPLE) && + !categories.some( + category => category.name === ItemCategory.OFFICIAL_EXAMPLE, + ) && userInfo.username === item.author ) { return true; @@ -41,7 +43,9 @@ async function checkWritePermission(tokenInfo, item, categories) { categories = await MarketplaceItem.getCategories(item); } if ( - !categories.some(category => category.name === ItemCategory.OFFICIAL_EXAMPLE) && + !categories.some( + category => category.name === ItemCategory.OFFICIAL_EXAMPLE, + ) && tokenInfo.username === item.author ) { return true; @@ -259,7 +263,10 @@ const addCategory = asyncHandler(async (req, res, next) => { let result = await MarketplaceItem.get(req.params.itemId); if (await checkWritePermission(req.tokenInfo, result)) { const category = await ItemCategory.get(req.params.categoryId); - if (category.name === ItemCategory.OFFICIAL_EXAMPLE && req.tokenInfo.admin !== true) { + if ( + category.name === ItemCategory.OFFICIAL_EXAMPLE && + req.tokenInfo.admin !== true + ) { return next( error.createForbidden( `Only admin can set "${ItemCategory.OFFICIAL_EXAMPLE}" category.`, diff --git a/rest_server/src/models/item_category.js b/rest_server/src/models/item_category.js index 4366a48d..820bc8d9 100644 --- a/rest_server/src/models/item_category.js +++ b/rest_server/src/models/item_category.js @@ -4,9 +4,9 @@ const { isNil } = require('lodash'); const modelSyncHandler = require('./model_init_handler'); class ItemCategory { - static OFFICIAL_EXAMPLE = 'official example'; - constructor(sequelize, DataTypes) { + this.OFFICIAL_EXAMPLE = 'official example'; + this.orm = sequelize.define('ItemCategory', { id: { type: DataTypes.STRING, From 5c34f2ce264b57a20710d8074d310a057ea63723 Mon Sep 17 00:00:00 2001 From: Yi Yi Date: Fri, 11 Jun 2021 15:44:42 +0800 Subject: [PATCH 8/8] merge checkReadPermission/checkWritePermission --- .../src/controllers/item_controller.js | 33 +++++++------------ 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/rest_server/src/controllers/item_controller.js b/rest_server/src/controllers/item_controller.js index 694f3958..6a7cb059 100644 --- a/rest_server/src/controllers/item_controller.js +++ b/rest_server/src/controllers/item_controller.js @@ -7,8 +7,8 @@ const yaml = require('js-yaml'); const protocolValidator = require('../utils/protocol'); const error = require('../models/error'); -async function checkReadPermission(userInfo, item, categories) { - if (userInfo.admin === true) { +async function checkWritePermission(tokenInfo, item, categories) { + if (tokenInfo.admin === true) { return true; } if (categories === undefined) { @@ -18,11 +18,18 @@ async function checkReadPermission(userInfo, item, categories) { !categories.some( category => category.name === ItemCategory.OFFICIAL_EXAMPLE, ) && - userInfo.username === item.author + tokenInfo.username === item.author ) { return true; } - if (item.isPublic) { + return false; +} + +async function checkReadPermission(userInfo, item, categories) { + if ( + item.isPublic || + (await checkWritePermission(userInfo, item, categories)) + ) { return true; } if (!item.isPrivate && (userInfo.grouplist && item.groupList)) { @@ -35,24 +42,6 @@ async function checkReadPermission(userInfo, item, categories) { return false; } -async function checkWritePermission(tokenInfo, item, categories) { - if (tokenInfo.admin === true) { - return true; - } - if (categories === undefined) { - categories = await MarketplaceItem.getCategories(item); - } - if ( - !categories.some( - category => category.name === ItemCategory.OFFICIAL_EXAMPLE, - ) && - tokenInfo.username === item.author - ) { - return true; - } - return false; -} - const list = asyncHandler(async (req, res, next) => { try { const result = await MarketplaceItem.list(