What is the "right" way to handle models/controller policies when these classes come from a gem, like, say, Devise?
Having a solid example for a public auth gem like Devise would make for a great learning experience for those who are a bit more green in ruby and rails.
Not sure I understand the question. Devise is authentication only, so your only thing to do should be to define #pundit_user in your controller and define policies.
When I followed the README examples, i.e. adding
after_action :verify_authorized, except: :index
to application_controller.rb, I get errors from the devise controllers unless I import all of them and authorise them. I do have a user policy but that doesn't seem to be enough for all the features in devise (sessions, confirm password functionality, forgot password functionality).
I momentarily resolved this problem by removing that line from the application controller and just added it to the controllers for app specific stuff that I control.
Alternatively I authorised the controllers themselves by importing them and doing authorise self in the methods.
I hope this clarifies even just a little the current scenario.
verify_authorized is just a safety net for you as the developer. It doesn't really do anything.
But once I removed it all the double render errors and the not authorised errors that were triggered in devise context (login, forgot password etc.) went away
@guareschi it's not a problem to remove it. You can also add a conditional to the before filter to exclude Devise's controller, IIRC before_action takes an if param, but I can't find it's documentation. (wtf?) Another way is to simply do something like:
def verify_authorized
super unless inside_devise?
end
Where inside_devise? somehow checks if you're inside a Devise controller. Haven't used Devise in years so I have no idea how you'd do that.
@guareschi Does each of your controller actions really need to be authorized? If not, just put this this in the controllers that carry authorization logic, and avoid the ApplicationController that all controllers inherit from.
@guareschi if you want to skip the verification when on the Devise controller you should try:
before_action :verify_authorized, except: index, unless: :devise_controller?
Worked for me
To me works with after_action :verify_authorized, except: :index
@fangari Is the except: index going to apply to most people reading this or is that specific to your situation? I'm concerned that people may copy and paste your line wholesale without realizing that except: index is (AFAICT) not a necessary part of the solution and pokes a hole in the intended safety net. Let me know if I'm misunderstanding something.
The version I used was:
after_action :verify_authorized, unless: :devise_controller?
now needs to be as follows I think:
after_action :verify_authorized, except: :index, unless: -> { devise_controller? }
Most helpful comment
@guareschi if you want to skip the verification when on the Devise controller you should try:
Worked for me