elpddev
elpddev

Reputation: 4494

Filter subscription bases on user roles in Meteor

I am using meteor-roles package for adding roles functionality to the app. Now I'm trying to filter a subscription of product based on the user of having a role to see that product category.

I thought I can use mongo $where in meteor but I can specify the $where function only as serialized string which does not have access to the roles package.

Example of adding a user to a role for viewing specific category.

Roles.addUsersToRoles(userIdA, 'view-product-category', 'product-category-a');

Current code that does not work. userId does not exists when the function get deserialized in mongo engine.

Meteor.publish('products', function () {
  let userId = this.userId;

  let query = {
    $where: function () {
      return Roles.userIsInRole(userId, 'view-product-category', `product-catogory-${this.category}`);
    }.toString();
  };

  return Products.find(query);
});

How does one filter a collection based on values different collection, which what I'm trying to do here ?

Current direction is to serialize the function myself and put the values needed there. I'm looking to know if there is more general and robust way of doing this kind of acl access filtering on subscriptions.

Upvotes: 0

Views: 225

Answers (1)

Michel Floyd
Michel Floyd

Reputation: 20246

$where is unindexed and slow. I believe what you're trying to do is filter products that have a category key. The user has a number of roles that allow them to view various categories.

You want to setup your query as:

Products.find({category: {$in: userCategories}});

Fortunately, the roles api has a getRolesForUser function that will get all the user's roles for you.

So do:

const myRoles = getRolesForUser(Meteor.userId());
const userCategories = f(myRoles); // whatever you need to do to format these roles as categories
Products.find({category: {$in: userCategories}});

I'm not clear on how your role groups play into this hence the pseudo-answer. But basically you want userCategories to be an array of the category names the user has access to. This query will be fast as long as the category field is indexed.

Upvotes: 1

Related Questions