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 +5 -3
- data/example/Gemfile.lock +14 -9
- data/lib/omniauth/facebook/version.rb +1 -1
- data/lib/omniauth/strategies/facebook.rb +9 -1
- data/omniauth-facebook.gemspec +3 -2
- data/test/helper.rb +54 -0
- data/test/support/shared_examples.rb +85 -0
- data/test/test.rb +494 -0
- metadata +38 -17
- data/spec/omniauth/strategies/facebook_spec.rb +0 -507
- data/spec/spec_helper.rb +0 -6
- data/spec/support/shared_examples.rb +0 -42
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: omniauth-facebook
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.4.
|
4
|
+
version: 1.4.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-07-07 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: omniauth-oauth2
|
@@ -18,7 +18,7 @@ dependencies:
|
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version: 1.0
|
21
|
+
version: 1.1.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -26,23 +26,39 @@ dependencies:
|
|
26
26
|
requirements:
|
27
27
|
- - ~>
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version: 1.0
|
29
|
+
version: 1.1.0
|
30
30
|
- !ruby/object:Gem::Dependency
|
31
|
-
name:
|
31
|
+
name: minitest
|
32
32
|
requirement: !ruby/object:Gem::Requirement
|
33
33
|
none: false
|
34
34
|
requirements:
|
35
|
-
- -
|
35
|
+
- - ! '>='
|
36
36
|
- !ruby/object:Gem::Version
|
37
|
-
version: '
|
37
|
+
version: '0'
|
38
38
|
type: :development
|
39
39
|
prerelease: false
|
40
40
|
version_requirements: !ruby/object:Gem::Requirement
|
41
41
|
none: false
|
42
42
|
requirements:
|
43
|
-
- -
|
43
|
+
- - ! '>='
|
44
44
|
- !ruby/object:Gem::Version
|
45
|
-
version: '
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: mocha
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
46
62
|
- !ruby/object:Gem::Dependency
|
47
63
|
name: rake
|
48
64
|
requirement: !ruby/object:Gem::Requirement
|
@@ -79,9 +95,9 @@ files:
|
|
79
95
|
- lib/omniauth/facebook/version.rb
|
80
96
|
- lib/omniauth/strategies/facebook.rb
|
81
97
|
- omniauth-facebook.gemspec
|
82
|
-
-
|
83
|
-
-
|
84
|
-
-
|
98
|
+
- test/helper.rb
|
99
|
+
- test/support/shared_examples.rb
|
100
|
+
- test/test.rb
|
85
101
|
homepage: https://github.com/mkdynamic/omniauth-facebook
|
86
102
|
licenses: []
|
87
103
|
post_install_message:
|
@@ -94,20 +110,25 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
94
110
|
- - ! '>='
|
95
111
|
- !ruby/object:Gem::Version
|
96
112
|
version: '0'
|
113
|
+
segments:
|
114
|
+
- 0
|
115
|
+
hash: 1875274478054024285
|
97
116
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
98
117
|
none: false
|
99
118
|
requirements:
|
100
119
|
- - ! '>='
|
101
120
|
- !ruby/object:Gem::Version
|
102
121
|
version: '0'
|
122
|
+
segments:
|
123
|
+
- 0
|
124
|
+
hash: 1875274478054024285
|
103
125
|
requirements: []
|
104
126
|
rubyforge_project:
|
105
|
-
rubygems_version: 1.8.
|
127
|
+
rubygems_version: 1.8.24
|
106
128
|
signing_key:
|
107
129
|
specification_version: 3
|
108
130
|
summary: Facebook strategy for OmniAuth
|
109
131
|
test_files:
|
110
|
-
-
|
111
|
-
-
|
112
|
-
-
|
113
|
-
has_rdoc:
|
132
|
+
- test/helper.rb
|
133
|
+
- test/support/shared_examples.rb
|
134
|
+
- test/test.rb
|
@@ -1,507 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'omniauth-facebook'
|
3
|
-
require 'openssl'
|
4
|
-
require 'base64'
|
5
|
-
|
6
|
-
describe OmniAuth::Strategies::Facebook do
|
7
|
-
before :each do
|
8
|
-
@request = double('Request')
|
9
|
-
@request.stub(:params) { {} }
|
10
|
-
@request.stub(:cookies) { {} }
|
11
|
-
@request.stub(:env) { {} }
|
12
|
-
|
13
|
-
@client_id = '123'
|
14
|
-
@client_secret = '53cr3tz'
|
15
|
-
end
|
16
|
-
|
17
|
-
subject do
|
18
|
-
args = [@client_id, @client_secret, @options].compact
|
19
|
-
OmniAuth::Strategies::Facebook.new(nil, *args).tap do |strategy|
|
20
|
-
strategy.stub(:request) { @request }
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
it_should_behave_like 'an oauth2 strategy'
|
25
|
-
|
26
|
-
describe '#client' do
|
27
|
-
it 'has correct Facebook site' do
|
28
|
-
subject.client.site.should eq('https://graph.facebook.com')
|
29
|
-
end
|
30
|
-
|
31
|
-
it 'has correct authorize url' do
|
32
|
-
subject.client.options[:authorize_url].should eq('/oauth/authorize')
|
33
|
-
end
|
34
|
-
|
35
|
-
it 'has correct token url' do
|
36
|
-
subject.client.options[:token_url].should eq('/oauth/access_token')
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
describe '#callback_url' do
|
41
|
-
it "returns the default callback url" do
|
42
|
-
url_base = 'http://auth.request.com'
|
43
|
-
@request.stub(:url) { "#{url_base}/some/page" }
|
44
|
-
subject.stub(:script_name) { '' } # as not to depend on Rack env
|
45
|
-
subject.callback_url.should eq("#{url_base}/auth/facebook/callback")
|
46
|
-
end
|
47
|
-
|
48
|
-
it "returns path from callback_path option" do
|
49
|
-
@options = { :callback_path => "/auth/FB/done"}
|
50
|
-
url_base = 'http://auth.request.com'
|
51
|
-
@request.stub(:url) { "#{url_base}/page/path" }
|
52
|
-
subject.stub(:script_name) { '' } # as not to depend on Rack env
|
53
|
-
subject.callback_url.should eq("#{url_base}/auth/FB/done")
|
54
|
-
end
|
55
|
-
|
56
|
-
it "returns url from callback_url option" do
|
57
|
-
url = 'https://auth.myapp.com/auth/fb/callback'
|
58
|
-
@options = { :callback_url => url }
|
59
|
-
subject.callback_url.should eq(url)
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
describe '#authorize_params' do
|
64
|
-
it 'includes default scope for email' do
|
65
|
-
subject.authorize_params.should be_a(Hash)
|
66
|
-
subject.authorize_params[:scope].should eq('email')
|
67
|
-
end
|
68
|
-
|
69
|
-
it 'includes display parameter from request when present' do
|
70
|
-
@request.stub(:params) { { 'display' => 'touch' } }
|
71
|
-
subject.authorize_params.should be_a(Hash)
|
72
|
-
subject.authorize_params[:display].should eq('touch')
|
73
|
-
end
|
74
|
-
|
75
|
-
it 'includes state parameter from request when present' do
|
76
|
-
@request.stub(:params) { { 'state' => 'some_state' } }
|
77
|
-
subject.authorize_params.should be_a(Hash)
|
78
|
-
subject.authorize_params[:state].should eq('some_state')
|
79
|
-
end
|
80
|
-
|
81
|
-
it 'overrides default scope with parameter passed from request' do
|
82
|
-
@request.stub(:params) { { 'scope' => 'email' } }
|
83
|
-
subject.authorize_params.should be_a(Hash)
|
84
|
-
subject.authorize_params[:scope].should eq('email')
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
describe '#token_params' do
|
89
|
-
it 'has correct parse strategy' do
|
90
|
-
subject.token_params[:parse].should eq(:query)
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
describe '#access_token_options' do
|
95
|
-
it 'has correct param name by default' do
|
96
|
-
subject.access_token_options[:param_name].should eq('access_token')
|
97
|
-
end
|
98
|
-
|
99
|
-
it 'has correct header format by default' do
|
100
|
-
subject.access_token_options[:header_format].should eq('OAuth %s')
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
describe '#uid' do
|
105
|
-
before :each do
|
106
|
-
subject.stub(:raw_info) { { 'id' => '123' } }
|
107
|
-
end
|
108
|
-
|
109
|
-
it 'returns the id from raw_info' do
|
110
|
-
subject.uid.should eq('123')
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
describe '#info' do
|
115
|
-
context 'when optional data is not present in raw info' do
|
116
|
-
before :each do
|
117
|
-
@raw_info ||= { 'name' => 'Fred Smith' }
|
118
|
-
subject.stub(:raw_info) { @raw_info }
|
119
|
-
end
|
120
|
-
|
121
|
-
it 'has no email key' do
|
122
|
-
subject.info.should_not have_key('email')
|
123
|
-
end
|
124
|
-
|
125
|
-
it 'has no nickname key' do
|
126
|
-
subject.info.should_not have_key('nickname')
|
127
|
-
end
|
128
|
-
|
129
|
-
it 'has no first name key' do
|
130
|
-
subject.info.should_not have_key('first_name')
|
131
|
-
end
|
132
|
-
|
133
|
-
it 'has no last name key' do
|
134
|
-
subject.info.should_not have_key('last_name')
|
135
|
-
end
|
136
|
-
|
137
|
-
it 'has no location key' do
|
138
|
-
subject.info.should_not have_key('location')
|
139
|
-
end
|
140
|
-
|
141
|
-
it 'has no description key' do
|
142
|
-
subject.info.should_not have_key('description')
|
143
|
-
end
|
144
|
-
|
145
|
-
it 'has no urls' do
|
146
|
-
subject.info.should_not have_key('urls')
|
147
|
-
end
|
148
|
-
|
149
|
-
it 'has no verified key' do
|
150
|
-
subject.info.should_not have_key('verified')
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
|
-
context 'when optional data is present in raw info' do
|
155
|
-
before :each do
|
156
|
-
@raw_info ||= { 'name' => 'Fred Smith' }
|
157
|
-
subject.stub(:raw_info) { @raw_info }
|
158
|
-
end
|
159
|
-
|
160
|
-
it 'returns the name' do
|
161
|
-
subject.info['name'].should eq('Fred Smith')
|
162
|
-
end
|
163
|
-
|
164
|
-
it 'returns the email' do
|
165
|
-
@raw_info['email'] = 'fred@smith.com'
|
166
|
-
subject.info['email'].should eq('fred@smith.com')
|
167
|
-
end
|
168
|
-
|
169
|
-
it 'returns the username as nickname' do
|
170
|
-
@raw_info['username'] = 'fredsmith'
|
171
|
-
subject.info['nickname'].should eq('fredsmith')
|
172
|
-
end
|
173
|
-
|
174
|
-
it 'returns the first name' do
|
175
|
-
@raw_info['first_name'] = 'Fred'
|
176
|
-
subject.info['first_name'].should eq('Fred')
|
177
|
-
end
|
178
|
-
|
179
|
-
it 'returns the last name' do
|
180
|
-
@raw_info['last_name'] = 'Smith'
|
181
|
-
subject.info['last_name'].should eq('Smith')
|
182
|
-
end
|
183
|
-
|
184
|
-
it 'returns the location name as location' do
|
185
|
-
@raw_info['location'] = { 'id' => '104022926303756', 'name' => 'Palo Alto, California' }
|
186
|
-
subject.info['location'].should eq('Palo Alto, California')
|
187
|
-
end
|
188
|
-
|
189
|
-
it 'returns bio as description' do
|
190
|
-
@raw_info['bio'] = 'I am great'
|
191
|
-
subject.info['description'].should eq('I am great')
|
192
|
-
end
|
193
|
-
|
194
|
-
it 'returns the square format facebook avatar url' do
|
195
|
-
@raw_info['id'] = '321'
|
196
|
-
subject.info['image'].should eq('http://graph.facebook.com/321/picture?type=square')
|
197
|
-
end
|
198
|
-
|
199
|
-
it 'returns the Facebook link as the Facebook url' do
|
200
|
-
@raw_info['link'] = 'http://www.facebook.com/fredsmith'
|
201
|
-
subject.info['urls'].should be_a(Hash)
|
202
|
-
subject.info['urls']['Facebook'].should eq('http://www.facebook.com/fredsmith')
|
203
|
-
end
|
204
|
-
|
205
|
-
it 'returns website url' do
|
206
|
-
@raw_info['website'] = 'https://my-wonderful-site.com'
|
207
|
-
subject.info['urls'].should be_a(Hash)
|
208
|
-
subject.info['urls']['Website'].should eq('https://my-wonderful-site.com')
|
209
|
-
end
|
210
|
-
|
211
|
-
it 'return both Facebook link and website urls' do
|
212
|
-
@raw_info['link'] = 'http://www.facebook.com/fredsmith'
|
213
|
-
@raw_info['website'] = 'https://my-wonderful-site.com'
|
214
|
-
subject.info['urls'].should be_a(Hash)
|
215
|
-
subject.info['urls']['Facebook'].should eq('http://www.facebook.com/fredsmith')
|
216
|
-
subject.info['urls']['Website'].should eq('https://my-wonderful-site.com')
|
217
|
-
end
|
218
|
-
|
219
|
-
it 'returns the positive verified status' do
|
220
|
-
@raw_info['verified'] = true
|
221
|
-
subject.info['verified'].should be_true
|
222
|
-
end
|
223
|
-
|
224
|
-
it 'returns the negative verified status' do
|
225
|
-
@raw_info['verified'] = false
|
226
|
-
subject.info['verified'].should be_false
|
227
|
-
end
|
228
|
-
end
|
229
|
-
|
230
|
-
it 'returns the secure facebook avatar url when `secure_image_url` option is specified' do
|
231
|
-
@options = { :secure_image_url => true }
|
232
|
-
raw_info = { 'name' => 'Fred Smith', 'id' => '321' }
|
233
|
-
subject.stub(:raw_info) { raw_info }
|
234
|
-
subject.info['image'].should eq('https://graph.facebook.com/321/picture?type=square')
|
235
|
-
end
|
236
|
-
|
237
|
-
it 'returns the image size specified in the `image_size` option' do
|
238
|
-
@options = { :image_size => 'normal' }
|
239
|
-
raw_info = { 'name' => 'Fred Smith', 'id' => '321' }
|
240
|
-
subject.stub(:raw_info) { raw_info }
|
241
|
-
subject.info['image'].should eq('http://graph.facebook.com/321/picture?type=normal')
|
242
|
-
end
|
243
|
-
end
|
244
|
-
|
245
|
-
describe '#raw_info' do
|
246
|
-
before :each do
|
247
|
-
@access_token = double('OAuth2::AccessToken')
|
248
|
-
end
|
249
|
-
|
250
|
-
it 'performs a GET to https://graph.facebook.com/me' do
|
251
|
-
subject.stub(:access_token) { @access_token }
|
252
|
-
@access_token.stub(:get) { double('OAuth2::Response').as_null_object }
|
253
|
-
@access_token.should_receive(:get).with('/me')
|
254
|
-
subject.raw_info
|
255
|
-
end
|
256
|
-
|
257
|
-
it 'returns a Hash' do
|
258
|
-
subject.stub(:access_token) { @access_token }
|
259
|
-
@access_token.stub(:get).with('/me') do
|
260
|
-
raw_response = double('Faraday::Response')
|
261
|
-
raw_response.stub(:body) { '{ "ohai": "thar" }' }
|
262
|
-
raw_response.stub(:status) { 200 }
|
263
|
-
raw_response.stub(:headers) { { 'Content-Type' => 'application/json' } }
|
264
|
-
OAuth2::Response.new(raw_response)
|
265
|
-
end
|
266
|
-
subject.raw_info.should be_a(Hash)
|
267
|
-
subject.raw_info['ohai'].should eq('thar')
|
268
|
-
end
|
269
|
-
|
270
|
-
it 'returns an empty hash when the response is false' do
|
271
|
-
subject.stub(:access_token) { @access_token }
|
272
|
-
@access_token.stub(:get).with('/me') do
|
273
|
-
response = double('OAuth2::Response')
|
274
|
-
response.stub(:parsed => false)
|
275
|
-
response
|
276
|
-
end
|
277
|
-
subject.raw_info.should be_a(Hash)
|
278
|
-
end
|
279
|
-
|
280
|
-
it 'should not include raw_info in extras hash when skip_info is specified' do
|
281
|
-
@options = { :skip_info => true }
|
282
|
-
subject.stub(:raw_info) { { :foo => 'bar' } }
|
283
|
-
subject.extra.should_not have_key('raw_info')
|
284
|
-
end
|
285
|
-
end
|
286
|
-
|
287
|
-
describe '#credentials' do
|
288
|
-
before :each do
|
289
|
-
@access_token = double('OAuth2::AccessToken')
|
290
|
-
@access_token.stub(:token)
|
291
|
-
@access_token.stub(:expires?)
|
292
|
-
@access_token.stub(:expires_at)
|
293
|
-
@access_token.stub(:refresh_token)
|
294
|
-
subject.stub(:access_token) { @access_token }
|
295
|
-
end
|
296
|
-
|
297
|
-
it 'returns a Hash' do
|
298
|
-
subject.credentials.should be_a(Hash)
|
299
|
-
end
|
300
|
-
|
301
|
-
it 'returns the token' do
|
302
|
-
@access_token.stub(:token) { '123' }
|
303
|
-
subject.credentials['token'].should eq('123')
|
304
|
-
end
|
305
|
-
|
306
|
-
it 'returns the expiry status' do
|
307
|
-
@access_token.stub(:expires?) { true }
|
308
|
-
subject.credentials['expires'].should eq(true)
|
309
|
-
|
310
|
-
@access_token.stub(:expires?) { false }
|
311
|
-
subject.credentials['expires'].should eq(false)
|
312
|
-
end
|
313
|
-
|
314
|
-
it 'returns the refresh token and expiry time when expiring' do
|
315
|
-
ten_mins_from_now = (Time.now + 600).to_i
|
316
|
-
@access_token.stub(:expires?) { true }
|
317
|
-
@access_token.stub(:refresh_token) { '321' }
|
318
|
-
@access_token.stub(:expires_at) { ten_mins_from_now }
|
319
|
-
subject.credentials['refresh_token'].should eq('321')
|
320
|
-
subject.credentials['expires_at'].should eq(ten_mins_from_now)
|
321
|
-
end
|
322
|
-
|
323
|
-
it 'does not return the refresh token when it is nil and expiring' do
|
324
|
-
@access_token.stub(:expires?) { true }
|
325
|
-
@access_token.stub(:refresh_token) { nil }
|
326
|
-
subject.credentials['refresh_token'].should be_nil
|
327
|
-
subject.credentials.should_not have_key('refresh_token')
|
328
|
-
end
|
329
|
-
|
330
|
-
it 'does not return the refresh token when not expiring' do
|
331
|
-
@access_token.stub(:expires?) { false }
|
332
|
-
@access_token.stub(:refresh_token) { 'XXX' }
|
333
|
-
subject.credentials['refresh_token'].should be_nil
|
334
|
-
subject.credentials.should_not have_key('refresh_token')
|
335
|
-
end
|
336
|
-
end
|
337
|
-
|
338
|
-
describe '#extra' do
|
339
|
-
before :each do
|
340
|
-
@raw_info = { 'name' => 'Fred Smith' }
|
341
|
-
subject.stub(:raw_info) { @raw_info }
|
342
|
-
end
|
343
|
-
|
344
|
-
it 'returns a Hash' do
|
345
|
-
subject.extra.should be_a(Hash)
|
346
|
-
end
|
347
|
-
|
348
|
-
it 'contains raw info' do
|
349
|
-
subject.extra.should eq({ 'raw_info' => @raw_info })
|
350
|
-
end
|
351
|
-
end
|
352
|
-
|
353
|
-
describe '#signed_request' do
|
354
|
-
context 'cookie/param not present' do
|
355
|
-
it 'is nil' do
|
356
|
-
subject.send(:signed_request).should be_nil
|
357
|
-
end
|
358
|
-
end
|
359
|
-
|
360
|
-
context 'cookie present' do
|
361
|
-
before :each do
|
362
|
-
@payload = {
|
363
|
-
'algorithm' => 'HMAC-SHA256',
|
364
|
-
'code' => 'm4c0d3z',
|
365
|
-
'issued_at' => Time.now.to_i,
|
366
|
-
'user_id' => '123456'
|
367
|
-
}
|
368
|
-
|
369
|
-
@request.stub(:cookies) do
|
370
|
-
{ "fbsr_#{@client_id}" => signed_request(@payload, @client_secret) }
|
371
|
-
end
|
372
|
-
end
|
373
|
-
|
374
|
-
it 'parses the access code out from the cookie' do
|
375
|
-
subject.send(:signed_request).should eq(@payload)
|
376
|
-
end
|
377
|
-
end
|
378
|
-
|
379
|
-
context 'param present' do
|
380
|
-
before :each do
|
381
|
-
@payload = {
|
382
|
-
'algorithm' => 'HMAC-SHA256',
|
383
|
-
'oauth_token' => 'XXX',
|
384
|
-
'issued_at' => Time.now.to_i,
|
385
|
-
'user_id' => '123456'
|
386
|
-
}
|
387
|
-
|
388
|
-
@request.stub(:params) do
|
389
|
-
{ 'signed_request' => signed_request(@payload, @client_secret) }
|
390
|
-
end
|
391
|
-
end
|
392
|
-
|
393
|
-
it 'parses the access code out from the param' do
|
394
|
-
subject.send(:signed_request).should eq(@payload)
|
395
|
-
end
|
396
|
-
end
|
397
|
-
|
398
|
-
context 'cookie + param present' do
|
399
|
-
before :each do
|
400
|
-
@payload_from_cookie = {
|
401
|
-
'algorithm' => 'HMAC-SHA256',
|
402
|
-
'from' => 'cookie'
|
403
|
-
}
|
404
|
-
|
405
|
-
@request.stub(:cookies) do
|
406
|
-
{ "fbsr_#{@client_id}" => signed_request(@payload_from_cookie, @client_secret) }
|
407
|
-
end
|
408
|
-
|
409
|
-
@payload_from_param = {
|
410
|
-
'algorithm' => 'HMAC-SHA256',
|
411
|
-
'from' => 'param'
|
412
|
-
}
|
413
|
-
|
414
|
-
@request.stub(:params) do
|
415
|
-
{ 'signed_request' => signed_request(@payload_from_param, @client_secret) }
|
416
|
-
end
|
417
|
-
end
|
418
|
-
|
419
|
-
it 'picks param over cookie' do
|
420
|
-
subject.send(:signed_request).should eq(@payload_from_param)
|
421
|
-
end
|
422
|
-
end
|
423
|
-
end
|
424
|
-
|
425
|
-
describe '#request_phase' do
|
426
|
-
describe 'params contain a signed request with an access token' do
|
427
|
-
before do
|
428
|
-
payload = {
|
429
|
-
'algorithm' => 'HMAC-SHA256',
|
430
|
-
'oauth_token' => 'm4c0d3z'
|
431
|
-
}
|
432
|
-
@raw_signed_request = signed_request(payload, @client_secret)
|
433
|
-
@request.stub(:params) do
|
434
|
-
{ "signed_request" => @raw_signed_request }
|
435
|
-
end
|
436
|
-
|
437
|
-
subject.stub(:callback_url) { '/' }
|
438
|
-
end
|
439
|
-
|
440
|
-
it 'redirects to callback passing along signed request' do
|
441
|
-
subject.should_receive(:redirect).with("/?signed_request=#{Rack::Utils.escape(@raw_signed_request)}").once
|
442
|
-
subject.request_phase
|
443
|
-
end
|
444
|
-
end
|
445
|
-
end
|
446
|
-
|
447
|
-
describe '#build_access_token' do
|
448
|
-
describe 'params contain a signed request with an access token' do
|
449
|
-
before do
|
450
|
-
@payload = {
|
451
|
-
'algorithm' => 'HMAC-SHA256',
|
452
|
-
'oauth_token' => 'm4c0d3z',
|
453
|
-
'expires' => Time.now.to_i
|
454
|
-
}
|
455
|
-
@raw_signed_request = signed_request(@payload, @client_secret)
|
456
|
-
@request.stub(:params) do
|
457
|
-
{ "signed_request" => @raw_signed_request }
|
458
|
-
end
|
459
|
-
|
460
|
-
subject.stub(:callback_url) { '/' }
|
461
|
-
end
|
462
|
-
|
463
|
-
it 'returns a new access token from the signed request' do
|
464
|
-
result = subject.build_access_token
|
465
|
-
result.should be_an_instance_of(::OAuth2::AccessToken)
|
466
|
-
result.token.should eq(@payload['oauth_token'])
|
467
|
-
end
|
468
|
-
|
469
|
-
it 'returns an access token with the correct expiry time' do
|
470
|
-
result = subject.build_access_token
|
471
|
-
result.expires_at.should eq(@payload['expires'])
|
472
|
-
end
|
473
|
-
end
|
474
|
-
|
475
|
-
describe 'params contain an access token string' do
|
476
|
-
before do
|
477
|
-
@request.stub(:params) do
|
478
|
-
{ 'access_token' => 'm4c0d3z' }
|
479
|
-
end
|
480
|
-
|
481
|
-
subject.stub(:callback_url) { '/' }
|
482
|
-
end
|
483
|
-
|
484
|
-
it 'returns a new access token' do
|
485
|
-
result = subject.build_access_token
|
486
|
-
result.should be_an_instance_of(::OAuth2::AccessToken)
|
487
|
-
result.token.should eq('m4c0d3z')
|
488
|
-
end
|
489
|
-
end
|
490
|
-
end
|
491
|
-
|
492
|
-
private
|
493
|
-
|
494
|
-
def signed_request(payload, secret)
|
495
|
-
encoded_payload = base64_encode_url(MultiJson.encode(payload))
|
496
|
-
encoded_signature = base64_encode_url(signature(encoded_payload, secret))
|
497
|
-
[encoded_signature, encoded_payload].join('.')
|
498
|
-
end
|
499
|
-
|
500
|
-
def base64_encode_url(value)
|
501
|
-
Base64.encode64(value).tr('+/', '-_').gsub(/\n/, '')
|
502
|
-
end
|
503
|
-
|
504
|
-
def signature(payload, secret, algorithm = OpenSSL::Digest::SHA256.new)
|
505
|
-
OpenSSL::HMAC.digest(algorithm, secret, payload)
|
506
|
-
end
|
507
|
-
end
|