Code Monkey home page Code Monkey logo

meteor-roles's Introduction

meteor-roles v3

Project Status: Active – The project has reached a stable, usable state and is being actively developed. GitHub JavaScript Style Guide CodeQL GitHub tag (latest SemVer)

Authorization package for Meteor - compatible with built-in accounts package.

There are also older versions of this package:


Table of Contents


Contributors

Thanks to:


Authorization

This package lets you attach roles to a user, which you can then check against later when deciding whether to grant access to Meteor methods or publish data. The core concept is very simple, essentially you are creating an assignment of roles to a user and then checking for the existence of those roles later. This package provides helper methods to make the process of adding, removing, and verifying those roles easier.


Permissions vs roles (or What's in a name...)

Although the name of this package is roles, you can define your roles, scopes or permissions however you like. They are essentially just tags that you assign to a user and which you can check upon later.

You can have traditional roles like, admin or webmaster, or you can assign more granular permissions such as, view-secrets, users.view, or users.manage. Often, more granular is actually better because you are able to handle all those pesky edge cases that come up in real-life usage without creating a ton of higher-level roles. With the roles package, it's all just a role object.

Roles can be put into a hierarchy. Roles can have multiple parents and can be children (subroles) of multiple roles. If a parent role is set to the user, all its descendants are also applying. You can use this to create "super roles" aggregating permissions all the way through the bottom of the tree. For example, you could name two top-level roles user and admin and then you could use your second-level roles as permissions and name them USERS_VIEW, POST_EDIT, and similar. Then you could set admin role as parent role for USERS_VIEW and POST_EDIT, while user would be parent only of the POST_EDIT role. You can then assign user and admin roles to your users. And if you need to change permissions later for the whole role, just add or remove children roles. You can create roles from this example with:

import { Roles } from 'meteor/alanning:roles';

Roles.createRole('user');
Roles.createRole('admin');
Roles.createRole('USERS_VIEW');
Roles.createRole('POST_EDIT');
Roles.addRolesToParent('USERS_VIEW', 'admin');
Roles.addRolesToParent('POST_EDIT', 'admin');
Roles.addRolesToParent('POST_EDIT', 'user');

What are "scopes"?

Sometimes it is useful to let a user have independent sets of roles. The roles package calls these independent sets "scopes" for lack of a better term. You can use them to represent various communities inside your application. Or maybe your application supports multiple tenants. You can put each of those tenants into their own scope. Alternatively, you can use scopes to represent various resources you have.

Users can have both scope roles assigned, and global roles. Global roles are in effect for all scopes. But scopes are independent of each other. Users can have one set of roles in scope A and another set of roles in scope B. Let's go through an example of this using soccer/football teams as scopes.

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

In this example, we can see that Joe manages Manchester United and plays for Real Madrid. By using scopes, we can assign roles independently and make sure that they don't get mixed up between scopes.

Now, let's take a look at how to use the global roles. Say we want to give Joe permission to do something across all of our scopes. That is what the global roles are for:

Roles.addUsersToRoles(joesUserId, 'super-admin', null); // Or you could just omit the last argument.

if (Roles.userIsInRole(joesUserId, ['manage-team', 'super-admin'], 'real-madrid.com')) {
  // True! Even though Joe doesn't manage Real Madrid, he has
  // a 'super-admin' global role so this check succeeds.
}

Changes to default Meteor behavior

  1. A new collection Meteor.roleAssignment contains the information about which role has been assigned to which user.
  2. A new collection Meteor.roles contains a global list of defined role names.
  3. All existing roles are automatically published to the client.

Installing

  1. Add one of the built-in accounts packages so the Meteor.users collection exists. From a command prompt:

    meteor add accounts-password
  2. Add this package to your project. From a command prompt:

    meteor add alanning:roles
  3. Publish the role assignments you need to the client:

    Meteor.publish(null, function () {
      if (this.userId) {
        return Meteor.roleAssignment.find({ 'user._id': this.userId });
      } else {
        this.ready()
      }
    })
  4. Run your application:

    meteor

Migration to 3.0

If you are currently using this package in a version older than 2.x, please upgrade to 2.0 by running the migration script required there: https://github.com/Meteor-Community-Packages/meteor-roles/tree/v2#migration-to-20

In meteor-roles 3.0, functions are mostly backwards compatible with 2.x, but roles are stored differently in the database. Please take a backup of the users collection before migrating. To migrate the database to the new schema, run Meteor._forwardMigrate2() on the server:

meteor shell
> Package['alanning:roles'].Roles._forwardMigrate2()

In case something fails, there is also a script available for rolling back the changes. But be warned that a backward migration takes a magnitude longer than a forward migration. To migrate the database back to the old schema, run Meteor._backwardMigrate2() on the server:

meteor shell
> Package['alanning:roles'].Roles._backwardMigrate2()

Changes between 2.x and 3.0

Here is the list of important changes between meteor-roles 2.x and 3.0 to consider when migrating to 3.0:

  • Role assignments have been moved from the users documents to a separate collection called role-assignment, available at Meteor.roleAssignment.
  • Role assignments are not published automatically. If you want all your role-assignments to be published automatically, please include the following code:
Meteor.publish(null, function () {
  if (this.userId) {
    return Meteor.roleAssignment.find({ 'user._id': this.userId });
  } else {
    this.ready()
  }
})
  • [BC] The behavior of getRolesForUser() used with the option fullObjects changed. In case you need the old behavior ...
  • Added option anyScope to removeUsersFromRoles()
  • Add option onlyScoped to getRolesForUser() to allow limiting the result to only scoped permissions
  • All functions (excepted for those listed above) work with 2.x arguments, but in 3.x accept extra arguments and/or options.
  • Details and reasoning can be found in #276

Usage Examples


Here are some potential use cases:


-- Server --

Add users to roles:

var users = [
      {name:"Normal User",email:"[email protected]",roles:[]},
      {name:"View-Secrets User",email:"[email protected]",roles:['view-secrets']},
      {name:"Manage-Users User",email:"[email protected]",roles:['manage-users']},
      {name:"Admin User",email:"[email protected]",roles:['admin']}
    ];

users.forEach(function (user) {
  var id;

  id = Accounts.createUser({
    email: user.email,
    password: "apple1",
    profile: { name: user.name }
  });

  if (Meteor.roleAssignment.find({ 'user._id': id }).count() === 0) {
    import { Roles } from 'meteor/alanning:roles';
    
    user.roles.forEach(function (role) {
      Roles.createRole(role, {unlessExists: true});
    });
    // Need _id of existing user record so this call must come after `Accounts.createUser`.
    Roles.addUsersToRoles(id, user.roles);
  }

});

Note that the `Roles.addUsersToRoles` call needs to come _after_ `Accounts.createUser` or else the roles package won't be able to find the user record (since it hasn't been created yet). You can use `postSignUpHook` to assign roles when using [user accounts package](https://github.com/meteor-useraccounts/core). This SO answer gives more detail: http://stackoverflow.com/a/22650399/219238

Check user roles before publishing sensitive data:

// server/publish.js
import { Roles } from 'meteor/alanning:roles'

// Give authorized users access to sensitive data by scope
Meteor.publish('secrets', function (scope) {
  check(scope, String);

  if (Roles.userIsInRole(this.userId, ['view-secrets','admin'], scope)) {
    
    return Meteor.secrets.find({scope: scope});
    
  } else {

    // user not authorized. do not publish secrets
    this.stop();
    return;

  }
});

Prevent non-authorized users from creating new users:

Accounts.validateNewUser(function (user) {
  import { Roles } from 'meteor/alanning:roles'
  
  var loggedInUser = Meteor.user();

  if (Roles.userIsInRole(loggedInUser, ['admin','manage-users'])) {
    return true;
  }

  throw new Meteor.Error('unauthorized', "Not authorized to create new users");
});

Prevent access to certain functionality, such as deleting a user:

// server/userMethods.js
import { Roles } from 'meteor/alanning:roles'

Meteor.methods({
  /**
   * Revokes roles for a user in a specific scope.
   * 
   * @method revokeUser
   * @param {String} targetUserId ID of user to revoke roles for.
   * @param {String} scope Company to update roles for.
   */
  revokeUser: function (targetUserId, scope) {
    check(targetUserId, String);
    check(scope, String);
  
    var loggedInUser = Meteor.user();

    if (!loggedInUser ||
        !Roles.userIsInRole(loggedInUser, 
                            ['manage-users', 'support-staff'], scope)) {
      throw new Meteor.Error('access-denied', "Access denied")
    }

    // remove roles for target scope
    Roles.setUserRoles(targetUserId, [], scope)
  }
})

Manage a user's roles:

// server/userMethods.js
import { Roles } from 'meteor/alanning:roles'

Meteor.methods({
  /**
   * Update a user's roles.
   *
   * @param {Object} targetUserId Id of user to update.
   * @param {Array} roles User's new roles.
   * @param {String} scope Company to update roles for.
   */
  updateRoles: function (targetUserId, roles, scope) {
    check(targetUserId, String);
    check(roles, [String]);
    check(scope, String);

    var loggedInUser = Meteor.user();

    if (!loggedInUser ||
        !Roles.userIsInRole(loggedInUser, 
                            ['manage-users', 'support-staff'], scope)) {
      throw new Meteor.Error('access-denied', "Access denied");
    }

    Roles.setUserRoles(targetUserId, roles, scope);
  }
})

-- Client --

Client JavaScript does not by default have access to all the same Roles functions as the server unless you publish these role-assignments. In addition, Blaze will have the addition of a isInRole handlebars helper which is automatically registered by the Roles package.

As with all Meteor applications, client-side checks are a convenience, rather than a true security implementation since Meteor bundles the same client-side code to all users. Providing the Roles functions client-side also allows for latency compensation during Meteor method calls. Roles functions which modify the database should not be called directly, but inside the Meteor methods.

NOTE: Any sensitive data needs to be controlled server-side to prevent unwanted disclosure. To be clear, Meteor sends all templates, client-side JavaScript, and published data to the client's browser. This is by design and is a good thing. The following example is just sugar to help improve the user experience for normal users. Those interested in seeing the 'admin_nav' template in the example below will still be able to do so by manually reading the bundled client.js file. It won't be pretty, but it is possible. But this is not a problem as long as the actual data is restricted server-side.

To check for global roles or when not using scopes:

<!-- client/myApp.html -->

<template name="header">
  ... regular header stuff
  {{#if isInRole 'admin'}}
    {{> admin_nav}}  
  {{/if}}
  {{#if isInRole 'admin,editor'}}
    {{> editor_stuff}}
  {{/if}}
</template>

To check for roles when using scopes:

<!-- client/myApp.html -->

<template name="header">
  ... regular header stuff
  {{#if isInRole 'admin,editor' 'group1'}}
    {{> editor_stuff}}  
  {{/if}}
</template>

API Docs

Online API docs found here: https://meteor-community-packages.github.io/meteor-roles/

API docs generated using YUIDoc

To re-generate documentation:

  1. install YUIDoc
  2. cd meteor-roles
  3. yuidoc

To serve documentation locally:

  1. install YUIDoc
  2. cd meteor-roles
  3. yuidoc --server 5000
  4. point browser at http://localhost:5000/

Example Apps

The examples directory contains Meteor apps which show off the following features:

  • Server-side publishing with authorization to secure sensitive data

  • Client-side navigation with link visibility based on user roles

  • 'Sign-in required' app with up-front login page using accounts-ui

  • Client-side routing

    1. git clone https://github.com/Meteor-Community-Packages/meteor-roles.git
    2. choose an example, eg.
    • cd meteor-roles/examples/iron-router or
    • cd meteor-roles/examples/flow-router
    1. meteor
    2. point browser to http://localhost:3000

Contributions, development and tests

Please read our contribution guidelines, which also describes how to set up and run the linter and tests.

meteor-roles's People

Contributors

alanning avatar bratelefant avatar bruceborrett avatar captainn avatar challett avatar chip avatar copleykj avatar dependabot[bot] avatar felixrabe avatar ianserlin avatar jamgold avatar jankapunkt avatar jedwards1211 avatar kevb avatar kulttuuri avatar leebenson avatar mcrider avatar mihailgaberov avatar mitar avatar nickmoylan avatar olivierjm avatar pascoual avatar simonsimcity avatar storytellercz avatar timsun28 avatar zimme avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

meteor-roles's Issues

Error adding role for single user

When calling Roles.addUsersToRoles to add a single user to a single role, I get an "Uncaught [object Object]" error stemming from roles_common.js::132. The code

 Meteor.users.update(
    {       _id: { $in: users } },
    { $addToSet: { roles: { $each: roles } } },
    {     multi: true }

Seems to not like the '$in' specifier; When I change it to

Meteor.users.update(
    {       _id: users[0] },
    { $addToSet: { roles: { $each: roles } } },
    {     multi: true }

Everything works properly. I'm wondering if I'm just doing something dumb with my allow/deny rules (which are completely open, all operations are currently set to true), or if this is a bug with the MongoDB interface. Thanks for your work on the roles package!

Published Logged-In User Roles

In roles_server.js, the auto publish on line 20 is a nice addition, but isn't quite working for me.

In particular, in lib/router.js, I have the following function that checks for roles. If I visit the /admin page as the admin, then getRolesForUser on the third line returns []. This is even though the admin user has role 'admin', confirmed by asking the chrome inspector after the page has loaded.

Router.onBeforeAction(ir_before_hooks.is_admin, {only:['admin']});

var ir_before_hooks = {
  is_admin: function(pause) {
    role_check('admin', 'home', pause)
  }
}

var role_check = function(role, redirect, pause) {
  redirect = redirect || 'home';
  console.log(Roles.getRolesForUser(Meteor.userId()));
  if (!Roles.userIsInRole(Meteor.userId(), role)) {
    go_to(redirect, pause);
  }
};

If I instead institute my own 'user_roles' publication, then the following works but isn't smooth because the page flickers. What am I doing wrong and how can I make this work with the Roles package?

var role_check = function(role, redirect, pause) {
  redirect = redirect || 'home';
  console.log(Roles.getRolesForUser(Meteor.userId()));
  if (Meteor.subscribe('user_roles', Meteor.userId()).ready() && !Roles.userIsInRole(Meteor.userId(), role)) {
    go_to(redirect, pause);
  }
};

Remove user to a role doesn't work

i've been trying to call the Roles.removeUsersFromRoles(Meteor.userId(),"Tutor") but it is returning an error. Please see error details below:

insert failed: MongoError: E11000 duplicate key error index: meteor.roles.$name_1 dup key: { : "Tutor" }

Doesn't work for groups with multiple '.'s in name

Repro test which fails in v1.2.9:

Tinytest.add(
  "roles - can use multiple periods in group name",
  function (test) {
    reset()

    Roles.addUsersToRoles(users.joe, ['admin'], 'example.k12.va.us')
    testUser(test, 'joe', ['admin'], 'example.k12.va.us')
})

Roles -> Permissions

Hi, this isn't a real issue, its more an idea. Wouldn't it be awesome, if you could attach permissions to roles and check them on server/client like Roles.isPermitted(loggedInUser, "admin:users:write"); instead of Roles.userIsInRole(loggedInUser, ['user-manager']). I would suggest a permission system like Apache Shiro.
This way, you could manage what e.g. the admin-user or user-manager can do apart of the role.

Therefore you can change the meaning of being in a role and don't have to change every users roles if features of your app change in future.

"error: no such package: 'roles'"

Hi alanning!
I created new project, added only accounts-password package, and then added your roles package.

Console 1:

karol@karol-laptop ~/Workspaces/meteor $ meteor create forum
forum: created.

To run your new app:
   cd forum
   meteor
karol@karol-laptop ~/Workspaces/meteor $ cd forum/
karol@karol-laptop ~/Workspaces/meteor/forum $ meteor
[[[[[ ~/Workspaces/meteor/forum ]]]]]

=> Meteor server running on: http://localhost:3000/
=> Meteor server restarted (x5)
=> Errors prevented startup:

While building the application:
error: no such package: 'roles'

=> Your application has errors. Waiting for file change.

Console 2:

karol@karol-laptop ~/Workspaces/meteor/forum $ meteor add accounts-password
accounts-password: Password support for accounts.
karol@karol-laptop ~/Workspaces/meteor/forum $ mrt add roles
✓ roles
    tag: https://github.com/alanning/meteor-roles.git#v1.0.6

Done installing smart packages

Stand back while Meteorite does its thing

Done installing smart packages

Ok, everything's ready. Here comes Meteor!

roles: Role-based authorization

I got "error: no such package: 'roles'" in Console 1 after adding roles package.

I googled this question on stackoverflow.com:
http://stackoverflow.com/questions/18264145/meteor-error-no-such-package-accounts-urls

I downgraded Meteor to 0.6.4.1 and application works correctly, so I conclude it is the new Meteor's package system issue. I will try to create fix based on https://github.com/meteor/meteor/blob/devel/History.md#v065 and check if it works (it can take some time, because I've just started learning Meteor).

Please let me know if I am wrong with conclusion.

Examples - How to do server side filter

I am trying to figure out how to filter for all my routes and found the examples directory. I noticed the filtering happens in the /client directory. How can i filter out for example, users who are behind in payment. I would like to do the logic on the server side. Right now, i call a Meteor.Method('paidUser') in the Filters object?

Roles.userIsInRole() returns the whole user record

For some reason, using Roles.userIsInRole() is returning the whole user record for me.

Looks like on line 223 of roles_common.js:

return Meteor.users.findOne(
    { _id: id, roles: { $in: roles } },
    { _id: 1 }
  )

should be:

return Meteor.users.findOne(
  {_id: id, roles: { $in: roles } },
  { fields: { _id: 1 } }
)

However, since field specifiers are ignored on the client, it doesn't make sense to do this in roles_common.

problem installing examples...

following the examples instructions I get a an app that launches to an error...

`
dev@sbox2:/projects$ git clone https://github.com/alanning/meteor-roles.git
Cloning into 'meteor-roles'...
remote: Reusing existing pack: 929, done.
remote: Total 929 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (929/929), 271.72 KiB | 222.00 KiB/s, done.
Resolving deltas: 100% (470/470), done.
Checking connectivity... done
dev@sbox2:
/projects$ cd meteor-roles/examples/router
dev@sbox2:~/projects/meteor-roles/examples/router$ meteor
Installing Meteor 0.7.2:

  • 'meteor' build tool (version 8e197f29c5)
  • Package updates: accounts-base accounts-facebook accounts-github
    accounts-google accounts-meetup accounts-meteor-developer accounts-oauth
    accounts-password accounts-twitter accounts-ui accounts-ui-unstyled
    accounts-weibo deps domutils facebook facts github google handlebars htmljs
    http less livedata liverange madewith meetup meteor meteor-developer
    minifiers minimongo mongo-livedata oauth1 preserve-inputs
    service-configuration showdown spark spiderable standard-app-packages stylus
    templating test-helpers test-in-browser twitter universal-events weibo

[[[[[ ~/projects/meteor-roles/examples/router ]]]]]

=> Started proxy.
=> Meteor 0.8.2 is available. Update this project with 'meteor update'.
=> Started MongoDB.
=> Errors prevented startup:

While building the application:
error: no such package: 'router'
error: no such package: 'roles'

=> Your application has errors. Waiting for file change.
`

Any advice?

relation to meteor-authorization

Hi,
there seems to be an almost identical project "meteor-authorization" with the same contributors from this project.

Which project is the oprefered one?
I suppose the "meteor-roles" because this supports groups.
Am I right?
If this is the case, please make aremark in meteor-authorization/README.md

thanks,
ALex.

Default Role of created user

Is there a way to create a default user role ... say "default"

As the docs say, this cannot be included in the Accounts.onCreateUser function as the user has not been created yet.

Roles is not work with meteor 0.9.1.1

I create a simple application with

meteor create test-roles
cd test-roles
meteor add alanning:roles
meteor

When I access the web page I get in the console

WARNING: Roles template helpers not registered. Handlebars or UI package not found

What do I need to initialize Meteor.ui?

WARNING: Roles Handlebars helpers not registered. Handlebars not defined

I am using Meteor release : 0.8.0-rc0.
When I run mrt I get this Warning message on the client console:
"WARNING: Roles Handlebars helpers not registered. Handlebars not defined roles_client.js:78:

At line 75:
Need to replace "Handlebars.registerHelper(name, func)"
with : "UI.registerHelper(name, func)"

Tests don't run?

Hey Adrian,

Can't run tests with latest version of meteor (0.8.1.2). To reproduce, just run testing instructions in README (meteor test-packages ./roles).

I get:

% meteor test-packages ./roles
[[[[[ Tests ]]]]]

=> Started proxy.
=> Started MongoDB.     
=> Errors prevented startup:

While building package `roles`:
fs.js:427:18: ENOENT, no such file or directory '/Users/gerard/_work/meteor-roles/.meteor/packages'
  at Object.fs.openSync (fs.js:427:18)
  at Object.fs.readFileSync (fs.js:284:15)
  at uiExists (package.js:40:27)
  at Object.Package.on_test.both (package.js:14:6)
  at /Users/gerard/.meteor/tools/6f23056589/tools/packages.js:1616:29
  at Array.forEach (native)
  ...

Line 40 is looking for the .meteor/packages file. Is there a way in package.js to determine if we're running inside of a test? Or perhaps just do some filesystem check, like in this package.js: https://github.com/arunoda/meteor-fast-render/blob/master/package.js#L61 (hacky)

Thanks,
Gerard

incompatible with [email protected]

when adding this package to a [email protected] project, all hell breaks loose.

[Error] TypeError: 'undefined' is not an object (evaluating 'Package.ui.UI.registerHelper')
(anonymous function) (alanning:roles.js, line 829)
forEach (underscore.js, line 164)
(anonymous function) (alanning:roles.js, line 828)
(anonymous function) (alanning:roles.js, line 839)
(anonymous function) (alanning:roles.js, line 843)
[Error] TypeError: 'undefined' is not an object (evaluating 'Package['alanning:roles'].Roles')
global code (global-imports.js, line 10)

Error message on server: 'has no method 'complete''

Exception from sub aMBTXeGfjSbWRRHy2 TypeError: Object [object Object] has no method 'complete'
    at null._handler (app/packages/roles/roles_server.js:20:10)
    at _.extend._runHandler (app/packages/livedata/livedata_server.js:816:31)
    at _.extend._startSubscription (app/packages/livedata/livedata_server.js:715:9)
    at _.extend.protocol_handlers.sub (app/packages/livedata/livedata_server.js:520:12)
    at _.extend.processMessage.processNext (app/packages/livedata/livedata_server.js:484:43)

I think this is caused by the latest Meteor release:
https://github.com/meteor/meteor/blob/master/History.md#v057

Publish APIs have changed.

using meteor 0.7, only rows added to roles collection, but no link from users to roles

basically Roles.addUsersToRoles() is not fully working.

if I do this:

Roles.addUsersToRoles(user._id, ['admin', 'user'])

I get the following in db.roles from the mongo command line:

{ "name" : "admin", "_id" : "5maafKfuKzusSHfFq" }
{ "name" : "user", "_id" : "XA8Gp5aFYGZePm4PK" }

but that's all that's been added to the mongo database. there is no link from the users to these roles.

FYI I'm executing Roles.addUsersToRoles() in Accounts.onCreateUser().

Any help as to what's wrong would be much appreciated.

Roles per group

It would be nice to be able to group roles in Roles collection.

I have i Orgs collection with organizations and my groups are orgId's i.e. a user have permissions per organization. I would like to be able to set roles based on the same groups, and only show those roles when an admin are going to update the roles on a user

I can't get roles working with spiderable

I created a new meteor project and added meteor-roles and spiderable. If i get "http://localhost:3000/?_escaped_fragment_=", the request ends after a 15 seconds delay without the body. If i remove meteor-roles spiderable works.

It also works if i just remove Meteor.subscribe('_roles_own_user_roles');
So i think the problem might be anywhere there?!

Could you confirm this problem or does it work for you? I really like your package, but i really do need spiderable, too.

Thanks

Roles not defined - Add Users To Roles

Roles.addUsersToRoles(userId, roles);

That method call when ran from the server is returning an error:

ReferenceError: Roles is not defined

Is there anything that has changed? , I am using the latest version '1.2.8`

Unexpected publishing of all user records.

In roles_server.js if userId is undefined then ALL users in the database are published. I suspect the desired behavior is that no users are published? In my app, I see publish with undefined user triggered frequently, so it should be guarded.

Meteor.publish(null, function () {
  var userId = this.userId,
      fields = {roles:1}

  return Meteor.users.find({_id:userId}, {fields: fields})
})

Roles.userIsInRole returns false in onBeforeAction

Updated to latest iron:router and latest alanning:roles and Meteor 0.9.3, and now Roles.userIsInRole does not seem to work within a route's onBeforeAction.

this.route('admin', {
    onBeforeAction: function (pause) {
      if (!Roles.userIsInRole(Meteor.userId(), 'admin')) {
        console.log(Roles.userIsInRole(Meteor.userId(), 'admin'), Meteor.userId());
        this.redirect("home");
      }
    }
  });

I can see from the console.log that the user ID is correct, but userIsInRole is returning false. However, after it redirects, I can enter Roles.userIsInRole(Meteor.userId(), 'admin') in the browser console and it prints true.

So it seems like the roles are not being correctly determined until after onBeforeAction runs. Possibly I need to waitOn the subscription to the roles field, but I don't think I had to do that before.

Roles bypassing allow/deny rules

To Test

  • Create some roles and a group (as usual) in a new meteor project with the roles package
  • Create a new user and assign that user to a role within the group (as usual)
  • Create allow rules for insert/update/delete (just return true for each)
  • Create a deny rule that disallows a user from updating his own role for that group:
Meteor.users.deny({
    // disallow users making themselves admins
    update: function(userId, doc, fields, modifier) {
      return _.contains(_.values(_.find(modifier, 'roles.somegroup')), 'admin')
    }
  })
  • In Chrome Dev Tools, try making yourself an admin via minimongo:
Meteor.users.update({ _id: "someID" }, { $addToSet: { 'roles.somegroup': 'admin' } })
  • Verify that this fails as expected
  • In Chrome Dev Tools, try making yourself an admin via Roles.addUserToRoles:
Roles.addUsersToRoles(Meteor.user(), 'admin', 'somegroup')
  • Verify that you get insert failed: Access denied in CDT
  • Go to mrt mongo shell and find your user (or inspect your user object in CDT with Meteor.user())
  • Verify that the user has been updated with the role, after all

This may be related to the use of Meteor methods, as per the Meteor docs:

Server code is trusted and isn't subject to allow and deny restrictions. That includes methods that are called with Meteor.call — they are expected to do their own access checking rather than relying on allow and deny.

Helpers not registered on template engine 10.1

Hi, I am new to Meteor and successfully used Roles until I needed to use the new Meteor template engine 10.1. It looks like Roles works fine, but helpers are not registered.

So I launch my app with mrt --release template-engine-preview-10.1

This is what I guess in the console:

WARNING: Roles Handlebars helpers not registered. Handlebars not defined 

I managed to make it work by including in a client-side .js file the code from roles_client.js:

_.each(Roles._handlebarsHelpers, function(func, name) {
  Handlebars.registerHelper(name, func);
});

But I'm sure there must be a better way.

Missing package.js

running "mrt update" in root of project:

/usr/local/lib/node_modules/meteorite/lib/dependencies/package.js:106
throw('Could not locate package.js within path ' + self.source.packagePa
^
Could not locate package.js within path /Users/xxxxx/.meteorite/packages/roles/alanning/meteor-roles/ca41ca5775f1dd954258da141ab92be22b991829

Doesn't package.js need to be at root of meteorite package?

Permission error

First of all im not sure is the error is with Roles or the jasmine for meteor package. But my best guess is that it's here.

Im trying to write some test, where I would validate the output from a template based on the roles i've setup.

In /test/jasmine I have a function in one of my specs that creates a user and adds a role to this user.

function createUser(user) {
        Accounts.createUser({
            email: user.email,
            password: user.password,
            profile: { name: user.name }
        }, function (error) {
            if (error != null) {
                // Need _id of existing user record so this call must come
                // after `Accounts.createUser` or `Accounts.onCreate`
                //Meteor.users.update({_id: Meteor.userId()}, {$set: {'emails.0.verified': true}});
                Roles.addUsersToRoles( Meteor.userId(), user.roles);
            }
        });
    };

The idea is that everytime i need a user i create a user and attach the roles needed. This seems to work. But I am getting this error / warning in the console.
insert failed: MongoError: E11000 duplicate key error index: mocha-web.roles.$name_1 dup key: { : "athlete" }
This error is not showing up when I run the same 'code' in my /client og /server directories.

Furthermore i have for the purpose of test inserted this in my /server
Meteor.users.allow({
update: function (userId, user) {
return true;
}
});
Because otherwise i'm getting a Access denied from roles.js when updating the user. And I can't seem figure out why, since the Meteor documentation states that when creating a user with Accounts.createUser the users is also logged in. Any idea why i can't update the user object without a general update-allow for the Meteor.users?

Thanks in advance

groups cant be string starting with number...

hi im trying to set user role : Roles.setUserRoles(user_id, 'manage-entity', entityId);
When entity id start with number the Roles.userIsInRole(Meteor.userId(),'manage-entity' , entityId) returns false, but cants ee any error
When start with no number char evetything is ok .
Can please tell me what is the problem?
regards,
G.P.

Add isInRole to JS API as well

Something you frequently do in the application, is check if the current user is allowed to access something. As there currently is no shorthand for this in the Javascript API, you have to do something like:

if ( Roles.userIsInRole( Meteor.userId(), 'permission' ) )
    // ...

I noticed the UI helper offers a beautiful shortand syntax for this, using the currently logged in user. I think it would make a lot of sense to add this to the API as well, so that one can simply do:

if ( Roles.isInRole( 'permission' ) )
    // ...

or even better:

if ( Roles.has( 'permission' ) )
    // ...

New to meteor roles a bit confused

After created roles and checked it with

console.log(Roles.getAllRoles().fetch());

in server, trying same in client but an empty array returned, what i'm doing wrong?

thanks in advance.

A.

Not working on Meteor 0.9.3

Below is code what i am using. i checked its creating roles and users and not adding roles field to users.

server/collections/users.js
var users = [
        {name:"Normal User",email:"[email protected]",roles:[]},
        {name:"View-Secrets User",email:"[email protected]",roles:['view-secrets']},
        {name:"Manage-Users User",email:"[email protected]",roles:['manage-users']},
        {name:"Admin User",email:"[email protected]",roles:['admin']}
    ];

    _.each(users, function (user) {
        var id;

        id = Accounts.createUser({
            email: user.email,
            password: "apple1",
            profile: { name: user.name }
        });

        if (user.roles.length > 0) {
            // Need _id of existing user record so this call must come
            // after `Accounts.createUser` or `Accounts.onCreate`
            Roles.addUsersToRoles(id, user.roles);
        }

    });

mrt add roles

Hi Guys,

I am integrating the roles package to my Meteor but it seems like when you use mrt add roles it doesnt get the latest commit which already have the integration for 0.6.5 of meteor which uses api.export to make the Roles variable available to use.

Groups as objects

I'd like to have groups as objects, such that a group can have an id, name and description for example. For my use-case, name is not necessarily unique, just _id.

The way I'm thinking of approaching this right now is to have a separate 'groups' collection, and use the _id of a group in the roles array of the user, e.g.

//Group
{
  "_id" : ObjectId("as23r3fsffsdv34768"),
  "name" : "Group A",
  "description" : "The best group"
}
//User
{
  _id: ObjectId("0i9r9fiijivh2n3jknddf"),
  //...
  roles: {
    ObjectId("as23r3fsffsdv34768") : ["admin"]
  }
}

Problem with this is, currently 'group' must be a string when calling addUsersToRoles, so an ObjectId won't work.

So my questions - is my approach right? If so - can you modify the code to allow 'group' to be an ObjectId when creating and updating roles?

Thanks

Use package in other collections

Can this package be used in other collections, i know this works well with the Meteor.users collection but i was wondering if i could tack on the roles: [] array in any collection and still use methods like 'Roles.userIsInRole` and pass in instead of 'user' another type of document ?

New to roles

Hi, I am fairly new to Meteor, so please let me know if I am missing something obvious here.

I ran 'meteor add roles' in my project directory and then wrote the following lines in my server.js file:

var users = [
    {name:"admin",roles:['admin']}
];

_.each(users, function(user) {
    var id = user._id;
    if (user.roles.length > 0) {
        Roles.addUsersToRoles(id, user.roles);
    }
});

I am getting the following error on the server.js file:
ReferenceError: Roles is not defined

I confirmed that 'roles' is listed in the .meteor/local/packages file, so I am not sure what to do. Any thoughts would be appreciated, thank you.

Uncaught Error: Missing 'users' param

This error comes up in chrome inspector after I click signUp in my signUp form.

Template.signUp.events({
'click #signup': function (e, t) {
    e.preventDefault();

    var users = [
        {
            name: t.find('#fullName').value,
            email: t.find('#email').value,
            roles:['admin']
        },
        {
            name:"View-Secrets User",
            email:"[email protected]",
            roles:[
                'view-secrets'
            ]
        }
    ];

    _.each(users, function (user) {
        var id;

        id = Accounts.createUser({
            email: user.email,
            password: t.find('#password').value,
            profile: {
                name: user.name
            }
        });

        if (user.roles.length > 0) {
            // Need _id of existing user record so this call must come
            // after `Accounts.createUser` or `Accounts.onCreate`
            Roles.addUsersToRoles(id, user.roles);
        }

    });
    }
});

Any help would be appreciated. Thanks...

deleteRole by _id, not name for untrusted code

As per the documentation, it is now not possible to remove an item from a collection via a selector if it is untrusted code.

If you run the deletRole function now, you get:

Error: Not permitted. Untrusted code may only remove documents by ID. [403]

Best bet would be to delete via _id for the client within this function.

Set User Roles doesn't work

I want to set user Roles inside onCreateUser and it doesn't work. I have:

Roles.setUserRoles(user, 'admin', 'tesgroup');
console.log(Roles.userIsInRole(user,'admin','tesgroup'));

And it's always false. Any ideas on this?

I can't add roles outside onCreateUser.

Roles.getAllRoles returns empty set with no Autopublish.

I'm still new to Meteor.

The Roles.getAllRoles() returns the roles defined in db.roles when Autopublish is added to the meteor project. But when autopublish is removed through

mrt remove autopublish

Then Roles.getAllRoles fail to return roles defined under db.roles.

I tried defining a publish for roles, but it resulted in an error
In Server:

Meteor.publish("roles", function() {return roles.find({},{})};

Resulted in an error:

Error: A method named '/roles/insert' is already defined

Judging from the above, the roles are already published. What would I need to subscribe to (on the client) to gain access to the Roles.getAllRoles() function, such that it'll return the roles defined in db.roles?

mrt add roles gets old version

I see from the Atmosphere site that 1.2.8 is the most recent version of the roles package. However, when add it to my application, I end up with version 1.2.6, as determined by viewing <projectname>/packages/roles/smart.json.

Here's the output from a standard add:

$ mrt add roles 

Done installing smart packages

Stand back while Meteorite does its thing

Done installing smart packages

Ok, everything's ready. Here comes Meteor!

roles: Role-based authorization

And from adding with version argument:

$ mrt add roles --version 1.2.8
Meteorite version 0.7.2
✓ roles
    tag: https://github.com/alanning/meteor-roles.git#v1.2.6

Done installing smart packages
roles: Role-based authorization

I've removed the package several times (by mrt remove roles and deleting the package folder) before adding, but each time still end up with 1.2.6.

Updating to 0.6.0: Meteor

I am just trying to see if the packages that i use are going to be updating to the latest version of meteor. The new version introduces scoping changes that might break if i update blindly. Please let me know if you plan on updating this package. Thanks for the wonderful work as always.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.