permissionary
v0.1.1
Published
Tiny and framework-agnostic role-based permission management using composition over inheritance
Downloads
13
Maintainers
Readme
Permissionary - bringing permissions to the lawless
Tiny and framework-agnostic role-based permission management using a model of composition over inheritance.
npm install --save permissionary
Usage
var {checkPermission, findRoles} = require('permissionary');
Philosophy
Many permission systems use the idea of inheritance to define roles in terms of other roles. This can lead to the definition of non-flexible roles where the developer has to make decisions that determine what will be possible in the future. Mattias Petter Johansson has a good video explaining the phenomenon.
To combat this issue, Permissionary has no inheritance. Instead, groupings of grants are given names (known as roles), and multiple such roles can be assigned to a user. This allows one to define very minimal roles (containing the minimum number of grants necessary to carry meaning) and define types of users as being compositions of multiple such roles. If at any point in the future, a new type of user is required that shares the responsibility of formerly unassociated roles, all you'd have to do was assign both roles to that user.
API
checkPermission :: StrMap (Array String) -> Array String -> String -> Boolean
A curried function that takes three arguments and returns a Boolean:
- A mapping from role names to an array of grants represented by glob patterns to match permission names.
- An Array of role names.
- A permission name.
The glob patterns will be filtered down to contain only those associated with the given list of roles. The permission will be checked against the filtered glob patters using micromatch to produce the Boolean.
To make optimal use of this function, it is recommended to partially apply the function to produce new functions, as shown in the example below:
// This defines a mapping from roles to permissions.
// We can use wildcards to assign multiple permissions at once.
> var createVerifier = checkPermission({
. 'content-reader': ['content.read', 'images.read'],
. 'content-writer': ['content.write', 'images.upload'],
. 'superadmin': ['*']
. })
// Let's say our user Bob is a content-reader, and also a content-writer.
> var canBob = createVerifier(['content-reader', 'content-writer'])
// And Alice is an administrator.
> var canAlice = createVerifier(['superadmin'])
// Bob has this permission through his content-reader role.
> canBob('content.read')
true
// Bob does not have this permission.
> canBob('users.create')
false
// Alice, however, does. She has all permissions (even the ones
// we haven't thought of yet).
canAlice('users.create')
true
findRoles :: StrMap (Array String) -> String -> Array String
A curried function that takes two arguments and returns an Array of role names:
- A mapping from role names to an array of grants represented by glob patterns to match permission names.
- A permission name.
This function can be used to answer the question: "Which role do I need to obtain a given permission?"
> var getRequiredRoles = findRoles({
. 'content-reader': ['content.read', 'images.read'],
. 'content-writer': ['content.write', 'images.upload'],
. 'superadmin': ['*']
. })
> getRequiredRoles('content.read')
['content-reader', 'superadmin']