identity

Identity client

IDENTITY PLUGIN V4

This plugin includes 3 parts:

  1. Grunttask
  2. Openrecord Plugin
  3. Actionhero Plugin

The grunttask is for synchronising roles, role_entiteies and values. Values will be synchronized automatically if your define it in your openrecord model. (see: OpenRecord Plugin/Value Sync). The OpenRecord plugin enhances your model definition to also support permissions. Permissions will be applied to find, create, update and destroy. The actionhero plugin handles the OAuth2 handshake, user and sessions management, communication with other identity apps ans some more.

after installing identity your config folder should contain a identity.js config file. Every identity client has an id and secret to authenticate the application. Additionally every application has multiple roles, entities and values. An identity user can have multiple roles and every role could have multiple entities attached to it. set simplifyAdminRole to true, to combine the admin and application_admin role into admin.

Now you could grant User X permissions to Project A and B via the admin web interface of identity.

  • be sure to enable the plugin within actionhero (config/api.js)
  • you will need to add the identity package (npm install identity --save) to your package.json
`identity:sync`
`identity:values:resync`

grunt.login(callback) gives you a login prompt + starts the actionhero server.

var done = this.async()
grunt.login(function(apiaccess_tokenuser){
  if(!access_token){
    return done(false);
  }
});
    this.permission({
        role_name: true/false //global allow/deny 
        role_name: {
            find: true/false, //allow/deny a specific operation 
            findfunction(){
                //inside a beforeFind hook 
            },
            findfunction(querynext){
                //inside a async beforeFind hook 
            },
            
            create: true/false
            createfunction(){
                //inside a beforeCreate hook 
                //don't forget to call: this.errors.add('insufficient_permissions'); 
                return true/false
            }           
            createfunction(recordtransactionnext){
                //inside a beforeCreate hook 
                //don't forget to call: this.errors.add('insufficient_permissions'); 
                next(true/false);
            }
            
            //same for update, destroy 
            //modify includes create, update and destroy 
                
            fields: {
                all: true/false //globall allow/deny - it's true by default 
                field_name: true/false //allow/deny a specific field 
                field_name: 'find' //allow only find 
                field_name: ['find', 'create'] //allow find and create, 
                field_namefunction(){return true/false} //with custom function - no support for async functions! 
            }
        }
    })
    this.identityValue('entity_name', function(){ //optional function to control which records should be synced 
        return true/false (record scope)
    }); //in definition 

/api/oauth

/api/login, /api/logout, /api/profile, /api/user actions

connection.user is the current user

The User Model has the following helper methods:

  • .hasRole(role_name): boolean
  • .getValues(entity_id[, role]): array
  • .hasValue(entity_id, id[, role]): boolean
  • `.fromGroup(entity_id, id, role): object {name: 'GroupName', id:1}

connection.session is a object which will be saved into the actionhero cache.

requireAuth: true/false, requireRole: 'admin' / ['admin', 'lead']

the whole identity server is available via http://yourapp.com/api/identity/*. e.g. http://yourapp.com/api/identity/users and will only return values which belongs to the application

api.identity.application('application_name').get('action', {param:'value'}, callback) api.identity.application('application_name').post('action', {param:'value'}, callback) api.identity.application('application_name').put('action', {param:'value'}, callback) api.identity.application('application_name').delete('action', {param:'value'}, callback)

Test-Setup:

/test
    _setup.js
    actions/
    fixtures/
        sql/
            clear.sql
            default.sql

_setup.js

require('identity/spec_helper'); //require identity spec_helper 
 
before(test.startActionhero); //starts actionhero + initializes the database 
after(test.stopActionhero); //stops actionhero 
 
//add as many users as you need for your tests 
test.addUser('admin', {
  id: 1, //user's id 
  first_name: 'Administrator',
  last_name: 'Admin',
  permissions: [{ //array of permissions 
    role_id: 'admin', //role 
    values: {} //values. e.g. {domain: [1, 2, 3]} 
  }]
});

clear.sql

DROP TABLE openrecord_migrations;
# drop your tables and views here 

default.sql

# add your test data here 

Global object test has the following methods: test.action(name[, params, connectionParams], callback) test.loginAs(username).action(name, params, callback)

There are 2 callback-helpers: test.insufficientPermissions(callback) test.emptyResult(callback)

e.g. to test for insufficient permissions:

  it('"projects:destroy" should fail', function(done){    
    test.loginAs('user').action('projects:destroy', {id: 1}, test.insufficientPermissions(done));
  });