-
Notifications
You must be signed in to change notification settings - Fork 113
Managing Roles and Permissions
By default, all new Users are given the registered
role. There are two ways to create a new Role
:
Let's say you want to create a new Role called collaborator
, and assign it to User tjwebb
:
-
The same way you would create any other sails.js object:
User.findOne({ username: 'tjwebb' }) .then(function (user) { return Role.create({ name: 'collaborator', users: [ user.id ] }) .then(function (role) { console.log(role); }) .catch(function (error) { console.error(error); });
You can also use the sails.js blueprint endpoints to accomplish the same thing, e.g.
GET /role/create?name=collaborator
.Note: When using the REST endpoints, make sure you are authenticated as a user who has sufficient Permissions to create new Roles! By default, the only user allowed to do this is the admin user.
-
Via the PermissionService helper method ’createRole’. Note that this method requires creating one or more
Permission
objects as part of the method call (see the 'permissions' key in the object passed into the createRole function below).PermissionService.createRole({ name: 'collaborator', users: 'tjwebb', permissions: [{ model: 'mymodel', action: 'create' }, { model: 'myothermodel', action: 'read' }] })
Creating a Role is super easy. By default, new Roles have no Permissions. There are two ways to grant new Permissions
to a Role
:
Let's say you want to grant Users with the role collaborator with the ability to create and read all Project and Issue objects.
-
Create Permission objects just like any other sails.js model, and associate it with a Role.
Promise.bind({ }, Role.findOne({ name: 'collaborator' }) .then(function (role) { this.role = role; return Model.find({ name: [ 'Project', 'Issue' ] }); }) .map(function (model) { return [ Permission.create({ model: model.id, action: 'create', role: this.role.id }), Permission.create({ model: model.id, action: 'read', role: this.role.id }) ]; }) .spread(function (createPermission, readPermission) { sails.log('new create permission', createPermission); sails.log('new read permission', readPermission); }) .catch(sails.log.error);
-
Use the PermissionService helper method ‘grant’.
Promise.all([PermissionService.grant({ role: 'collaborator', model: 'Project', action: 'read'}), PermissionService.grant({ role: 'collaborator', model: 'Project', action: 'create'}), PermissionService.grant({ role: 'collaborator', model: 'Issue', action: 'read'}), PermissionService.grant({ role: 'collaborator', model: 'Issue', action: 'create'}]) .spread(function (projectRead, projectCreate, issueRead, issueCreate) { sails.log('new read Project permission', projectRead); sails.log('new create Project permission', projectCreate); sails.log('new read Issue permission', issueRead); sails.log('new create Issue permission', issueCreate); });
Permissions are revoked simply by deleting the relevant Permission object, or by using the PermissionService helper method ‘revoke’.
Let's say we want to revoke the create
Permission we just granted to the collaborator
Role for Project
.
Promise.bind({ }, Role.findOne({ name: 'collaborator' })
.then(function (role) {
this.role = role;
return Model.findOne({ name: 'Project' });
})
.then(function (model) {
return Permission.destroy({
model: model.id,
action: 'read',
role: role.id,
});
})
.then(function () {
sails.log('revoked "read" from "collaborator" on "Project"');
})
.catch(sails.log.error);
There is also a helper method in PermissionService named ‘revoke’:
PermissionService.revoke({ model: 'project', action: 'read', role: 'collaborator', relation: 'role' })
.then(function () {
sails.log('revoked “read” from “collaborator” on “Project”');
});
PermissionService has helpers to facilitate adding users to and removing users from a role. You can pass a single username or an array of usernames to these functions.
PermissionService.addUsersToRole('someusername', 'collaborator')
.then(function () {
sails.log('added “someusername” to role “collaborator”');
});
PermissionService.removeUsersFromRole(['someusername', 'tjwebb'], 'collaborator')
.then(function () {
sails.log('removed “someusername” and “tjwebb” from role “collaborator”');
});
Criteria
are used to specify further conditions that must be met for a Permission
to be valid. Criteria
have two important fields, 'where' and 'blacklist'. The 'where' field uses waterline query syntax to specify a condition that must be true for a Permission
to be valid.
For instance, a user may only have permission to update an Issue if it is a public issue (assume that Issue has a boolean field 'public'). The Criteria
for this situation would look like this:
{ where: { public: true } }
This Criteria
would be associated with a Permission
granting the update action on the Issue model to some particular role.
The 'blacklist' field is used for attribute-level permissions. For update and create requests, it returns an error if a field in the blacklist is included in the request. For get requests, it filters the blacklisted fields from the response.
For the same Issue 'update' Permission
, we could blacklist the 'public' field. This would prevent the role associated with this Permission
from updating the value of the field.
To create this Permission, we can use the PermissionService helper:
PermissionService.grant({role: 'collaborator', model: 'Issue', action: 'update',
criteria: { where: { public: true }, blacklist: ['public'] } })