2.0.6 • Published 7 years ago

dynamic-acl v2.0.6

Weekly downloads
2
License
ISC
Repository
github
Last release
7 years ago

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

new Acl(roleIdFetchFunc, resourceIdFetchFunc)

Constructor

ParamTypeDescription
roleIdFetchFuncfetchRoleIdFuncfunction that will let Acl fetch Role id (default will return empty string)
resourceIdFetchFuncfetchResourceIdFuncfunction 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

ParamTypeDescription
funcfetchRoleIdFuncthat 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

ParamTypeDescription
funcfetchResourceIdFuncthat 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
ParamTypeDescription
roleRole | stringinstance to add
ParentsArray.<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

ParamType
roleRole | 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

ParamTypeDescription
idstringof 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
ParamTypeDescription
resourceResourceto 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
ParamTypeDescription
resourceResource | stringto 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

ParamTypeDescription
idstring | Resourceof 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

ParamTypeDefaultDescription
roleIdstring | RoleRole Id or Role instance
resourceIdstring | ResourceResource Id or Resource instance
privilegestring | Array.<string>"*"Privilege (default is '*' all)
conditionpermissionConditionFuncConditional 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

ParamTypeDefaultDescription
roleIdstring | RoleRole Id or Role instance
resourceIdstring | ResourceResource Id or Resource instance
privilegestring | Array.<string>"*"Privilege (default is '*' all)
conditionpermissionConditionFuncConditional 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

ParamTypeDefaultDescription
allowbooleantrue = allowed, false = denied
roleIdstring | RoleRole Id or Role instance
resourceIdstring | ResourceResource Id or Resource instance
privilegestring"*"Privilege (default is '*' all)
conditionpermissionConditionFuncConditional 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

ParamTypeDefault
user*
resource*
privilegestring"*"

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

ParamTypeDefault
roleIdstring
resourceIdstring
privilegestring"*"

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

ParamType
roleIdstring
resourceIdstring
privilegestring

acl.getPermissions(roleId) ⇒ Array.<Object>

Returns an object representing roleId permissions

Kind: instance method of Acl
Returns: Array.<Object> - Permissions for each resource

ParamType
roleIdstring | 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
ParamTypeDefaultDescription
idstringrole's id
parentsArray.<string> | Array.<Role>list of parents
aclAclACL 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

ParamType
aclAcl

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
ParamTypeDescription
idstringRole 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
ParamTypeDescription
parentsArray.<string> | Array.<Role> | nullRole 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

ParamTypeDescription
roleRole | stringid 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
ParamTypeDescription
roleRole | stringParent 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
ParamTypeDescription
rolesArray.<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

ParamDescription
{Rolestringrole 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

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

ParamTypeDescription
idstringof this Resource
privilegesArray.<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
ParamType
idstring

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

ParamType
privilegestring

resource.removePrivilege(privilege) ⇒ Resource

Removes access privilege from this resource

Kind: instance method of Resource
Returns: Resource - - this instance

ParamTypeDescription
privilegestringaccess privilege to remove
2.0.6

7 years ago

2.0.5

7 years ago

2.0.4

8 years ago

2.0.3

8 years ago

2.0.1

8 years ago

2.0.2

8 years ago

2.0.0

8 years ago

1.2.0

8 years ago

1.1.0

8 years ago

1.0.10

8 years ago

1.0.9

8 years ago

1.0.8

8 years ago

1.0.7

8 years ago

1.0.6

8 years ago

1.0.3

8 years ago

1.0.2

8 years ago

1.0.1

8 years ago

1.0.0

8 years ago