stalniy / casl

CASL is an isomorphic authorization JavaScript library which restricts what resources a given user is allowed to access
https://casl.js.org/
MIT License
5.93k stars 269 forks source link

this.$ability.update() does not update the global ability instance #400

Closed freitaga closed 3 years ago

freitaga commented 4 years ago

Describe the bug Global $ability rules do not update when using this.$ability.update(). In this instance, a logged in admin user can view all users through the side nav bar. After logging in, the button in the sidebar does not show up.

I'm assuming this isn't a bug, just a misinterpretation of how to properly update the permissions globally. After revising the permissions update according to the documentation, the problem remains.

To Reproduce Steps to reproduce the behavior:

  1. Ability configuration (rules, detectSubjectType, etc)
export default function defineAbilitiesFor() {
  const { can, cannot, rules } = new AbilityBuilder();

  let user = store.getters.user;

  if (user) {
    if (user.role == 'superadmin') {
      can('view', 'all');
      can('manage', 'all');
      can('update', 'all');
      can('create', 'Organization');
    } else if (user.role == 'admin') {
      can('view', 'Admin');
      can('update', 'Body');
      can('approve', 'Application');
      can('update', 'Organization');
      can('view', 'User');
      cannot('delete', 'Body');
    }
  }
  return new Ability(rules);
};
  1. How do you check abilities

In App.vue:

<router-link
  to="users"
   v-if="$can('view', 'User')"
>
  Manage Users
</router-link>

After the user logs in the following code updates the permissions globally:

let rules = defineAbilitiesFor(); // user is grabbed from vuex inside this function
this.$ability.update(rules);
console.log(this.$can("view", "User")); // outputs false after updating

Checking the permission after updating the global ability function results in a false output. If the page is refreshed, the user will then be able to see the button in the sidebar as the initialization function is ran with the user already in existence.

Expected behavior After logging in, permissions checked through the $ability.can() function reflect the abilities of the currently logged in user.

Interactive example (optional, but highly desirable) provide a link to the example from http://repl.it/, https://codesandbox.io/ or similar, so we can quickly test and provide feedback. Otherwise

CASL Version

"@casl/ability": "^4.1.6", "@casl/vue": "^1.1.1",

Environment:

"vue": "^2.6.11",

stalniy commented 4 years ago

Hi @freitaga

Thanks for the issue. Did I understand correctly, that issue appears only after page refresh and without page refresh all good?

freitaga commented 3 years ago

The issue occurs while attempting to dynamically update the $ability instance without page refresh. A page refresh will solve the issue since this guarantees the $ability global var will be initialized with the current user in the vuex store.

stalniy commented 3 years ago

I see,

Did you check whether this works in https://github.com/stalniy/casl-examples/tree/master/packages/vue-blog?

stalniy commented 3 years ago

Could you please show how you initialize a casl-Vue plug-in?

stalniy commented 3 years ago

I cannot reproduce the issue. Please check the example - https://codesandbox.io/s/priceless-pike-g2r22?file=/src/App.vue

stalniy commented 3 years ago

Close as cannot reproduce.

But feel free to comment and provide additional details.