2

I am trying to give some custom roles within spree specific permissions. Cant find this answer anywhere

role_ability.rb

class RoleAbility
 include CanCan::Ability

 def initialize(user)

 user || User.new # for guest

 if user.has_role? "admin"
   can :manage, :all
 elsif user.has_role? "retailer"
   can :manage, Product
 else
   can :read, :all
 end


 end
end

I thought this might be a popular idea, of letting a user with role 'manager' manage only products and other certain Models...

if I change

 elsif user.has_role? "retailer"
can :manage, Product

to

 elsif user.has_role? "retailer"
can :manage, :all

It works as expected... I can access all of the admin area

I only want the "Retailer" to be able to :manage Products tho!! ;)

"admin" is only a role associated with a user, ie all roles are Users.

You can probably see where this is going, Retailers can sign up and sell items of their own.. well thats the goal.

Any pointers??

Zarne Dravitzki
  • 1,648
  • 1
  • 16
  • 15

2 Answers2

4

A quick fix to this problem would be to add a authorize_admin method to a Admin::ProductsController decorator.rb

app/controllers/admin_products_controller_decorator.rb

Admin::ProductsController.class_eval do
    def authorize_admin
        authorize! :admin, Product
        authorize! params[:action].to_sym, Product
    end
end

NOTE: This will override the one set in auth/app/controllers/admin_orders_controller_decorator.rb removing the ":admin, Object" requirement for this controller.

That means the role will have to have access to both the :admin AND :action for Product.. ie:

app/models/retailer_ability.rb

class RetailerAbility
  include CanCan::Ability

  def initialize(user)
    user ||= User.new
    if user.has_role? "retailer"
      can :read, Product
      can :admin, Product
    end
  end
end

Should allow retailers to read products on the admin.

Also Dont forget to add this to an initializer:

config/initializers/spree.rb

Ability.register_ability(RetailerAbility)
complistic
  • 2,610
  • 1
  • 29
  • 37
  • Just an update, I have submitted a patch to master that does this functionality by default so you wont need the decorator anymore :) The Ability's work the same way as described here so if you used my patch it shouldn't break anything.. just the decorator is not needed anymore. – complistic Sep 07 '11 at 07:57
  • can you give me a link to that patch? – Dominik Goltermann Nov 06 '12 at 16:38
  • Sorry for the late reply, here is the link to my old pull request. https://github.com/spree/spree/pull/513 I have no Idea if the functionality is still in core or not. – complistic Dec 11 '12 at 03:11
  • This was the solution I used for pre Spree V1... maybe Spree 0.6.2 onwards? Thanks. Best to follow native strategies in later versions as suggested below. – Zarne Dravitzki Jun 03 '14 at 00:01
2

There is a native way in spree_auth_devise to do this. It was not documented, but now is.

https://github.com/spree/spree_auth_devise Section: "Using in an existing Rails application"

John Hirbour
  • 536
  • 3
  • 5
  • Can you confirm this works for limiting/giving access to the parts admin GUI for users without the admin role? It looks like it might but doesn’t show that case in the README. (it reads like you can then use in it a view... but that would be ugly and surly not the recommended way) – complistic Jun 03 '14 at 03:28