omniauth-facebook 1.5.1 → 1.6.0.rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6df31b397c5361d54234d354ee57e9b04ee60d47
4
- data.tar.gz: a7ab41bed0a9fa303660f05e8982e71bca05f31e
3
+ metadata.gz: f7b030284d8a9bc6fbcf3906a96421b08624cf21
4
+ data.tar.gz: 4884decdc889f23340364cf73b94d827246c8df7
5
5
  SHA512:
6
- metadata.gz: 964b27002810318b96b5bc82d44ed4ee8fcff75783711e32ddabd939521474c5bed352932a8ae10d5e5382e7c66a45dd04bf0125a3bba710f6e6292b7cd26375
7
- data.tar.gz: cd32aa970b991a00984d1fd8b2ec730b56682872d64550bb2f6da7c9c4e44b0d8683b3eb60282bb52d34cf1bc7b71ee36b15fb1892ad72aaa4d8d6115856c7fe
6
+ metadata.gz: ece06ac88f1c8122aa22e54a81740611446af348ce4fb9ce91dcc586311a5d45086ad7ccf5f4b724641dcc3ce7bee171ffdfc1bc0c428a98647308da0077422b
7
+ data.tar.gz: 113c6ba0645ee31730f662cadd48f30f8292b12d3b72921f419bb0e5e4ecf63e54fa982323e16b4d3b9620054ac05112f8a15390c2da639c48f33e883f554cb2
@@ -2,4 +2,5 @@ rvm:
2
2
  - 1.8.7
3
3
  - 1.9.2
4
4
  - 1.9.3
5
+ - 2.0.0
5
6
  - jruby
@@ -0,0 +1,99 @@
1
+ ## 1.6.0.rc1 (Unreleased)
2
+
3
+ Features:
4
+
5
+ - ability to specify `auth_type` per-request (#78, @sebastian-stylesaint)
6
+ - image dimension can be set using `image_size` option (#91, @weilu)
7
+ - update Facebook authorize URL to fix broken authorization (#103, @dlackty)
8
+ - adds `info_fields` option (#109, @bloudermilk)
9
+ - adds `locale` parameter (#133, @donbobka, @simi)
10
+ - add automatically `appsecret_proof` (#140, @nlsrchtr, @simi)
11
+
12
+ Changes:
13
+
14
+ - `NoAuthorizationCodeError` and `UnknownSignatureAlgorithmError` will now `fail!` (#117, @nchelluri)
15
+ - don't try to parse the signature if it's nil (#127, @oriolgual)
16
+
17
+ ## 1.5.1 (2013-11-18)
18
+
19
+ Changes:
20
+
21
+ - don't use `access_token` in URL [CVE-2013-4593](https://github.com/mkdynamic/omniauth-facebook/wiki/Access-token-vulnerability:-CVE-2013-4593) (@homakov, @mkdynamic, @simi)
22
+
23
+ ## 1.5.0 (2013-11-13)
24
+
25
+ Changes:
26
+
27
+ - remove `state` param to fix CSRF vulnerabilty [CVE-2013-4562](https://github.com/mkdynamic/omniauth-facebook/wiki/CSRF-vulnerability:-CVE-2013-4562) (@homakov, @mkdynamic, @simi)
28
+
29
+ ## 1.4.1 (2012-07-07)
30
+
31
+ Changes:
32
+
33
+ - update to omniauth-oauth2 1.1.0 for csrf protection (@mkdynamic)
34
+
35
+ ## 1.4.0 (2012-06-24)
36
+
37
+ Features:
38
+
39
+ - obey `skip_info?` config (@mkdynamic)
40
+ - add support of the `:auth_type` option to `:authorize_options` (#58, @JHeidinga, @mkdynamic)
41
+ - support `access_token` parameter as part of the callback request (#62, @steverandy)
42
+
43
+ ## 1.3.0 (2012-05-05)
44
+
45
+ Features:
46
+
47
+ - dynamic permissions in the auth params (#30, @famoseagle)
48
+ - add support for facebook canvas (@mkdynamic)
49
+ - add verified key to the info hash (#34, @ryansobol)
50
+ - add option to use secure url for image in auth hash (@mkdynamic)
51
+ - add option to specify image size (@mkdynamic)
52
+
53
+ Changes:
54
+
55
+ - have `raw_info` return an empty hash if the Facebook response returns false (#44, @brianjlandau)
56
+ - prevent oauth2 from interpreting Facebook's expires field as `expires_in`, when it's really `expires_at` (#39, @watsonbox)
57
+ - remove deprecated `offline_access` permission (@mkdynamic)
58
+
59
+ Changes:
60
+
61
+ - tidy up the `callback_url` option (@mkdynamic)
62
+
63
+ ## 1.2.0 (2012-01-06)
64
+
65
+ Features:
66
+
67
+ - add `state` to authorization params (#19, @GermanDZ)
68
+
69
+ Changes:
70
+
71
+ - lock to `rack ~> 1.3.6` (@mkdynamic)
72
+
73
+ ## 1.1.0 (2011-12-10)
74
+
75
+ Features:
76
+
77
+ - add `callback_url` option (#13, @gumayunov)
78
+ - support for parsing code from signed request cookie (client-side flow) (@mkdynamic)
79
+
80
+ ## 1.0.0 (2011-11-19)
81
+
82
+ Features:
83
+
84
+ - allow passing of display via option (@mkdynamic)
85
+
86
+ Bugfixes:
87
+
88
+ - fix `ten_mins_from_now` calculation (#7, @olegkovalenko)
89
+
90
+ ## 1.0.0.rc2 (2011-11-11)
91
+
92
+ Features:
93
+
94
+ - allow passing `display` parameter (@mkdynamic)
95
+ - included default scope (@mkdynamic)
96
+
97
+ ## 1.0.0.rc1 (2011-10-29)
98
+
99
+ - first public gem release (@mkdynamic)
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
- source :rubygems
1
+ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
data/README.md CHANGED
@@ -1,6 +1,11 @@
1
- # OmniAuth Facebook  [![Build Status](http://travis-ci.org/mkdynamic/omniauth-facebook.png?branch=master)](http://travis-ci.org/mkdynamic/omniauth-facebook)
1
+ **NOTE: If you're running < 1.5.1, please upgrade to address 2 security vulnerabilities.
2
+ More details [here](https://github.com/mkdynamic/omniauth-facebook/wiki/CSRF-vulnerability:-CVE-2013-4562) and [here](https://github.com/mkdynamic/omniauth-facebook/wiki/Access-token-vulnerability:-CVE-2013-4593).**
2
3
 
3
- Facebook OAuth2 Strategy for OmniAuth 1.0.
4
+ ---
5
+
6
+ # OmniAuth Facebook &nbsp;[![Build Status](https://secure.travis-ci.org/mkdynamic/omniauth-facebook.png?branch=master)](https://travis-ci.org/mkdynamic/omniauth-facebook)
7
+
8
+ Facebook OAuth2 Strategy for OmniAuth.
4
9
 
5
10
  Supports the OAuth 2.0 server-side and client-side flows. Read the Facebook docs for more details: http://developers.facebook.com/docs/authentication
6
11
 
@@ -16,7 +21,7 @@ Then `bundle install`.
16
21
 
17
22
  ## Usage
18
23
 
19
- `OmniAuth::Strategies::Facebook` is simply a Rack middleware. Read the OmniAuth 1.0 docs for detailed instructions: https://github.com/intridea/omniauth.
24
+ `OmniAuth::Strategies::Facebook` is simply a Rack middleware. Read the OmniAuth docs for detailed instructions: https://github.com/intridea/omniauth.
20
25
 
21
26
  Here's a quick example, adding the middleware to a Rails app in `config/initializers/omniauth.rb`:
22
27
 
@@ -37,7 +42,9 @@ You can configure several options, which you pass in to the `provider` method vi
37
42
  * `auth_type`: Optionally specifies the requested authentication features as a comma-separated list, as per https://developers.facebook.com/docs/authentication/reauthentication/.
38
43
  Valid values are `https` (checks for the presence of the secure cookie and asks for re-authentication if it is not present), and `reauthenticate` (asks the user to re-authenticate unconditionally). Default is `nil`.
39
44
  * `secure_image_url`: Set to `true` to use https for the avatar image url returned in the auth hash. Default is `false`.
40
- * `image_size`: Set the size for the returned image url in the auth hash. Valid options are `square` (50x50), `small` (50 pixels wide, variable height), `normal` (100 pixels wide, variable height), or `large` (about 200 pixels wide, variable height). Default is `square` (50x50).
45
+ * `image_size`: Set the size for the returned image url in the auth hash. Valid options include `square` (50x50), `small` (50 pixels wide, variable height), `normal` (100 pixels wide, variable height), or `large` (about 200 pixels wide, variable height). Additionally, you can request a picture of a specific size by setting this option to a hash with `:width` and `:height` as keys. This will return an available profile picture closest to the requested size and requested aspect ratio. If only `:width` or `:height` is specified, we will return a picture whose width or height is closest to the requested size, respectively.
46
+ * `info_fields`: Specify exactly which fields should be returned when getting the user's info. Value should be a comma-separated string as per https://developers.facebook.com/docs/reference/api/user/ (only /me endpoint).
47
+ * `locale`: Specify locale which should be used when getting the user's info. Value should be locale string as per https://developers.facebook.com/docs/reference/api/locale/.
41
48
 
42
49
  For example, to request `email`, `user_birthday` and `read_stream` permissions and display the authentication page in a popup window:
43
50
 
@@ -50,7 +57,7 @@ end
50
57
 
51
58
  ### Per-Request Options
52
59
 
53
- If you want to set the `display` format 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`.
60
+ 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`.
54
61
 
55
62
  ### Custom Callback URL/Path
56
63
 
@@ -134,7 +141,7 @@ There are then 2 scenarios for what happens next:
134
141
 
135
142
  Take a look at [the example Sinatra app for one option of how you can integrate with a canvas page](https://github.com/mkdynamic/omniauth-facebook/blob/master/example/config.ru).
136
143
 
137
- Bear in mind you have several options (including [authenticated referrals](https://developers.facebook.com/docs/opengraph/authentication/#referrals)). Read [the Facebook docs on canvas page authentication](https://developers.facebook.com/docs/authentication/canvas/) for more info.
144
+ Bear in mind you have several [options](https://developers.facebook.com/docs/opengraph/authentication). Read [the Facebook docs on canvas page authentication](https://developers.facebook.com/docs/authentication/canvas/) for more info.
138
145
 
139
146
  ## Token Expiry
140
147
 
@@ -148,7 +155,7 @@ You can exchange this short lived access token for a longer lived version. Read
148
155
 
149
156
  ### Server-Side Flow
150
157
 
151
- If you use the server-side flow, Facebook will give you back a longer loved access token (~ 60 days).
158
+ If you use the server-side flow, Facebook will give you back a longer lived access token (~ 60 days).
152
159
 
153
160
  If you're having issue getting a long lived token with the server-side flow, make sure to enable the 'deprecate offline_access setting' in you Facebook app config. Read the [Facebook docs about the offline_access deprecation](https://developers.facebook.com/roadmap/offline-access-removal/) for more information.
154
161
 
@@ -156,12 +163,13 @@ If you're having issue getting a long lived token with the server-side flow, mak
156
163
 
157
164
  Actively tested with the following Ruby versions:
158
165
 
166
+ - MRI 2.0.0
159
167
  - MRI 1.9.3
160
168
  - MRI 1.9.2
161
169
  - MRI 1.8.7
162
- - JRuby 1.6.5
170
+ - JRuby 1.7.4
163
171
 
164
- *NB.* For JRuby, you'll need to install the `jruby-openssl` gem. There's no way to automatically specify this in a Rubygem gemspec, so you need to manually add it your project's own Gemfile:
172
+ *NB.* For JRuby < 1.7, you'll need to install the `jruby-openssl` gem. There's no way to automatically specify this in a Rubygem gemspec, so you need to manually add it your project's own Gemfile:
165
173
 
166
174
  ```ruby
167
175
  gem 'jruby-openssl', :platform => :jruby
@@ -1,4 +1,4 @@
1
- source :rubygems
1
+ source 'https://rubygems.org'
2
2
 
3
3
  gem 'sinatra'
4
4
  gem 'omniauth-facebook', :path => '../'
@@ -1,41 +1,40 @@
1
1
  PATH
2
2
  remote: ../
3
3
  specs:
4
- omniauth-facebook (1.4.0)
5
- omniauth-oauth2 (~> 1.1.0)
4
+ omniauth-facebook (1.6.0.rc1)
5
+ omniauth-oauth2 (~> 1.1)
6
6
 
7
7
  GEM
8
- remote: http://rubygems.org/
8
+ remote: https://rubygems.org/
9
9
  specs:
10
- faraday (0.8.1)
11
- multipart-post (~> 1.1)
12
- hashie (1.2.0)
13
- httpauth (0.1)
14
- json (1.7.3)
15
- jwt (0.1.4)
16
- json (>= 1.2.4)
17
- multi_json (1.3.6)
18
- multipart-post (1.1.5)
19
- oauth2 (0.8.0)
10
+ faraday (0.8.8)
11
+ multipart-post (~> 1.2.0)
12
+ hashie (2.0.5)
13
+ httpauth (0.2.0)
14
+ jwt (0.1.8)
15
+ multi_json (>= 1.5)
16
+ multi_json (1.8.2)
17
+ multipart-post (1.2.0)
18
+ oauth2 (0.8.1)
20
19
  faraday (~> 0.8)
21
20
  httpauth (~> 0.1)
22
21
  jwt (~> 0.1.4)
23
22
  multi_json (~> 1.0)
24
23
  rack (~> 1.2)
25
- omniauth (1.1.0)
26
- hashie (~> 1.2)
24
+ omniauth (1.1.4)
25
+ hashie (>= 1.2, < 3)
27
26
  rack
28
- omniauth-oauth2 (1.1.0)
27
+ omniauth-oauth2 (1.1.1)
29
28
  oauth2 (~> 0.8.0)
30
29
  omniauth (~> 1.0)
31
- rack (1.4.1)
32
- rack-protection (1.2.0)
30
+ rack (1.5.2)
31
+ rack-protection (1.5.1)
33
32
  rack
34
- sinatra (1.3.2)
35
- rack (~> 1.3, >= 1.3.6)
36
- rack-protection (~> 1.2)
37
- tilt (~> 1.3, >= 1.3.3)
38
- tilt (1.3.3)
33
+ sinatra (1.4.4)
34
+ rack (~> 1.4)
35
+ rack-protection (~> 1.4)
36
+ tilt (~> 1.3, >= 1.3.4)
37
+ tilt (1.4.1)
39
38
 
40
39
  PLATFORMS
41
40
  ruby
@@ -1,5 +1,5 @@
1
1
  module OmniAuth
2
2
  module Facebook
3
- VERSION = "1.5.1"
3
+ VERSION = "1.6.0.rc1"
4
4
  end
5
5
  end
@@ -2,16 +2,19 @@ require 'omniauth/strategies/oauth2'
2
2
  require 'base64'
3
3
  require 'openssl'
4
4
  require 'rack/utils'
5
+ require 'uri'
5
6
 
6
7
  module OmniAuth
7
8
  module Strategies
8
9
  class Facebook < OmniAuth::Strategies::OAuth2
9
10
  class NoAuthorizationCodeError < StandardError; end
11
+ class UnknownSignatureAlgorithmError < NotImplementedError; end
10
12
 
11
13
  DEFAULT_SCOPE = 'email'
12
14
 
13
15
  option :client_options, {
14
16
  :site => 'https://graph.facebook.com',
17
+ :authorize_url => "https://www.facebook.com/dialog/oauth",
15
18
  :token_url => '/oauth/access_token'
16
19
  }
17
20
 
@@ -35,7 +38,7 @@ module OmniAuth
35
38
  'name' => raw_info['name'],
36
39
  'first_name' => raw_info['first_name'],
37
40
  'last_name' => raw_info['last_name'],
38
- 'image' => "#{options[:secure_image_url] ? 'https' : 'http'}://graph.facebook.com/#{uid}/picture?type=#{options[:image_size] || 'square'}",
41
+ 'image' => image_url(uid, options),
39
42
  'description' => raw_info['bio'],
40
43
  'urls' => {
41
44
  'Facebook' => raw_info['link'],
@@ -53,28 +56,28 @@ module OmniAuth
53
56
  end
54
57
 
55
58
  def raw_info
56
- @raw_info ||= access_token.get('/me').parsed || {}
59
+ @raw_info ||= access_token.get('/me', info_options).parsed || {}
57
60
  end
58
61
 
59
- def build_access_token
60
- if signed_request_contains_access_token?
61
- hash = signed_request.clone
62
- ::OAuth2::AccessToken.new(
63
- client,
64
- hash.delete('oauth_token'),
65
- hash.merge!(access_token_options.merge(:expires_at => hash.delete('expires')))
66
- )
67
- else
68
- with_authorization_code! { super }.tap do |token|
69
- token.options.merge!(access_token_options)
70
- end
71
- end
62
+ def info_options
63
+ params = {:appsecret_proof => appsecret_proof}
64
+ params.merge!({:fields => options[:info_fields]}) if options[:info_fields]
65
+ params.merge!({:locale => options[:locale]}) if options[:locale]
66
+
67
+ { :params => params }
68
+ end
69
+
70
+ def callback_phase
71
+ super
72
+ rescue NoAuthorizationCodeError => e
73
+ fail!(:no_authorization_code, e)
74
+ rescue UnknownSignatureAlgorithmError => e
75
+ fail!(:unknown_signature_algoruthm, e)
72
76
  end
73
77
 
74
78
  def request_phase
75
79
  if signed_request_contains_access_token?
76
- # if we already have an access token, we can just hit the
77
- # callback URL directly and pass the signed request along
80
+ # If we already have an access token, we can just hit the callback URL directly and pass the signed request.
78
81
  params = { :signed_request => raw_signed_request }
79
82
  query = Rack::Utils.build_query(params)
80
83
 
@@ -89,10 +92,9 @@ module OmniAuth
89
92
  end
90
93
  end
91
94
 
92
- # NOTE if we're using code from the signed request
93
- # then FB sets the redirect_uri to '' during the authorize
94
- # phase + it must match during the access_token phase:
95
- # https://github.com/facebook/php-sdk/blob/master/src/base_facebook.php#L348
95
+ # NOTE If we're using code from the signed request then FB sets the redirect_uri to '' during the authorize
96
+ # phase and it must match during the access_token phase:
97
+ # https://github.com/facebook/php-sdk/blob/master/src/base_facebook.php#L348
96
98
  def callback_url
97
99
  if @authorization_code_from_signed_request
98
100
  ''
@@ -105,16 +107,13 @@ module OmniAuth
105
107
  options.access_token_options.inject({}) { |h,(k,v)| h[k.to_sym] = v; h }
106
108
  end
107
109
 
108
- ##
109
- # You can pass +display+ or +scope+ params to the auth request, if
110
- # you need to set them dynamically. You can also set these options
111
- # in the OmniAuth config :authorize_params option.
110
+ # You can pass +display+, +scope+, or +auth_type+ params to the auth request, if you need to set them dynamically.
111
+ # You can also set these options in the OmniAuth config :authorize_params option.
112
112
  #
113
113
  # /auth/facebook?display=popup
114
- #
115
114
  def authorize_params
116
115
  super.tap do |params|
117
- %w[display scope].each do |v|
116
+ %w[display scope auth_type].each do |v|
118
117
  if request.params[v]
119
118
  params[v.to_sym] = request.params[v]
120
119
  end
@@ -124,42 +123,49 @@ module OmniAuth
124
123
  end
125
124
  end
126
125
 
127
- ##
128
126
  # Parse signed request in order, from:
129
127
  #
130
- # 1. the request 'signed_request' param (server-side flow from canvas pages) or
131
- # 2. a cookie (client-side flow via JS SDK)
132
- #
128
+ # 1. The request 'signed_request' param (server-side flow from canvas pages) or
129
+ # 2. A cookie (client-side flow via JS SDK)
133
130
  def signed_request
134
- @signed_request ||= raw_signed_request &&
135
- parse_signed_request(raw_signed_request)
131
+ @signed_request ||= raw_signed_request && parse_signed_request(raw_signed_request)
132
+ end
133
+
134
+ protected
135
+
136
+ def build_access_token
137
+ if signed_request_contains_access_token?
138
+ hash = signed_request.clone
139
+ ::OAuth2::AccessToken.new(
140
+ client,
141
+ hash.delete('oauth_token'),
142
+ hash.merge!(access_token_options.merge(:expires_at => hash.delete('expires')))
143
+ )
144
+ else
145
+ with_authorization_code! { super }.tap do |token|
146
+ token.options.merge!(access_token_options)
147
+ end
148
+ end
136
149
  end
137
150
 
138
151
  private
139
152
 
140
153
  def raw_signed_request
141
- request.params['signed_request'] ||
142
- request.cookies["fbsr_#{client.id}"]
154
+ request.params['signed_request'] || request.cookies["fbsr_#{client.id}"]
143
155
  end
144
156
 
145
- ##
146
- # If the signed_request comes from a FB canvas page and the user
147
- # has already authorized your application, the JSON object will be
148
- # contain the access token.
157
+ # If the signed_request comes from a FB canvas page and the user has already authorized your application, the JSON
158
+ # object will be contain the access token.
149
159
  #
150
160
  # https://developers.facebook.com/docs/authentication/canvas/
151
- #
152
161
  def signed_request_contains_access_token?
153
- signed_request &&
154
- signed_request['oauth_token']
162
+ signed_request && signed_request['oauth_token']
155
163
  end
156
164
 
157
- ##
158
165
  # Picks the authorization code in order, from:
159
166
  #
160
- # 1. the request 'code' param (manual callback from standard server-side flow)
161
- # 2. a signed request (see #signed_request for more)
162
- #
167
+ # 1. The request 'code' param (manual callback from standard server-side flow)
168
+ # 2. A signed request (see #signed_request for more)
163
169
  def with_authorization_code!
164
170
  if request.params.key?('code')
165
171
  yield
@@ -186,12 +192,13 @@ module OmniAuth
186
192
 
187
193
  def parse_signed_request(value)
188
194
  signature, encoded_payload = value.split('.')
195
+ return if signature.nil?
189
196
 
190
197
  decoded_hex_signature = base64_decode_url(signature)
191
198
  decoded_payload = MultiJson.decode(base64_decode_url(encoded_payload))
192
199
 
193
200
  unless decoded_payload['algorithm'] == 'HMAC-SHA256'
194
- raise NotImplementedError, "unkown algorithm: #{decoded_payload['algorithm']}"
201
+ raise UnknownSignatureAlgorithmError, "unknown algorithm: #{decoded_payload['algorithm']}"
195
202
  end
196
203
 
197
204
  if valid_signature?(client.secret, decoded_hex_signature, encoded_payload)
@@ -207,6 +214,24 @@ module OmniAuth
207
214
  value += '=' * (4 - value.size.modulo(4))
208
215
  Base64.decode64(value.tr('-_', '+/'))
209
216
  end
217
+
218
+ def image_url(uid, options)
219
+ uri_class = options[:secure_image_url] ? URI::HTTPS : URI::HTTP
220
+ url = uri_class.build({:host => 'graph.facebook.com', :path => "/#{uid}/picture"})
221
+
222
+ query = if options[:image_size].is_a?(String)
223
+ { :type => options[:image_size] }
224
+ elsif options[:image_size].is_a?(Hash)
225
+ options[:image_size]
226
+ end
227
+ url.query = Rack::Utils.build_query(query) if query
228
+
229
+ url.to_s
230
+ end
231
+
232
+ def appsecret_proof
233
+ @appsecret_proof ||= OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA256.new, client.secret, access_token.token)
234
+ end
210
235
  end
211
236
  end
212
237
  end
@@ -5,17 +5,18 @@ require 'omniauth/facebook/version'
5
5
  Gem::Specification.new do |s|
6
6
  s.name = 'omniauth-facebook'
7
7
  s.version = OmniAuth::Facebook::VERSION
8
- s.authors = ['Mark Dodwell']
9
- s.email = ['mark@mkdynamic.co.uk']
10
- s.summary = 'Facebook strategy for OmniAuth'
8
+ s.authors = ['Mark Dodwell', 'Josef Šimánek']
9
+ s.email = ['mark@madeofcode.com', 'retro@ballgag.cz']
10
+ s.summary = 'Facebook OAuth2 Strategy for OmniAuth'
11
11
  s.homepage = 'https://github.com/mkdynamic/omniauth-facebook'
12
+ s.license = 'MIT'
12
13
 
13
14
  s.files = `git ls-files`.split("\n")
14
15
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
15
16
  s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
16
17
  s.require_paths = ['lib']
17
18
 
18
- s.add_runtime_dependency 'omniauth-oauth2', '~> 1.1.0'
19
+ s.add_runtime_dependency 'omniauth-oauth2', '~> 1.1'
19
20
 
20
21
  s.add_development_dependency 'minitest'
21
22
  s.add_development_dependency 'mocha'
@@ -1,6 +1,6 @@
1
1
  require 'bundler/setup'
2
2
  require 'minitest/autorun'
3
- require 'mocha'
3
+ require 'mocha/setup'
4
4
  require 'omniauth/strategies/facebook'
5
5
 
6
6
  OmniAuth.config.test_mode = true
@@ -25,7 +25,7 @@ module CustomAssertions
25
25
  end
26
26
  end
27
27
 
28
- class TestCase < MiniTest::Unit::TestCase
28
+ class TestCase < Minitest::Test
29
29
  extend BlockTestHelper
30
30
  include CustomAssertions
31
31
  end
@@ -36,6 +36,7 @@ class StrategyTestCase < TestCase
36
36
  @request.stubs(:params).returns({})
37
37
  @request.stubs(:cookies).returns({})
38
38
  @request.stubs(:env).returns({})
39
+ @request.stubs(:ssl?).returns(false)
39
40
 
40
41
  @client_id = '123'
41
42
  @client_secret = '53cr3tz'
@@ -13,7 +13,7 @@ class ClientTest < StrategyTestCase
13
13
  end
14
14
 
15
15
  test 'has correct authorize url' do
16
- assert_equal '/oauth/authorize', strategy.client.options[:authorize_url]
16
+ assert_equal 'https://www.facebook.com/dialog/oauth', strategy.client.options[:authorize_url]
17
17
  end
18
18
 
19
19
  test 'has correct token url' do
@@ -56,6 +56,12 @@ class AuthorizeParamsTest < StrategyTestCase
56
56
  assert_equal 'touch', strategy.authorize_params[:display]
57
57
  end
58
58
 
59
+ test 'includes auth_type parameter from request when present' do
60
+ @request.stubs(:params).returns({ 'auth_type' => 'reauthenticate' })
61
+ assert strategy.authorize_params.is_a?(Hash)
62
+ assert_equal 'reauthenticate', strategy.authorize_params[:auth_type]
63
+ end
64
+
59
65
  test 'overrides default scope with parameter passed from request' do
60
66
  @request.stubs(:params).returns({ 'scope' => 'email' })
61
67
  assert strategy.authorize_params.is_a?(Hash)
@@ -95,15 +101,28 @@ class InfoTest < StrategyTestCase
95
101
  @options = { :secure_image_url => true }
96
102
  raw_info = { 'name' => 'Fred Smith', 'id' => '321' }
97
103
  strategy.stubs(:raw_info).returns(raw_info)
98
- assert_equal 'https://graph.facebook.com/321/picture?type=square', strategy.info['image']
104
+ assert_equal 'https://graph.facebook.com/321/picture', strategy.info['image']
99
105
  end
100
106
 
101
- test 'returns the image size specified in the `image_size` option' do
107
+ test 'returns the image with size specified in the `image_size` option' do
102
108
  @options = { :image_size => 'normal' }
103
109
  raw_info = { 'name' => 'Fred Smith', 'id' => '321' }
104
110
  strategy.stubs(:raw_info).returns(raw_info)
105
111
  assert_equal 'http://graph.facebook.com/321/picture?type=normal', strategy.info['image']
106
112
  end
113
+
114
+ test 'returns the image with width and height specified in the `image_size` option' do
115
+ @options = { :image_size => { :width => 123, :height => 987 } }
116
+ raw_info = { 'name' => 'Fred Smith', 'id' => '321' }
117
+ strategy.stubs(:raw_info).returns(raw_info)
118
+ image_url = strategy.info['image']
119
+ path, query = image_url.split("?")
120
+ query_params = Hash[*query.split("&").map {|pair| pair.split("=") }.flatten]
121
+
122
+ assert_equal 'http://graph.facebook.com/321/picture', path
123
+ assert_equal '123', query_params['width']
124
+ assert_equal '987', query_params['height']
125
+ end
107
126
  end
108
127
 
109
128
  class InfoTestOptionalDataPresent < StrategyTestCase
@@ -147,9 +166,9 @@ class InfoTestOptionalDataPresent < StrategyTestCase
147
166
  assert_equal 'I am great', strategy.info['description']
148
167
  end
149
168
 
150
- test 'returns the square format facebook avatar url' do
169
+ test 'returns the facebook avatar url' do
151
170
  @raw_info['id'] = '321'
152
- assert_equal 'http://graph.facebook.com/321/picture?type=square', strategy.info['image']
171
+ assert_equal 'http://graph.facebook.com/321/picture', strategy.info['image']
153
172
  end
154
173
 
155
174
  test 'returns the Facebook link as the Facebook url' do
@@ -227,31 +246,58 @@ class RawInfoTest < StrategyTestCase
227
246
  def setup
228
247
  super
229
248
  @access_token = stub('OAuth2::AccessToken')
249
+ @appsecret_proof = 'appsecret_proof'
250
+ @options = {:appsecret_proof => @appsecret_proof}
230
251
  end
231
252
 
232
253
  test 'performs a GET to https://graph.facebook.com/me' do
254
+ strategy.stubs(:appsecret_proof).returns(@appsecret_proof)
255
+ strategy.stubs(:access_token).returns(@access_token)
256
+ params = {:params => @options}
257
+ @access_token.expects(:get).with('/me', params).returns(stub_everything('OAuth2::Response'))
258
+ strategy.raw_info
259
+ end
260
+
261
+ test 'performs a GET to https://graph.facebook.com/me with locale' do
262
+ @options.merge!({ :locale => 'cs_CZ' })
233
263
  strategy.stubs(:access_token).returns(@access_token)
234
- @access_token.expects(:get).with('/me').returns(stub_everything('OAuth2::Response'))
264
+ strategy.stubs(:appsecret_proof).returns(@appsecret_proof)
265
+ params = {:params => @options}
266
+ @access_token.expects(:get).with('/me', params).returns(stub_everything('OAuth2::Response'))
267
+ strategy.raw_info
268
+ end
269
+
270
+ test 'performs a GET to https://graph.facebook.com/me with info_fields' do
271
+ @options.merge!({:info_fields => 'about'})
272
+ strategy.stubs(:access_token).returns(@access_token)
273
+ strategy.stubs(:appsecret_proof).returns(@appsecret_proof)
274
+ params = {:params => {:appsecret_proof => @appsecret_proof, :fields => 'about'}}
275
+ @access_token.expects(:get).with('/me', params).returns(stub_everything('OAuth2::Response'))
235
276
  strategy.raw_info
236
277
  end
237
278
 
238
279
  test 'returns a Hash' do
239
280
  strategy.stubs(:access_token).returns(@access_token)
281
+ strategy.stubs(:appsecret_proof).returns(@appsecret_proof)
240
282
  raw_response = stub('Faraday::Response')
241
283
  raw_response.stubs(:body).returns('{ "ohai": "thar" }')
242
284
  raw_response.stubs(:status).returns(200)
243
285
  raw_response.stubs(:headers).returns({'Content-Type' => 'application/json' })
244
286
  oauth2_response = OAuth2::Response.new(raw_response)
245
- @access_token.stubs(:get).with('/me').returns(oauth2_response)
287
+ params = {:params => @options}
288
+ @access_token.stubs(:get).with('/me', params).returns(oauth2_response)
246
289
  assert_kind_of Hash, strategy.raw_info
247
290
  assert_equal 'thar', strategy.raw_info['ohai']
248
291
  end
249
292
 
250
293
  test 'returns an empty hash when the response is false' do
251
294
  strategy.stubs(:access_token).returns(@access_token)
295
+ strategy.stubs(:appsecret_proof).returns(@appsecret_proof)
252
296
  oauth2_response = stub('OAuth2::Response', :parsed => false)
253
- @access_token.stubs(:get).with('/me').returns(oauth2_response)
297
+ params = {:params => @options}
298
+ @access_token.stubs(:get).with('/me', params).returns(oauth2_response)
254
299
  assert_kind_of Hash, strategy.raw_info
300
+ assert_equal({}, strategy.raw_info)
255
301
  end
256
302
 
257
303
  test 'should not include raw_info in extras hash when skip_info is specified' do
@@ -354,13 +400,18 @@ module SignedRequestTests
354
400
  test 'is nil' do
355
401
  assert_nil strategy.send(:signed_request)
356
402
  end
403
+
404
+ test 'throws an error on calling build_access_token' do
405
+ assert_equal 'must pass either a `code` parameter or a signed request (via `signed_request` parameter or a `fbsr_XXX` cookie)',
406
+ assert_raises(OmniAuth::Strategies::Facebook::NoAuthorizationCodeError) { strategy.send(:build_access_token) }.message
407
+ end
357
408
  end
358
409
 
359
410
  class CookiePresentTest < TestCase
360
- def setup
361
- super
411
+ def setup(algo = nil)
412
+ super()
362
413
  @payload = {
363
- 'algorithm' => 'HMAC-SHA256',
414
+ 'algorithm' => algo || 'HMAC-SHA256',
364
415
  'code' => 'm4c0d3z',
365
416
  'issued_at' => Time.now.to_i,
366
417
  'user_id' => '123456'
@@ -372,13 +423,18 @@ module SignedRequestTests
372
423
  test 'parses the access code out from the cookie' do
373
424
  assert_equal @payload, strategy.send(:signed_request)
374
425
  end
426
+
427
+ test 'throws an error if the algorithm is unknown' do
428
+ setup('UNKNOWN-ALGO')
429
+ assert_equal "unknown algorithm: UNKNOWN-ALGO", assert_raises(OmniAuth::Strategies::Facebook::UnknownSignatureAlgorithmError) { strategy.send(:signed_request) }.message
430
+ end
375
431
  end
376
432
 
377
433
  class ParamPresentTest < TestCase
378
- def setup
379
- super
434
+ def setup(algo = nil)
435
+ super()
380
436
  @payload = {
381
- 'algorithm' => 'HMAC-SHA256',
437
+ 'algorithm' => algo || 'HMAC-SHA256',
382
438
  'oauth_token' => 'XXX',
383
439
  'issued_at' => Time.now.to_i,
384
440
  'user_id' => '123456'
@@ -390,6 +446,11 @@ module SignedRequestTests
390
446
  test 'parses the access code out from the param' do
391
447
  assert_equal @payload, strategy.send(:signed_request)
392
448
  end
449
+
450
+ test 'throws an error if the algorithm is unknown' do
451
+ setup('UNKNOWN-ALGO')
452
+ assert_equal "unknown algorithm: UNKNOWN-ALGO", assert_raises(OmniAuth::Strategies::Facebook::UnknownSignatureAlgorithmError) { strategy.send(:signed_request) }.message
453
+ end
393
454
  end
394
455
 
395
456
  class CookieAndParamPresentTest < TestCase
@@ -414,6 +475,18 @@ module SignedRequestTests
414
475
  assert_equal @payload_from_param, strategy.send(:signed_request)
415
476
  end
416
477
  end
478
+
479
+ class EmptySignedRequestTest < TestCase
480
+ def setup
481
+ super
482
+ @request.stubs(:params).returns({'signed_request' => ''})
483
+ end
484
+
485
+ test 'empty param' do
486
+ assert_equal nil, strategy.send(:signed_request)
487
+ end
488
+ end
489
+
417
490
  end
418
491
 
419
492
  class RequestPhaseWithSignedRequestTest < StrategyTestCase
@@ -459,13 +532,13 @@ module BuildAccessTokenTests
459
532
  end
460
533
 
461
534
  test 'returns a new access token from the signed request' do
462
- result = strategy.build_access_token
535
+ result = strategy.send(:build_access_token)
463
536
  assert_kind_of ::OAuth2::AccessToken, result
464
537
  assert_equal @payload['oauth_token'], result.token
465
538
  end
466
539
 
467
540
  test 'returns an access token with the correct expiry time' do
468
- result = strategy.build_access_token
541
+ result = strategy.send(:build_access_token)
469
542
  assert_equal @payload['expires'], result.expires_at
470
543
  end
471
544
  end
metadata CHANGED
@@ -1,14 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: omniauth-facebook
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.1
4
+ version: 1.6.0.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mark Dodwell
8
+ - Josef Šimánek
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2013-11-18 00:00:00.000000000 Z
12
+ date: 2013-12-03 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: omniauth-oauth2
@@ -16,14 +17,14 @@ dependencies:
16
17
  requirements:
17
18
  - - ~>
18
19
  - !ruby/object:Gem::Version
19
- version: 1.1.0
20
+ version: '1.1'
20
21
  type: :runtime
21
22
  prerelease: false
22
23
  version_requirements: !ruby/object:Gem::Requirement
23
24
  requirements:
24
25
  - - ~>
25
26
  - !ruby/object:Gem::Version
26
- version: 1.1.0
27
+ version: '1.1'
27
28
  - !ruby/object:Gem::Dependency
28
29
  name: minitest
29
30
  requirement: !ruby/object:Gem::Requirement
@@ -68,13 +69,15 @@ dependencies:
68
69
  version: '0'
69
70
  description:
70
71
  email:
71
- - mark@mkdynamic.co.uk
72
+ - mark@madeofcode.com
73
+ - retro@ballgag.cz
72
74
  executables: []
73
75
  extensions: []
74
76
  extra_rdoc_files: []
75
77
  files:
76
78
  - .gitignore
77
79
  - .travis.yml
80
+ - CHANGELOG.md
78
81
  - Gemfile
79
82
  - README.md
80
83
  - Rakefile
@@ -90,7 +93,8 @@ files:
90
93
  - test/support/shared_examples.rb
91
94
  - test/test.rb
92
95
  homepage: https://github.com/mkdynamic/omniauth-facebook
93
- licenses: []
96
+ licenses:
97
+ - MIT
94
98
  metadata: {}
95
99
  post_install_message:
96
100
  rdoc_options: []
@@ -103,15 +107,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
103
107
  version: '0'
104
108
  required_rubygems_version: !ruby/object:Gem::Requirement
105
109
  requirements:
106
- - - '>='
110
+ - - '>'
107
111
  - !ruby/object:Gem::Version
108
- version: '0'
112
+ version: 1.3.1
109
113
  requirements: []
110
114
  rubyforge_project:
111
- rubygems_version: 2.0.3
115
+ rubygems_version: 2.1.11
112
116
  signing_key:
113
117
  specification_version: 4
114
- summary: Facebook strategy for OmniAuth
118
+ summary: Facebook OAuth2 Strategy for OmniAuth
115
119
  test_files:
116
120
  - test/helper.rb
117
121
  - test/support/shared_examples.rb