omniauth-facebook 1.5.1 → 1.6.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
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