1.0.0 • Published 4 years ago

jupiter-acl-user v1.0.0

Weekly downloads
3
License
-
Repository
-
Last release
4 years ago

Features

  • Users
  • Roles
  • Hierarchies
  • Resources
  • Express middleware for protecting resources.
  • Robust implementation with good unit test coverage.

Installation

Using npm:

npm install jupiter-acl-user

Documentation

Examples

Create your acl module by requiring it and instantiating it with a valid backend instance:

var acl = require('jupiter-acl-user');

// Using redis backend
acl = new acl(new acl.redisBackend(redisClient, prefix));

// Or Using the memory backend
acl = new acl(new acl.memoryBackend());

// Or Using the mongodb backend
acl = new acl(new acl.mongodbBackend(dbInstance, prefix));

All the following functions return a promise or optionally take a callback with an err parameter as last parameter. We omit them in the examples for simplicity.

Create roles implicitly by giving them permissions:

// guest is allowed to view blogs
acl.allow('guest', 'blogs', 'view')

// allow function accepts arrays as any parameter
acl.allow('member', 'blogs', ['edit', 'view', 'delete'])

Users are likewise created implicitly by assigning them roles:

acl.addUserRoles('joed', 'guest')

Hierarchies of roles can be created by assigning parents to roles:

acl.addRoleParents('baz', ['foo', 'bar'])

Note that the order in which you call all the functions is irrelevant (you can add parents first and assign permissions to roles later)

acl.allow('foo', ['blogs', 'forums', 'news'], ['view', 'delete'])

Use the wildcard to give all permissions:

acl.allow('admin', ['blogs', 'forums'], '*')

Sometimes is necessary to set permissions on many different roles and resources. This would lead to unnecessary nested callbacks for handling errors. Instead use the following:

acl.allow([
    {
        roles:['guest', 'member'],
        allows:[
            {resources:'blogs', permissions:'get'},
            {resources:['forums', 'news'], permissions:['get', 'put', 'delete']}
        ]
    },
    {
        roles:['gold', 'silver'],
        allows:[
            {resources:'cash', permissions:['sell', 'exchange']},
            {resources:['account', 'deposit'], permissions:['put', 'delete']}
        ]
    }
])

You can check if a user has permissions to access a given resource with isAllowed:

acl.isAllowed('joed', 'blogs', 'view', function(err, res){
    if(res){
        console.log("User joed is allowed to view blogs")
    }
})

Of course arrays are also accepted in this function:

acl.isAllowed('jsmith', 'blogs', ['edit', 'view', 'delete'])

Note that all permissions must be fulfilled in order to get true.

Sometimes is necessary to know what permissions a given user has over certain resources:

acl.allowedPermissions('james', ['blogs', 'forums'], function(err, permissions){
    console.log(permissions)
})

It will return an array of resource:permissions like this:

[{'blogs' : ['get', 'delete']},
 {'forums':['get', 'put']}]

Finally, we provide a middleware for Express for easy protection of resources.

acl.middleware()

We can protect a resource like this:

app.put('/blogs/:id', acl.middleware(), function(req, res, next){…}

The middleware will protect the resource named by req.url, pick the user from req.session.userId and check the permission for req.method, so the above would be equivalent to something like this:

acl.isAllowed(req.session.userId, '/blogs/12345', 'put')

The middleware accepts 3 optional arguments, that are useful in some situations. For example, sometimes we cannot consider the whole url as the resource:

app.put('/blogs/:id/comments/:commentId', acl.middleware(3), function(req, res, next){…}

In this case the resource will be just the three first components of the url (without the ending slash).

It is also possible to add a custom userId or check for other permissions than the method:

app.put('/blogs/:id/comments/:commentId', acl.middleware(3, 'joed', 'post'), function(req, res, next){…}

Methods

addUserRoles( userId, roles, function(err) )

Adds roles to a given user id.

Arguments

    userId   {String|Number} User id.
    roles    {String|Array} Role(s) to add to the user id.
    callback {Function} Callback called when finished.

removeUserRoles( userId, roles, function(err) )

Remove roles from a given user.

Arguments

    userId   {String|Number} User id.
    roles    {String|Array} Role(s) to remove to the user id.
    callback {Function} Callback called when finished.

userRoles( userId, function(err, roles) )

Return all the roles from a given user.

Arguments

    userId   {String|Number} User id.
    callback {Function} Callback called when finished.

roleUsers( rolename, function(err, users) )

Return all users who has a given role.

Arguments

    rolename   {String|Number} User id.
    callback {Function} Callback called when finished.

hasRole( userId, rolename, function(err, hasRole) )

Return boolean whether user has the role

Arguments

    userId   {String|Number} User id.
    rolename {String|Number} role name.
    callback {Function} Callback called when finished.

addRoleParents( role, parents, function(err) )

Adds a parent or parent list to role.

Arguments

    role     {String} Child role.
    parents  {String|Array} Parent role(s) to be added.
    callback {Function} Callback called when finished.

removeRoleParents( role, parents, function(err) )

Removes a parent or parent list from role.

If parents is not specified, removes all parents.

Arguments

    role     {String} Child role.
    parents  {String|Array} Parent role(s) to be removed [optional].
    callback {Function} Callback called when finished [optional].

removeRole( role, function(err) )

Removes a role from the system.

Arguments

    role     {String} Role to be removed
    callback {Function} Callback called when finished.

Removes a resource from the system

Arguments

    resource {String} Resource to be removed
    callback {Function} Callback called when finished.

allow( roles, resources, permissions, function(err) )

Adds the given permissions to the given roles over the given resources.

Arguments

    roles       {String|Array} role(s) to add permissions to.
    resources   {String|Array} resource(s) to add permisisons to.
    permissions {String|Array} permission(s) to add to the roles over the resources.
    callback    {Function} Callback called when finished.

allow( permissionsArray, function(err) )

Arguments

    permissionsArray {Array} Array with objects expressing what permissions to give.
       [{roles:{String|Array}, allows:[{resources:{String|Array}, permissions:{String|Array}]]

    callback         {Function} Callback called when finished.

removeAllow( role, resources, permissions, function(err) )

Remove permissions from the given roles owned by the given role.

Note: we loose atomicity when removing empty role_resources.

Arguments

    role        {String}
    resources   {String|Array}
    permissions {String|Array}
    callback    {Function}

allowedPermissions( userId, resources, function(err, obj) )

Returns all the allowable permissions a given user have to access the given resources.

It returns an array of objects where every object maps a resource name to a list of permissions for that resource.

Arguments

    userId    {String|Number} User id.
    resources {String|Array} resource(s) to ask permissions for.
    callback  {Function} Callback called when finished.

isAllowed( userId, resource, permissions, function(err, allowed) )

Checks if the given user is allowed to access the resource for the given permissions (note: it must fulfill all the permissions).

Arguments

    userId      {String|Number} User id.
    resource    {String} resource to ask permissions for.
    permissions {String|Array} asked permissions.
    callback    {Function} Callback called with the result.

areAnyRolesAllowed( roles, resource, permissions, function(err, allowed) )

Returns true if any of the given roles have the right permissions.

Arguments

    roles       {String|Array} Role(s) to check the permissions for.
    resource    {String} resource to ask permissions for.
    permissions {String|Array} asked permissions.
    callback    {Function} Callback called with the result.

whatResources(role, function(err, {resourceName: permissions})

Returns what resources a given role has permissions over.

Arguments

    role        {String|Array} Roles
    callback    {Function} Callback called with the result.

whatResources(role, permissions, function(err, resources) )

Returns what resources a role has the given permissions over.

Arguments

    role        {String|Array} Roles
    permissions {String|Array} Permissions
    callback    {Function} Callback called with the result.

middleware( numPathComponents, userId, permissions )

Middleware for express.

To create a custom getter for userId, pass a function(req, res) which returns the userId when called (must not be async).

Arguments

    numPathComponents {Number} number of components in the url to be considered part of the resource name.
    userId            {String|Number|Function} the user id for the acl system (defaults to req.session.userId)
    permissions       {String|Array} the permission(s) to check for (defaults to req.method.toLowerCase())