james2m / canard

Makes role based authorization in Rails really simple. Wraps CanCan and RoleModel up with a smattering of syntactic sugar, some generators and scopes.
MIT License
125 stars 28 forks source link

Multiple Abilities? #18

Closed elsom25 closed 10 years ago

elsom25 commented 10 years ago

It would be awesome to have multiple ability definitions for applications that have multiple "apps" with different permissions (primary example being an admin app vs the standard app).

I know this is a relatively common use-case in plain old CanCan(Can), but was wondering how you'd suggest doing so with Canard?

I have a rudimentary solution working, but it requires me to create a custom Ability class from yours (partly due to the methods being private over protected, partly to provide a hook)

class CustomAbility < Ability
  def initialize(object=nil)
    @user = object.respond_to?(:user) ? object.user : object
    setup_abilities
  end

protected

  def setup_abilities
  end

  def add_role_abilities(roles)
    roles = [roles] unless roles.is_a? Array
    roles.each{ |role| self.send(:append_abilities, role) }
  end

  def get_ability_key(class_name)
    self.send(:ability_key, class_name)
  end
end

and then for my "custom" ablities, inheriting from the new class, and adjusting as necessary (currently by just simply appending admin_ to the front, just to see if it'd work)

class AdminAbility < CustomAbility
protected
  def setup_abilities
    return unless @user

    user_class_name = String(@user.class.name)
    add_role_abilities get_ability_key("admin_#{user_class_name}") unless user_class_name.empty?

    # If user has roles get those abilities
    add_role_abilities @user.roles.map{ |role| role.to_s.prepend('admin_').to_sym } if @user.respond_to?(:roles)
  end
end
james2m commented 10 years ago

I'd certainly entertain a pull request to make them protected. :)

james2m commented 10 years ago

Thanks for the pull request. That's merged. I'll do a new release shortly. In the mean time;

gem 'canard', git: 'https://github.com/james2m/canard.git'
elsom25 commented 10 years ago

thanks kindly... If I find a nicer way to handle multiple Abilities, I'll make a PR to reopen discussion

james2m commented 10 years ago

A subclass seems a pretty clean solution.

James McCarthy This is Hatch Ltd http://thisishatch.co.uk james@thisishatch.co.uk US: +1-212-203-7104 UK: +44-7946-463686

On 16 Jul 2014, at 11:20, Jesse McGinnis notifications@github.com wrote:

thanks kindly... If I find a nicer way to handle multiple Abilities, I'll make a PR to reopen discussion

— Reply to this email directly or view it on GitHub.