bookshelf-shield
Form a protective shield around your bookshelf models. This module adds ACL-based authorization, and a CRUD API to bookshelf models.
Dependencies
relations
As of right now, bookshelf-shield only can interact with the ACL module called relations Provides an intuitive interface for storing and querying Access Conrtol Lists. Relations is used to determine whether a user has been granted access to perform an action on the model.
ES6
This module utilizes ES6 features, including classes, arrow functions and Promises. As a result node 4.0.0+ is required.
Usage
- Set up your ACL
relations;
- Set up you bookshelf models
const models = Study: bookshelfModel //...;
- Create a shieldConfig for each model (see configuration section for more)
const config = defaults: modelName: 'Study' authKey: 'id' aclContextName: 'study' //optional action-specific configs here //...
- Shields up!
const shield = ;;
API
Once a model has been shielded, you can interact with it using a standard CRUD API, rather than the traditional fetch, save, destroy
bookshelf API. This was implemented to more easily map to user's permissions.
- create
const user = username: 'dylan' ; const widget = color: 'blue' ; widget;
- read
const user = username: 'dylan' ; const widget = id: '101' ; widget;
- readAll
const user = username: 'dylan' ; const widget = ; widget; widget;
- update (note: by default, read access is required to perform an update)
const user = username: 'dylan' ; widget; widget;
- delete (note: by default, read access is required to perform a delete)
const user = username: 'dylan' ; const widget = id: '101' ; widget;
- bypass
const widget = id: '101' ; widget;
Configuration
Each model to be shielded requires a config object. During initialization, these config objects should be provided as an array. Here is an example config object:
moduleexports = defaults: // These defaults will be applied to all CRUD access methods, unless overridden below. modelName: 'Study' // The name of the model: must match the key associated with the model in the models object passed to shield init. authKey: 'id' // The property that should be used for authorization. aclContextName: 'study' // The name of the ACL (relations) context to be used create: //specifying any CRUD method allows you to override the defaults secified above authKey: 'siteId' //alternative auth key to be used when evaluating create access aclContextName: 'site' { // this is a cusom authentication method that will be invoked instead of the generic method. // `this` refers to the current instance of the bookshelf model const siteId = this; // data stored on the shield can be accessed through the current object's constructor (the bookshelf Model). const Model = thisconstructor; const aclContext = Modelshieldaclsite; const aclQuestion = 'can ' + userusername + ' create_Study from ' + siteId; if !siteId return Promise; return ; } ;
Because there are no configuration objects specified for read
, update
and delete
operations, those operations will be protected using the generic method (see below).
Generic Auth Method
Unless a custom method is specified in the Model's config, the following generic method will be applied:
// Note options is the config for the current Model and action { const authVal = this; const aclQuestion = 'can ' + userusername + ' ' + permissionName + ' from ' + authVal; const aclContext = optionsaclaclContextName; //TODO: optimize to cache perms instead of loading from redis return ;
Examples
See test/integration/main.js
for a full example
Tests
Fully unit and integration tested
Contributing
Please follow the MRN Javascript Style Guide (forked from AirBnB). Use grunt lint
to check yo-self