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

aplusacl

v0.1.1

Published

AplusACL: the "A" is for "assertions". This means that instead of storing a record for every combination of role, resource and permission, we apply assertions that look to data already available.

Downloads

5

Readme

#AplusACL The "A" is for "assertions".

A+ACL is loosely modeled after Zend Framework's Zend_Acl package. The most significant difference between A+ACL and other NodeJs ACL modules, is that A+ACL is assertive, meaning that it provides a mechanism for making assertions when calling isAllowed().

Assertions allow us to assert based on all information already available rather than storing and retrieving granted privileges for each user/role, resource, and permission combination.

Getting started

  1. Install AplusACL
  2. Define roles, resources
  3. Grant permissions
  4. Apply assertions
  5. Query the ACL

##Installation npm install aplusacl

##Define Roles and Resources A+ACL is not opinionated in regards to roles, resources and permissions; it has no inherent idea what they are, only that they should exist. Therefore it is up to you to define them. For a "todo application" REST API, defining roles and resources can be done like so:

var AplusACL = require('aplusacl');
var aclConfig = {
  roles:['guest','user','admin'],
  resources:['users','todo']
};
var acl = new AplusACL(aclConfig);

Here we've simply defined our roles as 'guest', 'user', and 'admin', and we've defined our resources as:'users', and 'todos'. Note that it is up to you to determine what a user's role is.

##Grant Permissions Now that we've defined our roles and resources we can grant permissions to roles. A+ACL is not opinionated in regards to permissions, so it's up to us to define them under the property allows (continuing from previous example):

aclConfig.allows = [
  // a guest can create a user account but that is all
  {role:'guest', resource:'users', permissions:['create']},

  // a user can only get the details and update ( GET|PUT /users/:id)
  // a user cannot list, create, or delete users
  {role:'user', resource:'users', permissions:['detail','update']},

  // a user has full access to the todos resource
  {role:'user', resource:'todos', permissions:['list','detail','create','update','delete']},

  // an admin has full permissions to all resources
  {role:'admin', resource:'users', permissions:['list','detail','create','update','delete']},
  {role:'admin', resource:'todos', permissions:['list','detail','create','update','delete']}
];

##Apply Assertions In the previous configuration, we granted the user role the ability to get the details of and update a users record. We also gave the user full access to the todos resource, but what prevents one user from looking at or updating another user's record or todos? An assertion does!

Assertions are named using the following pattern:{role}_can_{privilege}_{resource}. We will add an assertion to test whether a user owns the user records they are trying to detail or update.


aclConfig.assertions = {
  // here params is a reference to arbitrary data, they could be req.query or req.body
  user_can_detail_users: function (user, resource, options) {
    // user is perhaps an instance of a mongoose user model and is the one currently authenticated
    // assert that the logged in user owns the requested resource
    return (user._id === options.id) // request.params was passed in as options to isAllowed()
  },

  user_can_list_todos: function (user, resource, options) {
    // user is perhaps an instance of a mongoose user model
    // users can only list their own todos
    // assert that the user query string param is the same as the authenticated user
    return (user._id === options.user); // request.query was passed in as options to isAllowed()
  }
}

##Query the ACL Now that our ACL is built, we can query it to determine if a user can perform privileged actions on the requested resource. Consider the following controller in a (Express+Mongoose powered) REST API:

var UserModel = mongoose.model('user');
var UsersControler = {

  // GET /users/:id
  detail: function (req, res) {
    // get the record
    UserModel.findById(req.params.id, function (err, doc) {
      if (!acl.isAllowed(req.session.user, doc, 'detail', req.params)) {
        return res.json(403, {error:"forbidden"});
      }

      res.json(200, doc);
    });
  }

  // PUT /users/:id
  update: function (req, res) {
    // get the record
    UserModel.findById(req.params.id, function (err, doc) {
      if (!acl.isAllowed(req.session.user, doc, 'update', req.params)) {
        return res.json(403, {error:"forbidden"});
      }

      res.json(204);
    });
  }
};

Note that A+ACL is not opinionated toward frameworks and inherently knows nothing of Express or Mongoose.