An Access Control List module, based on Redis with Express middleware support
This module provides a minimalistic ACL implementation inspired by Zend_ACL.
When you develop a web site or application you will soon notice that sessions are not enough to protect all the available resources. Avoiding that malicious users access other users content proves a much more complicated task than anticipated. ACL can solve this problem in a flexible and elegant way.
Create roles and assign roles to users. Sometimes it may even be useful to create one role per user, to get the finest granularity possible, while in other situations you will give the asterisk permission for admin kind of functionality.
A Redis, MongoDB and In-Memory based backends are provided built-in in the module. There are other third party backends such as knex based and firebase. There is also an alternative memory backend that supports regexps.
Follow manast for news and updates regarding this library.
npm install acl
Create your acl module by requiring it and instantiating it with a valid backend instance:
var acl = require'acl';// Using redis backendacl = redisClient prefix;// Or Using the memory backendacl = ;// Or Using the mongodb backendacl = 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 blogsaclallow'guest' 'blogs' 'view'// allow function accepts arrays as any parameteraclallow'member' 'blogs' 'edit''view' 'delete'
Users are likewise created implicitly by assigning them roles:
Hierarchies of roles can be created by assigning parents to roles:
Note that the order in which you call all the functions is irrelevant (you can add parents first and assign permissions to roles later)
aclallow'foo' 'blogs''forums''news' 'view' 'delete'
Use the wildcard to give all permissions:
aclallow'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:
aclallowroles:'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:
aclisAllowed'joed' 'blogs' 'view'ifresconsole.log"User joed is allowed to view blogs"
Of course arrays are also accepted in this function:
aclisAllowed'jsmith' 'blogs' 'edit''view''delete'
Note that all permissions must be full filed in order to get true.
Sometimes is necessary to know what permissions a given user has over certain resources:
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.
We can protect a resource like this:
appput'/blogs/:id' aclmiddleware …
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:
aclisAllowedreqsessionuserId '/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:
appput'/blogs/:id/comments/:commentId' aclmiddleware3 …
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:
### addUserRoles( userId, roles, function(err) )
appput'/blogs/:id/comments/:commentId' aclmiddleware3 'joed' 'post' …
Adds roles to a given user id.
userId String|Number User idroles String|Array Roles to add to the user idcallback Function Callback called when finished
Remove roles from a given user.
userId String|Number User idroles String|Array Roles to remove to the user idcallback Function Callback called when finished
Return all the roles from a given user.
userId String|Number User idcallback Function Callback called when finished
Return all users who has a given role.
rolename String|Number User idcallback Function Callback called when finished
Return boolean whether user has the role
userId String|Number User idrolename String|Number role namecallback Function Callback called when finished
Adds a parent or parent list to role.
role String Child roleparents String|Array Parent roles to be addedcallback Function Callback called when finished
Removes a parent or parent list from role.
parents is not specified, removes all parents.
role String Child roleparents String|Array Parent roles to be removed optionalcallback Function Callback called when finished optional
Removes a role from the system.
role String Role to be removedcallback Function Callback called when finished
Removes a resource from the system
resource String Resource to be removedcallback Function Callback called when finished
Adds the given permissions to the given roles over the given resources.
roles String|Array roles to add permissions toresources String|Array resources to add permisisons topermissions String|Array permissions to add to the roles over the resourcescallback Function Callback called when finished
permissionsArray Array Array with objects expressing what permissions to giveroles:String|Array allows:resources:String|Array permissions:String|Arraycallback Function Callback called when finished
Remove permissions from the given roles owned by the given role.
Note: we loose atomicity when removing empty role_resources.
role Stringresources String|Arraypermissions String|Arraycallback Function
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.
userId String|Number User idresources String|Array resources to ask permissions forcallback Function Callback called when finished
Checks if the given user is allowed to access the resource for the given permissions (note: it must fulfill all the permissions).
userId String|Number User idresource String resource to ask permissions forpermissions String|Array asked permissionscallback Function Callback called with the result
Returns true if any of the given roles have the right permissions.
roles String|Array Roles to check the permissions forresource String resource to ask permissions forpermissions String|Array asked permissionscallback Function Callback called with the result
Returns what resources a given role has permissions over.
role String|Array Rolescallback Function Callback called with the result
whatResources(role, permissions, function(err, resources) )
Returns what resources a role has the given permissions over.
role String|Array Rolespermissions String|Array Permissionscallback Function Callback called with the result
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).
numPathComponents Number number of components in the url to be considered part of the resource nameuserId String|Number|Function the user id for the acl system defaults to reqsessionuserIdpermissions String|Array the permissions to check for defaults to reqmethodtoLowerCase
Creates a backend instance. All backends except Memory require driver or database instance.
useSingle is only applicable to the MongoDB backend.
db Object Database instanceprefix String Optional collection prefixuseSingle Boolean Create one collection for all resources defaults to false
var mongodb = require'mongodb';mongodbconnect"mongodb://127.0.0.1:27017/acltest"var mongoBackend = db 'acl_';;
Creates a new MongoDB backend using database instance
var client = require'redis'createClient6379 '127.0.0.1' no_ready_check: true;var redisBackend = client;
Creates a new Redis backend using Redis client
Run tests with
npm (requires mocha):
(The MIT License)
Copyright (c) 2011-2013 Manuel Astudillo firstname.lastname@example.org
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.