Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an option 'use_redirect_back_or_to_by_rails' to avoid definition conflicts of redirect_back_or_to #373

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Changelog
## HEAD

* Add an option 'use_redirect_back_or_to_by_rails' to set whether to use 'redirect_back_or_to' defined in Rails 7 [#373](https://github.com/Sorcery/sorcery/pull/373)
* Add bug tracker & changelog URLs to gemspec metadata [#372](https://github.com/Sorcery/sorcery/pull/372)
* Remove form_authenticity_token method [#371](https://github.com/Sorcery/sorcery/pull/371)
* Remove legacy Rails version conditionals [#370](https://github.com/Sorcery/sorcery/pull/370)
Expand Down
9 changes: 9 additions & 0 deletions lib/generators/sorcery/templates/initializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,15 @@
#
# config.save_return_to_url =

# Set whether to use 'redirect_back_or_to' defined in Rails 7.
# Rails 7 released a new method called 'redirect_back_or_to' as a replacement for 'redirect_back'.
# That may conflict with the method by the same name defined by Sorcery.
# If you set this option to true, Sorcery's 'redirect_back_or_to' calls 'super' to use
# the method of the same name defined in Rails 7.
# Default: `false`
#
# config.use_redirect_back_or_to_by_rails =

# Set domain option for cookies; Useful for remember_me submodule.
# Default: `nil`
#
Expand Down
11 changes: 10 additions & 1 deletion lib/sorcery/controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,16 @@ def current_user=(user)

# used when a user tries to access a page while logged out, is asked to login,
# and we want to return him back to the page he originally wanted.
def redirect_back_or_to(url, flash_hash = {})
def redirect_back_or_to(...)
if Config.use_redirect_back_or_to_by_rails
Copy link
Member

@willnet willnet May 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you are using Rails 6.1, calling super will cause an exception. Therefore, I want to ensure that super is not called even if Config.use_redirect_back_or_to_by_rails returns true.

Can you update the tests to expect a NoMethodError exception when using Rails 6.1?

The tests are currently failing.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have fixed in 7a494fc

super
else
warn('[WARNING] `redirect_back_or_to` overrides the method of the same name defined in Rails 7. If you want to avoid overriding, you can set `config.use_redirect_back_or_to_by_rails = true` and use `redirect_to_before_login_path`. In a future version, `config.use_redirect_back_or_to_by_rails = true` will become the default.')
redirect_to_before_login_path(...)
end
end

def redirect_to_before_login_path(url, flash_hash = {})
redirect_to(session[:return_to_url] || url, flash: flash_hash)
session[:return_to_url] = nil
end
Expand Down
6 changes: 5 additions & 1 deletion lib/sorcery/controller/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ class << self
attr_accessor :after_logout
attr_accessor :after_remember_me

# set whether to use 'redirect_back_or_to' defined in Rails 7.
attr_accessor :use_redirect_back_or_to_by_rails

def init!
@defaults = {
:@user_class => nil,
Expand All @@ -32,7 +35,8 @@ def init!
:@after_logout => Set.new,
:@after_remember_me => Set.new,
:@save_return_to_url => true,
:@cookie_domain => nil
:@cookie_domain => nil,
:@use_redirect_back_or_to_by_rails => false
}
end

Expand Down
43 changes: 43 additions & 0 deletions spec/controllers/controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@

expect(Sorcery::Controller::Config.not_authenticated_action).to eq :my_action
end

it "enables configuration option 'use_redirect_back_or_to_by_rails'" do
sorcery_controller_property_set(:use_redirect_back_or_to_by_rails, true)

expect(Sorcery::Controller::Config.use_redirect_back_or_to_by_rails).to be true
end
end

# ----------------- PLUGIN ACTIVATED -----------------------
Expand Down Expand Up @@ -186,5 +192,42 @@

expect(assigns[:result]).to eq user
end

describe 'redirect_back_or_to' do
describe 'use_redirect_back_or_to_by_rails' do
context 'when true' do
before do
sorcery_controller_property_set(:use_redirect_back_or_to_by_rails, true)
allow_any_instance_of(ActionController::TestRequest).to receive(:referer).and_return('http://test.host/referer_action')
end

context 'when Rails::VERSION::MAJOR >= 7', skip: Rails::VERSION::MAJOR < 7 do
it 'uses Rails 7 redirect_back_or_to method' do
get :test_return_to

expect(response).to redirect_to('http://test.host/referer_action')
end
end

context 'when Rails::VERSION::MAJOR < 7', skip: Rails::VERSION::MAJOR >= 7 do
it 'raise NoMethodError' do
expect { get :test_return_to }.to raise_error(NoMethodError)
end
end
end

context 'when false' do
before { sorcery_controller_property_set(:use_redirect_back_or_to_by_rails, false) }

it 'uses Sorcery redirect_back_or_to method' do
session[:return_to_url] = 'http://test.host/some_action'
get :test_return_to

expect(response).to redirect_to('http://test.host/some_action')
expect(flash[:notice]).to eq 'haha!'
end
end
end
end
end
end