mirror of
https://github.com/strapi/strapi.git
synced 2025-12-27 15:13:21 +00:00
Merge pull request #14271 from strapi/api-token-v2/cleanup-content-api-core-service
Core Content API service cleanup
This commit is contained in:
commit
344d200582
@ -75,7 +75,7 @@ class Strapi {
|
||||
// Load the app configuration from the dist directory
|
||||
const appConfig = loadConfiguration({ appDir: rootDirs.app, distDir: rootDirs.dist }, opts);
|
||||
|
||||
// Instanciate the Strapi container
|
||||
// Instantiate the Strapi container
|
||||
this.container = createContainer(this);
|
||||
|
||||
// Register every Strapi registry in the container
|
||||
@ -100,7 +100,7 @@ class Strapi {
|
||||
this.isLoaded = false;
|
||||
this.reload = this.reload();
|
||||
|
||||
// Instanciate the Koa app & the HTTP server
|
||||
// Instantiate the Koa app & the HTTP server
|
||||
this.server = createServer(this);
|
||||
|
||||
// Strapi utils instanciation
|
||||
|
||||
@ -1,114 +1,13 @@
|
||||
'use strict';
|
||||
|
||||
const _ = require('lodash');
|
||||
const permissions = require('./permissions');
|
||||
|
||||
/**
|
||||
* Creates an handler which check that the permission's action exists in the action registry
|
||||
*/
|
||||
const createValidatePermissionHandler =
|
||||
(actionProvider) =>
|
||||
({ permission }) => {
|
||||
const action = actionProvider.get(permission.action);
|
||||
|
||||
// If the action isn't registered into the action provider, then ignore the permission and warn the user
|
||||
if (!action) {
|
||||
strapi.log.debug(
|
||||
`Unknown action "${permission.action}" supplied when registering a new permission`
|
||||
);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
const instantiatePermissionsUtilities = require('./permissions');
|
||||
|
||||
/**
|
||||
* Create a content API container that holds logic, tools and utils. (eg: permissions, ...)
|
||||
*/
|
||||
const createContentAPI = (strapi) => {
|
||||
// Add providers
|
||||
const providers = {
|
||||
action: permissions.providers.createActionProvider(),
|
||||
condition: permissions.providers.createConditionProvider(),
|
||||
};
|
||||
|
||||
const getActionsMap = () => {
|
||||
const actionMap = {};
|
||||
|
||||
const isContentApi = (action) => {
|
||||
if (!_.has(action, Symbol.for('__type__'))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return action[Symbol.for('__type__')].includes('content-api');
|
||||
};
|
||||
|
||||
const registerAPIsActions = (apis, source) => {
|
||||
_.forEach(apis, (api, apiName) => {
|
||||
const controllers = _.reduce(
|
||||
api.controllers,
|
||||
(acc, controller, controllerName) => {
|
||||
const contentApiActions = _.pickBy(controller, isContentApi);
|
||||
|
||||
if (_.isEmpty(contentApiActions)) {
|
||||
return acc;
|
||||
}
|
||||
|
||||
acc[controllerName] = Object.keys(contentApiActions);
|
||||
|
||||
return acc;
|
||||
},
|
||||
{}
|
||||
);
|
||||
|
||||
if (!_.isEmpty(controllers)) {
|
||||
actionMap[`${source}::${apiName}`] = { controllers };
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
registerAPIsActions(strapi.api, 'api');
|
||||
registerAPIsActions(strapi.plugins, 'plugin');
|
||||
|
||||
return actionMap;
|
||||
};
|
||||
|
||||
const registerActions = async () => {
|
||||
const actionsMap = getActionsMap();
|
||||
|
||||
// For each API
|
||||
for (const [api, value] of Object.entries(actionsMap)) {
|
||||
const { controllers } = value;
|
||||
|
||||
// Register controllers methods as actions
|
||||
for (const [controller, actions] of Object.entries(controllers)) {
|
||||
// Register each action individually
|
||||
await Promise.all(
|
||||
actions.map((action) => {
|
||||
const actionUID = `${api}.${controller}.${action}`;
|
||||
|
||||
return providers.action.register(actionUID, {
|
||||
api,
|
||||
controller,
|
||||
action,
|
||||
uid: actionUID,
|
||||
});
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// create permission engine
|
||||
const engine = permissions
|
||||
.createPermissionEngine({ providers })
|
||||
.on('before-format::validate.permission', createValidatePermissionHandler(providers.action));
|
||||
|
||||
return {
|
||||
permissions: {
|
||||
engine,
|
||||
providers,
|
||||
registerActions,
|
||||
getActionsMap,
|
||||
},
|
||||
permissions: instantiatePermissionsUtilities(strapi),
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@ -1,9 +1,148 @@
|
||||
'use strict';
|
||||
|
||||
const providers = require('./providers');
|
||||
const _ = require('lodash');
|
||||
const { createActionProvider, createConditionProvider } = require('./providers');
|
||||
const createPermissionEngine = require('./engine');
|
||||
|
||||
module.exports = {
|
||||
providers,
|
||||
createPermissionEngine,
|
||||
/**
|
||||
* Creates an handler that checks if the permission's action exists in the action registry
|
||||
*/
|
||||
const createValidatePermissionHandler =
|
||||
(actionProvider) =>
|
||||
({ permission }) => {
|
||||
const action = actionProvider.get(permission.action);
|
||||
|
||||
// If the action isn't registered into the action provider, then ignore the permission and warn the user
|
||||
if (!action) {
|
||||
strapi.log.debug(
|
||||
`Unknown action "${permission.action}" supplied when registering a new permission`
|
||||
);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Create instances of providers and permission engine for the core content-API service.
|
||||
* Also, expose utilities to get informations about available actions and such.
|
||||
*
|
||||
* @param {Strapi.Strapi} strapi
|
||||
*/
|
||||
module.exports = (strapi) => {
|
||||
// NOTE: Here we define both an action and condition provider,
|
||||
// but at the moment, we're only using the action one.
|
||||
const providers = {
|
||||
action: createActionProvider(),
|
||||
condition: createConditionProvider(),
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a tree representation of the available Content API actions
|
||||
* based on the methods of the Content API controllers.
|
||||
*
|
||||
* @note Only actions bound to a content-API route are returned.
|
||||
*
|
||||
* @return {{ [api: string]: { [controller: string]: string[] }}}
|
||||
*/
|
||||
const getActionsMap = () => {
|
||||
const actionMap = {};
|
||||
|
||||
/**
|
||||
* Check if a controller's action is bound to the
|
||||
* content-api by looking at a potential __type__ symbol
|
||||
*
|
||||
* @param {object} action
|
||||
*
|
||||
* @return {boolean}
|
||||
*/
|
||||
const isContentApi = (action) => {
|
||||
if (!_.has(action, Symbol.for('__type__'))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return action[Symbol.for('__type__')].includes('content-api');
|
||||
};
|
||||
|
||||
/**
|
||||
* Register actions from a specific API source into the result tree
|
||||
*
|
||||
* @param {{ [apiName]: { controllers: { [controller]: object } }}} apis The API container
|
||||
* @param {string} source The prefix to use in front the API name
|
||||
*
|
||||
* @return {void}
|
||||
*/
|
||||
const registerAPIsActions = (apis, source) => {
|
||||
_.forEach(apis, (api, apiName) => {
|
||||
const controllers = _.reduce(
|
||||
api.controllers,
|
||||
(acc, controller, controllerName) => {
|
||||
const contentApiActions = _.pickBy(controller, isContentApi);
|
||||
|
||||
if (_.isEmpty(contentApiActions)) {
|
||||
return acc;
|
||||
}
|
||||
|
||||
acc[controllerName] = Object.keys(contentApiActions);
|
||||
|
||||
return acc;
|
||||
},
|
||||
{}
|
||||
);
|
||||
|
||||
if (!_.isEmpty(controllers)) {
|
||||
actionMap[`${source}::${apiName}`] = { controllers };
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
registerAPIsActions(strapi.api, 'api');
|
||||
registerAPIsActions(strapi.plugins, 'plugin');
|
||||
|
||||
return actionMap;
|
||||
};
|
||||
|
||||
/**
|
||||
* Register all the content-API's controllers actions into the action provider.
|
||||
* This method make use of the {@link getActionsMap} to generate the list of actions to register.
|
||||
*
|
||||
* @return {void}
|
||||
*/
|
||||
const registerActions = async () => {
|
||||
const actionsMap = getActionsMap();
|
||||
|
||||
// For each API
|
||||
for (const [api, value] of Object.entries(actionsMap)) {
|
||||
const { controllers } = value;
|
||||
|
||||
// Register controllers methods as actions
|
||||
for (const [controller, actions] of Object.entries(controllers)) {
|
||||
// Register each action individually
|
||||
await Promise.all(
|
||||
actions.map((action) => {
|
||||
const actionUID = `${api}.${controller}.${action}`;
|
||||
|
||||
return providers.action.register(actionUID, {
|
||||
api,
|
||||
controller,
|
||||
action,
|
||||
uid: actionUID,
|
||||
});
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Create an instance of a content-API permission engine
|
||||
// and binds a custom validation handler to it
|
||||
const engine = createPermissionEngine({ providers }).on(
|
||||
'before-format::validate.permission',
|
||||
createValidatePermissionHandler(providers.action)
|
||||
);
|
||||
|
||||
return {
|
||||
engine,
|
||||
providers,
|
||||
registerActions,
|
||||
getActionsMap,
|
||||
};
|
||||
};
|
||||
|
||||
@ -52,7 +52,7 @@ export const useCropImg = () => {
|
||||
if (!cropperRef.current) {
|
||||
reject(
|
||||
new Error(
|
||||
'The cropper has not been instanciated: make sure to call the crop() function before calling produceFile().'
|
||||
'The cropper has not been instantiated: make sure to call the crop() function before calling produceFile().'
|
||||
)
|
||||
);
|
||||
} else {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user