RBAC in Meteor

Meteor development fascinated me. So I continue to play with it. And again I found the case that made me think that I can try to do that a little better. So let’s talk about access control in meteor js.

Meteor allows us to control low level mongo operations via collection.allow and collection.deny. But obviously that it’s not convenient because there’s no way how could I check certain right before actual DB operation. I mean I cannot check if user with “author” role can update its own article.

Ok let’s see what can we do to improve situation with access control in meteor.

Ok let’s see what we can find in atmosphere.js. I think the most popular package is alanning:roles I also started using it. It allows to assign roles to user and check access like this

Roles.userIsInRole(user, [‘admin’,’manage-users’])

Not bad… I’m not trying to advertise myself and all subsequent thought is just my personal opinion. I was confused with this syntax, it’s a mix of roles and actually permissions. Of course this is not end of the world… but I dislike it.

But the biggest drawback of this approach is following. We need to assign all allowed roles for each user. And this is not DRY approach. For example I have two users with “author” role. And say that accordingly to business logic of my app “authors” can add new article, update their own articles, manage comments to their articles. So if we know that user has “author” role we suppose that this user can do all these actions. And there’s no need to assign all that “subroles” (“add-article”, “update-article”, etc) for each user, all we need to know is basic user’s role.

The next question that I had is now can I check access to certain resource, like updating of own post. Tell me how can I do that with alanning:roles ?

And also I’d like to have role inheritance so that admin can do everything what author can.

So I tried to create my custom package for this. This is my first meteor package ;).

Good artists copy, great artists steal(c) he-he. All that questions appeared because I used yii2 RBAC package in my php apps. And I really like that approach and experience. So i tried to adapt it to meteor.

For the impatient – this is what I finally got meteor RBAC

I need to warn that at this moment I used it only in my toy project. And it’s not tested very well for different apps but I’m opened for issues.

You need to build your access control list and then you can check access for currently logged in user. You define roles and permissions, assign users to roles, and describe what permissions are allowed for roles.

rbac figure 1


    /*
        you have to save roles field to users collection so that
        Meteor.user() returns
        return {
            "_id": "54e45174cf36b30a26467890",
            // any other fields
            "roles": ["author", {more roles if needed}]
        }
    */

    // create lib/rbac.js and describe roles and rules
    // this is a small example. Review /tests/rbac-tests.js to see more examples.

    var rbac = new RbacManager({"defaultRoles": ['guest']});
    var authorRole = rbac.createRole("author");
    var adminRole = rbac.createRole("admin");

     var addArticle = rbac.createPermission("addArticle");
    // author can add article
    rbac.addChild(authorRole, addArticle);
    // now let's check that
    // test.isTrue(rbac.checkAccess("addArticle"));

    // create permission with rule callback
    var updateArticle = rbac.createPermission("updateArticle", function(user, article) {
        if (_.contains(user.roles, 'admin')) {
            return true;
        }

        return article.author_id == user._id
    });

    // author can update only its own article
    rbac.addChild(authorRole, updateArticle);
    // admin can do everything that author can
    rbac.addChild(adminRole, authorRole);

    var article = {
        "_id": "54e45174cf36b30a26445632",
        "author_id": "54e45174cf36b30a264e6724"
    };

    /** Assert meteor user returns
    Meteor.user = function() {
        return {
            "_id": "54e45174cf36b30a26467890",
            "roles": ["author"]
        }
    };
    */
    // test.isTrue(rbac.checkAccess("updateArticle", article));

I also added handlebars helper

    {{#if checkAccess "canAddReview"}}
        <button class="btn btn-primary btn-sm add-review">Add Review</button>
    {{else}}
        <a href="{{pathFor 'login'}}">Login</a> to add review
    {{/if}}

All details are available here meteor RBAC.

Repeat myself – I’m opened for issues. And I will appreciate any help of feedback.

One thought on “RBAC in Meteor

  1. Pingback: radzserg:rbac package | Atmosphere | CMDlineRambo

Leave a Reply

Your email address will not be published. Required fields are marked *