From a06336cdbb485789aadbcb33dac6fa27a9a8e2f0 Mon Sep 17 00:00:00 2001 From: Aurelsicoko Date: Mon, 22 Jan 2018 18:19:44 +0100 Subject: [PATCH] Update permissions from UI in database --- .../config/queries/mongoose.js | 18 +++-- .../controllers/UsersPermissions.js | 16 +++-- .../services/Jwt.js | 11 ++- .../services/UsersPermissions.js | 67 ++++++++++++------- 4 files changed, 78 insertions(+), 34 deletions(-) diff --git a/packages/strapi-plugin-users-permissions/config/queries/mongoose.js b/packages/strapi-plugin-users-permissions/config/queries/mongoose.js index f336274154..1f04e5db06 100644 --- a/packages/strapi-plugin-users-permissions/config/queries/mongoose.js +++ b/packages/strapi-plugin-users-permissions/config/queries/mongoose.js @@ -46,10 +46,20 @@ module.exports = { }); }, - update: async function (params) { - return this.update({ - [this.primaryKey]: params[this.primaryKey] || params.id - }, params, { + update: async function (search, params) { + if (!params) { + search = params; + } + + const primaryKey = params[this.primaryKey] || params.id; + + if (primaryKey) { + search = { + [this.primaryKey]: params[this.primaryKey] || params.id + } + } + + return this.update(search, params, { strict: false }) .catch((error) => { diff --git a/packages/strapi-plugin-users-permissions/controllers/UsersPermissions.js b/packages/strapi-plugin-users-permissions/controllers/UsersPermissions.js index 57e54f0c1c..8ec8473b45 100644 --- a/packages/strapi-plugin-users-permissions/controllers/UsersPermissions.js +++ b/packages/strapi-plugin-users-permissions/controllers/UsersPermissions.js @@ -128,10 +128,15 @@ module.exports = { return ctx.send(data); }, - updateRole: async (ctx) => { - const roleId = ctx.params.role; - // Prevent from updating the Administrator role - if (roleId === '0') { + updateRole: async function (ctx) { + // Fetch root role. + const root = await strapi.query('role', 'users-permissions').findOne({ type: 'root' }); + + const roleID = ctx.params.role; + const rootID = root.id || root._id; + + // Prevent from updating the root role. + if (roleID === rootID) { return ctx.badRequest(null, [{ messages: [{ id: 'Unauthorized' }] }]); } @@ -140,7 +145,8 @@ module.exports = { } try { - await strapi.plugins['users-permissions'].services.userspermissions.updateRole(roleId, ctx.request.body); + await strapi.plugins['users-permissions'].services.userspermissions.updateRole(roleID, ctx.request.body); + ctx.send({ ok: true }); } catch(error) { ctx.badRequest(null, [{ messages: [{ id: 'An error occurred' }] }]); diff --git a/packages/strapi-plugin-users-permissions/services/Jwt.js b/packages/strapi-plugin-users-permissions/services/Jwt.js index 1e7b1955ba..a7f2f5c5cf 100644 --- a/packages/strapi-plugin-users-permissions/services/Jwt.js +++ b/packages/strapi-plugin-users-permissions/services/Jwt.js @@ -51,10 +51,17 @@ module.exports = { token, process.env.JWT_SECRET || _.get(strapi.plugins['users-permissions'], 'config.jwtSecret') || 'oursecret', {}, - function (err, user) { - if (err || !user || !_.get(user, 'id', '').toString()) { + function (err, user = {}) { + if (err) { return reject('Invalid token.'); } + + const { _id, id } = user; + + if ((id || _id) === undefined) { + return reject('Invalid token #2.'); + } + resolve(user); } ); diff --git a/packages/strapi-plugin-users-permissions/services/UsersPermissions.js b/packages/strapi-plugin-users-permissions/services/UsersPermissions.js index 7625a196da..bf1f30f305 100644 --- a/packages/strapi-plugin-users-permissions/services/UsersPermissions.js +++ b/packages/strapi-plugin-users-permissions/services/UsersPermissions.js @@ -107,13 +107,20 @@ module.exports = { throw new Error('Cannot found this role'); } - // Add `information` key. - role.permissions - .filter(permission => permission.type !== 'application') - .map((permission, index) => { - role.permissions[index].information = plugins.find(plugin => plugin.id === permission.type) || {}; + // Group by `type`. + role.permissions = role.permissions.reduce((acc, permission) => { + _.set(acc, `${permission.type}.controllers.${permission.controller}.${permission.action}`, { + enabled: permission.enabled, + policy: permission.policy }); + if (permission.type !== 'application' && !acc[permission.type].information) { + acc[permission.type].information = plugins.find(plugin => plugin.id === permission.type) || {}; + } + + return acc; + }, {}); + return role; }, @@ -252,29 +259,43 @@ module.exports = { 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); + updateRole: async function (roleID, body) { + const [role, guest] = await Promise.all([ + this.getRole(roleID, []), + strapi.query('role', 'users-permissions').findOne({ type: 'guest' }, []) + ]); - // TODO: - // - Call request. - // Role.update() + const arrayOfPromises = Object.keys(body.permissions).reduce((acc, type) => { + 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}`, {}); - module.exports.writePermissions(appRoles); + if (_.differenceWith([bodyAction], [currentAction]).length > 0) { + acc.push(strapi.query('permission', 'users-permissions').update({ + role: roleID, + type, + controller, + action + }, bodyAction)); + } + }); + }); - const currentUsers = await strapi.query('user', 'users-permissions').find(strapi.utils.models.convertParams('user', { - role: roleId - })); - const userToAdd = _.differenceBy(body.users, currentUsers.toJSON ? currentUsers.toJSON() : currentUsers, 'id'); - const userToRemove = _.differenceBy(currentUsers.toJSON ? currentUsers.toJSON() : currentUsers, body.users, 'id'); + return acc; + }, []); - _.forEach(userToAdd, (user) => { - module.exports.updateUserRole(user, roleId); - }); - _.forEach(userToRemove, (user) => { - module.exports.updateUserRole(user, '1'); + // Add user to this role. + _.differenceBy(body.users, role.users, role._id ? '_id' : 'id').forEach(user => { + arrayOfPromises.push(this.updateUserRole(user, roleID)); + }) + + // Remove user to this role and link him to guest. + _.differenceBy(role.users, body.users, role._id ? '_id' : 'id').forEach(user => { + arrayOfPromises.push(this.updateUserRole(user, guest._id || guest.id)); }); + + return Promise.all(arrayOfPromises); }, updateUserRole: async (user, role) => {