mongoose-rbac
mongoose-rbac copied to clipboard
Role-based access control for mongoose apps.
mongoose-rbac
Role-based access control for mongoose apps.
Requirements
- mongoose 3.8.x
Installation
npm install mongoose-rbac --save
Usage
mongoose-rbac gives you the building blocks to lock down your app with role-based access control and gets out of your way.
Generally, you will want to do the following:
- Create a
Permission
for each action you desire to control. APermission
consists of asubject
and anaction
. - Create a
Role
for each role you wish to assign. ARole
only requires a uniquename
. - Assign the desired set of permissions to each role.
- Use the mongoose-rbac plugin in your user schema.
Example
Following is a typical example. Let's imagine we are managing a blog with users, preferences, posts and comments. First, we will define our permissions and roles:
// permissions.js
var rbac = require('mongoose-rbac')
, Permission = rbac.Permission
, Role = rbac.Role
, permissions;
permissions = [
{ subject: 'Post', action: 'create' }
, { subject: 'Post', action: 'read' }
, { subject: 'Post', action: 'update' }
, { subject: 'Post', action: 'delete' }
, { subject: 'Comment', action: 'create' }
, { subject: 'Comment', action: 'read' }
, { subject: 'Comment', action: 'update' }
, { subject: 'Comment', action: 'delete' }
, { subject: 'Preference', action: 'create' }
, { subject: 'Preference', action: 'read' }
, { subject: 'Preference', action: 'update' }
, { subject: 'Preference', action: 'delete' }
];
Permission.create(permissions, function (err) {
var perms, admin, developer, readonly;
perms = Array.prototype.slice.call(arguments, 1);
admin = new Role({ name: 'admin' });
admin.permissions = perms;
admin.save(function (err, admin) {
developer = new Role({ name: 'developer' });
developer.permissions = perms.slice(0, 7);
developer.save(function (err, developer) {
readonly = new Role({ name: 'readonly' });
readonly.permissions = [perms[1], perms[5], perms[9]];
readonly.save(function (err, readonly) {
// ...
});
});
});
});
Alternatively we can use init
to easily bootstrap roles and permissions:
// permissions.js
var rbac = require('mongoose-rbac');
rbac.init({
admin: [
['create', 'Post'],
['read', 'Post'],
['update', 'Post'],
['delete', 'Post']
],
readonly: [
// we can also specify permissions as an object
{ action: 'read', subject: 'Post' }
]
}, function (err, admin, readonly) {
console.log(admin);
/*
{ __v: 1,
name: 'admin',
_id: 513c14dbc90000d10100004e,
permissions: [ 513c14dbc90000d101000044,
513c14dbc90000d101000045,
513c14dbc90000d101000046,
513c14dbc90000d101000047 ] }
*/
console.log(readonly);
/*
{ __v: 1,
name: 'readonly',
_id: 513c14dbc90000d10100004f,
permissions: [ 513c14dbc90000d101000045 ] }
*/
});
Next, we will enhance our user model with the mongoose-rbac plugin:
// user.js
var mongoose = require('mongoose')
, rbac = require('mongoose-rbac')
, UserSchema
, User;
UserSchema = mongoose.Schema({
username: String,
passwordHash: String
});
UserSchema.plugin(rbac.plugin);
module.exports = mongoose.model('User', UserSchema);
Finally, we can assign roles to our users and control their access to system resources:
var User = require('user')
, user;
user = new User({ username: 'hercules' });
user.save();
user.addRole('admin', function (err) {});
user.hasRole('admin', function (err, isAdmin) {
console.log(isAdmin); // true
});
user.can('create', 'Post', function (err, can) {
if (can) {
// ok
}
else {
// insufficient privileges
}
});
user.canAny([['read', 'Post'], ['create', 'Post']], function (err, canReadOrCreate) {
if (canReadOrCreate) {
// ok
}
else {
// insufficient privileges
}
});
user.removeRole('admin', function (err) {});
Model Plugin API
hasRole(role, callback)
Check if the model has the given role.
-
role
String or Role -
callback(err, bool)
Function
addRole(role, callback)
Add the given role to the model.
-
role
String or Role -
callback(err)
Function
removeRole(role, callback)
Remove the given role from the model.
-
role
String or Role -
callback(err)
Function
can(action, subject, callback)
Check if the model has the given permisison.
-
action
String -
subject
String -
callback(err, bool)
Function
canAny(actionsAndSubjects, callback)
Check if the model has any of the given permissions.
-
actionsAndSubjects
Array (of[String, String]
) -
callback(err, bool)
Function
canAll(actionsAndSubjects, callback)
Check if the model has all of the given permissions.
-
actionsAndSubjects
Array (of [String, String]) -
callback(err, bool)
Function
Running Tests
To run the tests, clone the repository and install the dev dependencies:
git clone git://github.com/bryandragon/mongoose-rbac.git
cd mongoose-rbac && npm install
make test
License
MIT