1

So this is the authorization code I wrote based on Railscast #386.

The problem is that the block works on all controllers except for user_controller. In other words, any user can triger edit and update actions on any other user, even though the block given to it is the same as that of favors edit and update actions.

def initialize(user)
    allow :users, [:new, :create, :show]
    allow :sessions, [:new, :create, :destroy]
    allow :favors, [:index, :show]
    if user
      allow :users, [:edit, :update] do |usr|
        usr.id == user.id
      end
      allow :favors, [:new, :create]
      allow :favors, [:edit, :update] do |favor|
        favor.user_id == user.id
      end
      allow :acceptances, [:create, :update] do |acceptance|
        !acceptance.has_accepted_acceptance?
      end
    end
  end

Any help is highly appreciated :)

fardin
  • 1,399
  • 4
  • 16
  • 27
  • 2
    [It is available on YouTube](https://www.youtube.com/watch?v=GE-4chF3Tu0) for anyone who doesn't have a RailsCasts subscription – Richard Peck Feb 01 '16 at 12:01
  • Are you authorizing the `@user` in the users controller? – Richard Peck Feb 01 '16 at 13:02
  • I am passing `current_user` in a method called `current_resource` in `users_controller` which is overwriting `current_resource` method in `application_controller` which is then passed as an object to the `Permission` class. The problem is that I guess `current_resource` in users is not overwriting the one in `application_controller` – fardin Feb 01 '16 at 21:44
  • is there a reason why usr.id is used instead of user.id? – Matteo May 18 '16 at 03:58

1 Answers1

0

You are already passing in the (user) to the permission class. By calling it again in

if user... do |user|... end

you are re-initializing the passed-in user, making it nil. You then try to give a nil user permissions on the controller#action, in this case anything involving the user's account.

The reason Ryan Bates includes a block in permissions involving other models is because the model instance hasn't been passed to the permission class. That is why you see the likes of:

allow_action :topics, [:new, :create, :index]
allow_action :topics, [:edit, :update, :show] do |topic|
  topic.author_id == user.id
end
allow_attr :topic, [:title, :content]

This bit above grants permissions on all the topics the user may or has created.

SOLUTION Take out anything that re-initializes the (user) and then try again.

allow_action :users, [:edit, :update]
allow_attr :users, [:email, :invite_token, :name, :surname, :password, :password_confirmation]

NOTE I have renamed the allow action to allow_action, as per Ryan's suggestion in the Railscast. I also renamed the allow_param method to allow_attr since we are used to using attr_accessible anyway.

Matteo
  • 1,136
  • 1
  • 16
  • 36