[WIP] Read and update roles & permissions using database

This commit is contained in:
Aurelsicoko 2018-01-17 18:50:12 +01:00
parent b04a495bc4
commit 4aa28a196e
14 changed files with 373 additions and 133 deletions

View File

@ -27,10 +27,10 @@ class ListRow extends React.Component { // eslint-disable-line react/prefer-stat
// Roles that can't be deleted && modified // Roles that can't be deleted && modified
// Don't delete this line // Don't delete this line
protectedRoleIDs = ['0']; protectedRoleIDs = ['root'];
// Roles that can't be deleted; // Roles that can't be deleted;
undeletableIDs = ['1']; undeletableIDs = ['guest'];
generateContent = () => { generateContent = () => {
let icons = [ let icons = [
@ -46,11 +46,11 @@ class ListRow extends React.Component { // eslint-disable-line react/prefer-stat
switch (this.props.settingType) { switch (this.props.settingType) {
case 'roles': case 'roles':
if (includes(this.protectedRoleIDs, get(this.props.item, 'id').toString())) { if (includes(this.protectedRoleIDs, get(this.props.item, 'type').toString())) {
icons = []; 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 }]; icons = [{ icoType: 'pencil', onClick: this.handleClick }];
} }
@ -135,7 +135,7 @@ class ListRow extends React.Component { // eslint-disable-line react/prefer-stat
handleClick = () => { handleClick = () => {
switch (this.props.settingType) { switch (this.props.settingType) {
case 'roles': { 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 router.push(`${router.location.pathname}/edit/${this.props.item.id}`);
} }
return; return;

View File

@ -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"]}

View File

@ -17,6 +17,7 @@ module.exports = cb => {
if (!_.get(strapi.plugins['users-permissions'], 'config.jwtSecret')) { if (!_.get(strapi.plugins['users-permissions'], 'config.jwtSecret')) {
try { try {
const jwtSecret = uuid(); const jwtSecret = uuid();
fs.writeFileSync(path.join(strapi.config.appPath, 'plugins', 'users-permissions', 'config', 'jwt.json'), JSON.stringify({ fs.writeFileSync(path.join(strapi.config.appPath, 'plugins', 'users-permissions', 'config', 'jwt.json'), JSON.stringify({
jwtSecret jwtSecret
}, null, 2), 'utf8'); }, null, 2), 'utf8');
@ -28,6 +29,6 @@ module.exports = cb => {
} }
strapi.plugins['users-permissions'].services.userspermissions.syncSchema(() => { strapi.plugins['users-permissions'].services.userspermissions.syncSchema(() => {
strapi.plugins['users-permissions'].services.userspermissions.updatePermissions(cb); strapi.plugins['users-permissions'].services.userspermissions.initialize(cb);
}); });
}; };

View File

@ -1,6 +1,6 @@
module.exports = async (ctx, next) => { module.exports = async (ctx, next) => {
if (!ctx.state.user) { if (!ctx.state.user) {
throw new Error('Authentication required.'); return ctx.unauthorized();
} }
await next(); await next();

View File

@ -1,45 +1,54 @@
const _ = require('lodash'); const _ = require('lodash');
module.exports = async (ctx, next) => { module.exports = async (ctx, next) => {
const route = ctx.request.route; let role;
let role = '1';
if (ctx.request && ctx.request.header && ctx.request.header.authorization) { if (ctx.request && ctx.request.header && ctx.request.header.authorization) {
try { try {
const tokenUser = await strapi.plugins['users-permissions'].services.jwt.getToken(ctx); const token = await strapi.plugins['users-permissions'].services.jwt.getToken(ctx);
ctx.state.user = await strapi.plugins['users-permissions'].services.user.fetch(_.pick(tokenUser, ['_id', 'id']));
ctx.state.user = await strapi.query('user', 'users-permissions').findOne(_.pick(token, ['_id', 'id']), ['role'])
} catch (err) { } catch (err) {
return ctx.unauthorized(err); return ctx.unauthorized(err);
} }
if (!ctx.state.user) { if (!ctx.state.user) {
return ctx.unauthorized('This user doesn\'t exit.'); return ctx.unauthorized(`User Not Found.`);
} }
role = ctx.state.user.role; role = ctx.state.user.role;
if (role.toString() === '0') { if (role.type === 'root') {
return await next(); 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) { if (!permission) {
return await next(); return ctx.unauthorized();
} }
if (permission.enabled && permission.policy) { // Execute the policies.
try { if (permission.policy) {
await strapi.plugins['users-permissions'].config.policies[permission.policy](ctx, next); 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.');
} }
console.log("OKAY");
// Execute the action.
await next();
}; };

View File

@ -1,21 +1,22 @@
const _ = require('lodash'); const _ = require('lodash');
module.exports = { module.exports = {
find: async function (params) { find: async function (params = {}, populate) {
return this return this
.find(params.where) .find(params.where)
.limit(Number(params.limit)) .limit(Number(params.limit))
.sort(params.sort) .sort(params.sort)
.skip(Number(params.skip)) .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 return Number(await this
.count()); .count(params));
}, },
findOne: async function (params) { findOne: async function (params, populate) {
if (!params[this.primaryKey] && params.id) { if (!params[this.primaryKey] && params.id) {
params[this.primaryKey] = params.id; params[this.primaryKey] = params.id;
delete params.id; delete params.id;
@ -25,12 +26,12 @@ module.exports = {
return this return this
.findOne(params) .findOne(params)
.populate(this.associations.map(x => x.alias).join(' ')); .populate(populate || this.associations.map(x => x.alias).join(' '));
}, },
create: async function (params) { create: async function (params) {
return this.create(Object.keys(params).reduce((acc, current) => { 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]; 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);
} }
}; };

View File

@ -159,15 +159,18 @@ module.exports = {
} }
// First, check if the user is the first one to register as admin. // 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 // Check if the user is the first to register
if (adminUsers.length === 0) { const role = hasAdmin < 1 ?
params.role = '0'; await strapi.query('role', 'users-permissions').findOne({ type: 'root' }, []):
} else { await strapi.query('role', 'users-permissions').findOne({ type: 'guest' }, []);
params.role = '1';
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); params.password = await strapi.plugins['users-permissions'].services.user.hashPassword(params);
try { try {

View File

@ -90,10 +90,12 @@ module.exports = {
getRoles: async (ctx) => { getRoles: async (ctx) => {
try { try {
console.log("coucou");
const roles = await strapi.plugins['users-permissions'].services.userspermissions.getRoles(); const roles = await strapi.plugins['users-permissions'].services.userspermissions.getRoles();
ctx.send({ roles }); ctx.send({ roles });
} catch(err) { } catch(err) {
console.log(err);
ctx.badRequest(null, [{ messages: [{ id: 'Not found' }] }]); ctx.badRequest(null, [{ messages: [{ id: 'Not found' }] }]);
} }
}, },
@ -118,7 +120,7 @@ module.exports = {
}, },
init: async (ctx) => { 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 }); ctx.send({ hasAdmin: hasAdmin.length > 0 });
}, },

View 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) => {}
};

View File

@ -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"
}
}
}

View 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) => {}
};

View File

@ -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"
}
}
}

View File

@ -1,5 +1,5 @@
{ {
"collectionName": "", "connection": "default",
"info": { "info": {
"name": "user", "name": "user",
"description": "" "description": ""
@ -34,9 +34,10 @@
"configurable": false "configurable": false
}, },
"role": { "role": {
"type": "integer", "model": "role",
"via": "users",
"plugin": "users-permissions",
"configurable": false "configurable": false
} }
}, }
"connection": "default"
} }

View File

@ -2,7 +2,6 @@
const fs = require('fs') const fs = require('fs')
const path = require('path'); const path = require('path');
const stringify = JSON.stringify;
const _ = require('lodash'); const _ = require('lodash');
const request = require('request'); const request = require('request');
@ -59,7 +58,7 @@ module.exports = {
}); });
}, },
getActions: (plugins = []) => { getActions: (plugins = [], withInfo = true) => {
const generateActions = (data) => ( const generateActions = (data) => (
Object.keys(data).reduce((acc, key) => { Object.keys(data).reduce((acc, key) => {
acc[key] = { enabled: false, policy: '' }; acc[key] = { enabled: false, policy: '' };
@ -74,12 +73,20 @@ module.exports = {
}, { controllers: {} }); }, { controllers: {} });
const pluginsPermissions = Object.keys(strapi.plugins).reduce((acc, key) => { 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) => { acc[key] = Object.keys(strapi.plugins[key].controllers).reduce((obj, k) => {
obj.controllers[k] = generateActions(strapi.plugins[key].controllers[k]); obj.controllers[k] = generateActions(strapi.plugins[key].controllers[k]);
return obj; return obj;
}, { controllers: {}, information: plugins.find(plugin => plugin.id === key) || {} }); }, initialState);
return acc; return acc;
}, {}); }, {});
@ -108,111 +115,107 @@ module.exports = {
}, },
getRoles: async () => { getRoles: async () => {
const roles = strapi.plugins['users-permissions'].config.roles; const roles = await strapi.query('role', 'users-permissions').find({ sort: 'name ASC' }, []);
const usersCount = await strapi.query('user', 'users-permissions').countByRoles();
const formattedRoles = Object.keys(roles).reduce((acc, key) => {
const role = _.pick(roles[key], ['name', 'description']);
_.set(role, 'id', key); for (let i = 0; i < roles.length; ++i) {
_.set(role, 'nb_users', _.get(_.find(usersCount, { _id: parseFloat(key) }), 'total', 0)); role.nb_users = await strapi.query('user', 'users-permissions').count({ role: roles[i].id || roles[i]._id });
acc.push(role); }
return acc; return roles;
}, []);
return formattedRoles;
}, },
getRoutes: async () => { 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); 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; acc[current] = strapi.plugins[current].config.routes;
return acc; return acc;
}, []); }, []);
return _.merge({ application: apiRoutes}, pluginsRoutes); return _.merge({ application: routes }, pluginsRoutes);
}, },
getRoleConfigPath: () => ( updatePermissions: async function (cb) {
path.join( const actions = strapi.plugins['users-permissions'].config.actions || [];
strapi.config.appPath,
'plugins',
'users-permissions',
'config',
'roles.json',
)
),
updateData: (data, diff = 'unset') => { // Aggregate first level actions.
const dataToCompare = strapi.plugins['users-permissions'].services.userspermissions.getActions(); 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) => { acc = acc.concat(actions);
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: '' })
}
});
});
}); });
});
return data; return acc;
}, }, []);
updatePermissions: async (cb) => { // Aggregate plugins' actions.
const appActions = module.exports.getActions(); const pluginsActions = Object.keys(strapi.plugins).reduce((acc, plugin) => {
const writePermissions = module.exports.writePermissions; Object.keys(strapi.plugins[plugin].controllers)
const currentRoles = strapi.plugins['users-permissions'].config.roles || { .map(controller => {
'0': { const actions = Object.keys(strapi.plugins[plugin].controllers[controller])
description: '', .map(action => `${plugin}.${controller}.${action}`);
name: 'Administrator',
permissions: {
application: {
controllers: {},
},
},
},
'1': {
description: '',
name: 'Guest',
permissions: {
application: {
controllers: {},
},
},
},
};
const remove = await module.exports.updateData(_.cloneDeep(currentRoles)); acc = acc.concat(actions);
const added = await module.exports.updateData(_.cloneDeep(remove), 'set'); });
if (!_.isEqual(currentRoles, added)) { return acc;
writePermissions(added); }, []);
// 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) { 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) => { updateRole: async (roleId, body) => {
const appRoles = strapi.plugins['users-permissions'].config.roles const appRoles = strapi.plugins['users-permissions'].config.roles
const updatedRole = _.pick(body, ['name', 'description', 'permissions']); const updatedRole = _.pick(body, ['name', 'description', 'permissions']);
_.set(appRoles, [roleId], updatedRole); _.set(appRoles, [roleId], updatedRole);
// TODO:
// - Call request.
// Role.update()
module.exports.writePermissions(appRoles); module.exports.writePermissions(appRoles);
const currentUsers = await strapi.query('user', 'users-permissions').find(strapi.utils.models.convertParams('user', { const currentUsers = await strapi.query('user', 'users-permissions').find(strapi.utils.models.convertParams('user', {
@ -248,11 +280,13 @@ module.exports = {
}); });
}, },
writePermissions: (data) => { writeActions: (data) => {
const roleConfigPath = module.exports.getRoleConfigPath(); const actionsPath = path.join(strapi.config.appPath, 'plugins', 'users-permissions', 'config', 'actions.json');
try { 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); _.set(strapi.plugins['users-permissions'], 'config.roles', data);
} catch(err) { } catch(err) {
strapi.log.error(err); strapi.log.error(err);