Files
devise/test/integration/omniauthable_test.rb
Edouard CHIN 4f82235630 Use Omniauth.allowed_methods' as routing verbs for the auth path:
- ### Context

  Since version 2.0.0, Omniauth no longer recognizes `GET` request
  on the auth path (`/users/auth/<provider>`). `POST` is the only
  verb that is by default recognized in order to mitigate CSRF
  attack. 66110da85e/lib/omniauth/strategy.rb (L205)

  Ultimatelly, when a user try to access `GET /users/auth/facebook`,
  Devise [passthru action](6d32d2447c/app/controllers/devise/omniauth_callbacks_controller.rb (L6))
  will be called which just return a raw 404 page.

  ### Problem

  There is no problem per se and everything work. However the
  advantage of not matching GET request at the router layer allows
  to get that same 404 page stylized for "free" (Rails ending up
  rendering the 404 page of the app).

  I believe it's also more consistent and less surprising for users
  if this passthru action don't get called.

  ### Drawback

  An application can no longer override the `passthru` to perform
  the logic it wants (i.e. redirect the user).

  If this is a dealbreaker, feel free to close this PR :).
2023-06-09 23:46:12 +00:00

183 lines
5.3 KiB
Ruby

# frozen_string_literal: true
require 'test_helper'
class OmniauthableIntegrationTest < Devise::IntegrationTest
FACEBOOK_INFO = {
"id" => '12345',
"link" => 'http://facebook.com/josevalim',
"email" => 'user@example.com',
"first_name" => 'Jose',
"last_name" => 'Valim',
"website" => 'http://blog.plataformatec.com.br'
}
setup do
OmniAuth.config.test_mode = true
OmniAuth.config.mock_auth[:facebook] = {
"uid" => '12345',
"provider" => 'facebook',
"user_info" => {"nickname" => 'josevalim'},
"credentials" => {"token" => 'plataformatec'},
"extra" => {"user_hash" => FACEBOOK_INFO}
}
OmniAuth.config.add_camelization 'facebook', 'FaceBook'
if OmniAuth.config.respond_to?(:request_validation_phase)
OmniAuth.config.request_validation_phase = ->(env) {}
end
end
teardown do
OmniAuth.config.camelizations.delete('facebook')
OmniAuth.config.test_mode = false
end
def stub_action!(name)
Users::OmniauthCallbacksController.class_eval do
alias_method :__old_facebook, :facebook
alias_method :facebook, name
end
yield
ensure
Users::OmniauthCallbacksController.class_eval do
alias_method :facebook, :__old_facebook
end
end
test "omniauth sign in should not run model validations" do
stub_action!(:sign_in_facebook) do
create_user
post "/users/auth/facebook"
follow_redirect!
assert warden.authenticated?(:user)
assert_not User.validations_performed
end
end
test "can access omniauth.auth in the env hash" do
post "/users/auth/facebook"
follow_redirect!
json = ActiveSupport::JSON.decode(response.body)
assert_equal "12345", json["uid"]
assert_equal "facebook", json["provider"]
assert_equal "josevalim", json["user_info"]["nickname"]
assert_equal FACEBOOK_INFO, json["extra"]["user_hash"]
assert_equal "plataformatec", json["credentials"]["token"]
end
test "cleans up session on sign up" do
assert_no_difference "User.count" do
post "/users/auth/facebook"
follow_redirect!
end
assert session["devise.facebook_data"]
assert_difference "User.count" do
visit "/users/sign_up"
fill_in "Password", with: "12345678"
fill_in "Password confirmation", with: "12345678"
click_button "Sign up"
end
assert_current_url "/"
assert_contain "You have signed up successfully."
assert_contain "Hello User user@example.com"
assert_not session["devise.facebook_data"]
end
test "cleans up session on cancel" do
assert_no_difference "User.count" do
post "/users/auth/facebook"
follow_redirect!
end
assert session["devise.facebook_data"]
visit "/users/cancel"
assert_not session["devise.facebook_data"]
end
test "cleans up session on sign in" do
assert_no_difference "User.count" do
post "/users/auth/facebook"
follow_redirect!
end
assert session["devise.facebook_data"]
sign_in_as_user
assert_not session["devise.facebook_data"]
end
test "sign in and send remember token if configured" do
post "/users/auth/facebook"
follow_redirect!
assert_nil warden.cookies["remember_user_token"]
stub_action!(:sign_in_facebook) do
create_user
post "/users/auth/facebook"
follow_redirect!
assert warden.authenticated?(:user)
assert warden.cookies["remember_user_token"]
end
end
test "authorization path via GET when Omniauth allowed_request_methods includes GET" do
original_allowed = OmniAuth.config.allowed_request_methods
OmniAuth.config.allowed_request_methods = [:get, :post]
get "/users/auth/facebook"
assert_response(:redirect)
ensure
OmniAuth.config.allowed_request_methods = original_allowed
end
test "authorization path via GET when Omniauth allowed_request_methods doesn't include GET" do
original_allowed = OmniAuth.config.allowed_request_methods
OmniAuth.config.allowed_request_methods = [:post]
assert_raises(ActionController::RoutingError) do
get "/users/auth/facebook"
end
ensure
OmniAuth.config.allowed_request_methods = original_allowed
end
test "generates a link to authenticate with provider" do
visit "/users/sign_in"
assert_select "form[action=?][method=post]", "/users/auth/facebook" do
assert_select "input[type=submit][value=?]", "Sign in with FaceBook"
end
end
test "generates a proper link when SCRIPT_NAME is set" do
header 'SCRIPT_NAME', '/q'
visit "/users/sign_in"
assert_select "form[action=?][method=post]", "/q/users/auth/facebook" do
assert_select "input[type=submit][value=?]", "Sign in with FaceBook"
end
end
test "handles callback error parameter according to the specification" do
OmniAuth.config.mock_auth[:facebook] = :access_denied
visit "/users/auth/facebook/callback?error=access_denied"
assert_current_url "/users/sign_in"
assert_contain 'Could not authenticate you from FaceBook because "Access denied".'
end
test "handles other exceptions from OmniAuth" do
OmniAuth.config.mock_auth[:facebook] = :invalid_credentials
post "/users/auth/facebook"
follow_redirect!
follow_redirect!
assert_contain 'Could not authenticate you from FaceBook because "Invalid credentials".'
end
end