From f5d81bec035076cad1ef7b61adc1b32d206eeb2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josef=20=C5=A0im=C3=A1nek?= Date: Sat, 6 Dec 2014 06:26:11 +0100 Subject: [PATCH 1/9] Add verified access_token authentication. --- lib/omniauth/strategies/facebook.rb | 33 ++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/lib/omniauth/strategies/facebook.rb b/lib/omniauth/strategies/facebook.rb index b078eb3..5fb7faf 100644 --- a/lib/omniauth/strategies/facebook.rb +++ b/lib/omniauth/strategies/facebook.rb @@ -67,8 +67,13 @@ def info_options end def callback_phase - with_authorization_code! do + if access_token = request.params["access_token"] + options.provider_ignores_state = true super + else + with_authorization_code! do + super + end end rescue NoAuthorizationCodeError => e fail!(:no_authorization_code, e) @@ -110,13 +115,35 @@ def authorize_params protected def build_access_token - super.tap do |token| - token.options.merge!(access_token_options) + if request.params["access_token"] + build_access_token_from_request(request.params["access_token"]) + else + super.tap do |token| + token.options.merge!(access_token_options) + end end end private + def build_access_token_from_request(access_token_param) + token_hash = { :access_token => access_token_param } + access_token = ::OAuth2::AccessToken.from_hash(client, token_hash.update(access_token_options)) + verify_access_token!(access_token) + return access_token + end + + def app_access_token + "%s|%s" % [client.id, client.secret] + end + + def verify_access_token!(access_token) + token_info = access_token.get('/debug_token', :params => { :input_token => access_token.token, :access_token => app_access_token }) + # verify all needed scopes are allowed + missing_scopes = authorize_params.scope.split(',') - token_info.parsed.fetch("data", {}).fetch("scopes", []) + raise "missing scopes #{missing_scopes.join(', ')}" if missing_scopes.any? + end + def signed_request_from_cookie @signed_request_from_cookie ||= raw_signed_request_from_cookie && OmniAuth::Facebook::SignedRequest.parse(raw_signed_request_from_cookie, client.secret) end From d20554c446c776e98cdcb018d5e38faf54884cef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josef=20=C5=A0im=C3=A1nek?= Date: Thu, 14 May 2015 17:53:25 +0200 Subject: [PATCH 2/9] Strip scopes. --- lib/omniauth/strategies/facebook.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/omniauth/strategies/facebook.rb b/lib/omniauth/strategies/facebook.rb index 5fb7faf..ad35bfe 100644 --- a/lib/omniauth/strategies/facebook.rb +++ b/lib/omniauth/strategies/facebook.rb @@ -140,7 +140,7 @@ def app_access_token def verify_access_token!(access_token) token_info = access_token.get('/debug_token', :params => { :input_token => access_token.token, :access_token => app_access_token }) # verify all needed scopes are allowed - missing_scopes = authorize_params.scope.split(',') - token_info.parsed.fetch("data", {}).fetch("scopes", []) + missing_scopes = authorize_params.scope.split(',').collect(&:strip) - token_info.parsed.fetch("data", {}).fetch("scopes", []) raise "missing scopes #{missing_scopes.join(', ')}" if missing_scopes.any? end From 018c7cb6a8b48087a5dd6742c1cc37a5eeffef48 Mon Sep 17 00:00:00 2001 From: Eric Newbury Date: Wed, 30 Jan 2019 13:35:56 -0500 Subject: [PATCH 3/9] feature: test and refactor validated token flow --- .gitignore | 1 + lib/omniauth/strategies/facebook.rb | 55 ++++---- test/helper.rb | 4 +- test/strategy_test.rb | 212 ++++++++++++++++------------ 4 files changed, 154 insertions(+), 118 deletions(-) diff --git a/.gitignore b/.gitignore index 1d5d65a..620e725 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ pkg/* .powder tmp bin +.idea diff --git a/lib/omniauth/strategies/facebook.rb b/lib/omniauth/strategies/facebook.rb index e7eb04f..5fca938 100644 --- a/lib/omniauth/strategies/facebook.rb +++ b/lib/omniauth/strategies/facebook.rb @@ -7,7 +7,9 @@ module OmniAuth module Strategies class Facebook < OmniAuth::Strategies::OAuth2 - class NoAuthorizationCodeError < StandardError; end + class NoTokenOrCodeError < StandardError; end + class MissingScopesError < StandardError; end + class AppIdMismatchError < StandardError; end DEFAULT_SCOPE = 'email' @@ -63,16 +65,11 @@ def info_options end def callback_phase - if access_token = request.params["access_token"] - options.provider_ignores_state = true + with_authorization_parameter! do super - else - with_authorization_code! do - super - end end - rescue NoAuthorizationCodeError => e - fail!(:no_authorization_code, e) + rescue NoTokenOrCodeError => e + fail!(:no_token_or_code, e) rescue OmniAuth::Facebook::SignedRequest::UnknownSignatureAlgorithmError => e fail!(:unknown_signature_algorithm, e) end @@ -81,7 +78,7 @@ def callback_phase # phase and it must match during the access_token phase: # https://github.com/facebook/facebook-php-sdk/blob/master/src/base_facebook.php#L477 def callback_url - if @authorization_code_from_signed_request_in_cookie + if defined?(@auth_code_from_cookie) && @auth_code_from_cookie '' else # Fixes regression in omniauth-oauth2 v1.4.0 by https://github.com/intridea/omniauth-oauth2/commit/85fdbe117c2a4400d001a6368cc359d88f40abc7 @@ -130,35 +127,29 @@ def build_access_token_from_request(access_token_param) return access_token end - def app_access_token - "%s|%s" % [client.id, client.secret] - end - def verify_access_token!(access_token) - token_info = access_token.get('/debug_token', :params => { :input_token => access_token.token, :access_token => app_access_token }) - # verify all needed scopes are allowed + opts = { params: { input_token: access_token.token, access_token: app_access_token }} + token_info = access_token.get('/debug_token', opts) missing_scopes = authorize_params.scope.split(',').collect(&:strip) - token_info.parsed.fetch("data", {}).fetch("scopes", []) - raise "missing scopes #{missing_scopes.join(', ')}" if missing_scopes.any? - end - - def signed_request_from_cookie - @signed_request_from_cookie ||= raw_signed_request_from_cookie && OmniAuth::Facebook::SignedRequest.parse(raw_signed_request_from_cookie, client.secret) + raise MissingScopesError, "Missing scopes #{missing_scopes.join(', ')}" if missing_scopes.any? + rescue ::OAuth2::Error => e + raise AppIdMismatchError, "Failed to validate token: #{e.message}" end - def raw_signed_request_from_cookie - request.cookies["fbsr_#{client.id}"] + def app_access_token + "%s|%s" % [client.id, client.secret] end # Picks the authorization code in order, from: # # 1. The request 'code' param (manual callback from standard server-side flow) # 2. A signed request from cookie (passed from the client during the client-side flow) - def with_authorization_code! - if request.params.key?('code') + def with_authorization_parameter! + if request.params.key?('code') || request.params.key?('access_token') yield elsif code_from_signed_request = signed_request_from_cookie && signed_request_from_cookie['code'] request.params['code'] = code_from_signed_request - @authorization_code_from_signed_request_in_cookie = true + @auth_code_from_cookie = true # NOTE The code from the signed fbsr_XXX cookie is set by the FB JS SDK will confirm that the identity of the # user contained in the signed request matches the user loading the app. original_provider_ignores_state = options.provider_ignores_state @@ -167,14 +158,22 @@ def with_authorization_code! yield ensure request.params.delete('code') - @authorization_code_from_signed_request_in_cookie = false + @auth_code_from_cookie = false options.provider_ignores_state = original_provider_ignores_state end else - raise NoAuthorizationCodeError, 'must pass either a `code` (via URL or by an `fbsr_XXX` signed request cookie)' + raise NoTokenOrCodeError, 'must pass either a `access_token` param or a `code` (via URL param or by an `fbsr_XXX` signed request cookie)' end end + def signed_request_from_cookie + @signed_request_from_cookie ||= raw_signed_request_from_cookie && OmniAuth::Facebook::SignedRequest.parse(raw_signed_request_from_cookie, client.secret) + end + + def raw_signed_request_from_cookie + request.cookies["fbsr_#{client.id}"] + end + def prune!(hash) hash.delete_if do |_, value| prune!(value) if value.is_a?(Hash) diff --git a/test/helper.rb b/test/helper.rb index bd1b82b..e7e62ba 100644 --- a/test/helper.rb +++ b/test/helper.rb @@ -32,7 +32,7 @@ class TestCase < Minitest::Test class StrategyTestCase < TestCase def setup - @request = stub('Request') + @request = stub('Request', {}) @request.stubs(:params).returns({}) @request.stubs(:cookies).returns({}) @request.stubs(:env).returns({}) @@ -41,6 +41,8 @@ def setup @client_id = '123' @client_secret = '53cr3tz' + + @options = nil end def strategy diff --git a/test/strategy_test.rb b/test/strategy_test.rb index 3cc4a9a..8094163 100644 --- a/test/strategy_test.rb +++ b/test/strategy_test.rb @@ -391,118 +391,152 @@ def setup end end -module SignedRequestHelpers - def signed_request(payload, secret) - encoded_payload = base64_encode_url(MultiJson.encode(payload)) - encoded_signature = base64_encode_url(signature(encoded_payload, secret)) - [encoded_signature, encoded_payload].join('.') - end - - def base64_encode_url(value) - Base64.encode64(value).tr('+/', '-_').gsub(/\n/, '') - end - - def signature(payload, secret, algorithm = OpenSSL::Digest::SHA256.new) - OpenSSL::HMAC.digest(algorithm, secret, payload) - end -end - -module SignedRequestTests - class TestCase < StrategyTestCase - include SignedRequestHelpers - end - - class CookieAndParamNotPresentTest < TestCase +module GettingAccessTokenTests + class CookieAndParamNotPresentTest < StrategyTestCase test 'is nil' do assert_nil strategy.send(:signed_request_from_cookie) end test 'throws an error on calling build_access_token' do - assert_raises(OmniAuth::Strategies::Facebook::NoAuthorizationCodeError) { strategy.send(:with_authorization_code!) {} } + assert_raises(OmniAuth::Strategies::Facebook::NoTokenOrCodeError) { strategy.send(:with_authorization_parameter!) {} } end end - class CookiePresentTest < TestCase - def setup(algo = nil) - super() - @payload = { - 'algorithm' => algo || 'HMAC-SHA256', - 'code' => 'm4c0d3z', - 'issued_at' => Time.now.to_i, - 'user_id' => '123456' - } - - @request.stubs(:cookies).returns({"fbsr_#{@client_id}" => signed_request(@payload, @client_secret)}) - end - - test 'parses the access code out from the cookie' do - assert_equal @payload, strategy.send(:signed_request_from_cookie) - end - - test 'throws an error if the algorithm is unknown' do - setup('UNKNOWN-ALGO') - assert_equal "unknown algorithm: UNKNOWN-ALGO", assert_raises(OmniAuth::Facebook::SignedRequest::UnknownSignatureAlgorithmError) { strategy.send(:signed_request_from_cookie) }.message - end - end - - class EmptySignedRequestTest < TestCase - def setup - super - @request.stubs(:params).returns({'signed_request' => ''}) - end - - test 'empty param' do - assert_equal nil, strategy.send(:signed_request_from_cookie) + class MissingParamsAndCookieRequestTest < StrategyTestCase + test 'calls fail! when a code or access_token is not included in the params' do + strategy.expects(:fail!).times(1).with(:no_token_or_code, kind_of(OmniAuth::Strategies::Facebook::NoTokenOrCodeError)) + strategy.callback_phase end end - class MissingCodeInParamsRequestTest < TestCase + class BadTokenTest < StrategyTestCase def setup super - @request.stubs(:params).returns({}) + @access_token = stub('OAuth2::AccessToken') + @access_token.stubs(:token).returns('fake_token') + ::OAuth2::AccessToken.stubs(:from_hash).returns(@access_token) + @request.stubs(:params).returns({'access_token' => 'fake_token'}) + strategy.stubs(:app_access_token).returns('other_token') end - test 'calls fail! when a code is not included in the params' do - strategy.expects(:fail!).times(1).with(:no_authorization_code, kind_of(OmniAuth::Strategies::Facebook::NoAuthorizationCodeError)) - strategy.callback_phase + test 'throws error when access token bad' do + params = { params: { input_token: 'fake_token', access_token: 'other_token' } } + @access_token.expects(:get).with('/debug_token', params).raises(::OAuth2::Error.new(stub_everything('Faraday::Response'))) + strategy.stubs(:access_token).returns(@access_token) + assert_raises(OmniAuth::Strategies::Facebook::AppIdMismatchError) { strategy.send(:build_access_token) {} } end - end - class MissingCodeInCookieRequestTest < TestCase - def setup(algo = nil) - super() - @payload = { - 'algorithm' => algo || 'HMAC-SHA256', - 'code' => nil, - 'issued_at' => Time.now.to_i, - 'user_id' => '123456' - } - - @request.stubs(:cookies).returns({"fbsr_#{@client_id}" => signed_request(@payload, @client_secret)}) + test 'fails when good token with missing scope' do + params = { params: { input_token: 'fake_token', access_token: 'other_token' } } + missing_scopes_response = stub_everything('Faraday::Response') + missing_scopes_response.stubs(:parsed).returns({ 'data' => {'scopes' => [] }}) + @access_token.expects(:get).with('/debug_token', params).returns(missing_scopes_response) + assert_raises(OmniAuth::Strategies::Facebook::MissingScopesError) { strategy.send(:build_access_token) {} } end - test 'calls fail! when a code is not included in the cookie' do - strategy.expects(:fail!).times(1).with(:no_authorization_code, kind_of(OmniAuth::Strategies::Facebook::NoAuthorizationCodeError)) - strategy.callback_phase + test 'succeeds when good token and scope' do + params = { params: { input_token: 'fake_token', access_token: 'other_token' } } + good_response = stub_everything('Faraday::Response') + good_response.stubs(:parsed).returns({ 'data' => {'scopes' => %w(public_profile email)}}) + @access_token.expects(:get).with('/debug_token', params).returns(good_response) + assert_equal 'fake_token', strategy.send(:build_access_token).token end end - - class UnknownAlgorithmInCookieRequestTest < TestCase - def setup - super() - @payload = { - 'algorithm' => 'UNKNOWN-ALGO', - 'code' => nil, - 'issued_at' => Time.now.to_i, - 'user_id' => '123456' - } - - @request.stubs(:cookies).returns({"fbsr_#{@client_id}" => signed_request(@payload, @client_secret)}) + # Fails when good token with missing scope + # Passes when param and good token + module VerifiedAccessTokenTests + module SignedRequestHelpers + def signed_request(payload, secret) + encoded_payload = base64_encode_url(MultiJson.encode(payload)) + encoded_signature = base64_encode_url(signature(encoded_payload, secret)) + [encoded_signature, encoded_payload].join('.') + end + + def base64_encode_url(value) + Base64.encode64(value).tr('+/', '-_').gsub(/\n/, '') + end + + def signature(payload, secret, algorithm = OpenSSL::Digest::SHA256.new) + OpenSSL::HMAC.digest(algorithm, secret, payload) + end end - test 'calls fail! when an algorithm is unknown' do - strategy.expects(:fail!).times(1).with(:unknown_signature_algorithm, kind_of(OmniAuth::Facebook::SignedRequest::UnknownSignatureAlgorithmError)) - strategy.callback_phase + module SignedRequestTests + class TestCase < StrategyTestCase + include SignedRequestHelpers + end + + class CookiePresentTest < TestCase + def setup(algo = nil) + super() + @payload = { + 'algorithm' => algo || 'HMAC-SHA256', + 'code' => 'm4c0d3z', + 'issued_at' => Time.now.to_i, + 'user_id' => '123456' + } + + @request.stubs(:cookies).returns({"fbsr_#{@client_id}" => signed_request(@payload, @client_secret)}) + end + + test 'parses the access code out from the cookie' do + assert_equal @payload, strategy.send(:signed_request_from_cookie) + end + + test 'throws an error if the algorithm is unknown' do + setup('UNKNOWN-ALGO') + assert_equal "unknown algorithm: UNKNOWN-ALGO", assert_raises(OmniAuth::Facebook::SignedRequest::UnknownSignatureAlgorithmError) { strategy.send(:signed_request_from_cookie) }.message + end + end + + class EmptySignedRequestTest < TestCase + def setup + super + @request.stubs(:params).returns({'signed_request' => ''}) + end + + test 'empty param' do + assert_nil strategy.send(:signed_request_from_cookie) + end + end + + class MissingCodeInCookieRequestTest < TestCase + def setup(algo = nil) + super() + @payload = { + 'algorithm' => algo || 'HMAC-SHA256', + 'code' => nil, + 'issued_at' => Time.now.to_i, + 'user_id' => '123456' + } + + @request.stubs(:cookies).returns({"fbsr_#{@client_id}" => signed_request(@payload, @client_secret)}) + end + + test 'calls fail! when a code is not included in the cookie' do + strategy.expects(:fail!).times(1).with(:no_token_or_code, kind_of(OmniAuth::Strategies::Facebook::NoTokenOrCodeError)) + strategy.callback_phase + end + end + + class UnknownAlgorithmInCookieRequestTest < TestCase + def setup + super() + @payload = { + 'algorithm' => 'UNKNOWN-ALGO', + 'code' => nil, + 'issued_at' => Time.now.to_i, + 'user_id' => '123456' + } + + @request.stubs(:cookies).returns({"fbsr_#{@client_id}" => signed_request(@payload, @client_secret)}) + end + + test 'calls fail! when an algorithm is unknown' do + strategy.expects(:fail!).times(1).with(:unknown_signature_algorithm, kind_of(OmniAuth::Facebook::SignedRequest::UnknownSignatureAlgorithmError)) + strategy.callback_phase + end + end end end end From 3958a0600a2ed3c7f8bcca4bf736fcf40fb6b517 Mon Sep 17 00:00:00 2001 From: Eric Newbury Date: Wed, 30 Jan 2019 13:43:51 -0500 Subject: [PATCH 4/9] docs: update readme --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 09cf451..a246e84 100644 --- a/README.md +++ b/README.md @@ -136,6 +136,11 @@ When you call `/auth/facebook/callback` in the success callback of `FB.login` th 2. extract the authorization code contained in it 3. and hit Facebook and obtain an access token which will get placed in the `request.env['omniauth.auth']['credentials']` hash. +## Client-side Flow with Facebook Android and ioS SDK + +A long lived access token is returned by the native sdks. This flow is supported by sending an "access_token" query parameter to your callback. This token is then verified with facebook using your client_id and client_secret before being used. +Be sure to leave CSRF protection on for this method of authentication. + ## Token Expiry The expiration time of the access token you obtain will depend on which flow you are using. From c829ec69391ff13137f30964f6d907150bf0a3f0 Mon Sep 17 00:00:00 2001 From: Eric Newbury Date: Wed, 30 Jan 2019 15:50:11 -0500 Subject: [PATCH 5/9] add correct rescue --- lib/omniauth/strategies/facebook.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/omniauth/strategies/facebook.rb b/lib/omniauth/strategies/facebook.rb index 5fca938..2ee7be7 100644 --- a/lib/omniauth/strategies/facebook.rb +++ b/lib/omniauth/strategies/facebook.rb @@ -68,6 +68,8 @@ def callback_phase with_authorization_parameter! do super end + rescue AppIdMismatchError => e + fail!(:app_id_mismatch, e) rescue NoTokenOrCodeError => e fail!(:no_token_or_code, e) rescue OmniAuth::Facebook::SignedRequest::UnknownSignatureAlgorithmError => e From 3e83c808ae72487cee285931fc7cf2c8268b72c0 Mon Sep 17 00:00:00 2001 From: Eric Newbury Date: Wed, 30 Jan 2019 15:50:42 -0500 Subject: [PATCH 6/9] add extra catch --- lib/omniauth/strategies/facebook.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/omniauth/strategies/facebook.rb b/lib/omniauth/strategies/facebook.rb index 2ee7be7..09adc3e 100644 --- a/lib/omniauth/strategies/facebook.rb +++ b/lib/omniauth/strategies/facebook.rb @@ -70,6 +70,8 @@ def callback_phase end rescue AppIdMismatchError => e fail!(:app_id_mismatch, e) + rescue MissingScopesError => e + fail!(:missing_scopes, e) rescue NoTokenOrCodeError => e fail!(:no_token_or_code, e) rescue OmniAuth::Facebook::SignedRequest::UnknownSignatureAlgorithmError => e From 6e1ef6ab107a45499d8a8c3a140166b2fa8d3a65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josef=20=C5=A0im=C3=A1nek?= Date: Sat, 6 Dec 2014 06:26:11 +0100 Subject: [PATCH 7/9] Add verified access_token authentication. --- lib/omniauth/strategies/facebook.rb | 33 ++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/lib/omniauth/strategies/facebook.rb b/lib/omniauth/strategies/facebook.rb index 12a9003..6464c43 100644 --- a/lib/omniauth/strategies/facebook.rb +++ b/lib/omniauth/strategies/facebook.rb @@ -63,8 +63,13 @@ def info_options end def callback_phase - with_authorization_code! do + if access_token = request.params["access_token"] + options.provider_ignores_state = true super + else + with_authorization_code! do + super + end end rescue NoAuthorizationCodeError => e fail!(:no_authorization_code, e) @@ -107,13 +112,35 @@ def authorize_params protected def build_access_token - super.tap do |token| - token.options.merge!(access_token_options) + if request.params["access_token"] + build_access_token_from_request(request.params["access_token"]) + else + super.tap do |token| + token.options.merge!(access_token_options) + end end end private + def build_access_token_from_request(access_token_param) + token_hash = { :access_token => access_token_param } + access_token = ::OAuth2::AccessToken.from_hash(client, token_hash.update(access_token_options)) + verify_access_token!(access_token) + return access_token + end + + def app_access_token + "%s|%s" % [client.id, client.secret] + end + + def verify_access_token!(access_token) + token_info = access_token.get('/debug_token', :params => { :input_token => access_token.token, :access_token => app_access_token }) + # verify all needed scopes are allowed + missing_scopes = authorize_params.scope.split(',') - token_info.parsed.fetch("data", {}).fetch("scopes", []) + raise "missing scopes #{missing_scopes.join(', ')}" if missing_scopes.any? + end + def signed_request_from_cookie @signed_request_from_cookie ||= raw_signed_request_from_cookie && OmniAuth::Facebook::SignedRequest.parse(raw_signed_request_from_cookie, client.secret) end From 8b970933e390c88a0efb837f89f5936970d0ce80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josef=20=C5=A0im=C3=A1nek?= Date: Thu, 14 May 2015 17:53:25 +0200 Subject: [PATCH 8/9] Strip scopes. --- lib/omniauth/strategies/facebook.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/omniauth/strategies/facebook.rb b/lib/omniauth/strategies/facebook.rb index 6464c43..e7eb04f 100644 --- a/lib/omniauth/strategies/facebook.rb +++ b/lib/omniauth/strategies/facebook.rb @@ -137,7 +137,7 @@ def app_access_token def verify_access_token!(access_token) token_info = access_token.get('/debug_token', :params => { :input_token => access_token.token, :access_token => app_access_token }) # verify all needed scopes are allowed - missing_scopes = authorize_params.scope.split(',') - token_info.parsed.fetch("data", {}).fetch("scopes", []) + missing_scopes = authorize_params.scope.split(',').collect(&:strip) - token_info.parsed.fetch("data", {}).fetch("scopes", []) raise "missing scopes #{missing_scopes.join(', ')}" if missing_scopes.any? end From b940a3e63c8e4ba318c9786ca1a36c72b477f9e8 Mon Sep 17 00:00:00 2001 From: Eric Newbury Date: Tue, 12 Feb 2019 10:18:57 -0500 Subject: [PATCH 9/9] maintain backward compatability --- .gitignore | 1 - CHANGELOG.md | 6 ++++++ lib/omniauth/strategies/facebook.rb | 8 ++++---- test/strategy_test.rb | 6 +++--- 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index 620e725..1d5d65a 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,3 @@ pkg/* .powder tmp bin -.idea diff --git a/CHANGELOG.md b/CHANGELOG.md index 12eff04..8b0e345 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 5.1.0 (2019-02-12) + +Changes: + + - support for an access_token param, validated by facebook's debug token api + ## 5.0.0 (2018-03-29) Changes: diff --git a/lib/omniauth/strategies/facebook.rb b/lib/omniauth/strategies/facebook.rb index 09adc3e..61a12d5 100644 --- a/lib/omniauth/strategies/facebook.rb +++ b/lib/omniauth/strategies/facebook.rb @@ -7,7 +7,7 @@ module OmniAuth module Strategies class Facebook < OmniAuth::Strategies::OAuth2 - class NoTokenOrCodeError < StandardError; end + class NoAuthorizationCodeError < StandardError; end class MissingScopesError < StandardError; end class AppIdMismatchError < StandardError; end @@ -72,8 +72,8 @@ def callback_phase fail!(:app_id_mismatch, e) rescue MissingScopesError => e fail!(:missing_scopes, e) - rescue NoTokenOrCodeError => e - fail!(:no_token_or_code, e) + rescue NoAuthorizationCodeError => e + fail!(:no_authorization_code, e) rescue OmniAuth::Facebook::SignedRequest::UnknownSignatureAlgorithmError => e fail!(:unknown_signature_algorithm, e) end @@ -166,7 +166,7 @@ def with_authorization_parameter! options.provider_ignores_state = original_provider_ignores_state end else - raise NoTokenOrCodeError, 'must pass either a `access_token` param or a `code` (via URL param or by an `fbsr_XXX` signed request cookie)' + raise NoAuthorizationCodeError, 'must pass either a `access_token` param or a `code` (via URL param or by an `fbsr_XXX` signed request cookie)' end end diff --git a/test/strategy_test.rb b/test/strategy_test.rb index 8094163..3954260 100644 --- a/test/strategy_test.rb +++ b/test/strategy_test.rb @@ -398,13 +398,13 @@ class CookieAndParamNotPresentTest < StrategyTestCase end test 'throws an error on calling build_access_token' do - assert_raises(OmniAuth::Strategies::Facebook::NoTokenOrCodeError) { strategy.send(:with_authorization_parameter!) {} } + assert_raises(OmniAuth::Strategies::Facebook::NoAuthorizationCodeError) { strategy.send(:with_authorization_parameter!) {} } end end class MissingParamsAndCookieRequestTest < StrategyTestCase test 'calls fail! when a code or access_token is not included in the params' do - strategy.expects(:fail!).times(1).with(:no_token_or_code, kind_of(OmniAuth::Strategies::Facebook::NoTokenOrCodeError)) + strategy.expects(:fail!).times(1).with(:no_authorization_code, kind_of(OmniAuth::Strategies::Facebook::NoAuthorizationCodeError)) strategy.callback_phase end end @@ -514,7 +514,7 @@ def setup(algo = nil) end test 'calls fail! when a code is not included in the cookie' do - strategy.expects(:fail!).times(1).with(:no_token_or_code, kind_of(OmniAuth::Strategies::Facebook::NoTokenOrCodeError)) + strategy.expects(:fail!).times(1).with(:no_authorization_code, kind_of(OmniAuth::Strategies::Facebook::NoAuthorizationCodeError)) strategy.callback_phase end end