mirror of
https://github.com/heartcombo/devise.git
synced 2026-01-08 22:37:57 -05:00
- ### 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 :).
183 lines
5.3 KiB
Ruby
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
|