JSPM

  • Created
  • Published
  • Downloads 398
  • Score
    100M100P100Q94237F
  • License MIT

Attribute Based Access Control Library

Package Exports

  • abacl
  • abacl/dist/index.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (abacl) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

Attribute Based Access Control Library

npm Coverage Snyk Vulnerabilities for GitHub Repo npm node-current GitHub semantic-release: angular code style: prettier Gitter documentation Build, Test and Publish

The Attribute-Based Access-Control Library let you define five can access ability:

  • Who can? the answer is subject - Like RBAC a user can have multiple roles.
  • How can it? the answer is action - You can define any actions you want (scoped).
  • What can? the answer is object - You can define all objects you want (scoped).
  • Where can? the answer is location - With IP and CIDR you can find the location of users.
  • When can it? the answer is time - objects availabilities with cron expression and a duration.

Quick Start Guide

Read more on defining scoped action and object ability in this link.

installation

npm install --save abacl

Usage

Define your user abilities as a json array, so you can store it in your database:

import { Ability } from 'abacl';

enum Role {
  Admin = 'admin',
  User = 'user',
  Guest = 'guest',
  Manager = 'manager',
}

const abilities: Ability<Role>[] = [
  {
    subject: Role.Admin,
    action: 'any',
    object: 'all',
  },
  {
    subject: Role.Guest,
    action: 'read',
    object: 'article:published',
  },
  {
    subject: Role.Manager,
    action: 'any',
    object: 'article',
  },
  {
    subject: Role.User,
    action: 'create:own',
    object: 'article',
    field: ['*', '!owner'],
    location: ['127.0.0.1', '192.168.1.0/24'],
    time: [
      {
        cron_exp: '* * 8 * * *',
        duration: 20 * 60 * 60,
      },
    ],
  },
  {
    subject: Role.User,
    action: 'read:own',
    object: 'article',
  },
  {
    subject: Role.User,
    action: 'read:shared',
    object: 'article',
    filter: ['*', '!id'],
  },
  {
    subject: Role.User,
    action: 'delete:own',
    object: 'article',
  },
  {
    subject: Role.User,
    action: 'update:own',
    object: 'article',
    field: ['*', '!owner'],
  },
];

Article and User definition objects:

const user = {
  id: 1,
  subject: Role.User,
  ip: '192.168.1.100',
};

const article = {
  id: 1,
  owner: 'user1',
  title: 'title',
  content: 'content',
};

Create a new access control object, then get the permission grants:

import AccessControl from 'abacl';

// The `strict` `AccessControlOption` control the scoped functionality
// default strict value is true, you can change it on the `can` method

const ac = new AccessControl(abilities, { strict: false });
const permission = ac.can([user.subject], 'read', 'article');

// change strict mode dynamically, Example:
// const strictPermission = ac.can([user.subject], 'read', 'article', undefined, { strict: true });

/**
 *   it('should change strict mode dynamically', () => {
 *     const ac = new AccessControl(abilities, { strict: true });
 *
 *     expect(ac.can([Role.User], 'read', 'article:published').granted).toBeFalsy();
 *
 *     // After changing strict mode
 *     expect(ac.can([Role.User], 'read', 'article:published', undefined, { strict: false }).granted).toBeTruthy();
 *   });
 *
 * */

if (permission.granted) {
  // default scope for action and object is `any` and `all`

  if (permission.has('own')) {
    // Or pattern 'own:.*'
    // user has read owned article objects
  }

  if (permission.has('shared')) {
    // Or pattern 'shared:.*'
    // user can access shared article objects
  }

  if (permission.has('published')) {
    // Or pattern '.*:published'
    // user can access shared article objects
  }

  // do something ...

  // get grants by pattern 'shared' or 'shared:.*'
  // pattern: [action_scoped_regex]:[object_scoped_regex]
  const response = permission.filter(article); // OR
  const response = permission.grant('shared').filter(article);

  // Now response has no `id` property so sent it to user
}

Time and location access check example:

import { Permission } from 'abacl';

// default `strict` value is true
const ac = new AccessControl(abilities, { strict: true });

const permission = ac.can([user.subject], 'create', 'article', (perm: Permission) => {
  return perm.grant('own').location(user.ip) && perm.grant('own').time();
});

if (permission.granted) {
  const inputData = permission.field(article); // OR
  const inputData = permission.grant('.*').field(article);

  // the `inputData` has not `owner` property
  // do something and then return results to user
}

Thanks a lot

accesscontrol - Role and Attribute based Access Control for Node.js

CASL is an isomorphic authorization JavaScript library which restricts what resources a given user is allowed to access.

License

MIT