mirror of
https://github.com/strapi/strapi.git
synced 2025-12-15 17:22:57 +00:00
[WIP] Read and update roles & permissions using database
This commit is contained in:
parent
b04a495bc4
commit
4aa28a196e
@ -27,10 +27,10 @@ class ListRow extends React.Component { // eslint-disable-line react/prefer-stat
|
||||
|
||||
// Roles that can't be deleted && modified
|
||||
// Don't delete this line
|
||||
protectedRoleIDs = ['0'];
|
||||
protectedRoleIDs = ['root'];
|
||||
|
||||
// Roles that can't be deleted;
|
||||
undeletableIDs = ['1'];
|
||||
undeletableIDs = ['guest'];
|
||||
|
||||
generateContent = () => {
|
||||
let icons = [
|
||||
@ -46,11 +46,11 @@ class ListRow extends React.Component { // eslint-disable-line react/prefer-stat
|
||||
|
||||
switch (this.props.settingType) {
|
||||
case 'roles':
|
||||
if (includes(this.protectedRoleIDs, get(this.props.item, 'id').toString())) {
|
||||
if (includes(this.protectedRoleIDs, get(this.props.item, 'type').toString())) {
|
||||
icons = [];
|
||||
}
|
||||
|
||||
if (includes(this.undeletableIDs, get(this.props.item, 'id').toString())) {
|
||||
if (includes(this.undeletableIDs, get(this.props.item, 'type').toString())) {
|
||||
icons = [{ icoType: 'pencil', onClick: this.handleClick }];
|
||||
}
|
||||
|
||||
@ -135,7 +135,7 @@ class ListRow extends React.Component { // eslint-disable-line react/prefer-stat
|
||||
handleClick = () => {
|
||||
switch (this.props.settingType) {
|
||||
case 'roles': {
|
||||
if (!includes(this.protectedRoleIDs, get(this.props.item, 'id').toString())) {
|
||||
if (!includes(this.protectedRoleIDs, get(this.props.item, 'type').toString())) {
|
||||
return router.push(`${router.location.pathname}/edit/${this.props.item.id}`);
|
||||
}
|
||||
return;
|
||||
|
||||
@ -0,0 +1 @@
|
||||
{"actions":["content-manager.contentmanager.models","content-manager.contentmanager.find","content-manager.contentmanager.count","content-manager.contentmanager.findOne","content-manager.contentmanager.create","content-manager.contentmanager.update","content-manager.contentmanager.delete","content-manager.contentmanager.identity","content-type-builder.contenttypebuilder.getModels","content-type-builder.contenttypebuilder.getModel","content-type-builder.contenttypebuilder.getConnections","content-type-builder.contenttypebuilder.createModel","content-type-builder.contenttypebuilder.updateModel","content-type-builder.contenttypebuilder.deleteModel","content-type-builder.contenttypebuilder.autoReload","content-type-builder.contenttypebuilder.checkTableExists","content-type-builder.contenttypebuilder.identity","settings-manager.settingsmanager.menu","settings-manager.settingsmanager.environments","settings-manager.settingsmanager.languages","settings-manager.settingsmanager.databases","settings-manager.settingsmanager.database","settings-manager.settingsmanager.databaseModel","settings-manager.settingsmanager.get","settings-manager.settingsmanager.update","settings-manager.settingsmanager.createLanguage","settings-manager.settingsmanager.deleteLanguage","settings-manager.settingsmanager.createDatabase","settings-manager.settingsmanager.updateDatabase","settings-manager.settingsmanager.deleteDatabase","settings-manager.settingsmanager.autoReload","settings-manager.settingsmanager.identity","users-permissions.auth.callback","users-permissions.auth.changePassword","users-permissions.auth.forgotPassword","users-permissions.auth.register","users-permissions.auth.identity","users-permissions.user.find","users-permissions.user.me","users-permissions.user.findOne","users-permissions.user.create","users-permissions.user.update","users-permissions.user.destroy","users-permissions.user.identity","users-permissions.userspermissions.createRole","users-permissions.userspermissions.deleteProvider","users-permissions.userspermissions.deleteRole","users-permissions.userspermissions.getPermissions","users-permissions.userspermissions.getPolicies","users-permissions.userspermissions.getRole","users-permissions.userspermissions.getRoles","users-permissions.userspermissions.getRoutes","users-permissions.userspermissions.index","users-permissions.userspermissions.init","users-permissions.userspermissions.searchUsers","users-permissions.userspermissions.updateRole","users-permissions.userspermissions.identity"]}
|
||||
@ -17,6 +17,7 @@ module.exports = cb => {
|
||||
if (!_.get(strapi.plugins['users-permissions'], 'config.jwtSecret')) {
|
||||
try {
|
||||
const jwtSecret = uuid();
|
||||
|
||||
fs.writeFileSync(path.join(strapi.config.appPath, 'plugins', 'users-permissions', 'config', 'jwt.json'), JSON.stringify({
|
||||
jwtSecret
|
||||
}, null, 2), 'utf8');
|
||||
@ -28,6 +29,6 @@ module.exports = cb => {
|
||||
}
|
||||
|
||||
strapi.plugins['users-permissions'].services.userspermissions.syncSchema(() => {
|
||||
strapi.plugins['users-permissions'].services.userspermissions.updatePermissions(cb);
|
||||
strapi.plugins['users-permissions'].services.userspermissions.initialize(cb);
|
||||
});
|
||||
};
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
module.exports = async (ctx, next) => {
|
||||
if (!ctx.state.user) {
|
||||
throw new Error('Authentication required.');
|
||||
return ctx.unauthorized();
|
||||
}
|
||||
|
||||
await next();
|
||||
|
||||
@ -1,45 +1,54 @@
|
||||
const _ = require('lodash');
|
||||
|
||||
module.exports = async (ctx, next) => {
|
||||
const route = ctx.request.route;
|
||||
let role = '1';
|
||||
let role;
|
||||
|
||||
if (ctx.request && ctx.request.header && ctx.request.header.authorization) {
|
||||
try {
|
||||
const tokenUser = await strapi.plugins['users-permissions'].services.jwt.getToken(ctx);
|
||||
|
||||
ctx.state.user = await strapi.plugins['users-permissions'].services.user.fetch(_.pick(tokenUser, ['_id', 'id']));
|
||||
const token = await strapi.plugins['users-permissions'].services.jwt.getToken(ctx);
|
||||
|
||||
ctx.state.user = await strapi.query('user', 'users-permissions').findOne(_.pick(token, ['_id', 'id']), ['role'])
|
||||
} catch (err) {
|
||||
return ctx.unauthorized(err);
|
||||
}
|
||||
|
||||
if (!ctx.state.user) {
|
||||
return ctx.unauthorized('This user doesn\'t exit.');
|
||||
return ctx.unauthorized(`User Not Found.`);
|
||||
}
|
||||
|
||||
role = ctx.state.user.role;
|
||||
|
||||
if (role.toString() === '0') {
|
||||
if (role.type === 'root') {
|
||||
return await next();
|
||||
}
|
||||
}
|
||||
|
||||
const permission = _.get(strapi.plugins['users-permissions'].config, ['roles', role.toString(), 'permissions', route.plugin || 'application', 'controllers', route.controller, route.action]);
|
||||
// Retrieve `guest` role.
|
||||
if (!role) {
|
||||
role = await strapi.query('role', 'users-permissions').findOne({ type: 'guest' }, []);
|
||||
}
|
||||
|
||||
const route = ctx.request.route;
|
||||
|
||||
const permission = await strapi.query('permission', 'users-permissions').findOne({
|
||||
role: role._id || role.id,
|
||||
type: route.plugin || 'application',
|
||||
controller: route.controller,
|
||||
action: route.action,
|
||||
enabled: true
|
||||
}, []);
|
||||
|
||||
if (!permission) {
|
||||
return await next();
|
||||
return ctx.unauthorized();
|
||||
}
|
||||
|
||||
if (permission.enabled && permission.policy) {
|
||||
try {
|
||||
await strapi.plugins['users-permissions'].config.policies[permission.policy](ctx, next);
|
||||
} catch (err) {
|
||||
ctx.unauthorized(err);
|
||||
}
|
||||
} else if (permission.enabled) {
|
||||
await next();
|
||||
} else {
|
||||
ctx.unauthorized('Access restricted for this action.');
|
||||
// Execute the policies.
|
||||
if (permission.policy) {
|
||||
await strapi.plugins['users-permissions'].config.policies[permission.policy](ctx, next);
|
||||
}
|
||||
|
||||
console.log("OKAY");
|
||||
|
||||
// Execute the action.
|
||||
await next();
|
||||
};
|
||||
|
||||
@ -1,21 +1,22 @@
|
||||
const _ = require('lodash');
|
||||
|
||||
module.exports = {
|
||||
find: async function (params) {
|
||||
find: async function (params = {}, populate) {
|
||||
return this
|
||||
.find(params.where)
|
||||
.limit(Number(params.limit))
|
||||
.sort(params.sort)
|
||||
.skip(Number(params.skip))
|
||||
.populate(this.associations.map(x => x.alias).join(' '));
|
||||
.populate(populate || this.associations.map(x => x.alias).join(' '))
|
||||
.lean();
|
||||
},
|
||||
|
||||
count: async function (params) {
|
||||
count: async function (params = {}) {
|
||||
return Number(await this
|
||||
.count());
|
||||
.count(params));
|
||||
},
|
||||
|
||||
findOne: async function (params) {
|
||||
findOne: async function (params, populate) {
|
||||
if (!params[this.primaryKey] && params.id) {
|
||||
params[this.primaryKey] = params.id;
|
||||
delete params.id;
|
||||
@ -25,12 +26,12 @@ module.exports = {
|
||||
|
||||
return this
|
||||
.findOne(params)
|
||||
.populate(this.associations.map(x => x.alias).join(' '));
|
||||
.populate(populate || this.associations.map(x => x.alias).join(' '));
|
||||
},
|
||||
|
||||
create: async function (params) {
|
||||
return this.create(Object.keys(params).reduce((acc, current) => {
|
||||
if (_.get(this._attributes, [current, 'type'])) {
|
||||
if (_.get(this._attributes, [current, 'type']) || _.get(this._attributes, [current, 'model'])) {
|
||||
acc[current] = params[current];
|
||||
}
|
||||
|
||||
@ -87,5 +88,20 @@ module.exports = {
|
||||
}
|
||||
}
|
||||
]);
|
||||
},
|
||||
|
||||
createRole: async function (params) {
|
||||
return this.
|
||||
create(params);
|
||||
},
|
||||
|
||||
addPermission: async function (params) {
|
||||
return this
|
||||
.create(params);
|
||||
},
|
||||
|
||||
removePermission: async function (params) {
|
||||
return this
|
||||
.remove(params);
|
||||
}
|
||||
};
|
||||
|
||||
@ -159,15 +159,18 @@ module.exports = {
|
||||
}
|
||||
|
||||
// First, check if the user is the first one to register as admin.
|
||||
const adminUsers = await strapi.query('user', 'users-permissions').find(strapi.utils.models.convertParams('user', { role: '0' }));
|
||||
const hasAdmin = await strapi.query('user', 'users-permissions').count(strapi.utils.models.convertParams('user', { type: 'root' }));
|
||||
|
||||
// Check if the user is the first to register
|
||||
if (adminUsers.length === 0) {
|
||||
params.role = '0';
|
||||
} else {
|
||||
params.role = '1';
|
||||
const role = hasAdmin < 1 ?
|
||||
await strapi.query('role', 'users-permissions').findOne({ type: 'root' }, []):
|
||||
await strapi.query('role', 'users-permissions').findOne({ type: 'guest' }, []);
|
||||
|
||||
if (!role) {
|
||||
return ctx.badRequest(null, ctx.request.admin ? [{ messages: [{ id: 'Auth.form.error.role.notFound' }] }] : 'Impossible to find the root role.');
|
||||
}
|
||||
|
||||
params.role = role._id || role.id;
|
||||
params.password = await strapi.plugins['users-permissions'].services.user.hashPassword(params);
|
||||
|
||||
try {
|
||||
|
||||
@ -90,10 +90,12 @@ module.exports = {
|
||||
|
||||
getRoles: async (ctx) => {
|
||||
try {
|
||||
console.log("coucou");
|
||||
const roles = await strapi.plugins['users-permissions'].services.userspermissions.getRoles();
|
||||
|
||||
ctx.send({ roles });
|
||||
} catch(err) {
|
||||
console.log(err);
|
||||
ctx.badRequest(null, [{ messages: [{ id: 'Not found' }] }]);
|
||||
}
|
||||
},
|
||||
@ -118,7 +120,7 @@ module.exports = {
|
||||
},
|
||||
|
||||
init: async (ctx) => {
|
||||
const hasAdmin = await strapi.query('user', 'users-permissions').find(strapi.utils.models.convertParams('user', { role: '0' }));
|
||||
const hasAdmin = await strapi.query('user', 'users-permissions').find(strapi.utils.models.convertParams('user', { type: 'guest' }));
|
||||
|
||||
ctx.send({ hasAdmin: hasAdmin.length > 0 });
|
||||
},
|
||||
|
||||
@ -0,0 +1,54 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Lifecycle callbacks for the `User` model.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
// Before saving a value.
|
||||
// Fired before an `insert` or `update` query.
|
||||
// beforeSave: async (model) => {},
|
||||
|
||||
// After saving a value.
|
||||
// Fired after an `insert` or `update` query.
|
||||
// afterSave: async (model, result) => {},
|
||||
|
||||
// Before fetching all values.
|
||||
// Fired before a `fetchAll` operation.
|
||||
// beforeFetchAll: async (model) => {},
|
||||
|
||||
// After fetching all values.
|
||||
// Fired after a `fetchAll` operation.
|
||||
// afterFetchAll: async (model, results) => {},
|
||||
|
||||
// Fired before a `fetch` operation.
|
||||
// beforeFetch: async (model) => {},
|
||||
|
||||
// After fetching a value.
|
||||
// Fired after a `fetch` operation.
|
||||
// afterFetch: async (model, result) => {},
|
||||
|
||||
// Before creating a value.
|
||||
// Fired before `insert` query.
|
||||
// beforeCreate: async (model) => {},
|
||||
|
||||
// After creating a value.
|
||||
// Fired after `insert` query.
|
||||
// afterCreate: async (model, result) => {},
|
||||
|
||||
// Before updating a value.
|
||||
// Fired before an `update` query.
|
||||
// beforeUpdate: async (model) => {},
|
||||
|
||||
// After updating a value.
|
||||
// Fired after an `update` query.
|
||||
// afterUpdate: async (model, result) => {},
|
||||
|
||||
// Before destroying a value.
|
||||
// Fired before a `delete` query.
|
||||
// beforeDestroy: async (model) => {},
|
||||
|
||||
// After destroying a value.
|
||||
// Fired after a `delete` query.
|
||||
// afterDestroy: async (model, result) => {}
|
||||
};
|
||||
@ -0,0 +1,34 @@
|
||||
{
|
||||
"connection": "default",
|
||||
"info": {
|
||||
"name": "permission",
|
||||
"description": ""
|
||||
},
|
||||
"attributes": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"required": true
|
||||
},
|
||||
"controller": {
|
||||
"type": "string",
|
||||
"required": true
|
||||
},
|
||||
"action": {
|
||||
"type": "string",
|
||||
"required": true
|
||||
},
|
||||
"enabled": {
|
||||
"type": "boolean",
|
||||
"required": true
|
||||
},
|
||||
"policy": {
|
||||
"type": "json",
|
||||
"required": true
|
||||
},
|
||||
"role": {
|
||||
"model": "role",
|
||||
"via": "permissions",
|
||||
"plugin": "users-permissions"
|
||||
}
|
||||
}
|
||||
}
|
||||
54
packages/strapi-plugin-users-permissions/models/Role.js
Normal file
54
packages/strapi-plugin-users-permissions/models/Role.js
Normal file
@ -0,0 +1,54 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Lifecycle callbacks for the `User` model.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
// Before saving a value.
|
||||
// Fired before an `insert` or `update` query.
|
||||
// beforeSave: async (model) => {},
|
||||
|
||||
// After saving a value.
|
||||
// Fired after an `insert` or `update` query.
|
||||
// afterSave: async (model, result) => {},
|
||||
|
||||
// Before fetching all values.
|
||||
// Fired before a `fetchAll` operation.
|
||||
// beforeFetchAll: async (model) => {},
|
||||
|
||||
// After fetching all values.
|
||||
// Fired after a `fetchAll` operation.
|
||||
// afterFetchAll: async (model, results) => {},
|
||||
|
||||
// Fired before a `fetch` operation.
|
||||
// beforeFetch: async (model) => {},
|
||||
|
||||
// After fetching a value.
|
||||
// Fired after a `fetch` operation.
|
||||
// afterFetch: async (model, result) => {},
|
||||
|
||||
// Before creating a value.
|
||||
// Fired before `insert` query.
|
||||
// beforeCreate: async (model) => {},
|
||||
|
||||
// After creating a value.
|
||||
// Fired after `insert` query.
|
||||
// afterCreate: async (model, result) => {},
|
||||
|
||||
// Before updating a value.
|
||||
// Fired before an `update` query.
|
||||
// beforeUpdate: async (model) => {},
|
||||
|
||||
// After updating a value.
|
||||
// Fired after an `update` query.
|
||||
// afterUpdate: async (model, result) => {},
|
||||
|
||||
// Before destroying a value.
|
||||
// Fired before a `delete` query.
|
||||
// beforeDestroy: async (model) => {},
|
||||
|
||||
// After destroying a value.
|
||||
// Fired after a `delete` query.
|
||||
// afterDestroy: async (model, result) => {}
|
||||
};
|
||||
@ -0,0 +1,31 @@
|
||||
{
|
||||
"connection": "default",
|
||||
"info": {
|
||||
"name": "role",
|
||||
"description": ""
|
||||
},
|
||||
"attributes": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"minLength": 3,
|
||||
"required": true
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"unique": true
|
||||
},
|
||||
"users": {
|
||||
"collection": "user",
|
||||
"via": "role",
|
||||
"plugin": "users-permissions"
|
||||
},
|
||||
"permissions": {
|
||||
"collection": "permission",
|
||||
"via": "role",
|
||||
"plugin": "users-permissions"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
{
|
||||
"collectionName": "",
|
||||
"connection": "default",
|
||||
"info": {
|
||||
"name": "user",
|
||||
"description": ""
|
||||
@ -34,9 +34,10 @@
|
||||
"configurable": false
|
||||
},
|
||||
"role": {
|
||||
"type": "integer",
|
||||
"model": "role",
|
||||
"via": "users",
|
||||
"plugin": "users-permissions",
|
||||
"configurable": false
|
||||
}
|
||||
},
|
||||
"connection": "default"
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
|
||||
const fs = require('fs')
|
||||
const path = require('path');
|
||||
const stringify = JSON.stringify;
|
||||
const _ = require('lodash');
|
||||
const request = require('request');
|
||||
|
||||
@ -59,7 +58,7 @@ module.exports = {
|
||||
});
|
||||
},
|
||||
|
||||
getActions: (plugins = []) => {
|
||||
getActions: (plugins = [], withInfo = true) => {
|
||||
const generateActions = (data) => (
|
||||
Object.keys(data).reduce((acc, key) => {
|
||||
acc[key] = { enabled: false, policy: '' };
|
||||
@ -74,12 +73,20 @@ module.exports = {
|
||||
}, { controllers: {} });
|
||||
|
||||
const pluginsPermissions = Object.keys(strapi.plugins).reduce((acc, key) => {
|
||||
const initialState = {
|
||||
controllers: {}
|
||||
};
|
||||
|
||||
if (withInfo) {
|
||||
initialState.information = plugins.find(plugin => plugin.id === key) || {};
|
||||
}
|
||||
|
||||
acc[key] = Object.keys(strapi.plugins[key].controllers).reduce((obj, k) => {
|
||||
obj.controllers[k] = generateActions(strapi.plugins[key].controllers[k]);
|
||||
|
||||
return obj;
|
||||
|
||||
}, { controllers: {}, information: plugins.find(plugin => plugin.id === key) || {} });
|
||||
}, initialState);
|
||||
|
||||
return acc;
|
||||
}, {});
|
||||
@ -108,111 +115,107 @@ module.exports = {
|
||||
},
|
||||
|
||||
getRoles: async () => {
|
||||
const roles = strapi.plugins['users-permissions'].config.roles;
|
||||
const usersCount = await strapi.query('user', 'users-permissions').countByRoles();
|
||||
const formattedRoles = Object.keys(roles).reduce((acc, key) => {
|
||||
const role = _.pick(roles[key], ['name', 'description']);
|
||||
const roles = await strapi.query('role', 'users-permissions').find({ sort: 'name ASC' }, []);
|
||||
|
||||
_.set(role, 'id', key);
|
||||
_.set(role, 'nb_users', _.get(_.find(usersCount, { _id: parseFloat(key) }), 'total', 0));
|
||||
acc.push(role);
|
||||
for (let i = 0; i < roles.length; ++i) {
|
||||
role.nb_users = await strapi.query('user', 'users-permissions').count({ role: roles[i].id || roles[i]._id });
|
||||
}
|
||||
|
||||
return acc;
|
||||
}, []);
|
||||
|
||||
return formattedRoles;
|
||||
return roles;
|
||||
},
|
||||
|
||||
getRoutes: async () => {
|
||||
const apiRoutes = strapi.api ? Object.keys(strapi.api).reduce((acc, current) => {
|
||||
const routes = Object.keys(strapi.api || {}).reduce((acc, current) => {
|
||||
return acc.concat(strapi.api[current].config.routes);
|
||||
}, []) : [];
|
||||
}, []);
|
||||
|
||||
const pluginsRoutes = Object.keys(strapi.plugins).reduce((acc, current) => {
|
||||
const pluginsRoutes = Object.keys(strapi.plugins || {}).reduce((acc, current) => {
|
||||
acc[current] = strapi.plugins[current].config.routes;
|
||||
|
||||
return acc;
|
||||
}, []);
|
||||
|
||||
return _.merge({ application: apiRoutes}, pluginsRoutes);
|
||||
return _.merge({ application: routes }, pluginsRoutes);
|
||||
},
|
||||
|
||||
getRoleConfigPath: () => (
|
||||
path.join(
|
||||
strapi.config.appPath,
|
||||
'plugins',
|
||||
'users-permissions',
|
||||
'config',
|
||||
'roles.json',
|
||||
)
|
||||
),
|
||||
updatePermissions: async function (cb) {
|
||||
const actions = strapi.plugins['users-permissions'].config.actions || [];
|
||||
|
||||
updateData: (data, diff = 'unset') => {
|
||||
const dataToCompare = strapi.plugins['users-permissions'].services.userspermissions.getActions();
|
||||
// Aggregate first level actions.
|
||||
const appActions = Object.keys(strapi.api || {}).reduce((acc, api) => {
|
||||
Object.keys(strapi.api[api].controllers)
|
||||
.map(controller => {
|
||||
const actions = Object.keys(strapi.api[api].controllers[controller])
|
||||
.map(action => `application.${controller}.${action}`);
|
||||
|
||||
_.forEach(data, (roleData, roleId) => {
|
||||
const obj = diff === 'unset' ? roleData.permissions : dataToCompare;
|
||||
|
||||
_.forEach(obj, (pluginData, pluginName) => {
|
||||
_.forEach(pluginData.controllers, (controllerActions, controllerName) => {
|
||||
_.forEach(controllerActions, (actionData, actionName) => {
|
||||
if (diff === 'unset') {
|
||||
if (!_.get(dataToCompare, [pluginName, 'controllers', controllerName])) {
|
||||
_.unset(data, [roleId, 'permissions', pluginName, 'controllers', controllerName]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_.get(dataToCompare, [pluginName, 'controllers', controllerName, actionName])) {
|
||||
_.unset(data, [roleId, 'permissions', pluginName, 'controllers', controllerName, actionName]);
|
||||
}
|
||||
} else if (!_.get(data, [roleId, 'permissions', pluginName, 'controllers', controllerName, actionName])) {
|
||||
const isCallback = actionName === 'callback' && controllerName === 'auth' && pluginName === 'users-permissions' && roleId === '1';
|
||||
const isRegister = actionName === 'register' && controllerName === 'auth' && pluginName === 'users-permissions' && roleId === '1';
|
||||
const isPassword = actionName === 'forgotPassword' && controllerName === 'auth' && pluginName === 'users-permissions' && roleId === '1';
|
||||
const isNewPassword = actionName === 'changePassword' && controllerName === 'auth' && pluginName === 'users-permissions' && roleId === '1';
|
||||
const isInit = actionName === 'init' && controllerName === 'userspermissions';
|
||||
const isMe = actionName === 'me' && controllerName === 'user' && pluginName === 'users-permissions';
|
||||
const enabled = isCallback || isRegister || roleId === '0' || isInit || isPassword || isNewPassword || isMe;
|
||||
|
||||
_.set(data, [roleId, 'permissions', pluginName, 'controllers', controllerName, actionName], { enabled, policy: '' })
|
||||
}
|
||||
});
|
||||
});
|
||||
acc = acc.concat(actions);
|
||||
});
|
||||
});
|
||||
|
||||
return data;
|
||||
},
|
||||
return acc;
|
||||
}, []);
|
||||
|
||||
updatePermissions: async (cb) => {
|
||||
const appActions = module.exports.getActions();
|
||||
const writePermissions = module.exports.writePermissions;
|
||||
const currentRoles = strapi.plugins['users-permissions'].config.roles || {
|
||||
'0': {
|
||||
description: '',
|
||||
name: 'Administrator',
|
||||
permissions: {
|
||||
application: {
|
||||
controllers: {},
|
||||
},
|
||||
},
|
||||
},
|
||||
'1': {
|
||||
description: '',
|
||||
name: 'Guest',
|
||||
permissions: {
|
||||
application: {
|
||||
controllers: {},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
// Aggregate plugins' actions.
|
||||
const pluginsActions = Object.keys(strapi.plugins).reduce((acc, plugin) => {
|
||||
Object.keys(strapi.plugins[plugin].controllers)
|
||||
.map(controller => {
|
||||
const actions = Object.keys(strapi.plugins[plugin].controllers[controller])
|
||||
.map(action => `${plugin}.${controller}.${action}`);
|
||||
|
||||
const remove = await module.exports.updateData(_.cloneDeep(currentRoles));
|
||||
const added = await module.exports.updateData(_.cloneDeep(remove), 'set');
|
||||
acc = acc.concat(actions);
|
||||
});
|
||||
|
||||
if (!_.isEqual(currentRoles, added)) {
|
||||
writePermissions(added);
|
||||
return acc;
|
||||
}, []);
|
||||
|
||||
// Merge array into one.
|
||||
const currentActions = appActions.concat(pluginsActions);
|
||||
// Count permissions available.
|
||||
const permissions = await strapi.query('permission', 'users-permissions').count();
|
||||
|
||||
// Compare to know if actions have been added or removed from controllers.
|
||||
if (!_.isEqual(actions, currentActions) || permissions < 1) {
|
||||
const splitted = (str) => {
|
||||
const [type, controller, action] = str.split('.');
|
||||
|
||||
return { type, controller, action };
|
||||
};
|
||||
|
||||
const defaultPolicy = (obj, role) => {
|
||||
const isCallback = obj.action === 'callback' && obj.controller === 'auth' && obj.type === 'users-permissions' && role.type === 'guest';
|
||||
const isRegister = obj.action === 'register' && obj.controller === 'auth' && obj.type === 'users-permissions' && role.type === 'guest';
|
||||
const isPassword = obj.action === 'forgotPassword' && obj.controller === 'auth' && obj.type === 'users-permissions' && role.type === 'guest';
|
||||
const isNewPassword = obj.action === 'changePassword' && obj.controller === 'auth' && obj.type === 'users-permissions' && role.type === 'guest';
|
||||
const isInit = obj.action === 'init' && obj.controller === 'userspermissions';
|
||||
const isMe = obj.action === 'me' && obj.controller === 'user' && obj.type === 'users-permissions';
|
||||
const enabled = isCallback || isRegister || role.type === 'root' || isInit || isPassword || isNewPassword || isMe;
|
||||
|
||||
return Object.assign(obj, { enabled, policy: '' });
|
||||
};
|
||||
|
||||
// Retrieve roles
|
||||
const roles = await strapi.query('role', 'users-permissions').find();
|
||||
|
||||
// We have to know the difference to add or remove
|
||||
// the permissions entries in the database.
|
||||
const toRemove = _.difference(actions, currentActions).map(splitted);
|
||||
const toAdd = (permissions < 1 ? currentActions : _.difference(currentActions, actions))
|
||||
.map(splitted);
|
||||
|
||||
// Execute request to update entries in database for each role.
|
||||
await Promise.all(
|
||||
roles.map(role =>
|
||||
Promise.all(
|
||||
toAdd
|
||||
.map(action => defaultPolicy(action, role))
|
||||
.map(action => strapi.query('permission', 'users-permissions')
|
||||
.addPermission(Object.assign(action, { role: role.id || role._id }))
|
||||
)
|
||||
)
|
||||
),
|
||||
Promise.all(toRemove.map(action => strapi.query('permission', 'users-permissions').removePermission(action)))
|
||||
);
|
||||
|
||||
this.writeActions(currentActions);
|
||||
}
|
||||
|
||||
if (cb) {
|
||||
@ -220,11 +223,40 @@ module.exports = {
|
||||
}
|
||||
},
|
||||
|
||||
initialize: async function (cb) {
|
||||
const roles = await strapi.query('role', 'users-permissions').count();
|
||||
|
||||
// It's has been already initialized.
|
||||
if (roles > 0) {
|
||||
return await this.updatePermissions(cb);
|
||||
}
|
||||
|
||||
// Create two first default roles.
|
||||
await Promise.all([
|
||||
strapi.query('role', 'users-permissions').createRole({
|
||||
name: 'Administrator',
|
||||
description: 'These users have all access in the project.',
|
||||
type: 'root'
|
||||
}),
|
||||
strapi.query('role', 'users-permissions').createRole({
|
||||
name: 'Guest',
|
||||
description: 'Default role given to unauthenticated user.',
|
||||
type: 'guest'
|
||||
}),
|
||||
]);
|
||||
|
||||
await this.updatePermissions(cb);
|
||||
},
|
||||
|
||||
updateRole: async (roleId, body) => {
|
||||
const appRoles = strapi.plugins['users-permissions'].config.roles
|
||||
const updatedRole = _.pick(body, ['name', 'description', 'permissions']);
|
||||
_.set(appRoles, [roleId], updatedRole);
|
||||
|
||||
// TODO:
|
||||
// - Call request.
|
||||
// Role.update()
|
||||
|
||||
module.exports.writePermissions(appRoles);
|
||||
|
||||
const currentUsers = await strapi.query('user', 'users-permissions').find(strapi.utils.models.convertParams('user', {
|
||||
@ -248,11 +280,13 @@ module.exports = {
|
||||
});
|
||||
},
|
||||
|
||||
writePermissions: (data) => {
|
||||
const roleConfigPath = module.exports.getRoleConfigPath();
|
||||
writeActions: (data) => {
|
||||
const actionsPath = path.join(strapi.config.appPath, 'plugins', 'users-permissions', 'config', 'actions.json');
|
||||
|
||||
try {
|
||||
fs.writeFileSync(roleConfigPath, stringify({ roles: data }, null, 2), 'utf8');
|
||||
// Rewrite actions.json file.
|
||||
fs.writeFileSync(actionsPath, JSON.stringify({ actions: data }), 'utf8');
|
||||
// Set value to AST to avoid restart.
|
||||
_.set(strapi.plugins['users-permissions'], 'config.roles', data);
|
||||
} catch(err) {
|
||||
strapi.log.error(err);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user