Skip to content

Commit

Permalink
Evaluate callable redirects in context of controller (#203)
Browse files Browse the repository at this point in the history
* Evaluate callable redirects in context of controller

* Use instance_exec

* Optionally pass authenticatable as argument
  • Loading branch information
mikker authored Jan 26, 2024
1 parent fa40225 commit d69f28b
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 10 deletions.
25 changes: 20 additions & 5 deletions app/controllers/passwordless/sessions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,15 @@ def passwordless_query_redirect_path
nil
end

def passwordless_success_redirect_path
success_redirect_path = call_or_return(Passwordless.config.success_redirect_path)
def passwordless_success_redirect_path(authenticatable)
success_redirect_path = Passwordless.config.success_redirect_path

if success_redirect_path.respond_to?(:call)
success_redirect_path = call_or_return(
success_redirect_path,
*[authenticatable].first(success_redirect_path.arity)
)
end

if Passwordless.config.redirect_back_after_sign_in
session_redirect_url = reset_passwordless_redirect_location!(authenticatable_class)
Expand All @@ -142,7 +149,11 @@ def artificially_slow_down_brute_force_attacks(token)
def authenticate_and_sign_in(session, token)
if session.authenticate(token)
sign_in(session)
redirect_to(passwordless_success_redirect_path, status: :see_other, **redirect_to_options)
redirect_to(
passwordless_success_redirect_path(session.authenticatable),
status: :see_other,
**redirect_to_options
)
else
flash[:error] = I18n.t("passwordless.sessions.errors.invalid_token")
render(status: :forbidden, action: "show")
Expand All @@ -168,8 +179,12 @@ def authenticatable_class
authenticatable_type.constantize
end

def call_or_return(value)
value.respond_to?(:call) ? value.call : value
def call_or_return(value, *args)
if value.respond_to?(:call)
instance_exec(*args, &value)
else
value
end
end

def find_authenticatable
Expand Down
16 changes: 11 additions & 5 deletions test/controllers/passwordless/sessions_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -145,20 +145,26 @@ class << User
assert_equal pwless_session(User), Session.last!.id
end

test("PATCH /:passwordless_for/sign_in/:id -> SUCCESS / callable success path") do
test("PATCH /:passwordless_for/sign_in/:id -> SUCCESS / callable success path with no args") do
passwordless_session = create_pwless_session(token: "hi")

with_config(success_redirect_path: lambda { "/" }) do
patch("/users/sign_in/#{passwordless_session.identifier}", params: {passwordless: {token: "hi"}})
end

assert_equal 303, status

follow_redirect!
assert_equal 200, status
assert_equal "/", path
end

assert_equal pwless_session(User), Session.last!.id
test("PATCH /:passwordless_for/sign_in/:id -> SUCCESS / callable success path with 1 arg") do
passwordless_session = create_pwless_session(token: "hi")

with_config(success_redirect_path: lambda { |user| "/#{user.id}" }) do
patch("/users/sign_in/#{passwordless_session.identifier}", params: {passwordless: {token: "hi"}})
end

follow_redirect!
assert_equal "/#{passwordless_session.authenticatable.id}", path
end

test("PATCH /:passwordless_for/sign_in/:id -> ERROR") do
Expand Down

0 comments on commit d69f28b

Please sign in to comment.