Saturday, 27 May 2017

node_acl: store acl globally to access from different modules

I'm trying to use acl within my node/express application.

My current main goal is to instantiate node_acl with a mongo backend and store it in a global place to consume it later on.

My current solution looks like:

server.js:

The application connects with mongodb and initialises acl and the routes.

mongoose.connect(config.db, (err, db) => {
   // initialize acl
   aclConfig(mongoose.connection.db);

   // initialize api
   routesConfig(app);
});

aclConfig()

Instantiation of acl and to store it in aclStore. Later we try to access this stored data.

import Acl from 'acl';
import aclStore from '../helper/acl-store';

export default(dbConnection) => {

    let acl = new Acl(new Acl.mongodbBackend(dbConnection, 'acl_'));

    // Set roles
    acl.allow([
        {
            roles: 'admin',
            allows: [
                {resources: '/adminonly', permissions: '*'}
            ]
        },
        {
            roles: 'user',
            allows: [
                {resources: '/api/events', permissions: 'GET'}
            ]
        }
    ]);

    aclStore.acl = acl;
}

AclStore

Just a basic class to set/get the acl.

class AclStore {
    constructor() {
        this._acl = null;
    }

    set acl(acl) {
        this._acl = acl;
    }

    get acl() {
        return this._acl;
    }
}

let aclStore = new AclStore();

export default aclStore;

I expected to be able to get my created instance from everywhere I want, by importing the aclStore and accessing acl. The solution does not work, if I try to apply aclStore.acl.middleware() on a route, see here:

import express from 'express';
import ctrl from './auth.ctrl';
import aclStore from '../../helper/acl-store';

const router = express.Router();

router.route('/adminonly')
    .put(ctrl.login, aclStore.acl.middleware());
    // --> TypeError: Cannot read property 'middleware' of null

export default router;

It returns:

TypeError: Cannot read property 'middleware' of null. It looks like it is instantiated before the data were set in aclConfig().

For me it looks like a "Timing issue", i.e. when I try to get aclStore.acl the aclConfig() method (intatiates acl and stores it in aclStore) is not executed yet.

I've found out that I have access to aclStore.acl if I would use it within the route controller ctrl.login(), i.e. data are stored properly in aclStore.

I'm trying to achieve the same solution like in this stackoverflow question, but in my case I've to handle it with a mongo db backend, i.e. I've to connect to mongodb first and use the db information data to instantiate acl.



via mbppv

No comments:

Post a Comment