diff --git a/packages/core/admin/ee/middlewares/features-routes/routes.js b/packages/core/admin/ee/middlewares/features-routes/routes.js index 249bfde4f8..1612012426 100644 --- a/packages/core/admin/ee/middlewares/features-routes/routes.js +++ b/packages/core/admin/ee/middlewares/features-routes/routes.js @@ -24,7 +24,7 @@ module.exports = { config: { policies: [ 'admin::isAuthenticatedAdmin', - ['admin::hasPermissions', ['admin::provider-login.read']], + { name: 'admin::hasPermissions', options: { actions: ['admin::provider-login.read'] } }, ], }, }, @@ -35,7 +35,7 @@ module.exports = { config: { policies: [ 'admin::isAuthenticatedAdmin', - ['admin::hasPermissions', ['admin::provider-login.update']], + { name: 'admin::hasPermissions', options: { actions: ['admin::provider-login.update'] } }, ], }, }, diff --git a/packages/core/admin/server/config/policies/hasPermissions.js b/packages/core/admin/server/config/policies/hasPermissions.js index 48d64723e6..628d996da2 100644 --- a/packages/core/admin/server/config/policies/hasPermissions.js +++ b/packages/core/admin/server/config/policies/hasPermissions.js @@ -23,9 +23,11 @@ const inputModifiers = [ ]; module.exports = createPolicyFactory( - input => { - const permissions = input.map(val => - inputModifiers.find(modifier => modifier.check(val)).transform(val) + options => { + const { actions } = options; + + const permissions = actions.map(action => + inputModifiers.find(modifier => modifier.check(action)).transform(action) ); return (ctx, next) => { diff --git a/packages/core/admin/server/routes.js b/packages/core/admin/server/routes.js index f0877f130d..2ebb67dc55 100644 --- a/packages/core/admin/server/routes.js +++ b/packages/core/admin/server/routes.js @@ -8,7 +8,7 @@ module.exports = [ config: { policies: [ 'admin::isAuthenticatedAdmin', - ['admin::hasPermissions', ['admin::marketplace.read']], + { name: 'admin::hasPermissions', options: { actions: ['admin::marketplace.read'] } }, ], }, }, @@ -37,7 +37,10 @@ module.exports = [ config: { policies: [ 'admin::isAuthenticatedAdmin', - ['admin::hasPermissions', ['admin::marketplace.plugins.install']], + { + name: 'admin::hasPermissions', + options: { actions: ['admin::marketplace.plugins.install'] }, + }, ], }, }, @@ -48,7 +51,10 @@ module.exports = [ config: { policies: [ 'admin::isAuthenticatedAdmin', - ['admin::hasPermissions', ['admin::marketplace.plugins.uninstall']], + { + name: 'admin::hasPermissions', + options: { actions: ['admin::marketplace.plugins.uninstall'] }, + }, ], }, }, @@ -94,7 +100,7 @@ module.exports = [ config: { policies: [ 'admin::isAuthenticatedAdmin', - ['admin::hasPermissions', ['admin::webhooks.read']], + { name: 'admin::hasPermissions', options: { actions: ['admin::webhooks.read'] } }, ], }, }, @@ -105,7 +111,7 @@ module.exports = [ config: { policies: [ 'admin::isAuthenticatedAdmin', - ['admin::hasPermissions', ['admin::webhooks.create']], + { name: 'admin::hasPermissions', options: { actions: ['admin::webhooks.create'] } }, ], }, }, @@ -116,7 +122,7 @@ module.exports = [ config: { policies: [ 'admin::isAuthenticatedAdmin', - ['admin::hasPermissions', ['admin::webhooks.read']], + { name: 'admin::hasPermissions', options: { actions: ['admin::webhooks.read'] } }, ], }, }, @@ -127,7 +133,7 @@ module.exports = [ config: { policies: [ 'admin::isAuthenticatedAdmin', - ['admin::hasPermissions', ['admin::webhooks.update']], + { name: 'admin::hasPermissions', options: { actions: ['admin::webhooks.update'] } }, ], }, }, @@ -138,7 +144,7 @@ module.exports = [ config: { policies: [ 'admin::isAuthenticatedAdmin', - ['admin::hasPermissions', ['admin::webhooks.delete']], + { name: 'admin::hasPermissions', options: { actions: ['admin::webhooks.delete'] } }, ], }, }, @@ -149,7 +155,7 @@ module.exports = [ config: { policies: [ 'admin::isAuthenticatedAdmin', - ['admin::hasPermissions', ['admin::webhooks.delete']], + { name: 'admin::hasPermissions', options: { actions: ['admin::webhooks.delete'] } }, ], }, }, @@ -190,7 +196,10 @@ module.exports = [ path: '/users', handler: 'user.create', config: { - policies: ['admin::isAuthenticatedAdmin', ['admin::hasPermissions', ['admin::users.create']]], + policies: [ + 'admin::isAuthenticatedAdmin', + { name: 'admin::hasPermissions', options: { actions: ['admin::users.create'] } }, + ], }, }, { @@ -198,7 +207,10 @@ module.exports = [ path: '/users', handler: 'user.find', config: { - policies: ['admin::isAuthenticatedAdmin', ['admin::hasPermissions', ['admin::users.read']]], + policies: [ + 'admin::isAuthenticatedAdmin', + { name: 'admin::hasPermissions', options: { actions: ['admin::users.read'] } }, + ], }, }, { @@ -206,7 +218,10 @@ module.exports = [ path: '/users/:id', handler: 'user.findOne', config: { - policies: ['admin::isAuthenticatedAdmin', ['admin::hasPermissions', ['admin::users.read']]], + policies: [ + 'admin::isAuthenticatedAdmin', + { name: 'admin::hasPermissions', options: { actions: ['admin::users.read'] } }, + ], }, }, { @@ -214,7 +229,10 @@ module.exports = [ path: '/users/:id', handler: 'user.update', config: { - policies: ['admin::isAuthenticatedAdmin', ['admin::hasPermissions', ['admin::users.update']]], + policies: [ + 'admin::isAuthenticatedAdmin', + { name: 'admin::hasPermissions', options: { actions: ['admin::users.update'] } }, + ], }, }, { @@ -222,7 +240,7 @@ module.exports = [ path: '/users/:id', handler: 'user.deleteOne', config: { - policies: [['admin::hasPermissions', ['admin::users.delete']]], + policies: [{ name: 'admin::hasPermissions', options: { actions: ['admin::users.delete'] } }], }, }, { @@ -230,7 +248,7 @@ module.exports = [ path: '/users/batch-delete', handler: 'user.deleteMany', config: { - policies: [['admin::hasPermissions', ['admin::users.delete']]], + policies: [{ name: 'admin::hasPermissions', options: { actions: ['admin::users.delete'] } }], }, }, { @@ -238,7 +256,10 @@ module.exports = [ path: '/roles/:id/permissions', handler: 'role.getPermissions', config: { - policies: ['admin::isAuthenticatedAdmin', ['admin::hasPermissions', ['admin::roles.read']]], + policies: [ + 'admin::isAuthenticatedAdmin', + { name: 'admin::hasPermissions', options: { actions: ['admin::roles.read'] } }, + ], }, }, { @@ -246,7 +267,10 @@ module.exports = [ path: '/roles/:id/permissions', handler: 'role.updatePermissions', config: { - policies: ['admin::isAuthenticatedAdmin', ['admin::hasPermissions', ['admin::roles.update']]], + policies: [ + 'admin::isAuthenticatedAdmin', + { name: 'admin::hasPermissions', options: { actions: ['admin::roles.update'] } }, + ], }, }, { @@ -254,7 +278,10 @@ module.exports = [ path: '/roles/:id', handler: 'role.findOne', config: { - policies: ['admin::isAuthenticatedAdmin', ['admin::hasPermissions', ['admin::roles.read']]], + policies: [ + 'admin::isAuthenticatedAdmin', + { name: 'admin::hasPermissions', options: { actions: ['admin::roles.read'] } }, + ], }, }, { @@ -262,7 +289,10 @@ module.exports = [ path: '/roles', handler: 'role.findAll', config: { - policies: ['admin::isAuthenticatedAdmin', ['admin::hasPermissions', ['admin::roles.read']]], + policies: [ + 'admin::isAuthenticatedAdmin', + { name: 'admin::hasPermissions', options: { actions: ['admin::roles.read'] } }, + ], }, }, { @@ -270,7 +300,10 @@ module.exports = [ path: '/roles/:id', handler: 'role.update', config: { - policies: ['admin::isAuthenticatedAdmin', ['admin::hasPermissions', ['admin::roles.update']]], + policies: [ + 'admin::isAuthenticatedAdmin', + { name: 'admin::hasPermissions', options: { actions: ['admin::roles.update'] } }, + ], }, }, { diff --git a/packages/core/admin/server/validation/policies/hasPermissions.js b/packages/core/admin/server/validation/policies/hasPermissions.js index 5f69c43348..00f09a13b9 100644 --- a/packages/core/admin/server/validation/policies/hasPermissions.js +++ b/packages/core/admin/server/validation/policies/hasPermissions.js @@ -3,30 +3,32 @@ const _ = require('lodash'); const { yup, formatYupErrors } = require('@strapi/utils'); -const hasPermissionsSchema = yup.array().of( - yup.lazy(val => { - if (_.isArray(val)) { - return yup - .array() - .of(yup.string()) - .min(1) - .max(2); - } +const hasPermissionsSchema = yup.object({ + actions: yup.array().of( + yup.lazy(val => { + if (_.isArray(val)) { + return yup + .array() + .of(yup.string()) + .min(1) + .max(2); + } - if (_.isString(val)) { - return yup.string(); - } + if (_.isString(val)) { + return yup.string().required(); + } - return yup.object().shape({ - action: yup.string().required(), - subject: yup.string(), - }); - }) -); + return yup.object().shape({ + action: yup.string().required(), + subject: yup.string(), + }); + }) + ), +}); -const validateHasPermissionsInput = data => { +const validateHasPermissionsInput = options => { try { - return hasPermissionsSchema.validateSync(data, { strict: true, abortEarly: true }); + return hasPermissionsSchema.validateSync(options, { strict: true, abortEarly: true }); } catch (e) { throw new Error(formatYupErrors(e)); } diff --git a/packages/core/content-manager/config/policies/hasPermissions.js b/packages/core/content-manager/config/policies/hasPermissions.js index 56c432d517..d963a12641 100644 --- a/packages/core/content-manager/config/policies/hasPermissions.js +++ b/packages/core/content-manager/config/policies/hasPermissions.js @@ -6,7 +6,7 @@ const { const { validateHasPermissionsInput } = require('../../validation/policies/hasPermissions'); module.exports = createPolicyFactory( - (actions, { hasAtLeastOne = false } = {}) => (ctx, next) => { + ({ actions = [], hasAtLeastOne = false } = {}) => (ctx, next) => { const { state: { userAbility, isAuthenticatedAdmin }, params: { model }, diff --git a/packages/core/content-manager/config/routes.json b/packages/core/content-manager/config/routes.json deleted file mode 100644 index 91172460ad..0000000000 --- a/packages/core/content-manager/config/routes.json +++ /dev/null @@ -1,275 +0,0 @@ -{ - "routes": [ - { - "method": "GET", - "path": "/content-types", - "handler": "content-types.findContentTypes", - "config": { - "policies": [] - } - }, - { - "method": "GET", - "path": "/content-types-settings", - "handler": "content-types.findContentTypesSettings", - "config": { - "policies": [] - } - }, - { - "method": "GET", - "path": "/content-types/:uid/configuration", - "handler": "content-types.findContentTypeConfiguration", - "config": { - "policies": [] - } - }, - { - "method": "PUT", - "path": "/content-types/:uid/configuration", - "handler": "content-types.updateContentTypeConfiguration", - "config": { - "policies": ["admin::isAuthenticatedAdmin"] - } - }, - - { - "method": "GET", - "path": "/components", - "handler": "components.findComponents", - "config": { - "policies": [] - } - }, - { - "method": "GET", - "path": "/components/:uid/configuration", - "handler": "components.findComponentConfiguration", - "config": { - "policies": [] - } - }, - { - "method": "PUT", - "path": "/components/:uid/configuration", - "handler": "components.updateComponentConfiguration", - "config": { - "policies": [] - } - }, - - { - "method": "POST", - "path": "/uid/generate", - "handler": "uid.generateUID", - "config": { - "policies": [] - } - }, - { - "method": "POST", - "path": "/uid/check-availability", - "handler": "uid.checkUIDAvailability", - "config": { - "policies": [] - } - }, - { - "method": "POST", - "path": "/relations/:model/:targetField", - "handler": "relations.find", - "config": { - "policies": [ - "admin::isAuthenticatedAdmin", - [ - "plugin::content-manager.hasPermissions", - [ - "plugin::content-manager.explorer.create", - "plugin::content-manager.explorer.update" - ], - { "hasAtLeastOne": true } - ] - ] - } - }, - { - "method": "GET", - "path": "/single-types/:model", - "handler": "single-types.find", - "config": { - "policies": [ - "routing", - "admin::isAuthenticatedAdmin", - ["plugin::content-manager.hasPermissions", ["plugin::content-manager.explorer.read"]] - ] - } - }, - { - "method": "PUT", - "path": "/single-types/:model", - "handler": "single-types.createOrUpdate", - "config": { - "policies": [ - "routing", - "admin::isAuthenticatedAdmin", - [ - "plugin::content-manager.hasPermissions", - [ - "plugin::content-manager.explorer.create", - "plugin::content-manager.explorer.update" - ], - { "hasAtLeastOne": true } - ] - ] - } - }, - { - "method": "DELETE", - "path": "/single-types/:model", - "handler": "single-types.delete", - "config": { - "policies": [ - "routing", - "admin::isAuthenticatedAdmin", - ["plugin::content-manager.hasPermissions", ["plugin::content-manager.explorer.delete"]] - ] - } - }, - { - "method": "POST", - "path": "/single-types/:model/actions/publish", - "handler": "single-types.publish", - "config": { - "policies": [ - "routing", - "plugin::content-manager.has-draft-and-publish", - "admin::isAuthenticatedAdmin", - ["plugin::content-manager.hasPermissions", ["plugin::content-manager.explorer.publish"]] - ] - } - }, - { - "method": "POST", - "path": "/single-types/:model/actions/unpublish", - "handler": "single-types.unpublish", - "config": { - "policies": [ - "routing", - "plugin::content-manager.has-draft-and-publish", - "admin::isAuthenticatedAdmin", - ["plugin::content-manager.hasPermissions", ["plugin::content-manager.explorer.publish"]] - ] - } - }, - { - "method": "GET", - "path": "/collection-types/:model/:id/:targetField", - "handler": "collection-types.previewManyRelations", - "config": { - "policies": [ - "routing", - "admin::isAuthenticatedAdmin", - ["plugin::content-manager.hasPermissions", ["plugin::content-manager.explorer.read"]] - ] - } - }, - { - "method": "GET", - "path": "/collection-types/:model", - "handler": "collection-types.find", - "config": { - "policies": [ - "routing", - "admin::isAuthenticatedAdmin", - ["plugin::content-manager.hasPermissions", ["plugin::content-manager.explorer.read"]] - ] - } - }, - { - "method": "POST", - "path": "/collection-types/:model", - "handler": "collection-types.create", - "config": { - "policies": [ - "routing", - "admin::isAuthenticatedAdmin", - ["plugin::content-manager.hasPermissions", ["plugin::content-manager.explorer.create"]] - ] - } - }, - { - "method": "GET", - "path": "/collection-types/:model/:id", - "handler": "collection-types.findOne", - "config": { - "policies": [ - "routing", - "admin::isAuthenticatedAdmin", - ["plugin::content-manager.hasPermissions", ["plugin::content-manager.explorer.read"]] - ] - } - }, - { - "method": "PUT", - "path": "/collection-types/:model/:id", - "handler": "collection-types.update", - "config": { - "policies": [ - "routing", - "admin::isAuthenticatedAdmin", - ["plugin::content-manager.hasPermissions", ["plugin::content-manager.explorer.update"]] - ] - } - }, - { - "method": "DELETE", - "path": "/collection-types/:model/:id", - "handler": "collection-types.delete", - "config": { - "policies": [ - "routing", - "admin::isAuthenticatedAdmin", - ["plugin::content-manager.hasPermissions", ["plugin::content-manager.explorer.delete"]] - ] - } - }, - { - "method": "POST", - "path": "/collection-types/:model/:id/actions/publish", - "handler": "collection-types.publish", - "config": { - "policies": [ - "routing", - "plugin::content-manager.has-draft-and-publish", - "admin::isAuthenticatedAdmin", - ["plugin::content-manager.hasPermissions", ["plugin::content-manager.explorer.publish"]] - ] - } - }, - { - "method": "POST", - "path": "/collection-types/:model/:id/actions/unpublish", - "handler": "collection-types.unpublish", - "config": { - "policies": [ - "routing", - "plugin::content-manager.has-draft-and-publish", - "admin::isAuthenticatedAdmin", - ["plugin::content-manager.hasPermissions", ["plugin::content-manager.explorer.publish"]] - ] - } - }, - { - "method": "POST", - "path": "/collection-types/:model/actions/bulkDelete", - "handler": "collection-types.bulkDelete", - "config": { - "policies": [ - "routing", - "admin::isAuthenticatedAdmin", - ["plugin::content-manager.hasPermissions", ["plugin::content-manager.explorer.delete"]] - ] - } - } - ] -} diff --git a/packages/core/content-manager/server/routes/index.js b/packages/core/content-manager/server/routes/index.js index d21bca7432..0ae8fd0c79 100644 --- a/packages/core/content-manager/server/routes/index.js +++ b/packages/core/content-manager/server/routes/index.js @@ -1,5 +1,318 @@ 'use strict'; -const routes = require('../../config/routes'); +module.exports = [ + { + method: 'GET', + path: '/content-types', + handler: 'content-types.findContentTypes', + config: { + policies: [], + }, + }, + { + method: 'GET', + path: '/content-types-settings', + handler: 'content-types.findContentTypesSettings', + config: { + policies: [], + }, + }, + { + method: 'GET', + path: '/content-types/:uid/configuration', + handler: 'content-types.findContentTypeConfiguration', + config: { + policies: [], + }, + }, + { + method: 'PUT', + path: '/content-types/:uid/configuration', + handler: 'content-types.updateContentTypeConfiguration', + config: { + policies: ['admin::isAuthenticatedAdmin'], + }, + }, -module.exports = routes.routes; + { + method: 'GET', + path: '/components', + handler: 'components.findComponents', + config: { + policies: [], + }, + }, + { + method: 'GET', + path: '/components/:uid/configuration', + handler: 'components.findComponentConfiguration', + config: { + policies: [], + }, + }, + { + method: 'PUT', + path: '/components/:uid/configuration', + handler: 'components.updateComponentConfiguration', + config: { + policies: [], + }, + }, + + { + method: 'POST', + path: '/uid/generate', + handler: 'uid.generateUID', + config: { + policies: [], + }, + }, + { + method: 'POST', + path: '/uid/check-availability', + handler: 'uid.checkUIDAvailability', + config: { + policies: [], + }, + }, + { + method: 'POST', + path: '/relations/:model/:targetField', + handler: 'relations.find', + config: { + policies: [ + 'admin::isAuthenticatedAdmin', + { + name: 'plugin::content-manager.hasPermissions', + options: { + actions: [ + 'plugin::content-manager.explorer.create', + 'plugin::content-manager.explorer.update', + ], + hasAtLeastOne: true, + }, + }, + ], + }, + }, + { + method: 'GET', + path: '/single-types/:model', + handler: 'single-types.find', + config: { + policies: [ + 'routing', + 'admin::isAuthenticatedAdmin', + { + name: 'plugin::content-manager.hasPermissions', + options: { actions: ['plugin::content-manager.explorer.read'] }, + }, + ], + }, + }, + { + method: 'PUT', + path: '/single-types/:model', + handler: 'single-types.createOrUpdate', + config: { + policies: [ + 'routing', + 'admin::isAuthenticatedAdmin', + { + name: 'plugin::content-manager.hasPermissions', + options: { + actions: [ + 'plugin::content-manager.explorer.create', + 'plugin::content-manager.explorer.update', + ], + hasAtLeastOne: true, + }, + }, + ], + }, + }, + { + method: 'DELETE', + path: '/single-types/:model', + handler: 'single-types.delete', + config: { + policies: [ + 'routing', + 'admin::isAuthenticatedAdmin', + { + name: 'plugin::content-manager.hasPermissions', + options: { actions: ['plugin::content-manager.explorer.delete'] }, + }, + ], + }, + }, + { + method: 'POST', + path: '/single-types/:model/actions/publish', + handler: 'single-types.publish', + config: { + policies: [ + 'routing', + 'plugin::content-manager.has-draft-and-publish', + 'admin::isAuthenticatedAdmin', + { + name: 'plugin::content-manager.hasPermissions', + options: { actions: ['plugin::content-manager.explorer.publish'] }, + }, + ], + }, + }, + { + method: 'POST', + path: '/single-types/:model/actions/unpublish', + handler: 'single-types.unpublish', + config: { + policies: [ + 'routing', + 'plugin::content-manager.has-draft-and-publish', + 'admin::isAuthenticatedAdmin', + { + name: 'plugin::content-manager.hasPermissions', + options: { actions: ['plugin::content-manager.explorer.publish'] }, + }, + ], + }, + }, + { + method: 'GET', + path: '/collection-types/:model/:id/:targetField', + handler: 'collection-types.previewManyRelations', + config: { + policies: [ + 'routing', + 'admin::isAuthenticatedAdmin', + { + name: 'plugin::content-manager.hasPermissions', + options: { actions: ['plugin::content-manager.explorer.read'] }, + }, + ], + }, + }, + { + method: 'GET', + path: '/collection-types/:model', + handler: 'collection-types.find', + config: { + policies: [ + 'routing', + 'admin::isAuthenticatedAdmin', + { + name: 'plugin::content-manager.hasPermissions', + options: { actions: ['plugin::content-manager.explorer.read'] }, + }, + ], + }, + }, + { + method: 'POST', + path: '/collection-types/:model', + handler: 'collection-types.create', + config: { + policies: [ + 'routing', + 'admin::isAuthenticatedAdmin', + { + name: 'plugin::content-manager.hasPermissions', + options: { actions: ['plugin::content-manager.explorer.create'] }, + }, + ], + }, + }, + { + method: 'GET', + path: '/collection-types/:model/:id', + handler: 'collection-types.findOne', + config: { + policies: [ + 'routing', + 'admin::isAuthenticatedAdmin', + { + name: 'plugin::content-manager.hasPermissions', + options: { actions: ['plugin::content-manager.explorer.read'] }, + }, + ], + }, + }, + { + method: 'PUT', + path: '/collection-types/:model/:id', + handler: 'collection-types.update', + config: { + policies: [ + 'routing', + 'admin::isAuthenticatedAdmin', + { + name: 'plugin::content-manager.hasPermissions', + options: { actions: ['plugin::content-manager.explorer.update'] }, + }, + ], + }, + }, + { + method: 'DELETE', + path: '/collection-types/:model/:id', + handler: 'collection-types.delete', + config: { + policies: [ + 'routing', + 'admin::isAuthenticatedAdmin', + { + name: 'plugin::content-manager.hasPermissions', + options: { actions: ['plugin::content-manager.explorer.delete'] }, + }, + ], + }, + }, + { + method: 'POST', + path: '/collection-types/:model/:id/actions/publish', + handler: 'collection-types.publish', + config: { + policies: [ + 'routing', + 'plugin::content-manager.has-draft-and-publish', + 'admin::isAuthenticatedAdmin', + { + name: 'plugin::content-manager.hasPermissions', + options: { actions: ['plugin::content-manager.explorer.publish'] }, + }, + ], + }, + }, + { + method: 'POST', + path: '/collection-types/:model/:id/actions/unpublish', + handler: 'collection-types.unpublish', + config: { + policies: [ + 'routing', + 'plugin::content-manager.has-draft-and-publish', + 'admin::isAuthenticatedAdmin', + { + name: 'plugin::content-manager.hasPermissions', + options: { actions: ['plugin::content-manager.explorer.publish'] }, + }, + ], + }, + }, + { + method: 'POST', + path: '/collection-types/:model/actions/bulkDelete', + handler: 'collection-types.bulkDelete', + config: { + policies: [ + 'routing', + 'admin::isAuthenticatedAdmin', + { + name: 'plugin::content-manager.hasPermissions', + options: { actions: ['plugin::content-manager.explorer.delete'] }, + }, + ], + }, + }, +]; diff --git a/packages/core/content-manager/validation/policies/hasPermissions.js b/packages/core/content-manager/validation/policies/hasPermissions.js index 81298e9f6b..a4bfafe052 100644 --- a/packages/core/content-manager/validation/policies/hasPermissions.js +++ b/packages/core/content-manager/validation/policies/hasPermissions.js @@ -2,11 +2,14 @@ const { yup, formatYupErrors } = require('@strapi/utils'); -const hasPermissionsSchema = yup.array().of(yup.string()); +const hasPermissionsSchema = yup.object({ + actions: yup.array().of(yup.string()), + hasAtLeastOne: yup.boolean(), +}); -const validateHasPermissionsInput = actions => { +const validateHasPermissionsInput = options => { try { - return hasPermissionsSchema.validateSync(actions, { strict: true, abortEarly: true }); + return hasPermissionsSchema.validateSync(options, { strict: true, abortEarly: true }); } catch (e) { throw new Error(formatYupErrors(e)); } diff --git a/packages/core/content-type-builder/server/routes/index.js b/packages/core/content-type-builder/server/routes/index.js index 01f98d7b82..593ad2c2aa 100644 --- a/packages/core/content-type-builder/server/routes/index.js +++ b/packages/core/content-type-builder/server/routes/index.js @@ -1,5 +1,173 @@ 'use strict'; -const routes = require('./routes'); - -module.exports = routes.routes; +module.exports = [ + { + method: 'GET', + path: '/reserved-names', + handler: 'builder.getReservedNames', + config: { + policies: [ + { + name: 'admin::hasPermissions', + options: { actions: ['plugin::content-type-builder.read'] }, + }, + ], + }, + }, + { + method: 'GET', + path: '/content-types', + handler: 'content-types.getContentTypes', + config: { + policies: [ + { + name: 'admin::hasPermissions', + options: { actions: ['plugin::content-type-builder.read'] }, + }, + ], + }, + }, + { + method: 'GET', + path: '/content-types/:uid', + handler: 'content-types.getContentType', + config: { + policies: [ + { + name: 'admin::hasPermissions', + options: { actions: ['plugin::content-type-builder.read'] }, + }, + ], + }, + }, + { + method: 'POST', + path: '/content-types', + handler: 'content-types.createContentType', + config: { + policies: [ + { + name: 'admin::hasPermissions', + options: { actions: ['plugin::content-type-builder.read'] }, + }, + ], + }, + }, + { + method: 'PUT', + path: '/content-types/:uid', + handler: 'content-types.updateContentType', + config: { + policies: [ + { + name: 'admin::hasPermissions', + options: { actions: ['plugin::content-type-builder.read'] }, + }, + ], + }, + }, + { + method: 'DELETE', + path: '/content-types/:uid', + handler: 'content-types.deleteContentType', + config: { + policies: [ + { + name: 'admin::hasPermissions', + options: { actions: ['plugin::content-type-builder.read'] }, + }, + ], + }, + }, + { + method: 'GET', + path: '/components', + handler: 'components.getComponents', + config: { + policies: [ + { + name: 'admin::hasPermissions', + options: { actions: ['plugin::content-type-builder.read'] }, + }, + ], + }, + }, + { + method: 'GET', + path: '/components/:uid', + handler: 'components.getComponent', + config: { + policies: [ + { + name: 'admin::hasPermissions', + options: { actions: ['plugin::content-type-builder.read'] }, + }, + ], + }, + }, + { + method: 'POST', + path: '/components', + handler: 'components.createComponent', + config: { + policies: [ + { + name: 'admin::hasPermissions', + options: { actions: ['plugin::content-type-builder.read'] }, + }, + ], + }, + }, + { + method: 'PUT', + path: '/components/:uid', + handler: 'components.updateComponent', + config: { + policies: [ + { + name: 'admin::hasPermissions', + options: { actions: ['plugin::content-type-builder.read'] }, + }, + ], + }, + }, + { + method: 'DELETE', + path: '/components/:uid', + handler: 'components.deleteComponent', + config: { + policies: [ + { + name: 'admin::hasPermissions', + options: { actions: ['plugin::content-type-builder.read'] }, + }, + ], + }, + }, + { + method: 'PUT', + path: '/component-categories/:name', + handler: 'component-categories.editCategory', + config: { + policies: [ + { + name: 'admin::hasPermissions', + options: { actions: ['plugin::content-type-builder.read'] }, + }, + ], + }, + }, + { + method: 'DELETE', + path: '/component-categories/:name', + handler: 'component-categories.deleteCategory', + config: { + policies: [ + { + name: 'admin::hasPermissions', + options: { actions: ['plugin::content-type-builder.read'] }, + }, + ], + }, + }, +]; diff --git a/packages/core/content-type-builder/server/routes/routes.json b/packages/core/content-type-builder/server/routes/routes.json deleted file mode 100644 index fad542a565..0000000000 --- a/packages/core/content-type-builder/server/routes/routes.json +++ /dev/null @@ -1,108 +0,0 @@ -{ - "routes": [ - { - "method": "GET", - "path": "/reserved-names", - "handler": "builder.getReservedNames", - "config": { - "policies": [["admin::hasPermissions", ["plugin::content-type-builder.read"]]] - } - }, - { - "method": "GET", - "path": "/content-types", - "handler": "content-types.getContentTypes", - "config": { - "policies": [["admin::hasPermissions", ["plugin::content-type-builder.read"]]] - } - }, - { - "method": "GET", - "path": "/content-types/:uid", - "handler": "content-types.getContentType", - "config": { - "policies": [["admin::hasPermissions", ["plugin::content-type-builder.read"]]] - } - }, - { - "method": "POST", - "path": "/content-types", - "handler": "content-types.createContentType", - "config": { - "policies": [["admin::hasPermissions", ["plugin::content-type-builder.read"]]] - } - }, - { - "method": "PUT", - "path": "/content-types/:uid", - "handler": "content-types.updateContentType", - "config": { - "policies": [["admin::hasPermissions", ["plugin::content-type-builder.read"]]] - } - }, - { - "method": "DELETE", - "path": "/content-types/:uid", - "handler": "content-types.deleteContentType", - "config": { - "policies": [["admin::hasPermissions", ["plugin::content-type-builder.read"]]] - } - }, - { - "method": "GET", - "path": "/components", - "handler": "components.getComponents", - "config": { - "policies": [["admin::hasPermissions", ["plugin::content-type-builder.read"]]] - } - }, - { - "method": "GET", - "path": "/components/:uid", - "handler": "components.getComponent", - "config": { - "policies": [["admin::hasPermissions", ["plugin::content-type-builder.read"]]] - } - }, - { - "method": "POST", - "path": "/components", - "handler": "components.createComponent", - "config": { - "policies": [["admin::hasPermissions", ["plugin::content-type-builder.read"]]] - } - }, - { - "method": "PUT", - "path": "/components/:uid", - "handler": "components.updateComponent", - "config": { - "policies": [["admin::hasPermissions", ["plugin::content-type-builder.read"]]] - } - }, - { - "method": "DELETE", - "path": "/components/:uid", - "handler": "components.deleteComponent", - "config": { - "policies": [["admin::hasPermissions", ["plugin::content-type-builder.read"]]] - } - }, - { - "method": "PUT", - "path": "/component-categories/:name", - "handler": "component-categories.editCategory", - "config": { - "policies": [["admin::hasPermissions", ["plugin::content-type-builder.read"]]] - } - }, - { - "method": "DELETE", - "path": "/component-categories/:name", - "handler": "component-categories.deleteCategory", - "config": { - "policies": [["admin::hasPermissions", ["plugin::content-type-builder.read"]]] - } - } - ] -} diff --git a/packages/core/email/server/routes/index.js b/packages/core/email/server/routes/index.js index 01f98d7b82..b517ede188 100644 --- a/packages/core/email/server/routes/index.js +++ b/packages/core/email/server/routes/index.js @@ -1,5 +1,49 @@ 'use strict'; -const routes = require('./routes'); - -module.exports = routes.routes; +module.exports = [ + { + method: 'POST', + path: '/', + handler: 'Email.send', + config: { + policies: [], + description: 'Send an email', + tag: { + plugin: 'email', + name: 'Email', + }, + }, + }, + { + method: 'POST', + path: '/test', + handler: 'Email.test', + config: { + policies: [ + 'admin::isAuthenticatedAdmin', + { name: 'admin::hasPermissions', options: { actions: ['plugin::email.settings.read'] } }, + ], + description: 'Send an test email', + tag: { + plugin: 'email', + name: 'Email', + }, + }, + }, + { + method: 'GET', + path: '/settings', + handler: 'Email.getSettings', + config: { + policies: [ + 'admin::isAuthenticatedAdmin', + { name: 'admin::hasPermissions', options: { actions: ['plugin::email.settings.read'] } }, + ], + description: 'Get the email settings', + tag: { + plugin: 'email', + name: 'Email', + }, + }, + }, +]; diff --git a/packages/core/email/server/routes/routes.json b/packages/core/email/server/routes/routes.json deleted file mode 100644 index 55df34aca7..0000000000 --- a/packages/core/email/server/routes/routes.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "routes": [ - { - "method": "POST", - "path": "/", - "handler": "Email.send", - "config": { - "policies": [], - "description": "Send an email", - "tag": { - "plugin": "email", - "name": "Email" - } - } - }, - { - "method": "POST", - "path": "/test", - "handler": "Email.test", - "config": { - "policies": [ - "admin::isAuthenticatedAdmin", - ["admin::hasPermissions", ["plugin::email.settings.read"]] - ], - "description": "Send an test email", - "tag": { - "plugin": "email", - "name": "Email" - } - } - }, - { - "method": "GET", - "path": "/settings", - "handler": "Email.getSettings", - "config": { - "policies": [ - "admin::isAuthenticatedAdmin", - ["admin::hasPermissions", ["plugin::email.settings.read"]] - ], - "description": "Get the email settings", - "tag": { - "plugin": "email", - "name": "Email" - } - } - } - ] -} diff --git a/packages/core/strapi/lib/middlewares/router/index.js b/packages/core/strapi/lib/middlewares/router/index.js index 2648cdecd5..4e156a2caa 100644 --- a/packages/core/strapi/lib/middlewares/router/index.js +++ b/packages/core/strapi/lib/middlewares/router/index.js @@ -12,7 +12,7 @@ const createEndpointComposer = require('./utils/composeEndpoint'); module.exports = strapi => { const composeEndpoint = createEndpointComposer(strapi); - const registerAdminRoutes = strapi => { + const registerAdminRoutes = () => { const router = new Router({ prefix: '/admin' }); strapi.admin.routes.forEach(route => { @@ -22,33 +22,35 @@ module.exports = strapi => { strapi.app.use(router.routes()).use(router.allowedMethods()); }; - return { - initialize() { - _.forEach(strapi.config.routes, value => { - composeEndpoint(value, { router: strapi.router }); + const registerPluginRoutes = () => { + _.forEach(strapi.plugins, (plugin, pluginName) => { + const router = new Router({ prefix: `/${pluginName}` }); + + (plugin.routes || []).forEach(route => { + const hasPrefix = _.has(route.config, 'prefix'); + composeEndpoint(route, { + plugin: pluginName, + router: hasPrefix ? strapi.router : router, + }); }); - strapi.router.prefix(strapi.config.get('middleware.settings.router.prefix', '')); + strapi.app.use(router.routes()).use(router.allowedMethods()); + }); + }; - registerAdminRoutes(strapi); + const registerAPIRoutes = () => { + strapi.router.prefix(strapi.config.get('middleware.settings.router.prefix', '')); - if (strapi.plugins) { - // Parse each plugin's routes. - _.forEach(strapi.plugins, (plugin, pluginName) => { - const router = new Router({ prefix: `/${pluginName}` }); + _.forEach(strapi.config.routes, value => { + composeEndpoint(value, { router: strapi.router }); + }); + }; - (plugin.routes || []).forEach(route => { - const hasPrefix = _.has(route.config, 'prefix'); - composeEndpoint(route, { - plugin: pluginName, - router: hasPrefix ? strapi.router : router, - }); - }); - - // Mount plugin router - strapi.app.use(router.routes()).use(router.allowedMethods()); - }); - } + return { + initialize() { + registerAPIRoutes(); + registerAdminRoutes(); + registerPluginRoutes(); }, }; }; diff --git a/packages/core/strapi/lib/middlewares/router/utils/composeEndpoint.js b/packages/core/strapi/lib/middlewares/router/utils/composeEndpoint.js index 77189786ca..d921957eaf 100644 --- a/packages/core/strapi/lib/middlewares/router/utils/composeEndpoint.js +++ b/packages/core/strapi/lib/middlewares/router/utils/composeEndpoint.js @@ -2,24 +2,177 @@ const _ = require('lodash'); const compose = require('koa-compose'); -const createRouteChecker = require('./routerChecker'); +const { yup } = require('@strapi/utils'); + +const policyOrMiddlewareSchema = yup.lazy(value => { + if (typeof value === 'string') { + return yup.string().required(); + } + + if (typeof value === 'function') { + return yup.mixed().isFunction(); + } + + return yup.object({ + name: yup.string().required(), + options: yup.object().notRequired(), // any options + }); +}); + +const routeSchema = yup.object({ + method: yup + .string() + .oneOf(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'ALL']) + .required(), + path: yup.string().required(), + handler: yup.lazy(value => { + if (typeof value === 'string') { + return yup.string().required(); + } + + return yup + .mixed() + .isFunction() + .required(); + }), + config: yup + .object({ + policies: yup + .array() + .of(policyOrMiddlewareSchema) + .notRequired(), + middlwares: yup + .array() + .of(policyOrMiddlewareSchema) + .notRequired(), + }) + .notRequired(), +}); + +const validateRouteConfig = routeConfig => { + try { + return routeSchema.validateSync(routeConfig, { + strict: true, + abortEarly: false, + stripUnknown: true, + }); + } catch (error) { + console.error(error); + throw new Error('Invalid route config'); + } +}; + +// Strapi utilities. +const { finder, policy: policyUtils } = require('@strapi/utils'); module.exports = strapi => { const routerChecker = createRouteChecker(strapi); - return (value, { plugin, router }) => { - if (_.isEmpty(_.get(value, 'method')) || _.isEmpty(_.get(value, 'path'))) { - return; - } + return (routeConfig, { plugin, router }) => { + validateRouteConfig(routeConfig); - const { method, endpoint, policies, action } = routerChecker(value, plugin); + // const { method, path, handler, config } = routeConfig; + // const { policies, middlewares /* validate, auth, ...rest */ } = config; + + // const requestMethod = _.trim(_.toLower(method)); + // const endpoint = _.trim(path); + + // const requestHandler = compose([ + // // ...buildValidator(validate), + // // ...buildAuth(auth), + // ...resolvePolicies(policies), + // ...resolveMiddlewares(middlewares), + // ...resolveHandler(handler), + // ]); + + // router[requestMethod](endpoint, requestHandler); + + const { method, endpoint, policies, action } = routerChecker(routeConfig, plugin); if (_.isUndefined(action) || !_.isFunction(action)) { return strapi.log.warn( - `Ignored attempt to bind route '${value.method} ${value.path}' to unknown controller/action.` + `Ignored attempt to bind route '${routeConfig.method} ${routeConfig.path}' to unknown controller/action.` ); } - router[method](endpoint, compose(policies), action); + router[method](endpoint, compose(policies, action)); }; }; + +const getMethod = route => _.trim(_.toLower(route.method)); +const getEndpoint = route => _.trim(route.path); + +const createRouteChecker = strapi => + function routerChecker(value, plugin) { + const method = getMethod(value); + const endpoint = getEndpoint(value); + + // Define controller and action names. + const [controllerName, actionName] = _.trim(value.handler).split('.'); + const controllerKey = _.toLower(controllerName); + + let controller; + + if (plugin) { + if (plugin === 'admin') { + controller = strapi.admin.controllers[controllerKey]; + } else { + controller = strapi.plugin(plugin).controller(controllerKey); + } + } else { + controller = strapi.controllers[controllerKey]; + } + + if (!_.isFunction(controller[actionName])) { + strapi.stopWithError( + `Error creating endpoint ${method} ${endpoint}: handler not found "${controllerKey}.${actionName}"` + ); + } + + const action = controller[actionName].bind(controller); + + // Retrieve the API's name where the controller is located + // to access to the right validators + const currentApiName = finder( + strapi.plugin(plugin) || strapi.api || strapi.admin, + controllerKey + ); + + // Add the `globalPolicy`. + const globalPolicy = policyUtils.globalPolicy({ + controller: controllerKey, + action: actionName, + method, + endpoint, + plugin, + }); + + // Init policies array. + const policies = [globalPolicy]; + + let policyOption = _.get(value, 'config.policies', []); + + policyOption.forEach(policyConfig => { + try { + policies.push(policyUtils.get(policyConfig, plugin, currentApiName)); + } catch (error) { + throw new Error(`Error creating endpoint ${method} ${endpoint}: ${error.message}`); + } + }); + + policies.push(async (ctx, next) => { + // Set body. + const values = await next(); + + if (_.isNil(ctx.body) && !_.isNil(values)) { + ctx.body = values; + } + }); + + return { + method, + endpoint, + policies, + action, + }; + }; diff --git a/packages/core/upload/server/routes/index.js b/packages/core/upload/server/routes/index.js index 01f98d7b82..43a6305165 100644 --- a/packages/core/upload/server/routes/index.js +++ b/packages/core/upload/server/routes/index.js @@ -1,5 +1,98 @@ 'use strict'; -const routes = require('./routes'); - -module.exports = routes.routes; +module.exports = [ + { + method: 'GET', + path: '/settings', + handler: 'upload.getSettings', + config: { + policies: [], + }, + }, + { + method: 'PUT', + path: '/settings', + handler: 'upload.updateSettings', + config: { + policies: [], + }, + }, + { + method: 'POST', + path: '/', + handler: 'upload.upload', + config: { + policies: [], + description: 'upload a file', + tag: { + plugin: 'upload', + name: 'File', + }, + }, + }, + { + method: 'GET', + path: '/files/count', + handler: 'upload.count', + config: { + policies: [], + description: 'Retrieve the total number of uploaded files', + tag: { + plugin: 'upload', + name: 'File', + }, + }, + }, + { + method: 'GET', + path: '/files', + handler: 'upload.find', + config: { + policies: [], + description: 'Retrieve all file documents', + tag: { + plugin: 'upload', + name: 'File', + }, + }, + }, + { + method: 'GET', + path: '/files/:id', + handler: 'upload.findOne', + config: { + policies: [], + description: 'Retrieve a single file depending on its id', + tag: { + plugin: 'upload', + name: 'File', + }, + }, + }, + { + method: 'GET', + path: '/search/:id', + handler: 'upload.search', + config: { + policies: [], + description: 'Search for an uploaded file', + tag: { + plugin: 'upload', + name: 'File', + }, + }, + }, + { + method: 'DELETE', + path: '/files/:id', + handler: 'upload.destroy', + config: { + policies: [], + description: 'Delete an uploaded file', + tag: { + plugin: 'upload', + name: 'File', + }, + }, + }, +]; diff --git a/packages/core/upload/server/routes/routes.json b/packages/core/upload/server/routes/routes.json deleted file mode 100644 index 44222ace2b..0000000000 --- a/packages/core/upload/server/routes/routes.json +++ /dev/null @@ -1,98 +0,0 @@ -{ - "routes": [ - { - "method": "GET", - "path": "/settings", - "handler": "upload.getSettings", - "config": { - "policies": [] - } - }, - { - "method": "PUT", - "path": "/settings", - "handler": "upload.updateSettings", - "config": { - "policies": [] - } - }, - { - "method": "POST", - "path": "/", - "handler": "upload.upload", - "config": { - "policies": [], - "description": "upload a file", - "tag": { - "plugin": "upload", - "name": "File" - } - } - }, - { - "method": "GET", - "path": "/files/count", - "handler": "upload.count", - "config": { - "policies": [], - "description": "Retrieve the total number of uploaded files", - "tag": { - "plugin": "upload", - "name": "File" - } - } - }, - { - "method": "GET", - "path": "/files", - "handler": "upload.find", - "config": { - "policies": [], - "description": "Retrieve all file documents", - "tag": { - "plugin": "upload", - "name": "File" - } - } - }, - { - "method": "GET", - "path": "/files/:id", - "handler": "upload.findOne", - "config": { - "policies": [], - "description": "Retrieve a single file depending on its id", - "tag": { - "plugin": "upload", - "name": "File" - } - } - }, - { - "method": "GET", - "path": "/search/:id", - "handler": "upload.search", - "config": { - "policies": [], - "description": "Search for an uploaded file", - "tag": { - "plugin": "upload", - "name": "File" - } - } - }, - { - "method": "DELETE", - "path": "/files/:id", - "handler": "upload.destroy", - "config": { - "policies": [], - "description": "Delete an uploaded file", - "tag": { - "plugin": "upload", - "name": "File" - } - } - } - ] -} diff --git a/packages/core/utils/lib/policy.js b/packages/core/utils/lib/policy.js index e134c26b52..f602b23a41 100644 --- a/packages/core/utils/lib/policy.js +++ b/packages/core/utils/lib/policy.js @@ -10,8 +10,6 @@ const PLUGIN_PREFIX = 'plugin::'; const ADMIN_PREFIX = 'admin::'; const APPLICATION_PREFIX = 'api::'; -const isPolicyFactory = _.isArray; - const getPolicyIn = (container, policy) => { return ( _.get(container, ['config', 'policies', policy]) || @@ -23,12 +21,19 @@ const policyExistsIn = (container, policy) => !_.isUndefined(getPolicyIn(contain const stripPolicy = (policy, prefix) => policy.replace(prefix, ''); -const createPolicy = (policyName, ...args) => ({ policyName, args }); +const createPolicy = (policyName, args) => ({ policyName, args }); +// TODO: could be removed policy should only be a function. const resolveHandler = policy => (_.isFunction(policy) ? policy : policy.handler); -const parsePolicy = policy => - isPolicyFactory(policy) ? createPolicy(...policy) : createPolicy(policy); +const parsePolicy = policy => { + if (typeof policy === 'string') { + return createPolicy(policy); + } + + const { name, options = {} } = policy; + return createPolicy(name, options); +}; const resolvePolicy = policyName => { const resolver = policyResolvers.find(resolver => resolver.exists(policyName)); @@ -85,6 +90,7 @@ const policyResolvers = [ get: policy => { const [, policyWithoutPrefix] = policy.split('::'); const [api = '', policyName = ''] = policyWithoutPrefix.split('.'); + // TODO: move api policies into global registry return getPolicyIn(_.get(strapi, ['api', api]), policyName); }, }, @@ -96,7 +102,8 @@ const policyResolvers = [ exists(policy) { return this.is(policy) && !_.isUndefined(this.get(policy)); }, - get: policy => { + get(policy) { + // TODO: move admin policies into global registry return getPolicyIn(_.get(strapi, 'admin'), stripPolicy(policy, ADMIN_PREFIX)); }, }, @@ -129,12 +136,16 @@ const policyResolvers = [ ]; const get = (policy, plugin, apiName) => { + if (typeof policy === 'function') { + return policy; + } + const { policyName, args } = parsePolicy(policy); const resolvedPolicy = resolvePolicy(policyName); if (resolvedPolicy !== undefined) { - return isPolicyFactory(policy) ? resolvedPolicy(...args) : resolvedPolicy; + return _.isPlainObject(policy) ? resolvedPolicy(args) : resolvedPolicy; } const localPolicy = searchLocalPolicy(policy, plugin, apiName); @@ -157,12 +168,13 @@ const createPolicyFactory = (factoryCallback, options) => { } }; - return (...args) => { + return options => { + console.log(options); if (validator) { - validate(...args); + validate(options); } - return factoryCallback(...args); + return factoryCallback(options); }; }; diff --git a/packages/plugins/documentation/server/routes/index.js b/packages/plugins/documentation/server/routes/index.js index 01f98d7b82..74caedd46a 100644 --- a/packages/plugins/documentation/server/routes/index.js +++ b/packages/plugins/documentation/server/routes/index.js @@ -1,5 +1,90 @@ 'use strict'; -const routes = require('./routes'); - -module.exports = routes.routes; +module.exports = [ + { + method: 'GET', + path: '/', + handler: 'Documentation.index', + config: { + policies: [ + 'plugin::documentation.index', + { name: 'admin::hasPermissions', options: { actions: ['plugin::documentation.read'] } }, + ], + }, + }, + { + method: 'GET', + path: '/v:major(\\d+).:minor(\\d+).:patch(\\d+)', + handler: 'Documentation.index', + config: { + policies: [ + 'plugin::documentation.index', + { name: 'admin::hasPermissions', options: { actions: ['plugin::documentation.read'] } }, + ], + }, + }, + { + method: 'GET', + path: '/login', + handler: 'Documentation.loginView', + config: { + policies: [ + { name: 'admin::hasPermissions', options: { actions: ['plugin::documentation.read'] } }, + ], + }, + }, + { + method: 'POST', + path: '/login', + handler: 'Documentation.login', + config: { + policies: [ + { name: 'admin::hasPermissions', options: { actions: ['plugin::documentation.read'] } }, + ], + }, + }, + { + method: 'GET', + path: '/getInfos', + handler: 'Documentation.getInfos', + config: { + policies: [ + { name: 'admin::hasPermissions', options: { actions: ['plugin::documentation.read'] } }, + ], + }, + }, + { + method: 'POST', + path: '/regenerateDoc', + handler: 'Documentation.regenerateDoc', + config: { + policies: [ + { + name: 'admin::hasPermissions', + options: { actions: ['plugin::documentation.settings.regenerate'] }, + }, + ], + }, + }, + { + method: 'PUT', + path: '/updateSettings', + handler: 'Documentation.updateSettings', + config: { + policies: [ + { + name: 'admin::hasPermissions', + options: { actions: ['plugin::documentation.settings.update'] }, + }, + ], + }, + }, + { + method: 'DELETE', + path: '/deleteDoc/:version', + handler: 'Documentation.deleteDoc', + config: { + policies: [], + }, + }, +]; diff --git a/packages/plugins/documentation/server/routes/routes.json b/packages/plugins/documentation/server/routes/routes.json deleted file mode 100755 index 3831b21e35..0000000000 --- a/packages/plugins/documentation/server/routes/routes.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "routes": [ - { - "method": "GET", - "path": "/", - "handler": "Documentation.index", - "config": { - "policies": [ - "plugin::documentation.index", - ["admin::hasPermissions", ["plugin::documentation.read"]] - ] - } - }, - { - "method": "GET", - "path": "/v:major(\\d+).:minor(\\d+).:patch(\\d+)", - "handler": "Documentation.index", - "config": { - "policies": [ - "plugin::documentation.index", - ["admin::hasPermissions", ["plugin::documentation.read"]] - ] - } - }, - { - "method": "GET", - "path": "/login", - "handler": "Documentation.loginView", - "config": { - "policies": [["admin::hasPermissions", ["plugin::documentation.read"]]] - } - }, - { - "method": "POST", - "path": "/login", - "handler": "Documentation.login", - "config": { - "policies": [["admin::hasPermissions", ["plugin::documentation.read"]]] - } - }, - { - "method": "GET", - "path": "/getInfos", - "handler": "Documentation.getInfos", - "config": { - "policies": [["admin::hasPermissions", ["plugin::documentation.read"]]] - } - }, - { - "method": "POST", - "path": "/regenerateDoc", - "handler": "Documentation.regenerateDoc", - "config": { - "policies": [["admin::hasPermissions", ["plugin::documentation.settings.regenerate"]]] - } - }, - { - "method": "PUT", - "path": "/updateSettings", - "handler": "Documentation.updateSettings", - "config": { - "policies": [["admin::hasPermissions", ["plugin::documentation.settings.update"]]] - } - }, - { - "method": "DELETE", - "path": "/deleteDoc/:version", - "handler": "Documentation.deleteDoc", - "config": { - "policies": [] - } - } - ] -} diff --git a/packages/plugins/i18n/server/routes/index.js b/packages/plugins/i18n/server/routes/index.js index 16c2b55e75..ddfb9140cd 100644 --- a/packages/plugins/i18n/server/routes/index.js +++ b/packages/plugins/i18n/server/routes/index.js @@ -8,7 +8,10 @@ module.exports = [ config: { policies: [ 'admin::isAuthenticatedAdmin', - ['plugin::content-manager.hasPermissions', ['plugin::i18n.locale.read']], + { + name: 'plugin::content-manager.hasPermissions', + options: { actions: ['plugin::i18n.locale.read'] }, + }, ], }, }, @@ -27,7 +30,10 @@ module.exports = [ config: { policies: [ 'admin::isAuthenticatedAdmin', - ['plugin::content-manager.hasPermissions', ['plugin::i18n.locale.create']], + { + name: 'plugin::content-manager.hasPermissions', + options: { actions: ['plugin::i18n.locale.create'] }, + }, ], }, }, @@ -38,7 +44,10 @@ module.exports = [ config: { policies: [ 'admin::isAuthenticatedAdmin', - ['plugin::content-manager.hasPermissions', ['plugin::i18n.locale.update']], + { + name: 'plugin::content-manager.hasPermissions', + options: { actions: ['plugin::i18n.locale.update'] }, + }, ], }, }, @@ -49,7 +58,10 @@ module.exports = [ config: { policies: [ 'admin::isAuthenticatedAdmin', - ['plugin::content-manager.hasPermissions', ['plugin::i18n.locale.delete']], + { + name: 'plugin::content-manager.hasPermissions', + options: { actions: ['plugin::i18n.locale.delete'] }, + }, ], }, }, diff --git a/packages/plugins/users-permissions/server/routes/index.js b/packages/plugins/users-permissions/server/routes/index.js index 01f98d7b82..0f84ab0a8c 100644 --- a/packages/plugins/users-permissions/server/routes/index.js +++ b/packages/plugins/users-permissions/server/routes/index.js @@ -1,5 +1,430 @@ 'use strict'; -const routes = require('./routes'); +module.exports = [ + { + method: 'GET', + path: '/', + handler: 'users-permissions.index', + config: { + policies: [], + }, + }, + { + method: 'GET', + path: '/search/:id', + handler: 'users-permissions.searchUsers', + config: { + policies: [], + description: 'Search for users', + tag: { + plugin: 'users-permissions', + name: 'User', + actionType: 'find', + }, + }, + }, + { + method: 'GET', + path: '/policies', + handler: 'users-permissions.getPolicies', + config: { + policies: [], + }, + }, + { + method: 'GET', + path: '/roles/:id', + handler: 'users-permissions.getRole', + config: { + policies: [ + { + name: 'admin::hasPermissions', + options: { actions: ['plugin::users-permissions.roles.read'] }, + }, + ], + description: 'Retrieve a role depending on its id', + tag: { + plugin: 'users-permissions', + name: 'Role', + actionType: 'findOne', + }, + }, + }, + { + method: 'GET', + path: '/roles', + handler: 'users-permissions.getRoles', + config: { + policies: [ + { + name: 'admin::hasPermissions', + options: { actions: ['plugin::users-permissions.roles.read'] }, + }, + ], + description: 'Retrieve all role documents', + tag: { + plugin: 'users-permissions', + name: 'Role', + actionType: 'find', + }, + }, + }, + { + method: 'GET', + path: '/routes', + handler: 'users-permissions.getRoutes', + config: { + policies: [], + }, + }, + { + method: 'GET', + path: '/email-templates', + handler: 'users-permissions.getEmailTemplate', + config: { + policies: [ + { + name: 'admin::hasPermissions', + options: { actions: ['plugin::users-permissions.email-templates.read'] }, + }, + ], + }, + }, + { + method: 'PUT', + path: '/email-templates', + handler: 'users-permissions.updateEmailTemplate', + config: { + policies: [ + { + name: 'admin::hasPermissions', + options: { actions: ['plugin::users-permissions.email-templates.update'] }, + }, + ], + }, + }, + { + method: 'GET', + path: '/advanced', + handler: 'users-permissions.getAdvancedSettings', + config: { + policies: [ + { + name: 'admin::hasPermissions', + options: { actions: ['plugin::users-permissions.advanced-settings.read'] }, + }, + ], + }, + }, + { + method: 'PUT', + path: '/advanced', + handler: 'users-permissions.updateAdvancedSettings', + config: { + policies: [ + { + name: 'admin::hasPermissions', + options: { actions: ['plugin::users-permissions.advanced-settings.update'] }, + }, + ], + }, + }, + { + method: 'GET', + path: '/permissions', + handler: 'users-permissions.getPermissions', + config: { + policies: [], + }, + }, + { + method: 'GET', + path: '/providers', + handler: 'users-permissions.getProviders', + config: { + policies: [ + { + name: 'admin::hasPermissions', + options: { actions: ['plugin::users-permissions.providers.read'] }, + }, + ], + }, + }, -module.exports = routes.routes; + { + method: 'PUT', + path: '/providers', + handler: 'users-permissions.updateProviders', + config: { + policies: [ + { + name: 'admin::hasPermissions', + options: { actions: ['plugin::users-permissions.providers.update'] }, + }, + ], + }, + }, + { + method: 'POST', + path: '/roles', + handler: 'users-permissions.createRole', + config: { + policies: [ + { + name: 'admin::hasPermissions', + options: { actions: ['plugin::users-permissions.roles.create'] }, + }, + ], + description: 'Create a new role', + tag: { + plugin: 'users-permissions', + name: 'Role', + actionType: 'create', + }, + }, + }, + { + method: 'PUT', + path: '/roles/:role', + handler: 'users-permissions.updateRole', + config: { + policies: [ + { + name: 'admin::hasPermissions', + options: { actions: ['plugin::users-permissions.roles.update'] }, + }, + ], + description: 'Update a role', + tag: { + plugin: 'users-permissions', + name: 'Role', + actionType: 'update', + }, + }, + }, + { + method: 'DELETE', + path: '/roles/:role', + handler: 'users-permissions.deleteRole', + config: { + policies: [ + { + name: 'admin::hasPermissions', + options: { actions: ['plugin::users-permissions.roles.delete'] }, + }, + ], + description: 'Delete a role', + tag: { + plugin: 'users-permissions', + name: 'Role', + actionType: 'destroy', + }, + }, + }, + { + method: 'GET', + path: '/connect/*', + handler: 'auth.connect', + config: { + policies: ['plugin::users-permissions.rateLimit'], + prefix: '', + description: 'Connect a provider', + tag: { + plugin: 'users-permissions', + name: 'User', + }, + }, + }, + { + method: 'POST', + path: '/auth/local', + handler: 'auth.callback', + config: { + policies: ['plugin::users-permissions.rateLimit'], + prefix: '', + description: 'Login a user using the identifiers email and password', + tag: { + plugin: 'users-permissions', + name: 'User', + }, + }, + }, + { + method: 'POST', + path: '/auth/local/register', + handler: 'auth.register', + config: { + policies: ['plugin::users-permissions.rateLimit'], + prefix: '', + description: 'Register a new user with the default role', + tag: { + plugin: 'users-permissions', + name: 'User', + actionType: 'create', + }, + }, + }, + { + method: 'GET', + path: '/auth/:provider/callback', + handler: 'auth.callback', + config: { + policies: [], + prefix: '', + description: 'Successfull redirection after approving a provider', + tag: { + plugin: 'users-permissions', + name: 'User', + }, + }, + }, + { + method: 'POST', + path: '/auth/forgot-password', + handler: 'auth.forgotPassword', + config: { + policies: ['plugin::users-permissions.rateLimit'], + prefix: '', + description: 'Send the reset password email link', + tag: { + plugin: 'users-permissions', + name: 'User', + }, + }, + }, + { + method: 'POST', + path: '/auth/reset-password', + handler: 'auth.resetPassword', + config: { + policies: ['plugin::users-permissions.rateLimit'], + prefix: '', + description: 'Reset user password with a code (resetToken)', + tag: { + plugin: 'users-permissions', + name: 'User', + }, + }, + }, + { + method: 'GET', + path: '/auth/email-confirmation', + handler: 'auth.emailConfirmation', + config: { + policies: [], + prefix: '', + description: 'Validate a user account', + tag: { + plugin: 'users-permissions', + name: 'User', + }, + }, + }, + { + method: 'POST', + path: '/auth/send-email-confirmation', + handler: 'auth.sendEmailConfirmation', + config: { + policies: [], + prefix: '', + description: 'Send a confirmation email to user', + tag: { + plugin: 'users-permissions', + name: 'User', + }, + }, + }, + { + method: 'GET', + path: '/users/count', + handler: 'user.count', + config: { + prefix: '', + policies: [], + }, + }, + { + method: 'GET', + path: '/users', + handler: 'user.find', + config: { + policies: [], + prefix: '', + description: 'Retrieve all user documents', + tag: { + plugin: 'users-permissions', + name: 'User', + actionType: 'find', + }, + }, + }, + { + method: 'GET', + path: '/users/me', + handler: 'user.me', + config: { + policies: [], + prefix: '', + description: 'Retrieve the logged in user information', + tag: { + plugin: 'users-permissions', + name: 'User', + actionType: 'findOne', + }, + }, + }, + { + method: 'GET', + path: '/users/:id', + handler: 'user.findOne', + config: { + policies: [], + prefix: '', + description: 'Retrieve a single user depending on his id', + tag: { + plugin: 'users-permissions', + name: 'User', + actionType: 'findOne', + }, + }, + }, + { + method: 'POST', + path: '/users', + handler: 'user.create', + config: { + policies: [], + prefix: '', + }, + }, + { + method: 'PUT', + path: '/users/:id', + handler: 'user.update', + config: { + policies: [], + prefix: '', + description: 'Update an existing user', + tag: { + plugin: 'users-permissions', + name: 'User', + actionType: 'update', + }, + }, + }, + { + method: 'DELETE', + path: '/users/:id', + handler: 'user.destroy', + config: { + policies: [], + prefix: '', + description: 'Delete an existing user', + tag: { + plugin: 'users-permissions', + name: 'User', + actionType: 'destroy', + }, + }, + }, +]; diff --git a/packages/plugins/users-permissions/server/routes/routes.json b/packages/plugins/users-permissions/server/routes/routes.json deleted file mode 100644 index f7424d9c8c..0000000000 --- a/packages/plugins/users-permissions/server/routes/routes.json +++ /dev/null @@ -1,381 +0,0 @@ -{ - "routes": [ - { - "method": "GET", - "path": "/", - "handler": "users-permissions.index", - "config": { - "policies": [] - } - }, - { - "method": "GET", - "path": "/search/:id", - "handler": "users-permissions.searchUsers", - "config": { - "policies": [], - "description": "Search for users", - "tag": { - "plugin": "users-permissions", - "name": "User", - "actionType": "find" - } - } - }, - { - "method": "GET", - "path": "/policies", - "handler": "users-permissions.getPolicies", - "config": { - "policies": [] - } - }, - { - "method": "GET", - "path": "/roles/:id", - "handler": "users-permissions.getRole", - "config": { - "policies": [["admin::hasPermissions", ["plugin::users-permissions.roles.read"]]], - "description": "Retrieve a role depending on its id", - "tag": { - "plugin": "users-permissions", - "name": "Role", - "actionType": "findOne" - } - } - }, - { - "method": "GET", - "path": "/roles", - "handler": "users-permissions.getRoles", - "config": { - "policies": [["admin::hasPermissions", ["plugin::users-permissions.roles.read"]]], - "description": "Retrieve all role documents", - "tag": { - "plugin": "users-permissions", - "name": "Role", - "actionType": "find" - } - } - }, - { - "method": "GET", - "path": "/routes", - "handler": "users-permissions.getRoutes", - "config": { - "policies": [] - } - }, - { - "method": "GET", - "path": "/email-templates", - "handler": "users-permissions.getEmailTemplate", - "config": { - "policies": [["admin::hasPermissions", ["plugin::users-permissions.email-templates.read"]]] - } - }, - { - "method": "PUT", - "path": "/email-templates", - "handler": "users-permissions.updateEmailTemplate", - "config": { - "policies": [ - ["admin::hasPermissions", ["plugin::users-permissions.email-templates.update"]] - ] - } - }, - { - "method": "GET", - "path": "/advanced", - "handler": "users-permissions.getAdvancedSettings", - "config": { - "policies": [ - ["admin::hasPermissions", ["plugin::users-permissions.advanced-settings.read"]] - ] - } - }, - { - "method": "PUT", - "path": "/advanced", - "handler": "users-permissions.updateAdvancedSettings", - "config": { - "policies": [ - ["admin::hasPermissions", ["plugin::users-permissions.advanced-settings.update"]] - ] - } - }, - { - "method": "GET", - "path": "/permissions", - "handler": "users-permissions.getPermissions", - "config": { - "policies": [] - } - }, - { - "method": "GET", - "path": "/providers", - "handler": "users-permissions.getProviders", - "config": { - "policies": [["admin::hasPermissions", ["plugin::users-permissions.providers.read"]]] - } - }, - - { - "method": "PUT", - "path": "/providers", - "handler": "users-permissions.updateProviders", - "config": { - "policies": [["admin::hasPermissions", ["plugin::users-permissions.providers.update"]]] - } - }, - { - "method": "POST", - "path": "/roles", - "handler": "users-permissions.createRole", - "config": { - "policies": [["admin::hasPermissions", ["plugin::users-permissions.roles.create"]]], - "description": "Create a new role", - "tag": { - "plugin": "users-permissions", - "name": "Role", - "actionType": "create" - } - } - }, - { - "method": "PUT", - "path": "/roles/:role", - "handler": "users-permissions.updateRole", - "config": { - "policies": [["admin::hasPermissions", ["plugin::users-permissions.roles.update"]]], - "description": "Update a role", - "tag": { - "plugin": "users-permissions", - "name": "Role", - "actionType": "update" - } - } - }, - { - "method": "DELETE", - "path": "/roles/:role", - "handler": "users-permissions.deleteRole", - "config": { - "policies": [["admin::hasPermissions", ["plugin::users-permissions.roles.delete"]]], - "description": "Delete a role", - "tag": { - "plugin": "users-permissions", - "name": "Role", - "actionType": "destroy" - } - } - }, - { - "method": "GET", - "path": "/connect/*", - "handler": "auth.connect", - "config": { - "policies": ["plugin::users-permissions.rateLimit"], - "prefix": "", - "description": "Connect a provider", - "tag": { - "plugin": "users-permissions", - "name": "User" - } - } - }, - { - "method": "POST", - "path": "/auth/local", - "handler": "auth.callback", - "config": { - "policies": ["plugin::users-permissions.rateLimit"], - "prefix": "", - "description": "Login a user using the identifiers email and password", - "tag": { - "plugin": "users-permissions", - "name": "User" - } - } - }, - { - "method": "POST", - "path": "/auth/local/register", - "handler": "auth.register", - "config": { - "policies": ["plugin::users-permissions.rateLimit"], - "prefix": "", - "description": "Register a new user with the default role", - "tag": { - "plugin": "users-permissions", - "name": "User", - "actionType": "create" - } - } - }, - { - "method": "GET", - "path": "/auth/:provider/callback", - "handler": "auth.callback", - "config": { - "policies": [], - "prefix": "", - "description": "Successfull redirection after approving a provider", - "tag": { - "plugin": "users-permissions", - "name": "User" - } - } - }, - { - "method": "POST", - "path": "/auth/forgot-password", - "handler": "auth.forgotPassword", - "config": { - "policies": ["plugin::users-permissions.rateLimit"], - "prefix": "", - "description": "Send the reset password email link", - "tag": { - "plugin": "users-permissions", - "name": "User" - } - } - }, - { - "method": "POST", - "path": "/auth/reset-password", - "handler": "auth.resetPassword", - "config": { - "policies": ["plugin::users-permissions.rateLimit"], - "prefix": "", - "description": "Reset user password with a code (resetToken)", - "tag": { - "plugin": "users-permissions", - "name": "User" - } - } - }, - { - "method": "GET", - "path": "/auth/email-confirmation", - "handler": "auth.emailConfirmation", - "config": { - "policies": [], - "prefix": "", - "description": "Validate a user account", - "tag": { - "plugin": "users-permissions", - "name": "User" - } - } - }, - { - "method": "POST", - "path": "/auth/send-email-confirmation", - "handler": "auth.sendEmailConfirmation", - "config": { - "policies": [], - "prefix": "", - "description": "Send a confirmation email to user", - "tag": { - "plugin": "users-permissions", - "name": "User" - } - } - }, - { - "method": "GET", - "path": "/users/count", - "handler": "user.count", - "config": { - "prefix": "", - "policies": [] - } - }, - { - "method": "GET", - "path": "/users", - "handler": "user.find", - "config": { - "policies": [], - "prefix": "", - "description": "Retrieve all user documents", - "tag": { - "plugin": "users-permissions", - "name": "User", - "actionType": "find" - } - } - }, - { - "method": "GET", - "path": "/users/me", - "handler": "user.me", - "config": { - "policies": [], - "prefix": "", - "description": "Retrieve the logged in user information", - "tag": { - "plugin": "users-permissions", - "name": "User", - "actionType": "findOne" - } - } - }, - { - "method": "GET", - "path": "/users/:id", - "handler": "user.findOne", - "config": { - "policies": [], - "prefix": "", - "description": "Retrieve a single user depending on his id", - "tag": { - "plugin": "users-permissions", - "name": "User", - "actionType": "findOne" - } - } - }, - { - "method": "POST", - "path": "/users", - "handler": "user.create", - "config": { - "policies": [], - "prefix": "" - } - }, - { - "method": "PUT", - "path": "/users/:id", - "handler": "user.update", - "config": { - "policies": [], - "prefix": "", - "description": "Update an existing user", - "tag": { - "plugin": "users-permissions", - "name": "User", - "actionType": "update" - } - } - }, - { - "method": "DELETE", - "path": "/users/:id", - "handler": "user.destroy", - "config": { - "policies": [], - "prefix": "", - "description": "Delete an existing user", - "tag": { - "plugin": "users-permissions", - "name": "User", - "actionType": "destroy" - } - } - } - ] -}