2017-11-06 11:14:43 +01:00
|
|
|
'use strict';
|
|
|
|
|
2017-11-16 17:59:41 +01:00
|
|
|
const _ = require('lodash');
|
2018-01-05 16:19:53 +01:00
|
|
|
const request = require('request');
|
2017-12-07 18:16:18 +01:00
|
|
|
|
2017-11-06 11:14:43 +01:00
|
|
|
/**
|
|
|
|
* UsersPermissions.js service
|
|
|
|
*
|
|
|
|
* @description: A set of functions similar to controller's actions to avoid code duplication.
|
|
|
|
*/
|
|
|
|
|
|
|
|
module.exports = {
|
2019-07-15 23:16:50 +02:00
|
|
|
async createRole(params) {
|
2018-02-06 14:43:26 +01:00
|
|
|
if (!params.type) {
|
|
|
|
params.type = _.snakeCase(_.deburr(_.toLower(params.name)));
|
|
|
|
}
|
|
|
|
|
2019-07-15 23:16:50 +02:00
|
|
|
const role = await strapi
|
|
|
|
.query('role', 'users-permissions')
|
2019-04-09 12:09:03 +02:00
|
|
|
.create(_.omit(params, ['users', 'permissions']));
|
|
|
|
|
2019-07-16 20:52:31 +02:00
|
|
|
const arrayOfPromises = Object.keys(params.permissions || {}).reduce(
|
2019-04-09 12:09:03 +02:00
|
|
|
(acc, type) => {
|
|
|
|
Object.keys(params.permissions[type].controllers).forEach(
|
|
|
|
controller => {
|
|
|
|
Object.keys(
|
2019-06-08 16:23:52 +02:00
|
|
|
params.permissions[type].controllers[controller]
|
2019-04-09 12:09:03 +02:00
|
|
|
).forEach(action => {
|
|
|
|
acc.push(
|
2019-07-15 23:16:50 +02:00
|
|
|
strapi.query('permission', 'users-permissions').create({
|
2019-08-13 16:31:29 +02:00
|
|
|
role: role.id,
|
2019-07-15 23:16:50 +02:00
|
|
|
type,
|
|
|
|
controller,
|
|
|
|
action: action.toLowerCase(),
|
|
|
|
...params.permissions[type].controllers[controller][action],
|
|
|
|
})
|
2019-04-09 12:09:03 +02:00
|
|
|
);
|
|
|
|
});
|
2019-06-08 16:23:52 +02:00
|
|
|
}
|
2019-04-09 12:09:03 +02:00
|
|
|
);
|
2017-11-27 16:49:56 +01:00
|
|
|
|
2019-04-09 12:09:03 +02:00
|
|
|
return acc;
|
|
|
|
},
|
2019-06-08 16:23:52 +02:00
|
|
|
[]
|
2019-04-09 12:09:03 +02:00
|
|
|
);
|
2018-01-23 15:38:43 +01:00
|
|
|
|
|
|
|
// Use Content Manager business logic to handle relation.
|
2019-07-16 20:52:31 +02:00
|
|
|
if (params.users && params.users.length > 0)
|
|
|
|
arrayOfPromises.push(
|
|
|
|
strapi.query('role', 'users-permissions').update(
|
|
|
|
{
|
|
|
|
id: role.id,
|
|
|
|
},
|
|
|
|
{ users: params.users }
|
|
|
|
)
|
|
|
|
);
|
2017-12-01 16:06:16 +01:00
|
|
|
|
2018-01-23 15:38:43 +01:00
|
|
|
return await Promise.all(arrayOfPromises);
|
2017-11-27 17:02:45 +01:00
|
|
|
},
|
|
|
|
|
2019-07-15 23:16:50 +02:00
|
|
|
async deleteRole(roleID, publicRoleID) {
|
|
|
|
const role = await strapi
|
|
|
|
.query('role', 'users-permissions')
|
2019-04-09 12:09:03 +02:00
|
|
|
.findOne({ id: roleID }, ['users', 'permissions']);
|
2018-01-23 15:38:43 +01:00
|
|
|
|
|
|
|
if (!role) {
|
|
|
|
throw new Error('Cannot found this role');
|
|
|
|
}
|
|
|
|
|
|
|
|
// Move users to guest role.
|
|
|
|
const arrayOfPromises = role.users.reduce((acc, user) => {
|
2019-04-09 12:09:03 +02:00
|
|
|
acc.push(
|
2019-07-15 23:16:50 +02:00
|
|
|
strapi.query('user', 'users-permissions').update(
|
|
|
|
{
|
2019-08-13 16:31:29 +02:00
|
|
|
id: user.id,
|
2019-07-15 23:16:50 +02:00
|
|
|
},
|
|
|
|
{
|
|
|
|
role: publicRoleID,
|
|
|
|
}
|
|
|
|
)
|
2019-04-09 12:09:03 +02:00
|
|
|
);
|
2018-01-23 15:38:43 +01:00
|
|
|
|
|
|
|
return acc;
|
|
|
|
}, []);
|
2017-11-27 17:50:51 +01:00
|
|
|
|
2018-01-23 15:38:43 +01:00
|
|
|
// Remove permissions related to this role.
|
|
|
|
role.permissions.forEach(permission => {
|
2019-04-09 12:09:03 +02:00
|
|
|
arrayOfPromises.push(
|
2019-07-15 23:16:50 +02:00
|
|
|
strapi.query('permission', 'users-permissions').delete({
|
2019-08-13 16:31:29 +02:00
|
|
|
id: permission.id,
|
2019-07-15 23:16:50 +02:00
|
|
|
})
|
2019-04-09 12:09:03 +02:00
|
|
|
);
|
2018-04-30 18:26:56 +02:00
|
|
|
});
|
2017-12-01 16:06:16 +01:00
|
|
|
|
2018-01-23 15:38:43 +01:00
|
|
|
// Delete the role.
|
2019-04-09 12:09:03 +02:00
|
|
|
arrayOfPromises.push(
|
2019-07-15 23:16:50 +02:00
|
|
|
strapi.query('role', 'users-permissions').delete({ id: roleID })
|
2019-04-09 12:09:03 +02:00
|
|
|
);
|
2017-12-01 16:06:16 +01:00
|
|
|
|
2018-01-23 15:38:43 +01:00
|
|
|
return await Promise.all(arrayOfPromises);
|
2017-11-27 16:49:56 +01:00
|
|
|
},
|
|
|
|
|
2019-07-15 23:16:50 +02:00
|
|
|
getPlugins(plugin, lang = 'en') {
|
2019-04-09 12:09:03 +02:00
|
|
|
return new Promise(resolve => {
|
|
|
|
request(
|
|
|
|
{
|
|
|
|
uri: `https://marketplace.strapi.io/plugins?lang=${lang}`,
|
|
|
|
json: true,
|
|
|
|
headers: {
|
|
|
|
'cache-control': 'max-age=3600',
|
|
|
|
},
|
|
|
|
},
|
|
|
|
(err, response, body) => {
|
2019-06-17 00:02:27 +08:00
|
|
|
if (err || response.statusCode !== 200) {
|
2019-04-09 12:09:03 +02:00
|
|
|
return resolve([]);
|
|
|
|
}
|
2018-01-05 16:19:53 +01:00
|
|
|
|
2019-04-09 12:09:03 +02:00
|
|
|
resolve(body);
|
2019-06-08 16:23:52 +02:00
|
|
|
}
|
2019-04-09 12:09:03 +02:00
|
|
|
);
|
2018-01-05 16:19:53 +01:00
|
|
|
});
|
|
|
|
},
|
|
|
|
|
2019-07-15 23:16:50 +02:00
|
|
|
getActions(plugins = [], withInfo = true) {
|
2019-04-09 12:09:03 +02:00
|
|
|
const generateActions = data =>
|
2017-11-17 14:22:59 +01:00
|
|
|
Object.keys(data).reduce((acc, key) => {
|
2018-01-25 15:46:15 +01:00
|
|
|
if (_.isFunction(data[key])) {
|
|
|
|
acc[key] = { enabled: false, policy: '' };
|
|
|
|
}
|
2017-11-06 11:14:43 +01:00
|
|
|
|
2017-11-17 14:22:59 +01:00
|
|
|
return acc;
|
2019-04-09 12:09:03 +02:00
|
|
|
}, {});
|
2017-11-17 14:22:59 +01:00
|
|
|
|
2018-10-05 13:07:39 +02:00
|
|
|
const appControllers = Object.keys(strapi.api || {})
|
|
|
|
.filter(key => !!strapi.api[key].controllers)
|
2019-04-09 12:09:03 +02:00
|
|
|
.reduce(
|
|
|
|
(acc, key) => {
|
|
|
|
Object.keys(strapi.api[key].controllers).forEach(controller => {
|
|
|
|
acc.controllers[controller] = generateActions(
|
2019-06-08 16:23:52 +02:00
|
|
|
strapi.api[key].controllers[controller]
|
2019-04-09 12:09:03 +02:00
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
return acc;
|
|
|
|
},
|
2019-06-08 16:23:52 +02:00
|
|
|
{ controllers: {} }
|
2019-04-09 12:09:03 +02:00
|
|
|
);
|
2017-11-16 17:59:41 +01:00
|
|
|
|
2019-04-09 12:09:03 +02:00
|
|
|
const pluginsPermissions = Object.keys(strapi.plugins).reduce(
|
|
|
|
(acc, key) => {
|
|
|
|
const initialState = {
|
|
|
|
controllers: {},
|
|
|
|
};
|
2017-11-17 12:14:12 +01:00
|
|
|
|
2019-04-09 12:09:03 +02:00
|
|
|
if (withInfo) {
|
|
|
|
initialState.information =
|
|
|
|
plugins.find(plugin => plugin.id === key) || {};
|
|
|
|
}
|
2017-11-17 12:14:12 +01:00
|
|
|
|
2019-04-09 12:09:03 +02:00
|
|
|
acc[key] = Object.keys(strapi.plugins[key].controllers).reduce(
|
|
|
|
(obj, k) => {
|
|
|
|
obj.controllers[k] = generateActions(
|
2019-06-08 16:23:52 +02:00
|
|
|
strapi.plugins[key].controllers[k]
|
2019-04-09 12:09:03 +02:00
|
|
|
);
|
2017-11-17 12:14:12 +01:00
|
|
|
|
2019-04-09 12:09:03 +02:00
|
|
|
return obj;
|
|
|
|
},
|
2019-06-08 16:23:52 +02:00
|
|
|
initialState
|
2019-04-09 12:09:03 +02:00
|
|
|
);
|
2017-11-17 12:14:12 +01:00
|
|
|
|
2019-04-09 12:09:03 +02:00
|
|
|
return acc;
|
|
|
|
},
|
2019-06-08 16:23:52 +02:00
|
|
|
{}
|
2019-04-09 12:09:03 +02:00
|
|
|
);
|
2017-11-16 17:59:41 +01:00
|
|
|
|
|
|
|
const permissions = {
|
|
|
|
application: {
|
|
|
|
controllers: appControllers.controllers,
|
2017-11-17 12:14:12 +01:00
|
|
|
},
|
2017-11-16 17:59:41 +01:00
|
|
|
};
|
|
|
|
|
2018-04-30 18:26:56 +02:00
|
|
|
return _.merge(permissions, pluginsPermissions);
|
2017-11-17 16:36:57 +01:00
|
|
|
},
|
2017-11-17 14:22:59 +01:00
|
|
|
|
2019-07-15 23:16:50 +02:00
|
|
|
async getRole(roleID, plugins) {
|
|
|
|
const role = await strapi
|
|
|
|
.query('role', 'users-permissions')
|
2019-04-09 12:09:03 +02:00
|
|
|
.findOne({ id: roleID }, ['users', 'permissions']);
|
2018-01-05 16:19:53 +01:00
|
|
|
|
2018-01-19 17:57:10 +01:00
|
|
|
if (!role) {
|
2019-07-25 16:43:17 +02:00
|
|
|
throw new Error('Cannot find this role');
|
2018-01-19 17:57:10 +01:00
|
|
|
}
|
2017-11-27 17:50:51 +01:00
|
|
|
|
2018-01-22 18:19:44 +01:00
|
|
|
// Group by `type`.
|
2019-07-18 15:49:24 +02:00
|
|
|
const permissions = role.permissions.reduce((acc, permission) => {
|
2019-04-09 12:09:03 +02:00
|
|
|
_.set(
|
|
|
|
acc,
|
2019-07-15 23:16:50 +02:00
|
|
|
`${permission.type}.controllers.${permission.controller}.${permission.action}`,
|
2019-04-09 12:09:03 +02:00
|
|
|
{
|
|
|
|
enabled: _.toNumber(permission.enabled) == true,
|
|
|
|
policy: permission.policy,
|
2019-06-08 16:23:52 +02:00
|
|
|
}
|
2019-04-09 12:09:03 +02:00
|
|
|
);
|
2018-01-05 16:19:53 +01:00
|
|
|
|
2019-04-09 12:09:03 +02:00
|
|
|
if (
|
|
|
|
permission.type !== 'application' &&
|
|
|
|
!acc[permission.type].information
|
|
|
|
) {
|
|
|
|
acc[permission.type].information =
|
|
|
|
plugins.find(plugin => plugin.id === permission.type) || {};
|
2018-01-22 18:19:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return acc;
|
|
|
|
}, {});
|
|
|
|
|
2019-07-18 15:49:24 +02:00
|
|
|
return {
|
|
|
|
...role,
|
|
|
|
permissions,
|
|
|
|
};
|
2017-11-27 17:50:51 +01:00
|
|
|
},
|
|
|
|
|
2019-07-15 23:16:50 +02:00
|
|
|
async getRoles() {
|
|
|
|
const roles = await strapi
|
|
|
|
.query('role', 'users-permissions')
|
2019-04-09 16:01:01 +02:00
|
|
|
.find({ _sort: 'name' }, []);
|
2017-11-27 16:04:57 +01:00
|
|
|
|
2018-01-17 18:50:12 +01:00
|
|
|
for (let i = 0; i < roles.length; ++i) {
|
2019-07-15 23:16:50 +02:00
|
|
|
roles[i].nb_users = await strapi
|
|
|
|
.query('user', 'users-permissions')
|
2019-04-09 12:09:03 +02:00
|
|
|
.count({ role: roles[i].id });
|
2018-01-17 18:50:12 +01:00
|
|
|
}
|
2017-11-27 16:04:57 +01:00
|
|
|
|
2018-01-17 18:50:12 +01:00
|
|
|
return roles;
|
2017-11-27 16:04:57 +01:00
|
|
|
},
|
|
|
|
|
2019-07-15 23:16:50 +02:00
|
|
|
async getRoutes() {
|
2018-01-17 18:50:12 +01:00
|
|
|
const routes = Object.keys(strapi.api || {}).reduce((acc, current) => {
|
2018-04-23 14:39:27 +02:00
|
|
|
return acc.concat(_.get(strapi.api[current].config, 'routes', []));
|
2018-01-17 18:50:12 +01:00
|
|
|
}, []);
|
2018-10-01 14:29:11 +02:00
|
|
|
const clonedPlugins = _.cloneDeep(strapi.plugins);
|
2019-04-09 12:09:03 +02:00
|
|
|
const pluginsRoutes = Object.keys(clonedPlugins || {}).reduce(
|
|
|
|
(acc, current) => {
|
|
|
|
const routes = _.get(
|
|
|
|
clonedPlugins,
|
|
|
|
[current, 'config', 'routes'],
|
2019-06-08 16:23:52 +02:00
|
|
|
[]
|
2019-04-09 12:09:03 +02:00
|
|
|
).reduce((acc, curr) => {
|
2018-10-01 14:29:11 +02:00
|
|
|
const prefix = curr.config.prefix;
|
2019-04-09 12:09:03 +02:00
|
|
|
const path =
|
|
|
|
prefix !== undefined
|
|
|
|
? `${prefix}${curr.path}`
|
|
|
|
: `/${current}${curr.path}`;
|
2018-10-01 14:29:11 +02:00
|
|
|
_.set(curr, 'path', path);
|
2018-11-15 15:41:08 -06:00
|
|
|
|
2018-10-01 14:29:11 +02:00
|
|
|
return acc.concat(curr);
|
2018-11-15 15:41:08 -06:00
|
|
|
}, []);
|
2018-10-01 14:29:11 +02:00
|
|
|
|
2019-04-09 12:09:03 +02:00
|
|
|
acc[current] = routes;
|
2017-11-30 16:34:43 +01:00
|
|
|
|
2019-04-09 12:09:03 +02:00
|
|
|
return acc;
|
|
|
|
},
|
2019-06-08 16:23:52 +02:00
|
|
|
{}
|
2019-04-09 12:09:03 +02:00
|
|
|
);
|
2017-12-07 18:16:18 +01:00
|
|
|
|
2018-01-17 18:50:12 +01:00
|
|
|
return _.merge({ application: routes }, pluginsRoutes);
|
2017-11-30 16:34:43 +01:00
|
|
|
},
|
|
|
|
|
2019-04-10 18:11:55 +02:00
|
|
|
async updatePermissions() {
|
2018-07-03 15:23:13 +01:00
|
|
|
// fetch all the current permissions from the database, and format them into an array of actions.
|
2019-07-15 23:16:50 +02:00
|
|
|
const databasePermissions = await strapi
|
|
|
|
.query('permission', 'users-permissions')
|
2019-04-09 16:01:01 +02:00
|
|
|
.find({ _limit: -1 });
|
2019-07-15 23:16:50 +02:00
|
|
|
|
|
|
|
const actionsMap = databasePermissions.reduce((acc, permission) => {
|
|
|
|
acc[`${permission.type}.${permission.controller}.${permission.action}`] =
|
|
|
|
permission.id;
|
|
|
|
return acc;
|
|
|
|
}, {});
|
|
|
|
const stringActions = Object.keys(actionsMap);
|
2018-01-17 18:50:12 +01:00
|
|
|
|
|
|
|
// Aggregate first level actions.
|
|
|
|
const appActions = Object.keys(strapi.api || {}).reduce((acc, api) => {
|
2019-04-09 12:09:03 +02:00
|
|
|
Object.keys(_.get(strapi.api[api], 'controllers', {})).forEach(
|
|
|
|
controller => {
|
2018-01-17 18:50:12 +01:00
|
|
|
const actions = Object.keys(strapi.api[api].controllers[controller])
|
2019-04-09 12:09:03 +02:00
|
|
|
.filter(action =>
|
2019-06-08 16:23:52 +02:00
|
|
|
_.isFunction(strapi.api[api].controllers[controller][action])
|
2019-04-09 12:09:03 +02:00
|
|
|
)
|
2018-01-25 17:08:39 +01:00
|
|
|
.map(action => `application.${controller}.${action.toLowerCase()}`);
|
2018-01-17 18:50:12 +01:00
|
|
|
|
|
|
|
acc = acc.concat(actions);
|
2019-06-08 16:23:52 +02:00
|
|
|
}
|
2019-04-09 12:09:03 +02:00
|
|
|
);
|
2017-11-17 16:36:57 +01:00
|
|
|
|
2018-01-17 18:50:12 +01:00
|
|
|
return acc;
|
|
|
|
}, []);
|
2017-11-17 16:36:57 +01:00
|
|
|
|
2018-01-17 18:50:12 +01:00
|
|
|
// Aggregate plugins' actions.
|
|
|
|
const pluginsActions = Object.keys(strapi.plugins).reduce((acc, plugin) => {
|
2019-04-09 12:09:03 +02:00
|
|
|
Object.keys(strapi.plugins[plugin].controllers).forEach(controller => {
|
|
|
|
const actions = Object.keys(
|
2019-06-08 16:23:52 +02:00
|
|
|
strapi.plugins[plugin].controllers[controller]
|
2019-04-09 12:09:03 +02:00
|
|
|
)
|
|
|
|
.filter(action =>
|
2019-06-08 16:23:52 +02:00
|
|
|
_.isFunction(strapi.plugins[plugin].controllers[controller][action])
|
2019-04-09 12:09:03 +02:00
|
|
|
)
|
|
|
|
.map(action => `${plugin}.${controller}.${action.toLowerCase()}`);
|
2018-01-17 18:50:12 +01:00
|
|
|
|
2019-04-09 12:09:03 +02:00
|
|
|
acc = acc.concat(actions);
|
|
|
|
});
|
2017-12-07 10:16:36 +01:00
|
|
|
|
2018-01-17 18:50:12 +01:00
|
|
|
return acc;
|
|
|
|
}, []);
|
2017-11-17 16:36:57 +01:00
|
|
|
|
2018-01-17 18:50:12 +01:00
|
|
|
// Merge array into one.
|
|
|
|
const currentActions = appActions.concat(pluginsActions);
|
|
|
|
// Count permissions available.
|
2018-07-03 15:23:13 +01:00
|
|
|
const permissions = databasePermissions.length;
|
2018-01-17 18:50:12 +01:00
|
|
|
|
|
|
|
// Compare to know if actions have been added or removed from controllers.
|
2019-07-15 23:16:50 +02:00
|
|
|
if (!_.isEqual(stringActions, currentActions) || permissions < 1) {
|
2019-04-09 12:09:03 +02:00
|
|
|
const splitted = str => {
|
2018-01-17 18:50:12 +01:00
|
|
|
const [type, controller, action] = str.split('.');
|
|
|
|
|
|
|
|
return { type, controller, action };
|
|
|
|
};
|
|
|
|
|
|
|
|
const defaultPolicy = (obj, role) => {
|
2019-04-09 12:09:03 +02:00
|
|
|
const isAdminCallback =
|
|
|
|
obj.action === 'admincallback' &&
|
|
|
|
obj.controller === 'auth' &&
|
|
|
|
obj.type === 'users-permissions' &&
|
|
|
|
role.type === 'public';
|
|
|
|
const isAdminRegister =
|
|
|
|
obj.action === 'adminregister' &&
|
|
|
|
obj.controller === 'auth' &&
|
|
|
|
obj.type === 'users-permissions' &&
|
|
|
|
role.type === 'public';
|
|
|
|
const isCallback =
|
|
|
|
obj.action === 'callback' &&
|
|
|
|
obj.controller === 'auth' &&
|
|
|
|
obj.type === 'users-permissions' &&
|
|
|
|
role.type === 'public';
|
|
|
|
const isConnect =
|
|
|
|
obj.action === 'connect' &&
|
|
|
|
obj.controller === 'auth' &&
|
|
|
|
obj.type === 'users-permissions';
|
|
|
|
const isPassword =
|
|
|
|
obj.action === 'forgotpassword' &&
|
|
|
|
obj.controller === 'auth' &&
|
|
|
|
obj.type === 'users-permissions' &&
|
|
|
|
role.type === 'public';
|
|
|
|
const isRegister =
|
|
|
|
obj.action === 'register' &&
|
|
|
|
obj.controller === 'auth' &&
|
|
|
|
obj.type === 'users-permissions' &&
|
|
|
|
role.type === 'public';
|
|
|
|
const isConfirmation =
|
|
|
|
obj.action === 'emailconfirmation' &&
|
|
|
|
obj.controller === 'auth' &&
|
|
|
|
obj.type === 'users-permissions' &&
|
|
|
|
role.type === 'public';
|
|
|
|
const isNewPassword =
|
|
|
|
obj.action === 'changepassword' &&
|
|
|
|
obj.controller === 'auth' &&
|
|
|
|
obj.type === 'users-permissions' &&
|
|
|
|
role.type === 'public';
|
|
|
|
const isInit =
|
|
|
|
obj.action === 'init' && obj.controller === 'userspermissions';
|
|
|
|
const isMe =
|
|
|
|
obj.action === 'me' &&
|
|
|
|
obj.controller === 'user' &&
|
|
|
|
obj.type === 'users-permissions';
|
2018-01-25 17:08:39 +01:00
|
|
|
const isReload = obj.action === 'autoreload';
|
2019-04-09 12:09:03 +02:00
|
|
|
const enabled =
|
|
|
|
isCallback ||
|
|
|
|
isRegister ||
|
|
|
|
isInit ||
|
|
|
|
isPassword ||
|
|
|
|
isNewPassword ||
|
|
|
|
isMe ||
|
|
|
|
isReload ||
|
|
|
|
isConnect ||
|
|
|
|
isConfirmation ||
|
|
|
|
isAdminCallback ||
|
|
|
|
isAdminRegister;
|
2018-01-17 18:50:12 +01:00
|
|
|
|
|
|
|
return Object.assign(obj, { enabled, policy: '' });
|
|
|
|
};
|
|
|
|
|
|
|
|
// Retrieve roles
|
2019-11-14 16:36:35 +01:00
|
|
|
const roles = await strapi
|
|
|
|
.query('role', 'users-permissions')
|
|
|
|
.find({}, []);
|
2018-01-17 18:50:12 +01:00
|
|
|
|
|
|
|
// We have to know the difference to add or remove
|
|
|
|
// the permissions entries in the database.
|
2019-07-15 23:16:50 +02:00
|
|
|
const toRemove = _.difference(stringActions, currentActions).map(
|
2019-09-09 23:05:09 +02:00
|
|
|
splitted
|
2019-07-15 23:16:50 +02:00
|
|
|
);
|
|
|
|
|
2019-04-09 12:09:03 +02:00
|
|
|
const toAdd = (permissions < 1
|
|
|
|
? currentActions
|
2019-07-15 23:16:50 +02:00
|
|
|
: _.difference(currentActions, stringActions)
|
2019-04-09 12:09:03 +02:00
|
|
|
).map(splitted);
|
2018-01-17 18:50:12 +01:00
|
|
|
|
2019-07-15 23:16:50 +02:00
|
|
|
const query = strapi.query('permission', 'users-permissions');
|
|
|
|
|
|
|
|
const createActions = role =>
|
|
|
|
Promise.all(
|
|
|
|
toAdd.map(action => {
|
|
|
|
const data = {
|
|
|
|
...defaultPolicy(action, role),
|
2019-08-13 16:31:29 +02:00
|
|
|
role: role.id,
|
2019-07-15 23:16:50 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
return query.create(data);
|
|
|
|
})
|
|
|
|
);
|
|
|
|
|
2018-01-17 18:50:12 +01:00
|
|
|
// Execute request to update entries in database for each role.
|
2019-07-15 23:16:50 +02:00
|
|
|
await Promise.all([
|
|
|
|
Promise.all(roles.map(createActions)),
|
2019-09-09 23:05:09 +02:00
|
|
|
Promise.all(toRemove.map(action => query.delete(action))),
|
2019-07-15 23:16:50 +02:00
|
|
|
]);
|
2017-11-17 14:22:59 +01:00
|
|
|
}
|
2017-11-17 16:36:57 +01:00
|
|
|
},
|
2017-11-17 14:22:59 +01:00
|
|
|
|
2019-07-15 23:16:50 +02:00
|
|
|
async removeDuplicate() {
|
2019-07-17 13:50:07 +02:00
|
|
|
const { primaryKey } = strapi.query('permission', 'users-permissions');
|
2018-05-03 16:26:57 +02:00
|
|
|
|
|
|
|
// Retrieve permissions by creation date (ID or ObjectID).
|
2019-07-15 23:16:50 +02:00
|
|
|
const permissions = await strapi
|
|
|
|
.query('permission', 'users-permissions')
|
|
|
|
.find({ _sort: `${primaryKey}`, _limit: -1 });
|
2018-05-02 11:40:42 +02:00
|
|
|
|
2019-04-09 12:09:03 +02:00
|
|
|
const value = permissions.reduce(
|
|
|
|
(acc, permission) => {
|
2019-07-17 13:50:07 +02:00
|
|
|
const key = `${permission.type}.controllers.${permission.controller}.${permission.action}.${permission.role[primaryKey]}`;
|
|
|
|
|
|
|
|
const index = acc.toKeep.findIndex(element => element === key);
|
2019-04-09 12:09:03 +02:00
|
|
|
|
|
|
|
if (index === -1) {
|
2019-07-17 13:50:07 +02:00
|
|
|
acc.toKeep.push(key);
|
2019-04-09 12:09:03 +02:00
|
|
|
} else {
|
|
|
|
acc.toRemove.push(permission[primaryKey]);
|
|
|
|
}
|
2018-05-02 11:40:42 +02:00
|
|
|
|
2019-04-09 12:09:03 +02:00
|
|
|
return acc;
|
|
|
|
},
|
|
|
|
{
|
|
|
|
toKeep: [],
|
|
|
|
toRemove: [],
|
2019-06-08 16:23:52 +02:00
|
|
|
}
|
2019-04-09 12:09:03 +02:00
|
|
|
);
|
2018-05-02 11:40:42 +02:00
|
|
|
|
2019-07-16 20:11:34 +02:00
|
|
|
if (value.toRemove.length > 0) {
|
|
|
|
return strapi.query('permission', 'users-permissions').delete({
|
2019-07-16 23:27:34 +02:00
|
|
|
[`${primaryKey}_in`]: value.toRemove,
|
2019-07-16 20:11:34 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
return Promise.resolve();
|
2017-11-17 16:36:57 +01:00
|
|
|
},
|
2017-11-17 14:22:59 +01:00
|
|
|
|
2019-08-12 15:35:40 +02:00
|
|
|
async initialize() {
|
2019-07-15 23:16:50 +02:00
|
|
|
const roleCount = await strapi.query('role', 'users-permissions').count();
|
2018-01-17 18:50:12 +01:00
|
|
|
|
2018-05-23 14:25:32 +02:00
|
|
|
// It has already been initialized.
|
2019-04-10 18:11:55 +02:00
|
|
|
if (roleCount > 0) {
|
2019-08-12 15:35:40 +02:00
|
|
|
await this.updatePermissions();
|
|
|
|
await this.removeDuplicate();
|
|
|
|
return;
|
2018-01-17 18:50:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Create two first default roles.
|
|
|
|
await Promise.all([
|
2019-07-15 23:16:50 +02:00
|
|
|
strapi.query('role', 'users-permissions').create({
|
|
|
|
name: 'Authenticated',
|
|
|
|
description: 'Default role given to authenticated user.',
|
|
|
|
type: 'authenticated',
|
|
|
|
}),
|
|
|
|
strapi.query('role', 'users-permissions').create({
|
|
|
|
name: 'Public',
|
|
|
|
description: 'Default role given to unauthenticated user.',
|
|
|
|
type: 'public',
|
|
|
|
}),
|
2018-01-17 18:50:12 +01:00
|
|
|
]);
|
|
|
|
|
2019-08-12 15:35:40 +02:00
|
|
|
return this.updatePermissions();
|
2018-01-17 18:50:12 +01:00
|
|
|
},
|
|
|
|
|
2019-07-15 23:16:50 +02:00
|
|
|
async updateRole(roleID, body) {
|
2019-04-09 12:09:03 +02:00
|
|
|
const [role, authenticated] = await Promise.all([
|
2018-01-22 18:19:44 +01:00
|
|
|
this.getRole(roleID, []),
|
2019-07-15 23:16:50 +02:00
|
|
|
strapi
|
|
|
|
.query('role', 'users-permissions')
|
2019-04-09 12:09:03 +02:00
|
|
|
.findOne({ type: 'authenticated' }, []),
|
2018-01-22 18:19:44 +01:00
|
|
|
]);
|
2017-11-27 17:50:51 +01:00
|
|
|
|
2019-07-16 20:52:31 +02:00
|
|
|
await strapi
|
|
|
|
.query('role', 'users-permissions')
|
|
|
|
.update({ id: roleID }, _.pick(body, ['name', 'description']));
|
|
|
|
|
|
|
|
await Promise.all(
|
2019-07-17 10:15:22 +02:00
|
|
|
Object.keys(body.permissions || {}).reduce((acc, type) => {
|
2019-04-09 12:09:03 +02:00
|
|
|
Object.keys(body.permissions[type].controllers).forEach(controller => {
|
|
|
|
Object.keys(body.permissions[type].controllers[controller]).forEach(
|
|
|
|
action => {
|
|
|
|
const bodyAction =
|
|
|
|
body.permissions[type].controllers[controller][action];
|
|
|
|
const currentAction = _.get(
|
|
|
|
role.permissions,
|
|
|
|
`${type}.controllers.${controller}.${action}`,
|
2019-06-08 16:23:52 +02:00
|
|
|
{}
|
2019-04-09 12:09:03 +02:00
|
|
|
);
|
|
|
|
|
2019-07-17 14:28:36 +02:00
|
|
|
if (!_.isEqual(bodyAction, currentAction)) {
|
2019-04-09 12:09:03 +02:00
|
|
|
acc.push(
|
2019-07-15 23:16:50 +02:00
|
|
|
strapi.query('permission', 'users-permissions').update(
|
|
|
|
{
|
|
|
|
role: roleID,
|
|
|
|
type,
|
|
|
|
controller,
|
|
|
|
action: action.toLowerCase(),
|
|
|
|
},
|
|
|
|
bodyAction
|
|
|
|
)
|
2019-04-09 12:09:03 +02:00
|
|
|
);
|
|
|
|
}
|
2019-06-08 16:23:52 +02:00
|
|
|
}
|
2019-04-09 12:09:03 +02:00
|
|
|
);
|
2018-01-22 18:19:44 +01:00
|
|
|
});
|
2018-01-17 18:50:12 +01:00
|
|
|
|
2019-04-09 12:09:03 +02:00
|
|
|
return acc;
|
2019-07-16 20:52:31 +02:00
|
|
|
}, [])
|
2019-04-09 12:09:03 +02:00
|
|
|
);
|
2018-03-12 14:04:43 +01:00
|
|
|
|
2018-01-22 18:19:44 +01:00
|
|
|
// Add user to this role.
|
2019-07-16 20:52:31 +02:00
|
|
|
const newUsers = _.differenceBy(body.users, role.users, 'id');
|
|
|
|
await Promise.all(newUsers.map(user => this.updateUserRole(user, roleID)));
|
2017-12-05 16:44:54 +01:00
|
|
|
|
2019-07-16 20:52:31 +02:00
|
|
|
const oldUsers = _.differenceBy(role.users, body.users, 'id');
|
|
|
|
await Promise.all(
|
|
|
|
oldUsers.map(user => this.updateUserRole(user, authenticated.id))
|
2019-04-09 12:09:03 +02:00
|
|
|
);
|
2017-11-27 17:50:51 +01:00
|
|
|
},
|
|
|
|
|
2019-07-15 23:16:50 +02:00
|
|
|
async updateUserRole(user, role) {
|
|
|
|
return strapi
|
|
|
|
.query('user', 'users-permissions')
|
2019-07-16 20:52:31 +02:00
|
|
|
.update({ id: user.id }, { role });
|
2017-12-07 10:16:36 +01:00
|
|
|
},
|
|
|
|
|
2019-07-15 23:16:50 +02:00
|
|
|
template(layout, data) {
|
2018-01-25 08:38:46 +01:00
|
|
|
const compiledObject = _.template(layout);
|
|
|
|
return compiledObject(data);
|
2019-04-09 12:09:03 +02:00
|
|
|
},
|
2017-11-06 11:14:43 +01:00
|
|
|
};
|