Merge tag 'upstream/2.0.1'
Upstream version 2.0.1
nitesh jain
8 years ago
0 | ## 2.0.1 (2015-02-21) | |
1 | ||
2 | Bugfixes: | |
3 | ||
4 | - Allow versioning by not forcing absolute path for graph requests (#180, @frausto) | |
5 | - Allow the image_size option to be set as a symbol. (#182, @jgrau) | |
6 | ||
0 | 7 | ## 2.0.0 (2014-08-07) |
8 | ||
9 | Changes: | |
10 | ||
11 | - remove support for canvas app flow (765ed9, @mkdynamic) | |
1 | 12 | |
2 | 13 | Bugfixes: |
3 | 14 | |
4 | 15 | - bump omniauth-oauth2 dependency which addresses CVE-2012-6134 (#162, @linedotstar) |
16 | - rescue `NoAuthorizationCodeError` in callback_phase (a0036b, @tomoya55) | |
17 | - fix CSRF exception when using FB JS SDK and parsing signed request (765ed9, @mkdynamic) | |
5 | 18 | |
6 | 19 | ## 1.6.0 (2014-01-13) |
7 | 20 |
58 | 58 | end |
59 | 59 | ``` |
60 | 60 | |
61 | ### API Version | |
62 | ||
63 | OmniAuth Facebook uses unversioned API endpoints by default. You can configure custom endpoints via `client_options` hash passed to `provider`. | |
64 | ||
65 | ```ruby | |
66 | use OmniAuth::Builder do | |
67 | provider :facebook, ENV['APP_ID'], ENV['APP_SECRET'], | |
68 | :client_options => { | |
69 | :site => 'https://graph.facebook.com/v2.0', | |
70 | :authorize_url => "https://www.facebook.com/v2.0/dialog/oauth" | |
71 | } | |
72 | end | |
73 | ``` | |
61 | 74 | ### Per-Request Options |
62 | 75 | |
63 | 76 | If you want to set the `display` format, `auth_type`, or `scope` on a per-request basis, you can just pass it to the OmniAuth request phase URL, for example: `/auth/facebook?display=popup` or `/auth/facebook?scope=email`. |
0 | 0 | PATH |
1 | 1 | remote: ../ |
2 | 2 | specs: |
3 | omniauth-facebook (2.0.0.pre1) | |
4 | omniauth-oauth2 (~> 1.1) | |
3 | omniauth-facebook (2.0.0) | |
4 | omniauth-oauth2 (~> 1.2) | |
5 | 5 | |
6 | 6 | GEM |
7 | 7 | remote: https://rubygems.org/ |
9 | 9 | backports (3.3.5) |
10 | 10 | faraday (0.9.0) |
11 | 11 | multipart-post (>= 1.2, < 3) |
12 | hashie (2.1.1) | |
13 | jwt (0.1.13) | |
14 | multi_json (>= 1.5) | |
12 | hashie (3.2.0) | |
13 | jwt (1.0.0) | |
15 | 14 | multi_json (1.8.2) |
16 | 15 | multi_xml (0.5.5) |
17 | 16 | multipart-post (2.0.0) |
18 | oauth2 (0.9.3) | |
17 | oauth2 (1.0.0) | |
19 | 18 | faraday (>= 0.8, < 0.10) |
20 | jwt (~> 0.1.8) | |
19 | jwt (~> 1.0) | |
21 | 20 | multi_json (~> 1.3) |
22 | 21 | multi_xml (~> 0.5) |
23 | 22 | rack (~> 1.2) |
24 | omniauth (1.2.1) | |
25 | hashie (>= 1.2, < 3) | |
23 | omniauth (1.2.2) | |
24 | hashie (>= 1.2, < 4) | |
26 | 25 | rack (~> 1.0) |
27 | omniauth-oauth2 (1.1.2) | |
26 | omniauth-oauth2 (1.2.0) | |
28 | 27 | faraday (>= 0.8, < 0.10) |
29 | 28 | multi_json (~> 1.3) |
30 | oauth2 (~> 0.9.3) | |
29 | oauth2 (~> 1.0) | |
31 | 30 | omniauth (~> 1.2) |
32 | 31 | rack (1.5.2) |
33 | 32 | rack-protection (1.5.1) |
10 | 10 | class UnknownSignatureAlgorithmError < NotImplementedError; end |
11 | 11 | |
12 | 12 | DEFAULT_SCOPE = 'email' |
13 | SUPPORTED_ALGORITHM = 'HMAC-SHA256' | |
13 | 14 | |
14 | 15 | option :client_options, { |
15 | 16 | :site => 'https://graph.facebook.com', |
16 | 17 | :authorize_url => "https://www.facebook.com/dialog/oauth", |
17 | :token_url => '/oauth/access_token' | |
18 | :token_url => 'oauth/access_token' | |
18 | 19 | } |
19 | 20 | |
20 | 21 | option :token_params, { |
55 | 56 | end |
56 | 57 | |
57 | 58 | def raw_info |
58 | @raw_info ||= access_token.get('/me', info_options).parsed || {} | |
59 | @raw_info ||= access_token.get('me', info_options).parsed || {} | |
59 | 60 | end |
60 | 61 | |
61 | 62 | def info_options |
73 | 74 | rescue NoAuthorizationCodeError => e |
74 | 75 | fail!(:no_authorization_code, e) |
75 | 76 | rescue UnknownSignatureAlgorithmError => e |
76 | fail!(:unknown_signature_algoruthm, e) | |
77 | fail!(:unknown_signature_algorithm, e) | |
77 | 78 | end |
78 | 79 | |
79 | 80 | # NOTE If we're using code from the signed request then FB sets the redirect_uri to '' during the authorize |
165 | 166 | decoded_hex_signature = base64_decode_url(signature) |
166 | 167 | decoded_payload = MultiJson.decode(base64_decode_url(encoded_payload)) |
167 | 168 | |
168 | unless decoded_payload['algorithm'] == 'HMAC-SHA256' | |
169 | unless decoded_payload['algorithm'] == SUPPORTED_ALGORITHM | |
169 | 170 | raise UnknownSignatureAlgorithmError, "unknown algorithm: #{decoded_payload['algorithm']}" |
170 | 171 | end |
171 | 172 | |
185 | 186 | |
186 | 187 | def image_url(uid, options) |
187 | 188 | uri_class = options[:secure_image_url] ? URI::HTTPS : URI::HTTP |
188 | url = uri_class.build({:host => 'graph.facebook.com', :path => "/#{uid}/picture"}) | |
189 | ||
190 | query = if options[:image_size].is_a?(String) | |
189 | site_uri = URI.parse(client.site) | |
190 | url = uri_class.build({:host => site_uri.host, :path => "#{site_uri.path}/#{uid}/picture"}) | |
191 | ||
192 | query = if options[:image_size].is_a?(String) || options[:image_size].is_a?(Symbol) | |
191 | 193 | { :type => options[:image_size] } |
192 | 194 | elsif options[:image_size].is_a?(Hash) |
193 | 195 | options[:image_size] |
0 | 0 | --- !ruby/object:Gem::Specification |
1 | 1 | name: omniauth-facebook |
2 | 2 | version: !ruby/object:Gem::Version |
3 | version: 2.0.0 | |
3 | version: 2.0.1 | |
4 | 4 | platform: ruby |
5 | 5 | authors: |
6 | 6 | - Mark Dodwell |
8 | 8 | autorequire: |
9 | 9 | bindir: bin |
10 | 10 | cert_chain: [] |
11 | date: 2014-08-07 00:00:00.000000000 Z | |
11 | date: 2015-02-21 00:00:00.000000000 Z | |
12 | 12 | dependencies: |
13 | 13 | - !ruby/object:Gem::Dependency |
14 | 14 | name: omniauth-oauth2 |
15 | 15 | requirement: !ruby/object:Gem::Requirement |
16 | 16 | requirements: |
17 | - - ~> | |
17 | - - "~>" | |
18 | 18 | - !ruby/object:Gem::Version |
19 | 19 | version: '1.2' |
20 | 20 | type: :runtime |
21 | 21 | prerelease: false |
22 | 22 | version_requirements: !ruby/object:Gem::Requirement |
23 | 23 | requirements: |
24 | - - ~> | |
24 | - - "~>" | |
25 | 25 | - !ruby/object:Gem::Version |
26 | 26 | version: '1.2' |
27 | 27 | - !ruby/object:Gem::Dependency |
28 | 28 | name: minitest |
29 | 29 | requirement: !ruby/object:Gem::Requirement |
30 | 30 | requirements: |
31 | - - '>=' | |
31 | - - ">=" | |
32 | 32 | - !ruby/object:Gem::Version |
33 | 33 | version: '0' |
34 | 34 | type: :development |
35 | 35 | prerelease: false |
36 | 36 | version_requirements: !ruby/object:Gem::Requirement |
37 | 37 | requirements: |
38 | - - '>=' | |
38 | - - ">=" | |
39 | 39 | - !ruby/object:Gem::Version |
40 | 40 | version: '0' |
41 | 41 | - !ruby/object:Gem::Dependency |
42 | 42 | name: mocha |
43 | 43 | requirement: !ruby/object:Gem::Requirement |
44 | 44 | requirements: |
45 | - - '>=' | |
45 | - - ">=" | |
46 | 46 | - !ruby/object:Gem::Version |
47 | 47 | version: '0' |
48 | 48 | type: :development |
49 | 49 | prerelease: false |
50 | 50 | version_requirements: !ruby/object:Gem::Requirement |
51 | 51 | requirements: |
52 | - - '>=' | |
52 | - - ">=" | |
53 | 53 | - !ruby/object:Gem::Version |
54 | 54 | version: '0' |
55 | 55 | - !ruby/object:Gem::Dependency |
56 | 56 | name: rake |
57 | 57 | requirement: !ruby/object:Gem::Requirement |
58 | 58 | requirements: |
59 | - - '>=' | |
59 | - - ">=" | |
60 | 60 | - !ruby/object:Gem::Version |
61 | 61 | version: '0' |
62 | 62 | type: :development |
63 | 63 | prerelease: false |
64 | 64 | version_requirements: !ruby/object:Gem::Requirement |
65 | 65 | requirements: |
66 | - - '>=' | |
66 | - - ">=" | |
67 | 67 | - !ruby/object:Gem::Version |
68 | 68 | version: '0' |
69 | 69 | description: |
74 | 74 | extensions: [] |
75 | 75 | extra_rdoc_files: [] |
76 | 76 | files: |
77 | - .gitignore | |
78 | - .travis.yml | |
77 | - ".gitignore" | |
78 | - ".travis.yml" | |
79 | 79 | - CHANGELOG.md |
80 | 80 | - Gemfile |
81 | 81 | - README.md |
102 | 102 | - lib |
103 | 103 | required_ruby_version: !ruby/object:Gem::Requirement |
104 | 104 | requirements: |
105 | - - '>=' | |
105 | - - ">=" | |
106 | 106 | - !ruby/object:Gem::Version |
107 | 107 | version: '0' |
108 | 108 | required_rubygems_version: !ruby/object:Gem::Requirement |
109 | 109 | requirements: |
110 | - - '>=' | |
110 | - - ">=" | |
111 | 111 | - !ruby/object:Gem::Version |
112 | 112 | version: '0' |
113 | 113 | requirements: [] |
114 | 114 | rubyforge_project: |
115 | rubygems_version: 2.2.2 | |
115 | rubygems_version: 2.4.5 | |
116 | 116 | signing_key: |
117 | 117 | specification_version: 4 |
118 | 118 | summary: Facebook OAuth2 Strategy for OmniAuth |
15 | 15 | assert_equal 'https://www.facebook.com/dialog/oauth', strategy.client.options[:authorize_url] |
16 | 16 | end |
17 | 17 | |
18 | test 'has correct token url' do | |
19 | assert_equal '/oauth/access_token', strategy.client.options[:token_url] | |
18 | test 'has correct token url with versioning' do | |
19 | @options = {:client_options => {:site => 'https://graph.facebook.net/v2.2'}} | |
20 | assert_equal 'oauth/access_token', strategy.client.options[:token_url] | |
21 | assert_equal 'https://graph.facebook.net/v2.2/oauth/access_token', strategy.client.token_url | |
20 | 22 | end |
21 | 23 | end |
22 | 24 | |
103 | 105 | assert_equal 'https://graph.facebook.com/321/picture', strategy.info['image'] |
104 | 106 | end |
105 | 107 | |
108 | test 'returns the image_url based of the client site' do | |
109 | @options = { :secure_image_url => true, :client_options => {:site => "https://blah.facebook.com/v2.2"}} | |
110 | raw_info = { 'name' => 'Fred Smith', 'id' => '321' } | |
111 | strategy.stubs(:raw_info).returns(raw_info) | |
112 | assert_equal 'https://blah.facebook.com/v2.2/321/picture', strategy.info['image'] | |
113 | end | |
114 | ||
106 | 115 | test 'returns the image with size specified in the `image_size` option' do |
107 | 116 | @options = { :image_size => 'normal' } |
117 | raw_info = { 'name' => 'Fred Smith', 'id' => '321' } | |
118 | strategy.stubs(:raw_info).returns(raw_info) | |
119 | assert_equal 'http://graph.facebook.com/321/picture?type=normal', strategy.info['image'] | |
120 | end | |
121 | ||
122 | test 'returns the image with size specified as a symbol in the `image_size` option' do | |
123 | @options = { :image_size => :normal } | |
108 | 124 | raw_info = { 'name' => 'Fred Smith', 'id' => '321' } |
109 | 125 | strategy.stubs(:raw_info).returns(raw_info) |
110 | 126 | assert_equal 'http://graph.facebook.com/321/picture?type=normal', strategy.info['image'] |
249 | 265 | strategy.stubs(:appsecret_proof).returns(@appsecret_proof) |
250 | 266 | strategy.stubs(:access_token).returns(@access_token) |
251 | 267 | params = {:params => @options} |
252 | @access_token.expects(:get).with('/me', params).returns(stub_everything('OAuth2::Response')) | |
268 | @access_token.expects(:get).with('me', params).returns(stub_everything('OAuth2::Response')) | |
253 | 269 | strategy.raw_info |
254 | 270 | end |
255 | 271 | |
258 | 274 | strategy.stubs(:access_token).returns(@access_token) |
259 | 275 | strategy.stubs(:appsecret_proof).returns(@appsecret_proof) |
260 | 276 | params = {:params => @options} |
261 | @access_token.expects(:get).with('/me', params).returns(stub_everything('OAuth2::Response')) | |
277 | @access_token.expects(:get).with('me', params).returns(stub_everything('OAuth2::Response')) | |
262 | 278 | strategy.raw_info |
263 | 279 | end |
264 | 280 | |
267 | 283 | strategy.stubs(:access_token).returns(@access_token) |
268 | 284 | strategy.stubs(:appsecret_proof).returns(@appsecret_proof) |
269 | 285 | params = {:params => {:appsecret_proof => @appsecret_proof, :fields => 'about'}} |
270 | @access_token.expects(:get).with('/me', params).returns(stub_everything('OAuth2::Response')) | |
286 | @access_token.expects(:get).with('me', params).returns(stub_everything('OAuth2::Response')) | |
271 | 287 | strategy.raw_info |
272 | 288 | end |
273 | 289 | |
280 | 296 | raw_response.stubs(:headers).returns({'Content-Type' => 'application/json' }) |
281 | 297 | oauth2_response = OAuth2::Response.new(raw_response) |
282 | 298 | params = {:params => @options} |
283 | @access_token.stubs(:get).with('/me', params).returns(oauth2_response) | |
299 | @access_token.stubs(:get).with('me', params).returns(oauth2_response) | |
284 | 300 | assert_kind_of Hash, strategy.raw_info |
285 | 301 | assert_equal 'thar', strategy.raw_info['ohai'] |
286 | 302 | end |
290 | 306 | strategy.stubs(:appsecret_proof).returns(@appsecret_proof) |
291 | 307 | oauth2_response = stub('OAuth2::Response', :parsed => false) |
292 | 308 | params = {:params => @options} |
293 | @access_token.stubs(:get).with('/me', params).returns(oauth2_response) | |
309 | @access_token.stubs(:get).with('me', params).returns(oauth2_response) | |
294 | 310 | assert_kind_of Hash, strategy.raw_info |
295 | 311 | assert_equal({}, strategy.raw_info) |
296 | 312 | end |
442 | 458 | end |
443 | 459 | |
444 | 460 | test 'calls fail! when a code is not included in the params' do |
445 | strategy.expects(:fail!).times(1).with(:no_authorization_code, kind_of(Exception)) | |
461 | strategy.expects(:fail!).times(1).with(:no_authorization_code, kind_of(OmniAuth::Strategies::Facebook::NoAuthorizationCodeError)) | |
446 | 462 | strategy.callback_phase |
447 | 463 | end |
448 | 464 | end |
461 | 477 | end |
462 | 478 | |
463 | 479 | test 'calls fail! when a code is not included in the cookie' do |
464 | strategy.expects(:fail!).times(1).with(:no_authorization_code, kind_of(Exception)) | |
480 | strategy.expects(:fail!).times(1).with(:no_authorization_code, kind_of(OmniAuth::Strategies::Facebook::NoAuthorizationCodeError)) | |
465 | 481 | strategy.callback_phase |
466 | 482 | end |
467 | 483 | end |
468 | end | |
484 | ||
485 | class UnknownAlgorithmInCookieRequestTest < TestCase | |
486 | def setup | |
487 | super() | |
488 | @payload = { | |
489 | 'algorithm' => 'UNKNOWN-ALGO', | |
490 | 'code' => nil, | |
491 | 'issued_at' => Time.now.to_i, | |
492 | 'user_id' => '123456' | |
493 | } | |
494 | ||
495 | @request.stubs(:cookies).returns({"fbsr_#{@client_id}" => signed_request(@payload, @client_secret)}) | |
496 | end | |
497 | ||
498 | test 'calls fail! when an algorithm is unknown' do | |
499 | strategy.expects(:fail!).times(1).with(:unknown_signature_algorithm, kind_of(OmniAuth::Strategies::Facebook::UnknownSignatureAlgorithmError)) | |
500 | strategy.callback_phase | |
501 | end | |
502 | end | |
503 | end |