UNPKG

we-plugin-acl

Version:

Role-based access control (RBAC) for We.js framework

301 lines (271 loc) 8.29 kB
/** * Main ACL file */ const ACL = require('we-core-acl'), path = require('path'); module.exports = function loadPlugin(projectPath, Plugin) { const plugin = new Plugin(__dirname); plugin.setConfigs({ // auth settings acl : { disabled: true }, // default app permissions permissions: { 'find_user': { 'group': 'user', 'title': 'Find users', 'description': 'Find and find all users' }, 'create_user': { 'group': 'user', 'title': 'Create one user', 'description': 'Create one new user' }, 'update_user': { 'group': 'user', 'title': 'Update one user', 'description': 'Update one new user' }, 'delete_user': { 'group': 'user', 'title': 'Delete one user', 'description': 'Delete one user record' }, 'manage_role': { 'group': 'role', 'title': 'Manage roles', 'description': 'Change and update user roles' }, 'use_flag': { 'group': 'flag', 'title': 'Use flag API', 'description': '' }, 'use_follow': { 'group': 'follow', 'title': 'Use follow API', 'description': '' }, 'access_admin': { 'group': 'admin', 'title': 'Access admin page', 'description': '' }, 'manage_users': { 'group': 'admin', 'title': 'Manage users', 'description': '' }, 'manage_permissions': { 'group': 'admin', 'title': 'Manage permissions', 'description': '' }, 'manage_theme': { 'group': 'admin', 'title': 'Manage theme', 'description': '' }, 'setAlias': { 'group': 'router', 'title': 'Set url alias in form', 'description': 'Can set model alias' } }, // project roles roles: { administrator: { name: 'administrator', permissions: [] }, authenticated: { name: 'authenticated', permissions: [], isSystemRole: true }, unAuthenticated: { name: 'unAuthenticated', permissions: [], isSystemRole: true }, owner: { name: 'owner', permissions: [], isSystemRole: true } }, autoUpdateRolesConfig: true, rolesConfigFile: path.resolve(projectPath + '/config/roles.js') }); plugin.setRoutes({ 'get /acl/user/:userId([0-9]+)/roles': { 'titleHandler' : 'i18n', 'titleI18n' : 'admin.user.roles', 'controller' : 'role', 'action' : 'updateUserRoles', 'model' : 'user', 'permission' : 'manage_role', 'responseType' : 'json' }, 'post /acl/user/:userId([0-9]+)/roles': { 'titleHandler' : 'i18n', 'titleI18n' : 'admin.user.roles', 'controller' : 'role', 'action' : 'updateUserRoles', 'model' : 'user', 'permission' : 'manage_role', 'responseType' : 'json' }, 'get /acl/permission': { 'titleHandler' : 'i18n', 'titleI18n' : 'permission_manage', 'name' : 'permission_manage', 'controller' : 'permission', 'action' : 'manage', 'permission' : 'manage_permissions' }, 'post /acl/role/:roleName/permissions/:permissionName': { 'controller' : 'role', 'action' : 'addPermissionToRole', 'permission' : 'manage_permissions' }, 'delete /acl/role/:roleName/permissions/:permissionName': { 'controller' : 'role', 'action' : 'removePermissionFromRole', 'permission' : 'manage_permissions' }, 'get /acl/role': { 'name' : 'admin.role.find', 'controller' : 'role', 'action' : 'find', 'permission' : 'manage_permissions', 'responseType' : 'json' }, 'post /acl/role': { 'controller' : 'role', 'action' : 'find', 'permission' : 'manage_permissions', 'responseType' : 'json' } }); plugin.events.on('we:after:load:plugins', (we)=> { // access controll list we.acl = new ACL(); // override default write config to use the we.js setConfig we.acl.writeRolesToConfigFile = function writeRolesToConfigFile (done) { const roles = this.exportRoles(); we.setConfig('roles', roles, done); }; }); plugin.extendUserModel = function extendUserModel(we, done) { const P = we.db.Sequelize.Promise, MCU = we.db.modelsConfigs.user; MCU.definition.roles = { type: we.db.Sequelize.TEXT, formFieldType: null, skipSanitizer: true, emberConfiguration: 'DS.attr()', get() { if (this.getDataValue('roles')) { try { return JSON.parse( this.getDataValue('roles') ); } catch(e) { return []; } } return []; }, set(object) { if (typeof object == 'object') { this.setDataValue('roles', JSON.stringify(object)); } else if (typeof object == 'string') { try { // test if is valid format let nv = JSON.parse(object); if (nv && Array.isArray(nv)) { this.setDataValue('roles', object); } else { throw new Error('Invalid value'); } } catch(e) { throw new Error('invalid value in user.roles.set value: ', object); } } else { throw new Error('invalid error in user roles value: ', object); } } }; MCU.options.instanceMethods.getRoles = function () { return new we.db.Sequelize .Promise( (resolve)=> { resolve(this.roles); }); }; MCU.options.instanceMethods .setRoles = function (rolesToSave) { const self = this; return new P(function (resolve, reject) { self.roles = rolesToSave; self.save().then(resolve).catch(reject); }); }; MCU.options.instanceMethods .addRole = function (role) { if (typeof role == 'object') { role = role.name; } const self = this; return new P(function (resolve, reject) { const roles = self.roles; // if this user already have the role, do nothing if (roles.indexOf(role) > -1) return resolve(self); // else add the role and save the user roles.push(role); self.roles = roles; self.save().then(resolve).catch(reject); }); }; MCU.options.instanceMethods.removeRole = function (role) { if (typeof role == 'object') { role = role.name; } const self = this; return new we.db.Sequelize .Promise(function removeRolesPromisse(resolve, reject){ const roles = self.roles; let i = roles.indexOf(role); // skip if this user dont have the role if (i == -1) { return resolve(); } // remove the role roles.splice(i, 1); // update the array self.roles = roles; // save self.save().then(resolve).catch(reject); }); }; done(); }; plugin.initACL = function initACL(we) { we.log.verbose('initACL step'); we.acl.init(we, function afterInitAcl(){ we.acl.setModelDateFieldPermissions(we); }); }; plugin.addACLMiddleware = function addACLMiddleware(data) { // bind acl middleware data.middlewares.push(data.we.acl.canMiddleware.bind({ config: data.config })); }; plugin.crudPermissioPrefix = ['find', 'create', 'update', 'delete']; plugin.hooks.on('we:models:before:instance', plugin.extendUserModel); plugin.events.on('we:after:load:plugins', plugin.initACL); plugin.events.on('router:add:acl:middleware', plugin.addACLMiddleware); plugin.events.on('we-core:before:bind:one:resource:route', (data)=> { // set crud permissions plugin.crudPermissioPrefix.forEach( (ai)=> { if (!data.we.config.permissions[ai+'_'+data.configuration.model]) { data.we.config.permissions[ai+'_'+data.configuration.model] = { 'title': ai+'_'+data.configuration.model }; } }); }); return plugin; };