Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

About ability inheritance #110

Closed
tanekim88 opened this issue Sep 4, 2018 · 1 comment
Closed

About ability inheritance #110

tanekim88 opened this issue Sep 4, 2018 · 1 comment
Labels

Comments

@tanekim88
Copy link

tanekim88 commented Sep 4, 2018

Can Casl do such thing as ability inheritance?
For example how can I do such a thing like this?

const anyone = AbilityBuilder.define((can) => {
  can('read', 'all');
});
const admin = AbilityBuilder.define((can) => {
  can(What 'anyone' can do)
  can('update', 'all');
  can('remove', 'all');
});
@stalniy
Copy link
Owner

stalniy commented Sep 4, 2018

Hi @tanekim77

Sure, it's quite easy, you just need to keep everything in one ability. Just by quickly thinking I see 3 approaches:

  1. Use role index to detect what should be inherited
const ROLES = ['anyone', 'admin']

function defineAbilitiesFor(user) {
  const { can, rules } = AbilityBuilder.extract()
  const is = role => ROLES.indexOf(user.role) >= ROLES.indexOf(role);

  if (is('moderator')) {
     can('read', 'all')
  }

  if (is('admin')) {
    can('update', 'all');
    can('remove', 'all');
  }

  return new Ability(rules);
}
  1. Use class inheritance (this may be inflexible):
class AnyoneAbility {
  static build() {
    return new AnyoneAbility().ability;
  }

   constructor() {
      this.ability = AbilityBuilder.define(this.define.bind(this));
   }

   define(can, cannot) {
     can('read', 'all')
   }
}

class AdminAbility extends AnyoneAbility {
  define(can, cannot) {
    super.define(can, cannot);
    can('update', 'all');
    can('remove', 'all');
  }
}

const adminAbility = AdminAbility.build()
const anyoneAbility = AnyoneAbility.build()
  1. The same as above but with functions
function anyoneAbility(can, cannot) {
     can('read', 'all')
}

function adminAbility(can, cannot) {
    can('update', 'all');
    can('remove', 'all');
}

const ability = AbilityBuilder.define((can, cannot) => {
   if (/*something*/) {
      anyoneAbility(can, cannot);
   }

   if (/* something additionality */) {
     adminAbility(can, cannot);
   }
})

I guess you understood the basic idea :)

Thanks for using CASL!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants