omniauth-facebook 1.4.0 → 1.4.1

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.

Potentially problematic release.


This version of omniauth-facebook might be problematic. Click here for more details.

data/Rakefile CHANGED
@@ -1,6 +1,8 @@
1
1
  require 'bundler/gem_tasks'
2
- require 'rspec/core/rake_task'
2
+ require 'rake/testtask'
3
3
 
4
- RSpec::Core::RakeTask.new(:spec)
4
+ Rake::TestTask.new do |task|
5
+ task.libs << 'test'
6
+ end
5
7
 
6
- task :default => :spec
8
+ task :default => :test
@@ -1,27 +1,32 @@
1
1
  PATH
2
2
  remote: ../
3
3
  specs:
4
- omniauth-facebook (1.3.0)
5
- omniauth-oauth2 (~> 1.0.2)
4
+ omniauth-facebook (1.4.0)
5
+ omniauth-oauth2 (~> 1.1.0)
6
6
 
7
7
  GEM
8
8
  remote: http://rubygems.org/
9
9
  specs:
10
- faraday (0.8.0)
10
+ faraday (0.8.1)
11
11
  multipart-post (~> 1.1)
12
12
  hashie (1.2.0)
13
13
  httpauth (0.1)
14
- multi_json (1.3.4)
14
+ json (1.7.3)
15
+ jwt (0.1.4)
16
+ json (>= 1.2.4)
17
+ multi_json (1.3.6)
15
18
  multipart-post (1.1.5)
16
- oauth2 (0.6.1)
17
- faraday (~> 0.7)
19
+ oauth2 (0.8.0)
20
+ faraday (~> 0.8)
18
21
  httpauth (~> 0.1)
19
- multi_json (~> 1.3)
22
+ jwt (~> 0.1.4)
23
+ multi_json (~> 1.0)
24
+ rack (~> 1.2)
20
25
  omniauth (1.1.0)
21
26
  hashie (~> 1.2)
22
27
  rack
23
- omniauth-oauth2 (1.0.2)
24
- oauth2 (~> 0.6.0)
28
+ omniauth-oauth2 (1.1.0)
29
+ oauth2 (~> 0.8.0)
25
30
  omniauth (~> 1.0)
26
31
  rack (1.4.1)
27
32
  rack-protection (1.2.0)
@@ -1,5 +1,5 @@
1
1
  module OmniAuth
2
2
  module Facebook
3
- VERSION = "1.4.0"
3
+ VERSION = "1.4.1"
4
4
  end
5
5
  end
@@ -120,7 +120,15 @@ module OmniAuth
120
120
  #
121
121
  def authorize_params
122
122
  super.tap do |params|
123
- %w[display state scope].each { |v| params[v.to_sym] = request.params[v] if request.params[v] }
123
+ %w[display state scope].each do |v|
124
+ if request.params[v]
125
+ params[v.to_sym] = request.params[v]
126
+
127
+ # to support omniauth-oauth2's auto csrf protection
128
+ session['omniauth.state'] = params[:state] if v == 'state'
129
+ end
130
+ end
131
+
124
132
  params[:scope] ||= DEFAULT_SCOPE
125
133
  end
126
134
  end
@@ -15,8 +15,9 @@ Gem::Specification.new do |s|
15
15
  s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
16
16
  s.require_paths = ['lib']
17
17
 
18
- s.add_runtime_dependency 'omniauth-oauth2', '~> 1.0.2'
18
+ s.add_runtime_dependency 'omniauth-oauth2', '~> 1.1.0'
19
19
 
20
- s.add_development_dependency 'rspec', '~> 2'
20
+ s.add_development_dependency 'minitest'
21
+ s.add_development_dependency 'mocha'
21
22
  s.add_development_dependency 'rake'
22
23
  end
@@ -0,0 +1,54 @@
1
+ require 'bundler/setup'
2
+ require 'minitest/autorun'
3
+ require 'mocha'
4
+ require 'omniauth/strategies/facebook'
5
+
6
+ OmniAuth.config.test_mode = true
7
+
8
+ module BlockTestHelper
9
+ def test(name, &blk)
10
+ method_name = "test_#{name.gsub(/\s+/, '_')}"
11
+ raise "Method already defined: #{method_name}" if instance_methods.include?(method_name.to_sym)
12
+ define_method method_name, &blk
13
+ end
14
+ end
15
+
16
+ module CustomAssertions
17
+ def assert_has_key(key, hash, msg = nil)
18
+ msg = message(msg) { "Expected #{hash.inspect} to have key #{key.inspect}" }
19
+ assert hash.has_key?(key), msg
20
+ end
21
+
22
+ def refute_has_key(key, hash, msg = nil)
23
+ msg = message(msg) { "Expected #{hash.inspect} not to have key #{key.inspect}" }
24
+ refute hash.has_key?(key), msg
25
+ end
26
+ end
27
+
28
+ class TestCase < MiniTest::Unit::TestCase
29
+ extend BlockTestHelper
30
+ include CustomAssertions
31
+ end
32
+
33
+ class StrategyTestCase < TestCase
34
+ def setup
35
+ @request = stub('Request')
36
+ @request.stubs(:params).returns({})
37
+ @request.stubs(:cookies).returns({})
38
+ @request.stubs(:env).returns({})
39
+
40
+ @client_id = '123'
41
+ @client_secret = '53cr3tz'
42
+ end
43
+
44
+ def strategy
45
+ @strategy ||= begin
46
+ args = [@client_id, @client_secret, @options].compact
47
+ OmniAuth::Strategies::Facebook.new(nil, *args).tap do |strategy|
48
+ strategy.stubs(:request).returns(@request)
49
+ end
50
+ end
51
+ end
52
+ end
53
+
54
+ Dir[File.expand_path('../support/**/*', __FILE__)].each &method(:require)
@@ -0,0 +1,85 @@
1
+ # NOTE it would be useful if this lived in omniauth-oauth2 eventually
2
+ module OAuth2StrategyTests
3
+ def self.included(base)
4
+ base.class_eval do
5
+ include ClientTests
6
+ include AuthorizeParamsTests
7
+ include CSRFAuthorizeParamsTests
8
+ include TokenParamsTests
9
+ end
10
+ end
11
+
12
+ module ClientTests
13
+ extend BlockTestHelper
14
+
15
+ test 'should be initialized with symbolized client_options' do
16
+ @options = { :client_options => { 'authorize_url' => 'https://example.com' } }
17
+ assert_equal 'https://example.com', strategy.client.options[:authorize_url]
18
+ end
19
+ end
20
+
21
+ module AuthorizeParamsTests
22
+ extend BlockTestHelper
23
+
24
+ test 'should include any authorize params passed in the :authorize_params option' do
25
+ @options = { :authorize_params => { :foo => 'bar', :baz => 'zip' } }
26
+ assert_equal 'bar', strategy.authorize_params['foo']
27
+ assert_equal 'zip', strategy.authorize_params['baz']
28
+ end
29
+
30
+ test 'should include top-level options that are marked as :authorize_options' do
31
+ @options = { :authorize_options => [:scope, :foo], :scope => 'bar', :foo => 'baz' }
32
+ assert_equal 'bar', strategy.authorize_params['scope']
33
+ assert_equal 'baz', strategy.authorize_params['foo']
34
+ end
35
+
36
+ test 'should exclude top-level options that are not passed' do
37
+ @options = { :authorize_options => [:bar] }
38
+ refute_has_key :bar, strategy.authorize_params
39
+ refute_has_key 'bar', strategy.authorize_params
40
+ end
41
+ end
42
+
43
+ module CSRFAuthorizeParamsTests
44
+ extend BlockTestHelper
45
+
46
+ test 'should store random state in the session when none is present in authorize or request params' do
47
+ assert_includes strategy.authorize_params.keys, 'state'
48
+ refute_empty strategy.authorize_params['state']
49
+ refute_empty strategy.session['omniauth.state']
50
+ assert_equal strategy.authorize_params['state'], strategy.session['omniauth.state']
51
+ end
52
+
53
+ test 'should store state in the session when present in authorize params vs. a random one' do
54
+ @options = { :authorize_params => { :state => 'bar' } }
55
+ refute_empty strategy.authorize_params['state']
56
+ assert_equal 'bar', strategy.authorize_params[:state]
57
+ refute_empty strategy.session['omniauth.state']
58
+ assert_equal 'bar', strategy.session['omniauth.state']
59
+ end
60
+
61
+ test 'should store state in the session when present in request params vs. a random one' do
62
+ @request.stubs(:params).returns({ 'state' => 'foo' })
63
+ refute_empty strategy.authorize_params['state']
64
+ assert_equal 'foo', strategy.authorize_params[:state]
65
+ refute_empty strategy.session['omniauth.state']
66
+ assert_equal 'foo', strategy.session['omniauth.state']
67
+ end
68
+ end
69
+
70
+ module TokenParamsTests
71
+ extend BlockTestHelper
72
+
73
+ test 'should include any authorize params passed in the :token_params option' do
74
+ @options = { :token_params => { :foo => 'bar', :baz => 'zip' } }
75
+ assert_equal 'bar', strategy.token_params['foo']
76
+ assert_equal 'zip', strategy.token_params['baz']
77
+ end
78
+
79
+ test 'should include top-level options that are marked as :token_options' do
80
+ @options = { :token_options => [:scope, :foo], :scope => 'bar', :foo => 'baz' }
81
+ assert_equal 'bar', strategy.token_params['scope']
82
+ assert_equal 'baz', strategy.token_params['foo']
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,494 @@
1
+ require 'helper'
2
+ require 'omniauth-facebook'
3
+ require 'openssl'
4
+ require 'base64'
5
+
6
+ class StrategyTest < StrategyTestCase
7
+ include OAuth2StrategyTests
8
+ end
9
+
10
+ class ClientTest < StrategyTestCase
11
+ test 'has correct Facebook site' do
12
+ assert_equal 'https://graph.facebook.com', strategy.client.site
13
+ end
14
+
15
+ test 'has correct authorize url' do
16
+ assert_equal '/oauth/authorize', strategy.client.options[:authorize_url]
17
+ end
18
+
19
+ test 'has correct token url' do
20
+ assert_equal '/oauth/access_token', strategy.client.options[:token_url]
21
+ end
22
+ end
23
+
24
+ class CallbackUrlTest < StrategyTestCase
25
+ test "returns the default callback url" do
26
+ url_base = 'http://auth.request.com'
27
+ @request.stubs(:url).returns("#{url_base}/some/page")
28
+ strategy.stubs(:script_name).returns('') # as not to depend on Rack env
29
+ assert_equal "#{url_base}/auth/facebook/callback", strategy.callback_url
30
+ end
31
+
32
+ test "returns path from callback_path option" do
33
+ @options = { :callback_path => "/auth/FB/done"}
34
+ url_base = 'http://auth.request.com'
35
+ @request.stubs(:url).returns("#{url_base}/page/path")
36
+ strategy.stubs(:script_name).returns('') # as not to depend on Rack env
37
+ assert_equal "#{url_base}/auth/FB/done", strategy.callback_url
38
+ end
39
+
40
+ test "returns url from callback_url option" do
41
+ url = 'https://auth.myapp.com/auth/fb/callback'
42
+ @options = { :callback_url => url }
43
+ assert_equal url, strategy.callback_url
44
+ end
45
+ end
46
+
47
+ class AuthorizeParamsTest < StrategyTestCase
48
+ test 'includes default scope for email' do
49
+ assert strategy.authorize_params.is_a?(Hash)
50
+ assert_equal 'email', strategy.authorize_params[:scope]
51
+ end
52
+
53
+ test 'includes display parameter from request when present' do
54
+ @request.stubs(:params).returns({ 'display' => 'touch' })
55
+ assert strategy.authorize_params.is_a?(Hash)
56
+ assert_equal 'touch', strategy.authorize_params[:display]
57
+ end
58
+
59
+ test 'includes state parameter from request when present' do
60
+ @request.stubs(:params).returns({ 'state' => 'some_state' })
61
+ assert strategy.authorize_params.is_a?(Hash)
62
+ assert_equal 'some_state', strategy.authorize_params[:state]
63
+ end
64
+
65
+ test 'overrides default scope with parameter passed from request' do
66
+ @request.stubs(:params).returns({ 'scope' => 'email' })
67
+ assert strategy.authorize_params.is_a?(Hash)
68
+ assert_equal 'email', strategy.authorize_params[:scope]
69
+ end
70
+ end
71
+
72
+ class TokeParamsTest < StrategyTestCase
73
+ test 'has correct parse strategy' do
74
+ assert_equal :query, strategy.token_params[:parse]
75
+ end
76
+ end
77
+
78
+ class AccessTokenOptionsTest < StrategyTestCase
79
+ test 'has correct param name by default' do
80
+ assert_equal 'access_token', strategy.access_token_options[:param_name]
81
+ end
82
+
83
+ test 'has correct header format by default' do
84
+ assert_equal 'OAuth %s', strategy.access_token_options[:header_format]
85
+ end
86
+ end
87
+
88
+ class UidTest < StrategyTestCase
89
+ def setup
90
+ super
91
+ strategy.stubs(:raw_info).returns({ 'id' => '123' })
92
+ end
93
+
94
+ test 'returns the id from raw_info' do
95
+ assert_equal '123', strategy.uid
96
+ end
97
+ end
98
+
99
+ class InfoTest < StrategyTestCase
100
+ test 'returns the secure facebook avatar url when `secure_image_url` option is specified' do
101
+ @options = { :secure_image_url => true }
102
+ raw_info = { 'name' => 'Fred Smith', 'id' => '321' }
103
+ strategy.stubs(:raw_info).returns(raw_info)
104
+ assert_equal 'https://graph.facebook.com/321/picture?type=square', strategy.info['image']
105
+ end
106
+
107
+ test 'returns the image size specified in the `image_size` option' do
108
+ @options = { :image_size => 'normal' }
109
+ raw_info = { 'name' => 'Fred Smith', 'id' => '321' }
110
+ strategy.stubs(:raw_info).returns(raw_info)
111
+ assert_equal 'http://graph.facebook.com/321/picture?type=normal', strategy.info['image']
112
+ end
113
+ end
114
+
115
+ class InfoTestOptionalDataPresent < StrategyTestCase
116
+ def setup
117
+ super
118
+ @raw_info ||= { 'name' => 'Fred Smith' }
119
+ strategy.stubs(:raw_info).returns(@raw_info)
120
+ end
121
+
122
+ test 'returns the name' do
123
+ assert_equal 'Fred Smith', strategy.info['name']
124
+ end
125
+
126
+ test 'returns the email' do
127
+ @raw_info['email'] = 'fred@smith.com'
128
+ assert_equal 'fred@smith.com', strategy.info['email']
129
+ end
130
+
131
+ test 'returns the username as nickname' do
132
+ @raw_info['username'] = 'fredsmith'
133
+ assert_equal 'fredsmith', strategy.info['nickname']
134
+ end
135
+
136
+ test 'returns the first name' do
137
+ @raw_info['first_name'] = 'Fred'
138
+ assert_equal 'Fred', strategy.info['first_name']
139
+ end
140
+
141
+ test 'returns the last name' do
142
+ @raw_info['last_name'] = 'Smith'
143
+ assert_equal 'Smith', strategy.info['last_name']
144
+ end
145
+
146
+ test 'returns the location name as location' do
147
+ @raw_info['location'] = { 'id' => '104022926303756', 'name' => 'Palo Alto, California' }
148
+ assert_equal 'Palo Alto, California', strategy.info['location']
149
+ end
150
+
151
+ test 'returns bio as description' do
152
+ @raw_info['bio'] = 'I am great'
153
+ assert_equal 'I am great', strategy.info['description']
154
+ end
155
+
156
+ test 'returns the square format facebook avatar url' do
157
+ @raw_info['id'] = '321'
158
+ assert_equal 'http://graph.facebook.com/321/picture?type=square', strategy.info['image']
159
+ end
160
+
161
+ test 'returns the Facebook link as the Facebook url' do
162
+ @raw_info['link'] = 'http://www.facebook.com/fredsmith'
163
+ assert_kind_of Hash, strategy.info['urls']
164
+ assert_equal 'http://www.facebook.com/fredsmith', strategy.info['urls']['Facebook']
165
+ end
166
+
167
+ test 'returns website url' do
168
+ @raw_info['website'] = 'https://my-wonderful-site.com'
169
+ assert_kind_of Hash, strategy.info['urls']
170
+ assert_equal 'https://my-wonderful-site.com', strategy.info['urls']['Website']
171
+ end
172
+
173
+ test 'return both Facebook link and website urls' do
174
+ @raw_info['link'] = 'http://www.facebook.com/fredsmith'
175
+ @raw_info['website'] = 'https://my-wonderful-site.com'
176
+ assert_kind_of Hash, strategy.info['urls']
177
+ assert_equal 'http://www.facebook.com/fredsmith', strategy.info['urls']['Facebook']
178
+ assert_equal 'https://my-wonderful-site.com', strategy.info['urls']['Website']
179
+ end
180
+
181
+ test 'returns the positive verified status' do
182
+ @raw_info['verified'] = true
183
+ assert strategy.info['verified']
184
+ end
185
+
186
+ test 'returns the negative verified status' do
187
+ @raw_info['verified'] = false
188
+ refute strategy.info['verified']
189
+ end
190
+ end
191
+
192
+ class InfoTestOptionalDataNotPresent < StrategyTestCase
193
+ def setup
194
+ super
195
+ @raw_info ||= { 'name' => 'Fred Smith' }
196
+ strategy.stubs(:raw_info).returns(@raw_info)
197
+ end
198
+
199
+ test 'has no email key' do
200
+ refute_has_key 'email', strategy.info
201
+ end
202
+
203
+ test 'has no nickname key' do
204
+ refute_has_key 'nickname', strategy.info
205
+ end
206
+
207
+ test 'has no first name key' do
208
+ refute_has_key 'first_name', strategy.info
209
+ end
210
+
211
+ test 'has no last name key' do
212
+ refute_has_key 'last_name', strategy.info
213
+ end
214
+
215
+ test 'has no location key' do
216
+ refute_has_key 'location', strategy.info
217
+ end
218
+
219
+ test 'has no description key' do
220
+ refute_has_key 'description', strategy.info
221
+ end
222
+
223
+ test 'has no urls' do
224
+ refute_has_key 'urls', strategy.info
225
+ end
226
+
227
+ test 'has no verified key' do
228
+ refute_has_key 'verified', strategy.info
229
+ end
230
+ end
231
+
232
+ class RawInfoTest < StrategyTestCase
233
+ def setup
234
+ super
235
+ @access_token = stub('OAuth2::AccessToken')
236
+ end
237
+
238
+ test 'performs a GET to https://graph.facebook.com/me' do
239
+ strategy.stubs(:access_token).returns(@access_token)
240
+ @access_token.expects(:get).with('/me').returns(stub_everything('OAuth2::Response'))
241
+ strategy.raw_info
242
+ end
243
+
244
+ test 'returns a Hash' do
245
+ strategy.stubs(:access_token).returns(@access_token)
246
+ raw_response = stub('Faraday::Response')
247
+ raw_response.stubs(:body).returns('{ "ohai": "thar" }')
248
+ raw_response.stubs(:status).returns(200)
249
+ raw_response.stubs(:headers).returns({'Content-Type' => 'application/json' })
250
+ oauth2_response = OAuth2::Response.new(raw_response)
251
+ @access_token.stubs(:get).with('/me').returns(oauth2_response)
252
+ assert_kind_of Hash, strategy.raw_info
253
+ assert_equal 'thar', strategy.raw_info['ohai']
254
+ end
255
+
256
+ test 'returns an empty hash when the response is false' do
257
+ strategy.stubs(:access_token).returns(@access_token)
258
+ oauth2_response = stub('OAuth2::Response', :parsed => false)
259
+ @access_token.stubs(:get).with('/me').returns(oauth2_response)
260
+ assert_kind_of Hash, strategy.raw_info
261
+ end
262
+
263
+ test 'should not include raw_info in extras hash when skip_info is specified' do
264
+ @options = { :skip_info => true }
265
+ strategy.stubs(:raw_info).returns({:foo => 'bar' })
266
+ refute_has_key 'raw_info', strategy.extra
267
+ end
268
+ end
269
+
270
+ class CredentialsTest < StrategyTestCase
271
+ def setup
272
+ super
273
+ @access_token = stub('OAuth2::AccessToken')
274
+ @access_token.stubs(:token)
275
+ @access_token.stubs(:expires?)
276
+ @access_token.stubs(:expires_at)
277
+ @access_token.stubs(:refresh_token)
278
+ strategy.stubs(:access_token).returns(@access_token)
279
+ end
280
+
281
+ test 'returns a Hash' do
282
+ assert_kind_of Hash, strategy.credentials
283
+ end
284
+
285
+ test 'returns the token' do
286
+ @access_token.stubs(:token).returns('123')
287
+ assert_equal '123', strategy.credentials['token']
288
+ end
289
+
290
+ test 'returns the expiry status' do
291
+ @access_token.stubs(:expires?).returns(true)
292
+ assert strategy.credentials['expires']
293
+
294
+ @access_token.stubs(:expires?).returns(false)
295
+ refute strategy.credentials['expires']
296
+ end
297
+
298
+ test 'returns the refresh token and expiry time when expiring' do
299
+ ten_mins_from_now = (Time.now + 600).to_i
300
+ @access_token.stubs(:expires?).returns(true)
301
+ @access_token.stubs(:refresh_token).returns('321')
302
+ @access_token.stubs(:expires_at).returns(ten_mins_from_now)
303
+ assert_equal '321', strategy.credentials['refresh_token']
304
+ assert_equal ten_mins_from_now, strategy.credentials['expires_at']
305
+ end
306
+
307
+ test 'does not return the refresh token when test is nil and expiring' do
308
+ @access_token.stubs(:expires?).returns(true)
309
+ @access_token.stubs(:refresh_token).returns(nil)
310
+ assert_nil strategy.credentials['refresh_token']
311
+ refute_has_key 'refresh_token', strategy.credentials
312
+ end
313
+
314
+ test 'does not return the refresh token when not expiring' do
315
+ @access_token.stubs(:expires?).returns(false)
316
+ @access_token.stubs(:refresh_token).returns('XXX')
317
+ assert_nil strategy.credentials['refresh_token']
318
+ refute_has_key 'refresh_token', strategy.credentials
319
+ end
320
+ end
321
+
322
+ class ExtraTest < StrategyTestCase
323
+ def setup
324
+ super
325
+ @raw_info = { 'name' => 'Fred Smith' }
326
+ strategy.stubs(:raw_info).returns(@raw_info)
327
+ end
328
+
329
+ test 'returns a Hash' do
330
+ assert_kind_of Hash, strategy.extra
331
+ end
332
+
333
+ test 'contains raw info' do
334
+ assert_equal({ 'raw_info' => @raw_info }, strategy.extra)
335
+ end
336
+ end
337
+
338
+ module SignedRequestHelpers
339
+ def signed_request(payload, secret)
340
+ encoded_payload = base64_encode_url(MultiJson.encode(payload))
341
+ encoded_signature = base64_encode_url(signature(encoded_payload, secret))
342
+ [encoded_signature, encoded_payload].join('.')
343
+ end
344
+
345
+ def base64_encode_url(value)
346
+ Base64.encode64(value).tr('+/', '-_').gsub(/\n/, '')
347
+ end
348
+
349
+ def signature(payload, secret, algorithm = OpenSSL::Digest::SHA256.new)
350
+ OpenSSL::HMAC.digest(algorithm, secret, payload)
351
+ end
352
+ end
353
+
354
+ module SignedRequestTests
355
+ class TestCase < StrategyTestCase
356
+ include SignedRequestHelpers
357
+ end
358
+
359
+ class CookieAndParamNotPresentTest < TestCase
360
+ test 'is nil' do
361
+ assert_nil strategy.send(:signed_request)
362
+ end
363
+ end
364
+
365
+ class CookiePresentTest < TestCase
366
+ def setup
367
+ super
368
+ @payload = {
369
+ 'algorithm' => 'HMAC-SHA256',
370
+ 'code' => 'm4c0d3z',
371
+ 'issued_at' => Time.now.to_i,
372
+ 'user_id' => '123456'
373
+ }
374
+
375
+ @request.stubs(:cookies).returns({"fbsr_#{@client_id}" => signed_request(@payload, @client_secret)})
376
+ end
377
+
378
+ test 'parses the access code out from the cookie' do
379
+ assert_equal @payload, strategy.send(:signed_request)
380
+ end
381
+ end
382
+
383
+ class ParamPresentTest < TestCase
384
+ def setup
385
+ super
386
+ @payload = {
387
+ 'algorithm' => 'HMAC-SHA256',
388
+ 'oauth_token' => 'XXX',
389
+ 'issued_at' => Time.now.to_i,
390
+ 'user_id' => '123456'
391
+ }
392
+
393
+ @request.stubs(:params).returns({'signed_request' => signed_request(@payload, @client_secret)})
394
+ end
395
+
396
+ test 'parses the access code out from the param' do
397
+ assert_equal @payload, strategy.send(:signed_request)
398
+ end
399
+ end
400
+
401
+ class CookieAndParamPresentTest < TestCase
402
+ def setup
403
+ super
404
+ @payload_from_cookie = {
405
+ 'algorithm' => 'HMAC-SHA256',
406
+ 'from' => 'cookie'
407
+ }
408
+
409
+ @request.stubs(:cookies).returns({"fbsr_#{@client_id}" => signed_request(@payload_from_cookie, @client_secret)})
410
+
411
+ @payload_from_param = {
412
+ 'algorithm' => 'HMAC-SHA256',
413
+ 'from' => 'param'
414
+ }
415
+
416
+ @request.stubs(:params).returns({'signed_request' => signed_request(@payload_from_param, @client_secret)})
417
+ end
418
+
419
+ test 'picks param over cookie' do
420
+ assert_equal @payload_from_param, strategy.send(:signed_request)
421
+ end
422
+ end
423
+ end
424
+
425
+ class RequestPhaseWithSignedRequestTest < StrategyTestCase
426
+ include SignedRequestHelpers
427
+
428
+ def setup
429
+ super
430
+
431
+ payload = {
432
+ 'algorithm' => 'HMAC-SHA256',
433
+ 'oauth_token' => 'm4c0d3z'
434
+ }
435
+ @raw_signed_request = signed_request(payload, @client_secret)
436
+ @request.stubs(:params).returns("signed_request" => @raw_signed_request)
437
+
438
+ strategy.stubs(:callback_url).returns('/')
439
+ end
440
+
441
+ test 'redirects to callback passing along signed request' do
442
+ strategy.expects(:redirect).with("/?signed_request=#{Rack::Utils.escape(@raw_signed_request)}").once
443
+ strategy.request_phase
444
+ end
445
+ end
446
+
447
+ module BuildAccessTokenTests
448
+ class TestCase < StrategyTestCase
449
+ include SignedRequestHelpers
450
+ end
451
+
452
+ class ParamsContainSignedRequestWithAccessTokenTest < TestCase
453
+ def setup
454
+ super
455
+
456
+ @payload = {
457
+ 'algorithm' => 'HMAC-SHA256',
458
+ 'oauth_token' => 'm4c0d3z',
459
+ 'expires' => Time.now.to_i
460
+ }
461
+ @raw_signed_request = signed_request(@payload, @client_secret)
462
+ @request.stubs(:params).returns({"signed_request" => @raw_signed_request})
463
+
464
+ strategy.stubs(:callback_url).returns('/')
465
+ end
466
+
467
+ test 'returns a new access token from the signed request' do
468
+ result = strategy.build_access_token
469
+ assert_kind_of ::OAuth2::AccessToken, result
470
+ assert_equal @payload['oauth_token'], result.token
471
+ end
472
+
473
+ test 'returns an access token with the correct expiry time' do
474
+ result = strategy.build_access_token
475
+ assert_equal @payload['expires'], result.expires_at
476
+ end
477
+ end
478
+
479
+ class ParamsContainAccessTokenStringTest < TestCase
480
+ def setup
481
+ super
482
+
483
+ @request.stubs(:params).returns({'access_token' => 'm4c0d3z'})
484
+
485
+ strategy.stubs(:callback_url).returns('/')
486
+ end
487
+
488
+ test 'returns a new access token' do
489
+ result = strategy.build_access_token
490
+ assert_kind_of ::OAuth2::AccessToken, result
491
+ assert_equal 'm4c0d3z', result.token
492
+ end
493
+ end
494
+ end