Codebase list ruby-omniauth-facebook / 0859890
Move Utils to SignedRequest class. Josef Šimánek 9 years ago
3 changed file(s) with 43 addition(s) and 37 deletion(s). Raw diff Collapse all Expand all
0 require 'base64'
1 require 'openssl'
2
3 module OmniAuth
4 module Facebook
5 class SignedRequest
6 class UnknownSignatureAlgorithmError < NotImplementedError; end
7
8 SUPPORTED_ALGORITHM = 'HMAC-SHA256'
9
10 def self.parse_signed_request(value, secret)
11 signature, encoded_payload = value.split('.')
12 return if signature.nil?
13
14 decoded_hex_signature = base64_decode_url(signature)
15 decoded_payload = MultiJson.decode(base64_decode_url(encoded_payload))
16
17 unless decoded_payload['algorithm'] == SUPPORTED_ALGORITHM
18 raise UnknownSignatureAlgorithmError, "unknown algorithm: #{decoded_payload['algorithm']}"
19 end
20
21 if valid_signature?(secret, decoded_hex_signature, encoded_payload)
22 decoded_payload
23 end
24 end
25
26 def self.valid_signature?(secret, signature, payload, algorithm = OpenSSL::Digest::SHA256.new)
27 OpenSSL::HMAC.digest(algorithm, secret, payload) == signature
28 end
29
30 def self.base64_decode_url(value)
31 value += '=' * (4 - value.size.modulo(4))
32 Base64.decode64(value.tr('-_', '+/'))
33 end
34 end
35 end
36 end
00 require 'omniauth/strategies/oauth2'
1 require 'base64'
1 require 'omniauth/facebook/signed_request'
22 require 'openssl'
33 require 'rack/utils'
44 require 'uri'
55
66 module OmniAuth
7 module Utils
8 class UnknownSignatureAlgorithmError < NotImplementedError; end
9
10 SUPPORTED_ALGORITHM = 'HMAC-SHA256'
11
12 def Utils.parse_signed_request(value, secret)
13 signature, encoded_payload = value.split('.')
14 return if signature.nil?
15
16 decoded_hex_signature = base64_decode_url(signature)
17 decoded_payload = MultiJson.decode(base64_decode_url(encoded_payload))
18
19 unless decoded_payload['algorithm'] == SUPPORTED_ALGORITHM
20 raise UnknownSignatureAlgorithmError, "unknown algorithm: #{decoded_payload['algorithm']}"
21 end
22
23 if valid_signature?(secret, decoded_hex_signature, encoded_payload)
24 decoded_payload
25 end
26 end
27
28 def Utils.valid_signature?(secret, signature, payload, algorithm = OpenSSL::Digest::SHA256.new)
29 OpenSSL::HMAC.digest(algorithm, secret, payload) == signature
30 end
31
32 def Utils.base64_decode_url(value)
33 value += '=' * (4 - value.size.modulo(4))
34 Base64.decode64(value.tr('-_', '+/'))
35 end
36 end
37
387 module Strategies
398 class Facebook < OmniAuth::Strategies::OAuth2
409 class NoAuthorizationCodeError < StandardError; end
41
10
4211 DEFAULT_SCOPE = 'email'
4312
4413 option :client_options, {
10271 end
10372 rescue NoAuthorizationCodeError => e
10473 fail!(:no_authorization_code, e)
105 rescue Utils::UnknownSignatureAlgorithmError => e
74 rescue OmniAuth::Facebook::SignedRequest::UnknownSignatureAlgorithmError => e
10675 fail!(:unknown_signature_algorithm, e)
10776 end
10877
148117 private
149118
150119 def signed_request_from_cookie
151 @signed_request_from_cookie ||= raw_signed_request_from_cookie && Utils.parse_signed_request(raw_signed_request_from_cookie, client.secret)
120 @signed_request_from_cookie ||= raw_signed_request_from_cookie && OmniAuth::Facebook::SignedRequest.parse_signed_request(raw_signed_request_from_cookie, client.secret)
152121 end
153122
154123 def raw_signed_request_from_cookie
436436
437437 test 'throws an error if the algorithm is unknown' do
438438 setup('UNKNOWN-ALGO')
439 assert_equal "unknown algorithm: UNKNOWN-ALGO", assert_raises(OmniAuth::Utils::UnknownSignatureAlgorithmError) { strategy.send(:signed_request_from_cookie) }.message
439 assert_equal "unknown algorithm: UNKNOWN-ALGO", assert_raises(OmniAuth::Facebook::SignedRequest::UnknownSignatureAlgorithmError) { strategy.send(:signed_request_from_cookie) }.message
440440 end
441441 end
442442
496496 end
497497
498498 test 'calls fail! when an algorithm is unknown' do
499 strategy.expects(:fail!).times(1).with(:unknown_signature_algorithm, kind_of(OmniAuth::Utils::UnknownSignatureAlgorithmError))
499 strategy.expects(:fail!).times(1).with(:unknown_signature_algorithm, kind_of(OmniAuth::Facebook::SignedRequest::UnknownSignatureAlgorithmError))
500500 strategy.callback_phase
501501 end
502502 end