REST-GUARD
Library for Access Control to REST services in NODEJS.
Synopsis
The purpose of the library is to provide a lightweight library for access control to REST services.
Code Example
Middleware.
To denied all API endpoints access you must use the middleware:
vr app = require('express')();
var restGuard = require('rest-guard');
...
app.use('api_root', restGuard.middleware);
...
app.get('api_root/Promotion', your_callback);
User credentials.
You must define a function to get user credentials (id, role, share link, whatever you define)
restGuard.userCredentialsFn(function (req, callback) {
var userCredentials = ['admin', '60D15600Dec75a735051560D', 'share_link_id'];
var err = null;
callback(err, userCredentials);
});
Permission storage configuration.
var db = yourMongoose;
policyService.configureStorage(db, 'permissions_collection');
Models parenting and owner definitions.
First, you must define your models parenting and owner properties:
var owners = ['Business.user'];
var parenting = {'Branch.business': 'Business', 'Promotion.branch': 'Branch'};
restGuard.setModelOwnerFields(owners);
restGuard.setModelParentingFields(parenting);
Policy definition.
To define access you must create policies first:
restGuard.createPolicy('Promotion', 'ReadAll', '/Promotion', 'get');
at this point you have two options to grant access:
- assigning policies to roles.
- assigning policies to user and resources.
Assigning policies to roles.
restGuard.grantRoles(['admin'], [*], 'Model');
Assigning policies to user and resource.
You can define a resource's permission by id, owner, or parent.
By id.
var permission =
{user: '60D15600Dec75a735051560D',
resource: {id: '559806333ec75a390b407719'},
action: 'Read_Promotion'};
restGuard.grantPermission(permission);
By owner and parent (parent and ancestors).
You can define a resource permission by owner id:
var permission =
{user: '60D15600Dec75a735051560D',
resource: {owner: '559806333ec75a390b40771c'},
action: 'Read_Promotion'};
restGuard.grantPermission(permission);
Note: If the user is the owner of the resource, he will have full access. It is not necessary to define permission.
or by parent id:
var permission =
{user: '60D15600Dec75a735051560D',
resource: {parent: '559806333ec75a390b40771b'},
action: 'Read_Promotion'};
restGuard.grantPermission(permission);
and that's all. Your Rest API is guarded.
Additional features.
If you set the resource's id, owner or parent (or ancestor) in uri part, req.query or req.body as custom param,
you can define it as in the following examples:
restGuard.createPolicy('api/Model/:theId', ...).setResourceIdFromUri('theId');
//or
restGuard.createPolicy('api/Model/, ...).setResourceIdFromBody('theId');
//or
restGuard.createPolicy('api/Model', ...).setResourceIdFromQuery('theId');
in addition you could have the body/query request as follow:
//you could define body/query as a complex object (no depth restriction):
//your req.body = {query: {aResourceId: '60D15600Dec75a735051560D'}}
//you can define:
restGuard.createPolicy('api/Model', ...).setResourceIdFromBody('query.aResourceId');
//your req.body = {query: {subQuery:{aResourceId: '60D15600Dec75a735051560D'}}}
//you can define:
restGuard.createPolicy('api/Model', ...).setResourceIdFromBody('query.subQuery.aResourceId');
//even more, you could search over an stringified JSON object.
//your req.body = {query: '{"subQuery":{"aResourceId": "60D15600Dec75a735051560D"}}'}
//you can define:
restGuard.createPolicy('api/Model', ...).setResourceIdFromBody('query.subQuery.aResourceId');
Motivation
Security.
In other words, access to resource must be strong guarded by policies. Roles, users, or share links must be assigned to resource by policies.
Installation
Easy as npm install rest-guard.
API Reference
function setModelOwnerFields(modelOwnersFields);
function setModelParentingFields(modelOwnersFields);
function printPolicies();
function printRoles();
function createPolicy(model, actionAlias, uri, httpMethod);
function policiesCount();
function setResourceIdFromUri(param);
function setResourceOwnerIdFromUri(param);
function setResourceParentIdFromUri(param);
function setResourceIdFromBody(param);
function setResourceOwnerIdFromBody(param);
function setResourceParentIdFromBody(param);
function setResourceIdFromQuery(param);
function setResourceOwnerIdFromQuery(param);
function setResourceParentIdFromQuery(param);
function grantRoles(roles, methods, model);
function revokeRoles(roles, methods, model);
function grantPermission(permissions);
function revokePermission(permissions);
function userCredentialsFn(userCredentialsFn);
function middleware(req, res, next);
function grantAccess(modelName, actionName);
function denyAccess(modelName, actionName);
function defaultAccess(modelName, actionName);
function hasRolePolicyPermission(role);
function getRolesPermissions (role);
var ALL = '*';
Tests
npm test
You can check test/permission-test.js to see examples.
Contributors
People, welcome aboard. You are invited to improve this library. We saw the need to guarantee resource guard over REST. Thank you in advance.
License
MIT License.