OptimalBits / node_acl

Access control lists for node applications
2.62k stars 369 forks source link

MongoDB backend not generating resource and permission databases #194

Open PeterQFR opened 8 years ago

PeterQFR commented 8 years ago

Hi when implementing acl.middleware() in a route, It is not allowing my user to access the route. The permissions are:

   acll = new acl(new acl.memoryBackend());
    //Allow user to read update and delete their account
    acll.allow([
            {
            roles: ['registered'],
            allows:[
                    {resources: 'user', permissions:['put', 'get', 'delete']},
                    {resources: 'device/assign', permissions:['put']},
                    {resources: '/owner', permissions:['get']}
                    ]
            }]);

And the route:

                        router.get('/owner',
                    acll.middleware(), 
                    function(req, res){
            console.log("Params:" + req.params.user_email);
            console.log("ACL Auth " + req.session);
            console.log("Getting userID: ", req.session.userId);
            console.log("Url " + req.url);

in my req.sessions I have a correct userId that aligns with the key in the backend.

I logged to the console the values being used in the acl.middleware() module as shown below (from line 601):

return function(req, res, next){
    var _userId = userId,
        _actions = actions,
        resource,
        url;
  +     console.log("UserID " + _userId);
  +     console.log("Resource " + actions);
    // call function to fetch userId
    if(typeof userId === 'function'){

but all the parameters including userId and actions are undefined.

PeterQFR commented 8 years ago

Okay firstly I was taking my debugging statements from the wrong part of the code. Further down acl.js around lines 642 or so, the middleware has successfully extracted the data in the req. There were some issues with the formatting and routenames they are fixed.

However it is still not working in that the acl.isAllowed function is not returning true.

This was resolved due to an error that when adding roles to the id I was using JSON.stringify which prepended and appended %22 or " to the Id. Therefore acl.isAllowed would not match the id as they would be "id" in the backend.

PeterQFR commented 8 years ago

This was resolved by just casting to String: String(id) when adding the id to roles.

PeterQFR commented 8 years ago

Actually it is only working with the Memory backend. It doesn't work with the Mongoose backend, I am having the same issues. Will try with the redis backend for persistence.

I'm trying to follow the setting up of resources and permissions for the mongo db backend, but in the acl_ collections there is no explicit definition of the resources and the permissions. eg.

In acl_roles collection I have:

> db.acl_roles.find()
{ "_id" : ObjectId("5772030e6ce60eedb475eeaf"), "key" : "unverified", "%225772030e1add961d2270ffa2%22" : true, "%22577207fb80f54baa2480326b%22" : true, "%225773089cf4f4ffe3137c8987%22" : true, "%22577309e78a241ac215bbf871%22" : true, "%2257730c83ca19f84617d94409%22" : true, "%2257730eeeca19f84617d9440a%22" : true, "%2257730facca19f84617d9440b%22" : true, "%225773124e3b0891cd1a07a7a4%22" : true, "%22577314593d4000101c401daa%22" : true, "%2257731538df0a60b41c9fb896%22" : true, "%2257731a603e510e571de0d7c3%22" : true }
{ "_id" : ObjectId("57831e0977a8f4c916ca562d"), "key" : "registered", "%2257830d32dbda8aca29120d6e%22" : true, "%225783200d5116a46a2ee1c727%22" : true, "%22578329bc6cdfd2b72fd6d423%22" : true, "%2257832b5cc5b44b613050f33d%22" : true, "%2257832be8de5ff136313c9048%22" : true, "%225783327b2fee413c330cedd4%22" : true, "%2257833306cc7029bf33a864f2%22" : true, "%2257834b4cbbe7d27638b1f4a7%22" : true, "%2257834c96e1947213390bf041%22" : true, "%22578351dc1bfe06f3396341e2%22" : true, "578433c79c610e4950c8e25c" : true, "578434f59c610e4950c8e25d" : true, "5784389d165b13fb526c3480" : true, "57843942165b13fb526c3481" : true }

and in db.ac_meta.find()

{ "_id" : ObjectId("578438aa77a8f4c916ca563a"), "key" : "users", "5784389d165b13fb526c3480" : true, "57843942165b13fb526c3481" : true }

and in db.acl_users.find()

> db.acl_users.find()
{ "_id" : ObjectId("578438aa77a8f4c916ca563b"), "key" : "5784389d165b13fb526c3480", "registered" : true }
{ "_id" : ObjectId("5784394e77a8f4c916ca563c"), "key" : "57843942165b13fb526c3481", "registered" : true }

So I'm not sure where the resources and permissions are stored. In the code they are supposed to be stored in the backend, but I am unable to find them under my backend prefix.

I guess to recreate this bug is simply to open a route and try to use acl.middleware() with a mongoose backend.

PeterQFR commented 8 years ago

Just an update, tracking the data through the code. When isAllowed is called with a mongoose backend. The promise returned by backend.unionAsync on line 819 in acl.js, is empty with the mongodb backend, but with the memory backend returns 'get' the permission of the role and resource.