dynamic-acl

2.0.6 • Public • Published

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

<a name="Acl"></a>

Acl

This class holds all information about Roles, Resources and Permissions

Kind: global class

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

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.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

/dynamic-acl/

    Package Sidebar

    Install

    npm i dynamic-acl

    Weekly Downloads

    20

    Version

    2.0.6

    License

    ISC

    Last publish

    Collaborators

    • adnene