2017-11-06 11:14:43 +01:00
|
|
|
|
'use strict';
|
|
|
|
|
|
2017-11-17 14:22:59 +01:00
|
|
|
|
const fs = require('fs')
|
|
|
|
|
const path = require('path');
|
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 = {
|
2018-01-23 15:38:43 +01:00
|
|
|
|
createRole: async (params) => {
|
|
|
|
|
if (!strapi.plugins['content-manager']) {
|
|
|
|
|
return new Error('This feature requires to install the Content Manager plugin');
|
|
|
|
|
}
|
2017-11-27 16:49:56 +01:00
|
|
|
|
|
2018-02-06 14:43:26 +01:00
|
|
|
|
if (!params.type) {
|
|
|
|
|
params.type = _.snakeCase(_.deburr(_.toLower(params.name)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const role = await strapi.query('role', 'users-permissions').create(_.omit(params, ['users', 'permissions']));
|
2018-01-23 15:38:43 +01:00
|
|
|
|
|
|
|
|
|
const arrayOfPromises = Object.keys(params.permissions).reduce((acc, type) => {
|
|
|
|
|
Object.keys(params.permissions[type].controllers).forEach(controller => {
|
|
|
|
|
Object.keys(params.permissions[type].controllers[controller]).forEach(action => {
|
|
|
|
|
acc.push(strapi.query('permission', 'users-permissions').addPermission({
|
|
|
|
|
role: role._id || role.id,
|
|
|
|
|
type,
|
|
|
|
|
controller,
|
2018-01-25 17:08:39 +01:00
|
|
|
|
action: action.toLowerCase(),
|
2018-01-23 15:38:43 +01:00
|
|
|
|
...params.permissions[type].controllers[controller][action]
|
|
|
|
|
}));
|
|
|
|
|
});
|
|
|
|
|
});
|
2017-11-27 16:49:56 +01:00
|
|
|
|
|
2018-01-23 15:38:43 +01:00
|
|
|
|
return acc;
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
// Use Content Manager business logic to handle relation.
|
|
|
|
|
arrayOfPromises.push(strapi.plugins['content-manager'].services['contentmanager'].edit({
|
|
|
|
|
id: role._id || role.id,
|
|
|
|
|
model: 'role'
|
|
|
|
|
}, {
|
|
|
|
|
users: params.users
|
|
|
|
|
}, 'users-permissions'));
|
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
|
|
|
|
},
|
|
|
|
|
|
2018-03-12 16:37:20 +01:00
|
|
|
|
deleteRole: async (roleID, publicRoleID) => {
|
2018-01-23 15:38:43 +01:00
|
|
|
|
const role = await strapi.query('role', 'users-permissions').findOne({ id: roleID }, ['users', 'permissions']);
|
|
|
|
|
|
|
|
|
|
if (!role) {
|
|
|
|
|
throw new Error('Cannot found this role');
|
|
|
|
|
}
|
|
|
|
|
|
2018-01-23 18:54:17 +01:00
|
|
|
|
if (role.type === 'root') {
|
|
|
|
|
return new Error(`You cannot delete the root admin role.`);
|
|
|
|
|
}
|
|
|
|
|
|
2018-01-23 15:38:43 +01:00
|
|
|
|
// Move users to guest role.
|
|
|
|
|
const arrayOfPromises = role.users.reduce((acc, user) => {
|
|
|
|
|
acc.push(strapi.query('user', 'users-permissions').update({
|
|
|
|
|
id: user._id || user.id
|
|
|
|
|
}, {
|
2018-03-12 16:37:20 +01:00
|
|
|
|
role: publicRoleID
|
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 => {
|
|
|
|
|
arrayOfPromises.push(strapi.query('permission', 'users-permissions').delete({
|
|
|
|
|
id: permission._id || permission.id
|
|
|
|
|
}));
|
|
|
|
|
})
|
2017-12-01 16:06:16 +01:00
|
|
|
|
|
2018-01-23 15:38:43 +01:00
|
|
|
|
// Delete the role.
|
|
|
|
|
arrayOfPromises.push(strapi.query('role', 'users-permissions').delete({
|
|
|
|
|
id: roleID
|
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
|
|
|
|
},
|
|
|
|
|
|
2018-01-05 16:19:53 +01:00
|
|
|
|
getPlugins: (plugin, lang = 'en') => {
|
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
|
request({
|
|
|
|
|
uri: `https://marketplace.strapi.io/plugins?lang=${lang}`,
|
|
|
|
|
json: true,
|
|
|
|
|
headers: {
|
|
|
|
|
'cache-control': 'max-age=3600'
|
|
|
|
|
}
|
|
|
|
|
}, (err, response, body) => {
|
|
|
|
|
if (err) {
|
|
|
|
|
return reject(err);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
resolve(body);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
2018-01-17 18:50:12 +01:00
|
|
|
|
getActions: (plugins = [], withInfo = true) => {
|
2017-11-17 14:22:59 +01:00
|
|
|
|
const generateActions = (data) => (
|
|
|
|
|
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;
|
|
|
|
|
}, {}));
|
|
|
|
|
|
2017-11-17 17:49:50 +01:00
|
|
|
|
const appControllers = Object.keys(strapi.api || {}).reduce((acc, key) => {
|
2017-11-17 14:22:59 +01:00
|
|
|
|
acc.controllers[key] = generateActions(strapi.api[key].controllers[key]);
|
2017-11-16 17:59:41 +01:00
|
|
|
|
|
|
|
|
|
return acc;
|
2017-11-17 12:14:12 +01:00
|
|
|
|
}, { controllers: {} });
|
|
|
|
|
|
|
|
|
|
const pluginsPermissions = Object.keys(strapi.plugins).reduce((acc, key) => {
|
2018-01-17 18:50:12 +01:00
|
|
|
|
const initialState = {
|
|
|
|
|
controllers: {}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (withInfo) {
|
|
|
|
|
initialState.information = plugins.find(plugin => plugin.id === key) || {};
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-20 14:35:24 +01:00
|
|
|
|
acc[key] = Object.keys(strapi.plugins[key].controllers).reduce((obj, k) => {
|
2017-11-17 14:22:59 +01:00
|
|
|
|
obj.controllers[k] = generateActions(strapi.plugins[key].controllers[k]);
|
2017-11-17 12:14:12 +01:00
|
|
|
|
|
|
|
|
|
return obj;
|
|
|
|
|
|
2018-01-17 18:50:12 +01:00
|
|
|
|
}, initialState);
|
2017-11-17 12:14:12 +01:00
|
|
|
|
|
|
|
|
|
return acc;
|
|
|
|
|
}, {});
|
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
|
|
|
|
};
|
|
|
|
|
|
2017-12-11 11:14:07 +01:00
|
|
|
|
return _.merge(permissions, pluginsPermissions);;
|
2017-11-17 16:36:57 +01:00
|
|
|
|
},
|
2017-11-17 14:22:59 +01:00
|
|
|
|
|
2018-01-23 15:38:43 +01:00
|
|
|
|
getRole: async (roleID, plugins) => {
|
|
|
|
|
const role = await strapi.query('role', 'users-permissions').findOne({ id: roleID }, ['users', 'permissions']);
|
2018-01-05 16:19:53 +01:00
|
|
|
|
|
2018-01-19 17:57:10 +01:00
|
|
|
|
if (!role) {
|
|
|
|
|
throw new Error('Cannot found this role');
|
|
|
|
|
}
|
2017-11-27 17:50:51 +01:00
|
|
|
|
|
2018-01-22 18:19:44 +01:00
|
|
|
|
// Group by `type`.
|
|
|
|
|
role.permissions = role.permissions.reduce((acc, permission) => {
|
|
|
|
|
_.set(acc, `${permission.type}.controllers.${permission.controller}.${permission.action}`, {
|
2018-01-23 18:54:17 +01:00
|
|
|
|
enabled: _.toNumber(permission.enabled) == true,
|
2018-01-22 18:19:44 +01:00
|
|
|
|
policy: permission.policy
|
2018-01-05 16:19:53 +01:00
|
|
|
|
});
|
|
|
|
|
|
2018-01-22 18:19:44 +01:00
|
|
|
|
if (permission.type !== 'application' && !acc[permission.type].information) {
|
|
|
|
|
acc[permission.type].information = plugins.find(plugin => plugin.id === permission.type) || {};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return acc;
|
|
|
|
|
}, {});
|
|
|
|
|
|
2018-01-19 17:57:10 +01:00
|
|
|
|
return role;
|
2017-11-27 17:50:51 +01:00
|
|
|
|
},
|
|
|
|
|
|
2017-11-30 12:27:04 +01:00
|
|
|
|
getRoles: async () => {
|
2018-01-17 18:50:12 +01:00
|
|
|
|
const roles = await strapi.query('role', 'users-permissions').find({ sort: 'name ASC' }, []);
|
2017-11-27 16:04:57 +01:00
|
|
|
|
|
2018-01-17 18:50:12 +01:00
|
|
|
|
for (let i = 0; i < roles.length; ++i) {
|
2018-01-19 17:57:10 +01:00
|
|
|
|
roles[i].id = roles[i].id || roles[i]._id;
|
|
|
|
|
roles[i].nb_users = await strapi.query('user', 'users-permissions').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
|
|
|
|
},
|
|
|
|
|
|
2017-11-30 16:34:43 +01:00
|
|
|
|
getRoutes: async () => {
|
2018-01-17 18:50:12 +01:00
|
|
|
|
const routes = Object.keys(strapi.api || {}).reduce((acc, current) => {
|
2017-12-07 18:16:18 +01:00
|
|
|
|
return acc.concat(strapi.api[current].config.routes);
|
2018-01-17 18:50:12 +01:00
|
|
|
|
}, []);
|
2017-12-07 18:16:18 +01:00
|
|
|
|
|
2018-01-17 18:50:12 +01:00
|
|
|
|
const pluginsRoutes = Object.keys(strapi.plugins || {}).reduce((acc, current) => {
|
2017-11-30 16:34:43 +01:00
|
|
|
|
acc[current] = strapi.plugins[current].config.routes;
|
|
|
|
|
|
|
|
|
|
return acc;
|
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
|
|
|
|
},
|
|
|
|
|
|
2018-01-17 18:50:12 +01:00
|
|
|
|
updatePermissions: async function (cb) {
|
|
|
|
|
const actions = strapi.plugins['users-permissions'].config.actions || [];
|
|
|
|
|
|
|
|
|
|
// 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])
|
2018-01-25 15:46:15 +01:00
|
|
|
|
.filter(action => _.isFunction(strapi.api[api].controllers[controller][action]))
|
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);
|
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) => {
|
|
|
|
|
Object.keys(strapi.plugins[plugin].controllers)
|
|
|
|
|
.map(controller => {
|
|
|
|
|
const actions = Object.keys(strapi.plugins[plugin].controllers[controller])
|
2018-01-25 15:46:15 +01:00
|
|
|
|
.filter(action => _.isFunction(strapi.plugins[plugin].controllers[controller][action]))
|
2018-01-25 17:08:39 +01:00
|
|
|
|
.map(action => `${plugin}.${controller}.${action.toLowerCase()}`);
|
2018-01-17 18:50:12 +01: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.
|
|
|
|
|
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) => {
|
2018-03-12 16:37:20 +01:00
|
|
|
|
const isCallback = obj.action === 'callback' && obj.controller === 'auth' && obj.type === 'users-permissions' && role.type === 'public';
|
2018-01-25 14:36:12 +01:00
|
|
|
|
const isConnect = obj.action === 'connect' && obj.controller === 'auth' && obj.type === 'users-permissions';
|
2018-03-12 16:37:20 +01:00
|
|
|
|
const isRegister = obj.action === 'register' && obj.controller === 'auth' && obj.type === 'users-permissions' && role.type === 'public';
|
|
|
|
|
const isPassword = obj.action === 'forgotpassword' && 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';
|
2018-01-17 18:50:12 +01:00
|
|
|
|
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';
|
2018-01-25 14:36:12 +01:00
|
|
|
|
const enabled = isCallback || isRegister || role.type === 'root' || isInit || isPassword || isNewPassword || isMe || isReload || isConnect;
|
2018-01-17 18:50:12 +01:00
|
|
|
|
|
|
|
|
|
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)))
|
|
|
|
|
);
|
|
|
|
|
|
2018-04-23 14:21:24 +02:00
|
|
|
|
return this.writeActions(currentActions, cb);
|
2017-11-17 14:22:59 +01:00
|
|
|
|
}
|
2017-11-20 14:35:24 +01:00
|
|
|
|
|
2018-04-23 14:21:24 +02:00
|
|
|
|
cb();
|
2017-11-17 16:36:57 +01:00
|
|
|
|
},
|
2017-11-17 14:22:59 +01:00
|
|
|
|
|
2018-01-17 18:50:12 +01:00
|
|
|
|
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([
|
2018-01-23 15:38:43 +01:00
|
|
|
|
strapi.query('role', 'users-permissions').create({
|
2018-01-17 18:50:12 +01:00
|
|
|
|
name: 'Administrator',
|
|
|
|
|
description: 'These users have all access in the project.',
|
|
|
|
|
type: 'root'
|
|
|
|
|
}),
|
2018-03-12 14:04:43 +01:00
|
|
|
|
strapi.query('role', 'users-permissions').create({
|
2018-03-14 16:56:12 +01:00
|
|
|
|
name: 'Authenticated',
|
2018-03-12 14:04:43 +01:00
|
|
|
|
description: 'Default role given to authenticated user.',
|
2018-03-14 16:56:12 +01:00
|
|
|
|
type: 'authenticated'
|
2018-03-12 14:04:43 +01:00
|
|
|
|
}),
|
2018-01-23 15:38:43 +01:00
|
|
|
|
strapi.query('role', 'users-permissions').create({
|
2018-03-12 16:37:20 +01:00
|
|
|
|
name: 'Public',
|
2018-01-17 18:50:12 +01:00
|
|
|
|
description: 'Default role given to unauthenticated user.',
|
2018-03-12 16:37:20 +01:00
|
|
|
|
type: 'public'
|
2018-03-12 14:04:43 +01:00
|
|
|
|
})
|
2018-01-17 18:50:12 +01:00
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
await this.updatePermissions(cb);
|
|
|
|
|
},
|
|
|
|
|
|
2018-01-22 18:19:44 +01:00
|
|
|
|
updateRole: async function (roleID, body) {
|
2018-03-14 16:56:12 +01:00
|
|
|
|
const [role, root, authenticated] = await Promise.all([
|
2018-01-22 18:19:44 +01:00
|
|
|
|
this.getRole(roleID, []),
|
2018-01-23 15:38:43 +01:00
|
|
|
|
strapi.query('role', 'users-permissions').findOne({ type: 'root' }, []),
|
2018-03-14 16:56:12 +01:00
|
|
|
|
strapi.query('role', 'users-permissions').findOne({ type: 'authenticated' }, [])
|
2018-01-22 18:19:44 +01:00
|
|
|
|
]);
|
2017-11-27 17:50:51 +01:00
|
|
|
|
|
2018-01-22 18:19:44 +01:00
|
|
|
|
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}`, {});
|
|
|
|
|
|
|
|
|
|
if (_.differenceWith([bodyAction], [currentAction]).length > 0) {
|
|
|
|
|
acc.push(strapi.query('permission', 'users-permissions').update({
|
|
|
|
|
role: roleID,
|
|
|
|
|
type,
|
|
|
|
|
controller,
|
2018-01-25 17:08:39 +01:00
|
|
|
|
action: action.toLowerCase()
|
2018-01-22 18:19:44 +01:00
|
|
|
|
}, bodyAction));
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
});
|
2018-01-17 18:50:12 +01:00
|
|
|
|
|
2018-01-22 18:19:44 +01:00
|
|
|
|
return acc;
|
|
|
|
|
}, []);
|
2017-12-01 16:06:16 +01:00
|
|
|
|
|
2018-03-12 14:04:43 +01:00
|
|
|
|
arrayOfPromises.push(strapi.query('role', 'users-permissions').update({
|
|
|
|
|
id: roleID,
|
|
|
|
|
}, _.pick(body, ['name', 'description'])));
|
|
|
|
|
|
2018-02-24 17:42:33 +01:00
|
|
|
|
// stringify mongoDB _id for add/remove matching
|
|
|
|
|
if (role._id ? '_id' : 'id' === '_id') {
|
|
|
|
|
role.users.reduce((acc, user) => {
|
|
|
|
|
const key = role._id ? '_id' : 'id';
|
|
|
|
|
user[key] = user[key].toString();
|
|
|
|
|
acc.push(user);
|
|
|
|
|
return acc;
|
|
|
|
|
}, []);
|
|
|
|
|
}
|
|
|
|
|
|
2018-01-22 18:19:44 +01:00
|
|
|
|
// Add user to this role.
|
2018-01-23 15:38:43 +01:00
|
|
|
|
_.differenceBy(body.users, role.users, role._id ? '_id' : 'id')
|
|
|
|
|
.filter(user => user.role !== `${root._id || root.id}`.toString())
|
|
|
|
|
.forEach(user => {
|
|
|
|
|
arrayOfPromises.push(this.updateUserRole(user, roleID));
|
|
|
|
|
})
|
2017-12-05 16:44:54 +01:00
|
|
|
|
|
2018-03-14 16:56:12 +01:00
|
|
|
|
// Remove user to this role and link him to authenticated.
|
2018-01-23 15:38:43 +01:00
|
|
|
|
_.differenceBy(role.users, body.users, role._id ? '_id' : 'id')
|
|
|
|
|
.filter(user => user.role !== `${root._id || root.id}`.toString())
|
|
|
|
|
.forEach(user => {
|
2018-03-14 16:56:12 +01:00
|
|
|
|
arrayOfPromises.push(this.updateUserRole(user, authenticated._id || authenticated.id));
|
2018-01-23 15:38:43 +01:00
|
|
|
|
});
|
2018-01-22 18:19:44 +01:00
|
|
|
|
|
2018-01-23 18:54:17 +01:00
|
|
|
|
|
2018-01-22 18:19:44 +01:00
|
|
|
|
return Promise.all(arrayOfPromises);
|
2017-11-27 17:50:51 +01:00
|
|
|
|
},
|
|
|
|
|
|
2017-12-07 10:16:36 +01:00
|
|
|
|
updateUserRole: async (user, role) => {
|
2018-01-23 15:38:43 +01:00
|
|
|
|
return strapi.query('user', 'users-permissions').update({
|
|
|
|
|
id: user._id || user.id
|
|
|
|
|
}, {
|
2017-12-07 10:16:36 +01:00
|
|
|
|
role: role.toString()
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
2018-04-23 14:21:24 +02:00
|
|
|
|
writeActions: (data, cb) => {
|
2018-01-17 18:50:12 +01:00
|
|
|
|
const actionsPath = path.join(strapi.config.appPath, 'plugins', 'users-permissions', 'config', 'actions.json');
|
2017-11-17 16:36:57 +01:00
|
|
|
|
|
|
|
|
|
try {
|
2018-04-23 14:21:24 +02:00
|
|
|
|
// Disable auto-reload.
|
|
|
|
|
strapi.reload.isWatching = false;
|
2018-01-17 18:50:12 +01:00
|
|
|
|
// Rewrite actions.json file.
|
|
|
|
|
fs.writeFileSync(actionsPath, JSON.stringify({ actions: data }), 'utf8');
|
|
|
|
|
// Set value to AST to avoid restart.
|
2018-01-23 15:38:43 +01:00
|
|
|
|
_.set(strapi.plugins['users-permissions'], 'config.actions', data);
|
2018-04-23 14:21:24 +02:00
|
|
|
|
// Disable auto-reload.
|
|
|
|
|
strapi.reload.isWatching = true;
|
|
|
|
|
|
|
|
|
|
cb();
|
2017-11-17 16:36:57 +01:00
|
|
|
|
} catch(err) {
|
|
|
|
|
strapi.log.error(err);
|
|
|
|
|
}
|
2017-12-01 16:06:16 +01:00
|
|
|
|
},
|
2018-01-04 16:36:56 +01:00
|
|
|
|
|
2018-01-23 15:38:43 +01:00
|
|
|
|
syncSchema: async (cb) => {
|
|
|
|
|
if (strapi.plugins['users-permissions'].models.user.orm !== 'bookshelf') {
|
2018-01-11 15:00:34 +01:00
|
|
|
|
return cb();
|
|
|
|
|
}
|
|
|
|
|
|
2018-01-23 15:38:43 +01:00
|
|
|
|
// Extract necessary information from plugin's models.
|
|
|
|
|
const {
|
|
|
|
|
user: { collectionName: userTableName, connection: userConnection, client: userClient },
|
|
|
|
|
role: { collectionName: roleTableName, connection: roleConnection, client: roleClient },
|
|
|
|
|
permission: { collectionName: permissionTableName, connection: permissionConnection, client: permissionClient }
|
|
|
|
|
} = strapi.plugins['users-permissions'].models;
|
|
|
|
|
|
|
|
|
|
const details = {
|
|
|
|
|
user: {
|
|
|
|
|
tableName: userTableName,
|
|
|
|
|
connection: userConnection,
|
|
|
|
|
client: userClient
|
|
|
|
|
},
|
|
|
|
|
role: {
|
|
|
|
|
tableName: roleTableName,
|
|
|
|
|
connection: roleConnection,
|
|
|
|
|
client: roleClient
|
|
|
|
|
},
|
|
|
|
|
permission: {
|
|
|
|
|
tableName: permissionTableName,
|
|
|
|
|
connection: permissionConnection,
|
|
|
|
|
client: permissionClient
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Check if the tables are existing.
|
|
|
|
|
const hasTables = await Promise.all(Object.keys(details).map(name =>
|
|
|
|
|
strapi.connections[details[name].connection].schema.hasTable(details[name].tableName)
|
|
|
|
|
));
|
|
|
|
|
|
|
|
|
|
const missingTables = [];
|
|
|
|
|
const tablesToCreate = [];
|
|
|
|
|
|
|
|
|
|
for (let index = 0; index < hasTables.length; ++index) {
|
|
|
|
|
const hasTable = hasTables[index];
|
|
|
|
|
const currentModel = Object.keys(details)[index];
|
2018-01-25 11:19:53 +01:00
|
|
|
|
const quote = details[currentModel].client === 'pg' ? '"' : '`';
|
2018-01-11 15:00:34 +01:00
|
|
|
|
|
2018-01-23 15:38:43 +01:00
|
|
|
|
if (!hasTable) {
|
|
|
|
|
missingTables.push(`
|
|
|
|
|
⚠️ TABLE \`${details[currentModel].tableName}\` DOESN'T EXIST`);
|
2018-01-04 16:36:56 +01:00
|
|
|
|
|
2018-01-23 15:38:43 +01:00
|
|
|
|
switch (currentModel) {
|
|
|
|
|
case 'user':
|
|
|
|
|
tablesToCreate.push(`
|
2018-01-04 16:36:56 +01:00
|
|
|
|
|
2018-01-25 11:19:53 +01:00
|
|
|
|
CREATE TABLE ${quote}${details[currentModel].tableName}${quote} (
|
2018-01-23 15:38:43 +01:00
|
|
|
|
id ${details[currentModel].client === 'pg' ? 'SERIAL' : 'INT AUTO_INCREMENT'} NOT NULL PRIMARY KEY,
|
2018-01-11 15:00:34 +01:00
|
|
|
|
username text,
|
|
|
|
|
email text,
|
2018-01-17 14:32:38 +01:00
|
|
|
|
provider text,
|
2018-01-25 11:19:53 +01:00
|
|
|
|
role ${details[currentModel].client === 'pg' ? 'integer' : 'int'},
|
|
|
|
|
${quote}resetPasswordToken${quote} text,
|
2018-01-11 15:00:34 +01:00
|
|
|
|
password text,
|
2018-01-23 15:38:43 +01:00
|
|
|
|
updated_at ${details[currentModel].client === 'pg' ? 'timestamp with time zone' : 'timestamp'},
|
|
|
|
|
created_at ${details[currentModel].client === 'pg' ? 'timestamp with time zone' : 'timestamp'}
|
|
|
|
|
);`);
|
|
|
|
|
break;
|
|
|
|
|
case 'role':
|
|
|
|
|
tablesToCreate.push(`
|
|
|
|
|
|
2018-01-25 11:19:53 +01:00
|
|
|
|
CREATE TABLE ${quote}${details[currentModel].tableName}${quote} (
|
2018-01-23 15:38:43 +01:00
|
|
|
|
id ${details[currentModel].client === 'pg' ? 'SERIAL' : 'INT AUTO_INCREMENT'} NOT NULL PRIMARY KEY,
|
|
|
|
|
name text,
|
|
|
|
|
description text,
|
|
|
|
|
type text
|
|
|
|
|
);`);
|
|
|
|
|
break;
|
|
|
|
|
case 'permission':
|
|
|
|
|
tablesToCreate.push(`
|
|
|
|
|
|
2018-01-25 11:19:53 +01:00
|
|
|
|
CREATE TABLE ${quote}${details[currentModel].tableName}${quote} (
|
2018-01-23 15:38:43 +01:00
|
|
|
|
id ${details[currentModel].client === 'pg' ? 'SERIAL' : 'INT AUTO_INCREMENT'} NOT NULL PRIMARY KEY,
|
|
|
|
|
role ${details[currentModel].client === 'pg' ? 'integer' : 'int'},
|
|
|
|
|
type text,
|
|
|
|
|
controller text,
|
|
|
|
|
action text,
|
|
|
|
|
enabled boolean,
|
|
|
|
|
policy text
|
|
|
|
|
);`);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
2018-01-04 16:36:56 +01:00
|
|
|
|
|
2018-01-11 15:00:34 +01:00
|
|
|
|
}
|
2018-01-23 15:38:43 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
2018-01-04 16:36:56 +01:00
|
|
|
|
|
2018-01-23 15:38:43 +01:00
|
|
|
|
if (!_.isEmpty(tablesToCreate)) {
|
|
|
|
|
tablesToCreate.unshift(`
|
2018-01-11 15:00:34 +01:00
|
|
|
|
|
2018-01-23 15:38:43 +01:00
|
|
|
|
1️⃣ EXECUTE THE FOLLOWING SQL QUERY`);
|
2018-01-11 15:00:34 +01:00
|
|
|
|
|
2018-01-23 15:38:43 +01:00
|
|
|
|
tablesToCreate.push(`
|
2018-01-04 16:36:56 +01:00
|
|
|
|
|
2018-01-23 15:38:43 +01:00
|
|
|
|
2️⃣ RESTART YOUR SERVER`)
|
|
|
|
|
strapi.log.warn(missingTables.concat(tablesToCreate).join(''));
|
2018-01-04 16:36:56 +01:00
|
|
|
|
|
2018-01-23 15:38:43 +01:00
|
|
|
|
// Stop the server.
|
|
|
|
|
strapi.stop();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const missingColumns = [];
|
|
|
|
|
const tablesToAlter = [];
|
|
|
|
|
|
|
|
|
|
for (let index = 0; index < hasTables.length; ++index) {
|
|
|
|
|
const currentModel = Object.keys(details)[index];
|
2018-01-25 11:19:53 +01:00
|
|
|
|
const quote = details[currentModel].client === 'pg' ? '"' : '`';
|
2018-01-23 15:38:43 +01:00
|
|
|
|
const attributes = {
|
|
|
|
|
id: {
|
|
|
|
|
type: details[currentModel].client === 'pg' ? 'integer' : 'int'
|
|
|
|
|
},
|
|
|
|
|
..._.cloneDeep(strapi.plugins['users-permissions'].models[currentModel].attributes)
|
2018-01-11 15:00:34 +01:00
|
|
|
|
};
|
2018-01-04 16:36:56 +01:00
|
|
|
|
|
2018-01-23 15:38:43 +01:00
|
|
|
|
// Add created_at and updated_at attributes for the model User.
|
|
|
|
|
if (currentModel === 'user') {
|
|
|
|
|
Object.assign(attributes, {
|
|
|
|
|
created_at: {
|
|
|
|
|
type: details[currentModel].client === 'pg' ? 'timestamp with time zone' : 'timestamp'
|
|
|
|
|
},
|
|
|
|
|
updated_at: {
|
|
|
|
|
type: details[currentModel].client === 'pg' ? 'timestamp with time zone' : 'timestamp'
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const columns = Object.keys(attributes);
|
2018-01-04 16:36:56 +01:00
|
|
|
|
|
2018-01-23 15:38:43 +01:00
|
|
|
|
// Check if there are the required attributes.
|
|
|
|
|
const hasColumns = await Promise.all(columns.map(attribute =>
|
|
|
|
|
strapi.connections[details[currentModel].connection].schema.hasColumn(details[currentModel].tableName, attribute)
|
|
|
|
|
));
|
2018-01-04 16:36:56 +01:00
|
|
|
|
|
2018-01-23 15:38:43 +01:00
|
|
|
|
hasColumns.forEach((hasColumn, index) => {
|
|
|
|
|
const currentColumn = columns[index];
|
|
|
|
|
const attribute = attributes[currentColumn];
|
2018-01-04 16:36:56 +01:00
|
|
|
|
|
2018-01-23 15:38:43 +01:00
|
|
|
|
if (!hasColumn && !attribute.collection) {
|
2018-01-25 11:19:53 +01:00
|
|
|
|
const currentType = attribute.model ? 'integer' : attribute.type;
|
2018-01-23 15:38:43 +01:00
|
|
|
|
const type = currentType === 'string' ? 'text' : currentType;
|
|
|
|
|
|
|
|
|
|
missingColumns.push(`
|
|
|
|
|
⚠️ TABLE \`${details[currentModel].tableName}\` HAS MISSING COLUMNS`);
|
|
|
|
|
|
|
|
|
|
tablesToAlter.push(`
|
2018-01-04 16:36:56 +01:00
|
|
|
|
|
2018-01-25 11:19:53 +01:00
|
|
|
|
ALTER TABLE ${quote}${details[currentModel].tableName}${quote} ADD ${details[currentModel].client === 'pg' ? `${quote}${currentColumn}${quote}` : `${currentColumn}`} ${type};`);
|
2018-01-23 15:38:43 +01:00
|
|
|
|
}
|
2018-01-04 16:36:56 +01:00
|
|
|
|
});
|
2018-01-23 15:38:43 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!_.isEmpty(tablesToAlter)) {
|
|
|
|
|
tablesToAlter.unshift(`
|
|
|
|
|
|
|
|
|
|
1️⃣ EXECUTE THE FOLLOWING SQL QUERIES`);
|
|
|
|
|
|
|
|
|
|
tablesToAlter.push(`
|
|
|
|
|
|
|
|
|
|
2️⃣ RESTART YOUR SERVER`)
|
|
|
|
|
strapi.log.warn(missingColumns.concat(tablesToAlter).join(''));
|
|
|
|
|
|
|
|
|
|
// Stop the server.
|
|
|
|
|
return strapi.stop();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cb();
|
2018-01-25 08:38:46 +01:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
template: (layout, data) => {
|
|
|
|
|
const compiledObject = _.template(layout);
|
|
|
|
|
return compiledObject(data);
|
2018-01-04 16:36:56 +01:00
|
|
|
|
}
|
2017-11-06 11:14:43 +01:00
|
|
|
|
};
|