@inspire-platform/sails-hook-permissions
Version:
Comprehensive user permissions and entitlements system for sails.js and Waterline. Supports user authentication with passport.js, role-based permissioning, object ownership, and row-level security.
119 lines (102 loc) • 2.87 kB
JavaScript
/**
* @module Permission
*
* @description
* The actions a Role is granted on a particular Model and its attributes
*/
import _ from 'lodash'
module.exports = {
autoCreatedBy: false,
description: [
'Defines a particular `action` that a `Role` can perform on a `Model`.',
'A `User` can perform an `action` on a `Model` by having a `Role` which',
'grants the necessary `Permission`.'
].join(' '),
attributes: {
id: {
type: 'number',
autoIncrement: true
},
/**
* The Model that this Permission applies to.
*/
model: {
model: 'Model',
required: true
},
action: {
type: 'string',
required: true,
/**
* TODO remove enum and support permissions based on all controller
* actions, including custom ones
*/
isIn: [
'create',
'read',
'update',
'delete'
]
},
relation: {
type: 'string',
isIn: [
'role',
'owner',
'user'
],
defaultsTo: 'role'
},
/**
* The Role to which this Permission grants create, read, update, and/or
* delete privileges.
*/
role: {
model: 'Role',
// Validate manually
//required: true
},
/**
* The User to which this Permission grants create, read, update, and/or
* delete privileges.
*/
user: {
model: 'User'
// Validate manually
},
/**
* A list of object filters. Object ids are compiled into a where clause and forwarded to
* the criteria policy.
*/
objectFilters: {
collection: 'ObjectFilter',
via: 'permission'
},
/**
* A list of criteria. If any of the criteria match the request, the action is allowed.
* If no criteria are specified, it is ignored altogether.
*/
criteria: {
collection: 'Criteria',
via: 'permission'
}
},
afterValidate: [
function validateOwnerCreateTautology (permission, next) {
if (permission.relation == 'owner' && permission.action == 'create') {
next(new Error('Creating a Permission with relation=owner and action=create is tautological'));
}
if (permission.action === 'delete' &&
_.filter(permission.criteria, function (criteria) { return !_.isEmpty(criteria.blacklist); }).length) {
next(new Error('Creating a Permission with an attribute blacklist is not allowed when action=delete'));
}
if (permission.relation == 'user' && permission.user === "") {
next(new Error('A Permission with relation user MUST have the user attribute set'));
}
if (permission.relation == 'role' && permission.role === "") {
next(new Error('A Permission with relation role MUST have the role attribute set'));
}
next();
}
]
};