dynamic-acl v2.0.6
node-dynamic-acl
Dynamic Access Control List for Node.js to fully control your Roles, Resources, Privileges and Conditions
#Install
$ npm install dynamic-acl
#Quick Start
var Acl = require('../dist').Acl;
var Role = require('../dist').Role;
var Resource = require('../dist').Resource;
var anonymous = {
roleId: 'visitor'
};
var bob = {
firstname: 'Bob',
lastname: 'Marley',
roleId: 'user'
};
var me = {
firtname: 'Timmmmy',
lastname: 'Timmmmy',
roleId: 'admin'
};
var page1 = {
id: 'page 1',
title: 'Go further with node',
resourceId: 'page'
};
var book = {
id: 'book 1',
title: 'Go further with JS',
resourceId: 'book'
};
var getUserRoleId = (user) => new Promise(resolve => resolve(user.roleId));
var getResourceId = (resource) => new Promise(resolve => resolve(resource.resourceId));
var userCanMarkPage = (user, page) => new Promise((resolve,reject) => {
if (user.firstname == 'Timmmmy')
return resolve();
return reject();
});
var acl = new Acl(getUserRoleId, getResourceId);
acl.addRole('visitor') // equivalent to acl.addRole(new Role('visitor', [], acl))
.addRole(new Role('user', ['visitor'], acl))
.addRole('admin', ['user']) //equivalent to acl.addRole(new Role('admin', ['user'], acl))
.addResource(new Resource('page', ['read', 'mark', 'change title']))
.addResource(new Resource('book'))
.build();
acl.allow('visitor', 'page', 'read')
.allow('user', 'page')
.allow('user', 'page', 'mark', userCanMarkPage)
.deny('user', 'page', 'change title')
.allow('admin', 'page', 'change title')
.allow('admin', 'book');
//console.log('---built permissions---');
//console.log('---visitor---');
//console.log(acl.getPermissions('visitor'));
//console.log('---user---');
//console.log(acl.getPermissions('user'));
//console.log('---admin---');
//console.log(acl.getPermissions('admin'));
//console.log('---anonymous permissions check---');
acl.isAllowed(anonymous, page1).then(
() => {
// anonymous should not be allowed
console.error('This should not be printed in console');
},
() => {
// anonymous is not allowed
console.log('anonymous isAllowed page1:* -> false');
}
);
acl.isAllowed(anonymous, page1, 'read').then(
// anonymous is allowed
() => {console.log('anonymous isAllowed page1:read -> true')},
() => {console.error('This should not be printed in console')}
);
acl.isAllowed(anonymous, page1, 'mark').then(
() => {console.error('This should not be printed in console')},
// anonymous is not allowed
() => {console.log('anonymous isAllowed page1:mark -> false')}
);
acl.isAllowed(anonymous, page1, 'change title').then(
() => {console.error('This should not be printed in console')},
// anonymous is not allowed
() => {console.log('anonymous isAllowed page1:change title -> false')}
);
acl.isAllowed(anonymous, book).then(
() => {console.error('This should not be printed in console')},
// anonymous is not allowed
() => {console.log('anonymous isAllowed book:* -> false')}
);
acl.isAllowed(anonymous, book, 'sell').then(
() => {console.error('This should not be printed in console')},
// anonymous is not allowed
() => {console.log('anonymous isAllowed book:sell -> false')}
);
//console.log('---user permissions check---');
acl.isAllowed(bob, page1).then(
() => {console.log('bob isAllowed page1:* -> true')},
() => {console.error('This should not be printed in console')}
);
acl.isAllowed(bob, page1, 'read').then(
() => {console.log('bob isAllowed page1:read -> true')},
() => {console.error('This should not be printed in console')}
);
acl.isAllowed(bob, page1, 'mark').then(
() => {console.error('This should not be printed in console')},
() => {console.log('bob isAllowed page1:mark -> false')}
);
acl.isAllowed(bob, page1, 'change title').then(
() => {console.error('This should not be printed in console')},
() => {console.log('bob isAllowed page1:change title -> false')}
);
acl.isAllowed(bob, book, 'book:*').then(
() => {console.error('This should not be printed in console')},
() => {console.log('bob isAllowed book:* -> false')}
);
acl.isAllowed(bob, book, 'book:sell').then(
() => {console.error('This should not be printed in console')},
() => {console.log('bob isAllowed book:sell -> false')}//privilege was not declared previously -> inherit from book:*
);
//console.log('---admin permissions check---');
acl.isAllowed(me, page1).then(
() => {console.log('me isAllowed page1:* -> true')},
() => {console.error('This should not be printed in console')}
);
acl.isAllowed(me, page1, 'read').then(
() => {console.log('me isAllowed page1:read -> true')},
() => {console.error('This should not be printed in console')}
);
acl.isAllowed(me, page1, 'mark').then(
() => {console.log('me isAllowed page1:mark -> true')},
() => {console.error('This should not be printed in console')}
);
acl.isAllowed(me, page1, 'change title').then(
() => {console.log('me isAllowed page1:change title -> true')},
() => {console.error('This should not be printed in console')}
);
acl.isAllowed(me, book).then(
() => {console.log('me isAllowed book:* -> true')},
() => {console.error('This should not be printed in console')}
);
acl.isAllowed(me, book, 'sell').then(
() => {console.log('me isAllowed book:sell -> true')},//privilege was not declared previously -> inherit from book:*
() => {console.error('This should not be printed in console')}
);
#API Reference
Acl
This class holds all information about Roles, Resources and Permissions
Kind: global class
- Acl
- new Acl(roleIdFetchFunc, resourceIdFetchFunc)
- .setRoleIdFetchFunc(func) ⇒ Acl
- .setResourceIdFetchFunc(func) ⇒ Acl
- .addRole(role, Parents) ⇒ Acl
- .removeRole(role) ⇒ Acl
- .getRole(id) ⇒ Role
- .addResource(resource) ⇒ Acl
- .removeResource(resource) ⇒ Acl
- .getResource(id) ⇒ Resource | null
- .build() ⇒ Acl
- .allow(roleId, resourceId, privilege, condition) ⇒ Acl
- .deny(roleId, resourceId, privilege, condition) ⇒ Acl
- ._allowOrDeny(allow, roleId, resourceId, privilege, condition)
- .isAllowed(user, resource, privilege) ⇒ Promise
- .isRoleAllowed(roleId, resourceId, privilege) ⇒ Promise
- .isAnyParentAllowed(roleId, resourceId, privilege) ⇒ Promise
- .getPermissions(roleId) ⇒ Array.<Object>
new Acl(roleIdFetchFunc, resourceIdFetchFunc)
Constructor
Param | Type | Description |
---|---|---|
roleIdFetchFunc | fetchRoleIdFunc | function that will let Acl fetch Role id (default will return empty string) |
resourceIdFetchFunc | fetchResourceIdFunc | function that will let Acl fetch Resource id (default will return empty string) |
Example
var myAcl = new Acl(function(user){
return Promise.resolve(user.getRole());
}, function(resource){
return Promise.resolve(resource.getResourceId());
});
acl.setRoleIdFetchFunc(func) ⇒ Acl
Sets how Acl should retrieve Role Id
Kind: instance method of Acl
Returns: Acl - this instance for chaining
Param | Type | Description |
---|---|---|
func | fetchRoleIdFunc | that will let Acl fetch Role Id from an object that may have a role |
acl.setResourceIdFetchFunc(func) ⇒ Acl
Sets how Acl should retrieve Resource Id
Kind: instance method of Acl
Returns: Acl - this instance for chaining
Param | Type | Description |
---|---|---|
func | fetchResourceIdFunc | that will let Acl fetch Resource Id from an object that may be a resource |
acl.addRole(role, Parents) ⇒ Acl
Add a new Role to Access Control List
Kind: instance method of Acl
Returns: Acl - this instanc@e for chaining
Throws:
- Error if role is not an instance of Role or a string
Param | Type | Description |
---|---|---|
role | Role | string | instance to add |
Parents | Array.<string> | Array.<Role> | default is empty array |
Example
acl.addRole('anonyme');
acl.addRole('user', ['anonyme']);
acl.addRole(new Role('admin', ['user'], acl));
acl.addRole('super', [new Role('normal', [], acl)]);
acl.removeRole(role) ⇒ Acl
Deletes role from the list of declared roles
Kind: instance method of Acl
Returns: Acl - this instance for chaining
Param | Type |
---|---|
role | Role | string |
Example
acl.remove('anonymous');
acl.getRole(id) ⇒ Role
Retrieve an instance of Role identified by id. It must be added before calling this function
Kind: instance method of Acl
Returns: Role - a Role instance if it was previously added or null if not exists
Param | Type | Description |
---|---|---|
id | string | of Role to retrieve |
acl.addResource(resource) ⇒ Acl
Add a new resource to Access Control List
Kind: instance method of Acl
Returns: Acl - this instance for chaining
Throws:
- Error if resource is not an instance of Acl
Param | Type | Description |
---|---|---|
resource | Resource | to add to Access Control List |
Example
acl.addResource(new Resource('page'));
acl.addResource(new Resource('book', ['read', 'buy']);
acl.removeResource(resource) ⇒ Acl
Removes a resource from Access Control List
Kind: instance method of Acl
Returns: Acl - this instance for chaining
Throws:
- Error if resource is not an instance of Resource or of type string
Param | Type | Description |
---|---|---|
resource | Resource | string | to remove |
Example
acl.removeResource('page');
acl.removeResource(bookResourceInstance);
acl.getResource(id) ⇒ Resource | null
Get resource instance by its Id if it was previously added to Access Control List
Kind: instance method of Acl
Returns: Resource | null - Resource instance if it exists. will return null otherwise
Param | Type | Description |
---|---|---|
id | string | Resource | of resource to get |
Example
acl.getResource('page');
acl.build() ⇒ Acl
Build all permissions based on added Role and Resource. Permissions are initialized to allow = false and condition = null
Kind: instance method of Acl
Returns: Acl - this instance for chaining
acl.allow(roleId, resourceId, privilege, condition) ⇒ Acl
Allow User with Role Id to access Privileged Resource (which have Resource Id) under condition
Kind: instance method of Acl
Returns: Acl - this instance for chaining
Param | Type | Default | Description |
---|---|---|---|
roleId | string | Role | Role Id or Role instance | |
resourceId | string | Resource | Resource Id or Resource instance | |
privilege | string | Array.<string> | "*" | Privilege (default is '*' all) |
condition | permissionConditionFunc | Conditional permission function (default is null) |
Example
acl.allow('user', 'article', 'write')
.allow('user', 'article', ['read', 'comment']);
.allow('user', 'article', 'modify', function(user, blog){
return user.id == article.author_id;
});
acl.deny(roleId, resourceId, privilege, condition) ⇒ Acl
Deny User with Role Id to access Privileged Resource (which have Resource Id) under condition
Kind: instance method of Acl
Returns: Acl - this instance for chaining
Param | Type | Default | Description |
---|---|---|---|
roleId | string | Role | Role Id or Role instance | |
resourceId | string | Resource | Resource Id or Resource instance | |
privilege | string | Array.<string> | "*" | Privilege (default is '*' all) |
condition | permissionConditionFunc | Conditional permission function (default is null) |
Example
acl.deny('anonymous', 'article', 'write')
.deny('anonymous', 'article', ['modify', 'comment'])
.deny('anonymous', 'article', 'read', function(user, article){
return article.is_public;
});
acl._allowOrDeny(allow, roleId, resourceId, privilege, condition)
Allow User with Role Id to access Privileged Resource (which have Resource Id) under condition
Kind: instance method of Acl
Param | Type | Default | Description |
---|---|---|---|
allow | boolean | true = allowed, false = denied | |
roleId | string | Role | Role Id or Role instance | |
resourceId | string | Resource | Resource Id or Resource instance | |
privilege | string | "*" | Privilege (default is '*' all) |
condition | permissionConditionFunc | Conditional permission function (default is null) |
acl.isAllowed(user, resource, privilege) ⇒ Promise
Checks if user is allowed to access resource with a given privilege. If yes, it checks condition
Kind: instance method of Acl
Param | Type | Default |
---|---|---|
user | * | |
resource | * | |
privilege | string | "*" |
Example
acl.isAllowed(userObject, resourceObject, 'read');
acl.isAllowed(userObject, resourceObject);
acl.isRoleAllowed(roleId, resourceId, privilege) ⇒ Promise
Checks if roleId has access to resourceId with privilege. If not, it will check if one of the related parents has access to resource id
Kind: instance method of Acl
Param | Type | Default |
---|---|---|
roleId | string | |
resourceId | string | |
privilege | string | "*" |
Example
acl.isRoleAllowed('user', 'book', 'read');
acl.isRoleAllow('user', 'page');
acl.isAnyParentAllowed(roleId, resourceId, privilege) ⇒ Promise
Checks if any role's parents is allowed to access resourceId with privileges
Kind: instance method of Acl
Param | Type |
---|---|
roleId | string |
resourceId | string |
privilege | string |
acl.getPermissions(roleId) ⇒ Array.<Object>
Returns an object representing roleId permissions
Kind: instance method of Acl
Returns: Array.<Object> - Permissions for each resource
Param | Type |
---|---|
roleId | string | Role |
Example
acl.getPermissions('user');
<a name="Role"></a>
Role
Role class
Kind: global class
- Role
- new Role(id, parents, acl)
- .setAcl(acl)
- .getAcl() ⇒ Acl | *
- .setId(id) ⇒ Role
- .getId() ⇒ string
- .setParents(parents) ⇒ Role
- .getParents() ⇒ Array | Array.<Role>
- .getParent(role) ⇒ Role | null
- .addParent(role) ⇒ Role
- .addParents(roles) ⇒ Role
- .removeParent({Role|string) ⇒ Role
- .removeParents(roles) ⇒ Role
- .toString() ⇒ string
new Role(id, parents, acl)
Creates a new role and attach it to Acl
Throws:
- Error if acl is not an instance of {Acl} or given parents were not declared before
Param | Type | Default | Description |
---|---|---|---|
id | string | role's id | |
parents | Array.<string> | Array.<Role> | list of parents | |
acl | Acl | ACL to which this role will be attached |
role.setAcl(acl)
Sets the ACL to which this role will be attached
Kind: instance method of Role
Param | Type |
---|---|
acl | Acl |
role.getAcl() ⇒ Acl | *
Returns the ACL to which this role is attached
Kind: instance method of Role
role.setId(id) ⇒ Role
Sets the role id of this instance
Kind: instance method of Role
Returns: Role - - This object
Throws:
- Error - if id is not a string
Param | Type | Description |
---|---|---|
id | string | Role identification |
role.getId() ⇒ string
Returns this Role id
Kind: instance method of Role
Returns: string - id - Role id
role.setParents(parents) ⇒ Role
Sets role parents.
Kind: instance method of Role
Returns: Role - this instance for chaining
Throws:
- Error if one of the given parents was not declared before
Param | Type | Description |
---|---|---|
parents | Array.<string> | Array.<Role> | null | Role parents: must be declared as individual roles before |
role.getParents() ⇒ Array | Array.<Role>
Returns parents roles of this instance
Kind: instance method of Role
role.getParent(role) ⇒ Role | null
Get a parent from this role
Kind: instance method of Role
Returns: Role | null - null if parent role was not found
Param | Type | Description |
---|---|---|
role | Role | string | id or role instance to retrieve |
role.addParent(role) ⇒ Role
Add parent to this role. If it already exists in parents list, it will be replaced
Kind: instance method of Role
Returns: Role - this instance for chaining
Throws:
- Error if no Acl was attached to this role or if parent was not declared previously
Param | Type | Description |
---|---|---|
role | Role | string | Parent Role instance of its id |
role.addParents(roles) ⇒ Role
Add an array of parents role to this instance
Kind: instance method of Role
Returns: Role - this instance for chaining
Throws:
- Error if no Acl was attached to this role or if one parent was not declared previously
Param | Type | Description |
---|---|---|
roles | Array.<Role> | Array.<string> | to add as parents to this instance |
role.removeParent({Role|string) ⇒ Role
Remove a parent from the list of this role's parents
Kind: instance method of Role
Returns: Role - this instance for chaining
Param | Description | |
---|---|---|
{Role | string | role Parent role isntance or its role id |
role.removeParents(roles) ⇒ Role
Remove a role from parent list
Kind: instance method of Role
Returns: Role - this instance for chaining
Param | Type | Description |
---|---|---|
roles | Array.<string> | Array.<Role> | to remove from parents list |
role.toString() ⇒ string
Returns
Kind: instance method of Role
Returns: string - - role Id
Resource
Kind: global class
Trows: Error if privileges is not an Array of strings
new Resource(id, privileges)
Constructor
Param | Type | Description |
---|---|---|
id | string | of this Resource |
privileges | Array.<string> | access privileges for this resource |
resource.setId(id) ⇒ Resource
Sets this resource Id
Kind: instance method of Resource
Returns: Resource - instance for chaining
Throws:
- Error if id is not a string
Param | Type |
---|---|
id | string |
resource.getId() ⇒ string
Retrieve resource id
Kind: instance method of Resource
Returns: string - id of this resource
resource.getPrivileges() ⇒ Array.<string>
Retrieve access privileges for this resource
Kind: instance method of Resource
Returns: Array.<string> - Array of access privileges
resource.setPrivileges(privileges) ⇒ Resource
Sets access privileges for this resource
Kind: instance method of Resource
Throws:
- Error if privileges is not an array of strings
Param | Type | Description |
---|---|---|
privileges | Array.<string> | to set |
resource.addPrivilege(privilege) ⇒ Resource
Add an access privilege to this resource
Kind: instance method of Resource
Throw: Error - if privilege is not a string
Param | Type |
---|---|
privilege | string |
resource.removePrivilege(privilege) ⇒ Resource
Removes access privilege from this resource
Kind: instance method of Resource
Returns: Resource - - this instance
Param | Type | Description |
---|---|---|
privilege | string | access privilege to remove |
8 years ago
8 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago