Structural role management in a meteor application with alanination: roles

I need some tips for building the right role and management scheme in my meteor application.

Structure

  • I use alanning: roles@1.2.13 to add role management functionality to the application.
  • There are four different user types: Admin, Editor, Expert, and User.
  • In addition, there are several modules with different content, i.e. machines, math and images. Each module is organized in its own meteor packet.
  • Each module has several categories that can be dynamically added by editors.

Categories in modules

The module is structured as follows:

 elementSchema = new SimpleSchema({ element: {type: String, optional: true} }); Cars.attachSchema(new SimpleSchema({ title: { type: String }, content: { type: String }, category: { type: [elementSchema], optional: true }, }); 

As you can see, all available categories are inside the module collection.

The rights

  • Administrator: full rights
  • Editor: can edit elements in selected modules (i.e. editor_1 can edit elements in machines and images, but not for mathematics)
  • Expert: can get rights to the full module or only to some categories of the module (i.e.) expert_1 can edit images, but only elements in the "Honda" and "Mercedes" categories in Cars; without editing in Maths).
  • User: no editing

Here is how I do authentication technically:

router.js

 var filters = { authenticate: function () { var user; if (Meteor.loggingIn()) { this.layout('login'); this.render('loading'); } else { user = Meteor.user(); if (!user) { this.layout('login'); this.render('signin'); return; } this.layout('Standard'); this.next(); } } } Router.route('/car/:_id', { name: 'car', before: filters.authenticate, data: function () { return { cars: Cars.findOne({ _id: this.params._id }) }; } }); 

template

 <template name="car"> {{#if isInRole 'cars'}} Some form for editing {{else}} <h1>Restricted area</h1> {{/if}} </template> 

I put this router.js in every package. Only change is a data function that uses a collection of each package (cars, math, images).

Update: as Eliezer Steinbock said, you must restrict access to mongoDB itself. But so far I have only done this on routes.

permissions.js

 Cars.allow({ insert: function(userId) { var loggedInUser = Meteor.user() if (loggedInUser && Roles.userIsInRole(loggedInUser, ['admin','editor'])) return true; }, update: function(userId) { var loggedInUser = Meteor.user() if (loggedInUser && Roles.userIsInRole(loggedInUser, ['admin','editor'])) return true; } }); 

My problems

1) My first problem is how to use roles and groups. What would be the best way to use groups? And the second problem is that the modules do not have fixed categories. Right now, I have no idea about a useful role / group scheme.

2) How to check the roles? Since there are different roles that can be accessed: administrator, editor and expert. I also had a problem with these experts, who simply get access to certain categories of this module.

3) Isn't it better to make permission.js more general. I mean, is it possible to make a dynamic function, so I do not need to put the same code everywhere? How to implement roles in .js resolution in a useful way?

+7
javascript authentication meteor roles simple-schema
source share
1 answer

If the logic for permissions is the same, you can simply define it once in permissions.js

 App = App || {}; // We are using Namespaces, so you don't have to.. but it good App.Permissions = { insert: function(userId) { var loggedInUser = Meteor.user() if (loggedInUser && Roles.userIsInRole(loggedInUser, ['admin','editor'])) return true; }, update: function(userId) { var loggedInUser = Meteor.user() if (loggedInUser && Roles.userIsInRole(loggedInUser, ['admin','editor'])) return true; } } 

And then you can use it for your collections:

 Cars.allow(App.Permissions); // Or Cars.allow(App.Permissions.getPermissionsForGroup('cars')) 

Define roles somewhere ..

Roles

 // Give user the role "editor" in "cars" group Roles.addUsersToRoles(someUserId, ['editor'], 'cars'); Roles.addUsersToRoles(someOtherId, ['admin'], 'cars'); 

What can you prepare in permissions.js as follows:

Permissions

 App = App || {}; App.Permissions = { insert: function(userId) {...}, update: function(userId) {...}, getPermissionsForGroup: function(group) { return { insert: function(userId, doc) { // Only admin can insert return Roles.userIsInRole(userId, "admin", group); }, update: function(userId, doc, fields, modifier) { // Editor & Admin can edit return Roles.userIsInRole(userId, ["editor","admin"], group); }, remove: function(userId, doc) { // Only admin can remove return Roles.userIsInRole(userId, "admin", group); } } } 

In this example, admins can be inserted and updated .. and editors can be updated, but inserted.

Regarding the Alaning documentation: the roles you define and use such roles:

 // Super Admin definition.. Roles.addUsersToRoles(superAdminId, ['admin'], Roles.GLOBAL_GROUP); Roles.addUsersToRoles(joesUserId, ['manage-team','schedule-game'], 'manchester-united.com') Roles.addUsersToRoles(joesUserId, ['player','goalie'], 'real-madrid.com') Roles.userIsInRole(joesUserId, 'manage-team', 'manchester-united.com') // => true Roles.userIsInRole(joesUserId, 'manage-team', 'real-madrid.com') // => false 

Yes, make sure that permission logic is enabled before defining your collection. Obviously :)

+8
source share

All Articles