Hey hey
I cannot find this info in docs or in source code
Let’s say we have a base action:
class Action < Hanami::Action
include Dry::Monads[:result]
before do |request, response|
authenticate_user(request, response)
end
So that all our actions inheriting from this, are authenticated
But we might not want to do it on ALL actions that inherit the base Action (but still want to inherit the rest of the logic, like for example LoginAction).
One solution is something like:
def skip_authenticate_user
false
end
def authenticate_user(request, _response)
return if skip_authenticate_user
return if current_user(request)
halt 401, { errors: { login: "Unauthorized" } }.to_json
end
Or just overwriting authenticate_user in actions you want to skip, but is there some more natural way, like skip_before_action? Do you think it makes sense to have it, or overwriting callback methods or doing stuff like above makes more sense?
What do you think about adding an intermediate Action-class (i.e AuthenticatedAction).
class AuthenticatedAction < MyApp::Action
before do |request, response|
authenticate_user(request, response)
end
def authenticate_user(req, res)
#...
end
end
# Login doesn't require authentication
class LoginAction < MyApp::Action
def handle(request, response)
end
end
# Action which uses authentication
class AnotherAction < AuthenticatedAction
def handle(request, response)
# only accessible when authenticated
end
end
Another option could be to override authenticate_user in the inheriting class. In Ruby 3 it would be more concise: def authenticate_user = nil
I guess it’s a matter of taste. I’ve always felt dirty when using skip_before_action, as if my code was saying one thing at high level (this class inherits from X) and doing a different one (well, actually…), so I like the lack if skip_before_action as it won’t encourage that pattern.
Yea I would agree in general. I was asking the question cause I was leaning towards not having those skip_ things either, good to see other think alike :v
Yea, I don’t think we should add any skip callbacks functionality. There are better ways to solve that problem, and developers should pick the one that suits their situation best.
In my app, I just use before :require_authentication! in all the actions that need authentication. It’s ~50% though, if it were 90%+, then I’d likely just do it for all actions, then override the method as a no-op like @raul suggested.