npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

rest-guard

v1.0.5

Published

Library for Access Control to REST services in NODEJS

Downloads

4

Readme

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');
...
//rest-guard middleware
app.use('api_root', restGuard.middleware);
...
//your api endpoint
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) {
        //you must provide an Array of user's credentials.        
        var userCredentials = ['admin', '60D15600Dec75a735051560D', 'share_link_id'];
         var err = null;
        callback(err, userCredentials);
    });

Permission storage configuration.

var db = yourMongoose; // mongoose
policyService.configureStorage(db, 'permissions_collection');

Models parenting and owner definitions.

First, you must define your models parenting and owner properties:

//Configuring model data owners, parenting;
//The field that represents the owner of Business is user.
var owners = ['Business.user'];
//Branch is parent of Promotion, Business is parent of Branch. 
//Business has not parent.
//With this relationship, Promotion owner is the same as Business.
var parenting = {'Branch.business': 'Business', 'Promotion.branch': 'Branch'};

restGuard.setModelOwnerFields(owners);
restGuard.setModelParentingFields(parenting);

Policy definition.

To define access you must create policies first:

//Policy over path /Promotion and method GET. 
//The method GET has an alias: ReadAll.
//The policy id is ReadAll_Promotion.

//parameters: [Model, actionAlias, uri, method]
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.

// parameters: 
//    [roles], 
//    [GET_Alias, POST_Alias, PUT_ALIAS, DELETE_Alias, * (all)], 
//    resource
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'};
    //accepts object or Array
   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', 
     //parent could be direct parent id or ancestor id.
     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


/**
* @param modelOwnersFields, an Array of string with 
* 'Model.ownerField' format.
*/
function setModelOwnerFields(modelOwnersFields);

/**
* @param modelOwnersFields, an Object with properties with 
* 'Model.parentField': 'ParentModel' format.
*/
function setModelParentingFields(modelOwnersFields);

/**
* Prints policies Object.
*/
function printPolicies();
/**
* Prints roles Object.
*/
function printRoles();

/**
 * @param model, the Model's name.
 * @param actionAlias, alias for uri/method.
 * @param uri, the route.
 * @param httpMethod, the http method
 */
function createPolicy(model, actionAlias, uri, httpMethod);

/**
* Returns policies count.
*/
function policiesCount();

/**
* When a policy is created, if the uri has a param 
* you could define if is the resource id.
*/
function setResourceIdFromUri(param);

/**
* When a policy is created, if the uri has a param 
* you could define if is the resource owner id.
*/
function setResourceOwnerIdFromUri(param);

/**
* When a policy is created, if the uri has a param 
* you could define if is the resource parent id.
*/
function setResourceParentIdFromUri(param);

/**
* When a policy is created, if the req.body has a param 
* you could define if is the resource id.
*/
function setResourceIdFromBody(param);

/**
* When a policy is created, if the req.body has a param 
* you could define if is the resource owner id.
*/
function setResourceOwnerIdFromBody(param);

/**
* When a policy is created, if the req.body has a param 
* you could define if is the resource parent id.
*/
function setResourceParentIdFromBody(param);

/**
* When a policy is created, if the req.query has a param 
* you could define if is the resource id.
*/
function setResourceIdFromQuery(param);

/**
* When a policy is created, if the req.query has a param 
* you could define if is the resource owner id.
*/
function setResourceOwnerIdFromQuery(param);

/**
* When a policy is created, if the req.query has a param 
* you could define if is the resource parent id.
*/
function setResourceParentIdFromQuery(param);


/**
 * To grant access roles.
 * @param roles sting or Array of string
 * @param methods Array of string (get, post, put, delete)
 * @param model modelName
 */
function grantRoles(roles, methods, model);

/**
 * To revoke access roles.
 * @param roles sting or Array of string
 * @param methods Array of string (get, post, put, delete)
 * @param model modelName
 */
function revokeRoles(roles, methods, model);

/**
 * Grant permission to an user.
 * @param permissions {user, resource:{id | owner | parent}, action}
 * @param callback
 */
function grantPermission(permissions);

/**
 * Grant permission to an user.
 * @param permissions {user, resource:{id | owner | parent}, action}
 * @param callback
 */
function revokePermission(permissions);

/**
 * Function to get an Array of user ids, like id, role, alias, 
 * (whatever you define).
 * @param userCredentialsFn =  
 *function(callback){ ...; var ids=[];...; callback(ids);}
 * 
 */
function userCredentialsFn(userCredentialsFn);

/**
* Middleware that allow or deny REST API.
*
*/
function middleware(req, res, next);

/**
 * Grant access to the endpoint represented by action_model, 
 * ignoring all permissions.
 * @param model
 * @param action
 * @returns {*}
 */
function grantAccess(modelName, actionName);

/**
 * Deny access to the endpoint represented by action_model, 
 * ignoring all permissions. 
 * @param model
 * @param action
 * @returns {*}
 */
function denyAccess(modelName, actionName);

/**
 * Default access to the endpoint represented by action_model, 
 * looking for permissions to allow access. 
 * @param model
 * @param action
 * @returns {*}
 */
function defaultAccess(modelName, actionName);

/**
*@param role, the role 
*/
function hasRolePolicyPermission(role);

/**
 * Get the roles permission object.
 * @param role
 * @returns {*|{}}
 */
function getRolesPermissions (role);


/**
* var to specify that a Role can access all methods.
*/
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.