Meteor-Community-Packages / meteor-roles

Authorization package for Meteor, compatible with built-in accounts packages
http://meteor-community-packages.github.io/meteor-roles/
MIT License
921 stars 167 forks source link

userIsInRole returning incorrect values during page rendering #237

Closed RavDanny closed 7 years ago

RavDanny commented 7 years ago

I am finding that Roles.userIsInRole is at times returning incorrect 'false' values at the initial time of rendering a page and the correct 'true' values afterwards. This leads to my page rendering incorrectly.

Here is the use case. I have a page which displays "data set" record details. If the user is authorized to edit data sets (i.e. Roles.userIsInRole(userId, "edit", "dataSets") == true) they will see an "Update Data Set" button which they can click on, sending them to an Update Data Set page where they can edit the data set. Otherwise that button should be invisible.

I am encountering a situation where the "Update Data Set" button displays for an authorized user, as it should, but when one clicks on it and is taken to the "Update Data Set" page, it checks whether the user is authorized to edit the data set, and it incorrectly returns false, causing the page to render incorrectly. Once the page is fully rendered, however, it returns true, as it should.

Here is my code for the "Update Data Set" page: HTML:

<template name="dataSet">
  <div class="detail-form">

    // Extra flags to check Roles functionality
    {{#if authorized 'dataSet' _id}}Authorised! (1) {{else}}Not Authorized! (1){{/if}}
    <script>
      if (Roles.userIsInRole("<current user's id>", "edit", "dataSets")) console.log("Roles working now (1)");
      console.log('Rights', Meteor.user().roles.dataSets);
    </script>

  {{#if authorized 'dataSet' _id}}
    ...
  {{else}}
    // More added flags
    {{#if authorized 'dataSet' _id}}Authorised! (2){{else}}Not Authorized! (2){{/if}}
    <script>
      if (Roles.userIsInRole("<current user's id>", "edit", "dataSets")) console.log("Roles working now (2)");
      console.log('Rights', Meteor.user().roles.dataSets);
    </script>

    {{> unauthorized}}
  {{/if}}

JS:

Template.registerHelper("authorized", function(objType, id) {
    var userId = Meteor.userId();
    var screenMode = getScreenMode();
    var group = objType + ' ' + id;
    console.log('authToEdit', authorisedToEdit(userId, objType, id));

    if (screenMode == 'display' || (screenMode == 'create' && userId) ||
        (screenMode == 'update' && authorisedToEdit(userId, objType, id)) ||
        (screenMode != 'display' && screenMode != 'update' && screenMode != 'create'))
        return true;
    } else
        return false;
});

authorisedToEdit = function(objType, id) {
  var userId = Meteor.userId();
  var group = objType + "s";
  var groupWithId = objType + ": " + id;
  // User is authorized if they are allowed to edit the object type as a whole (e.g. 'dataSets') or if they are allowed to edit the specific object in question (e.g. 'dataSet: sdf34df3fsdf3')
  var authorised = Roles.userIsInRole(userId, 'edit', group) || Roles.userIsInRole(userId, 'edit', groupWithId);
  console.log('authorised', authorised)
  return authorised;
};

When I run it with a user authorised to edit data sets, I am getting the following console output:

helpers.js:133authorised false
helpers.js:133 authorised false
helpers.js:133 authorised true
helpers.js:133 authorised true
helpers.js:133 authorised true
helpers.js:133 authorised true
helpers.js:133 authorised true
helpers.js:133 authorised true
helpers.js:67 authToEdit false
helpers.js:67 authToEdit false
helpers.js:67 authToEdit false
VM12561:1 Roles working now 1
VM12561:2 Rights ["edit"]
VM12562:1 Roles working now 2
VM12562:2 Rights ["edit"]

Have I done something wrong or is this a bug?

RavDanny commented 7 years ago

My problem. Found a bug.