signet 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,119 @@
1
+ # Copyright (C) 2010 Google Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ module Signet #:nodoc:
16
+ module OAuth1
17
+ class Credential
18
+ ##
19
+ # Creates a token object from a key and secret.
20
+ #
21
+ # @example
22
+ # Signet::OAuth1::Credential.new(
23
+ # :key => "dpf43f3p2l4k3l03",
24
+ # :secret => "kd94hf93k423kf44"
25
+ # )
26
+ #
27
+ # @example
28
+ # Signet::OAuth1::Credential.new([
29
+ # ["oauth_token", "dpf43f3p2l4k3l03"],
30
+ # ["oauth_token_secret", "kd94hf93k423kf44"]
31
+ # ])
32
+ #
33
+ # @example
34
+ # Signet::OAuth1::Credential.new(
35
+ # "dpf43f3p2l4k3l03", "kd94hf93k423kf44"
36
+ # )
37
+ def initialize(*args)
38
+ # We want to be particularly flexible in how we initialize a token
39
+ # object for maximum interoperability. However, this flexibility
40
+ # means we need to be careful about returning an unexpected value for
41
+ # key or secret to avoid difficult-to-debug situations. Thus lots
42
+ # of type-checking.
43
+
44
+ # This is cheaper than coercing to some kind of Hash with
45
+ # indifferent access. Also uglier.
46
+ key_from_hash = lambda do |parameters|
47
+ parameters["oauth_token"] ||
48
+ parameters[:oauth_token] ||
49
+ parameters["key"] ||
50
+ parameters[:key]
51
+ end
52
+ secret_from_hash = lambda do |parameters|
53
+ parameters["oauth_token_secret"] ||
54
+ parameters[:oauth_token_secret] ||
55
+ parameters["secret"] ||
56
+ parameters[:secret]
57
+ end
58
+ if args.first.respond_to?(:to_hash)
59
+ parameters = args.first.to_hash
60
+ @key = key_from_hash.call(parameters)
61
+ @secret = secret_from_hash.call(parameters)
62
+ unless @key && @secret
63
+ raise ArgumentError,
64
+ "Could not find both key and secret in #{hash.inspect}."
65
+ end
66
+ else
67
+ # Normalize to an Array
68
+ if !args.first.kind_of?(String) &&
69
+ !args.first.respond_to?(:to_str) &&
70
+ args.first.kind_of?(Enumerable)
71
+ # We need to special-case strings since they're technically
72
+ # Enumerable objects.
73
+ args = args.first.to_a
74
+ elsif args.first.respond_to?(:to_ary)
75
+ args = args.first.to_ary
76
+ end
77
+ if args.all? { |value| value.kind_of?(Array) }
78
+ parameters = Hash[args]
79
+ @key = key_from_hash.call(parameters)
80
+ @secret = secret_from_hash.call(parameters)
81
+ elsif args.size == 2
82
+ @key, @secret = args
83
+ else
84
+ raise ArgumentError,
85
+ "wrong number of arguments (#{args.size} for 2)"
86
+ end
87
+ end
88
+ if @key.respond_to?(:to_str)
89
+ @key = @key.to_str
90
+ else
91
+ raise TypeError, "Expected String, got #{@key.class}."
92
+ end
93
+ if @secret.respond_to?(:to_str)
94
+ @secret = @secret.to_str
95
+ else
96
+ raise TypeError, "Expected String, got #{@secret.class}."
97
+ end
98
+ end
99
+
100
+ attr_accessor :key, :secret
101
+
102
+ def to_hash
103
+ return {
104
+ "oauth_token" => self.key,
105
+ "oauth_token_secret" => self.secret
106
+ }
107
+ end
108
+ alias_method :to_h, :to_hash
109
+
110
+ def ==(other)
111
+ if other.respond_to?(:key) && other.respond_to?(:secret)
112
+ return self.key == other.key && self.secret == other.secret
113
+ else
114
+ return false
115
+ end
116
+ end
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,31 @@
1
+ begin
2
+ require 'digest/hmac'
3
+ rescue LoadError
4
+ require 'compat/digest/hmac'
5
+ end
6
+ require 'digest/sha1'
7
+ require 'base64'
8
+
9
+ require 'signet'
10
+
11
+ module Signet #:nodoc:
12
+ module OAuth1
13
+ module HMACSHA1
14
+ def self.generate_signature(
15
+ base_string, client_credential_secret, token_credential_secret)
16
+ # Both the client secret and token secret must be escaped
17
+ client_credential_secret =
18
+ Signet::OAuth1.encode(client_credential_secret)
19
+ token_credential_secret =
20
+ Signet::OAuth1.encode(token_credential_secret)
21
+ # The key for the signature is just the client secret and token
22
+ # secret joined by the '&' character. If the token secret is omitted,
23
+ # the '&' must still be present.
24
+ key = [client_credential_secret, token_credential_secret].join("&")
25
+ return Base64.encode64(Digest::HMAC.digest(
26
+ base_string, key, Digest::SHA1
27
+ )).strip
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,26 @@
1
+ # Copyright (C) 2010 Google Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ # Used to prevent the class/module from being loaded more than once
16
+ unless defined? Signet::VERSION
17
+ module Signet #:nodoc:
18
+ module VERSION #:nodoc:
19
+ MAJOR = 0
20
+ MINOR = 1
21
+ TINY = 0
22
+
23
+ STRING = [MAJOR, MINOR, TINY].join('.')
24
+ end
25
+ end
26
+ end
@@ -0,0 +1 @@
1
+ raise LoadError, "Forcing compat-mode for testing."
@@ -0,0 +1 @@
1
+ raise LoadError, "Forcing compat-mode for testing."
@@ -0,0 +1,687 @@
1
+ # Copyright (C) 2010 Google Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require 'spec_helper'
16
+
17
+ require 'signet/oauth_1/client'
18
+ require 'addressable/uri'
19
+
20
+ def merge_body(chunked_body)
21
+ merged_body = StringIO.new
22
+ chunked_body.each do |chunk|
23
+ merged_body.write(chunk)
24
+ end
25
+ return merged_body.string
26
+ end
27
+
28
+ describe Signet::OAuth1::Client, 'unconfigured' do
29
+ before do
30
+ @client = Signet::OAuth1::Client.new
31
+ end
32
+
33
+ it 'should have no temporary_credential_uri' do
34
+ @client.temporary_credential_uri.should == nil
35
+ end
36
+
37
+ it 'should allow the temporary_credential_uri to be set to a String' do
38
+ @client.temporary_credential_uri = "http://example.com/"
39
+ @client.temporary_credential_uri.should === "http://example.com/"
40
+ end
41
+
42
+ it 'should allow the temporary_credential_uri to be set to a URI' do
43
+ @client.temporary_credential_uri =
44
+ Addressable::URI.parse("http://example.com/")
45
+ @client.temporary_credential_uri.should === "http://example.com/"
46
+ end
47
+
48
+ it 'should have no authorization_uri' do
49
+ @client.authorization_uri.should == nil
50
+ end
51
+
52
+ it 'should allow the authorization_uri to be set to a String' do
53
+ @client.authorization_uri = 'http://example.com/authorize'
54
+ @client.authorization_uri.to_s.should include(
55
+ 'http://example.com/authorize'
56
+ )
57
+ end
58
+
59
+ it 'should allow the authorization_uri to be set to a URI' do
60
+ @client.authorization_uri =
61
+ Addressable::URI.parse('http://example.com/authorize')
62
+ @client.authorization_uri.to_s.should include(
63
+ 'http://example.com/authorize'
64
+ )
65
+ end
66
+
67
+ it 'should have no token_credential_uri' do
68
+ @client.token_credential_uri.should == nil
69
+ end
70
+
71
+ it 'should allow the token_credential_uri to be set to a String' do
72
+ @client.token_credential_uri = "http://example.com/"
73
+ @client.token_credential_uri.should === "http://example.com/"
74
+ end
75
+
76
+ it 'should allow the token_credential_uri to be set to a URI' do
77
+ @client.token_credential_uri =
78
+ Addressable::URI.parse("http://example.com/")
79
+ @client.token_credential_uri.should === "http://example.com/"
80
+ end
81
+
82
+ it 'should have no client_credential' do
83
+ @client.client_credential.should == nil
84
+ end
85
+
86
+ it 'should raise an error for partially set client credentials' do
87
+ @client.client_credential_key = "12345"
88
+ @client.client_credential_secret = nil
89
+ (lambda do
90
+ @client.client_credential
91
+ end).should raise_error(ArgumentError)
92
+ end
93
+
94
+ it 'should raise an error for partially set client credentials' do
95
+ @client.client_credential_key = nil
96
+ @client.client_credential_secret = "54321"
97
+ (lambda do
98
+ @client.client_credential
99
+ end).should raise_error(ArgumentError)
100
+ end
101
+
102
+ it 'should allow the client_credential to be set to a ' +
103
+ 'Signet::OAuth1::Credential' do
104
+ @client.client_credential =
105
+ Signet::OAuth1::Credential.new("12345", "54321")
106
+ @client.client_credential_key.should == "12345"
107
+ @client.client_credential_secret.should == "54321"
108
+ @client.client_credential.should ==
109
+ Signet::OAuth1::Credential.new("12345", "54321")
110
+ end
111
+
112
+ it 'should allow the client_credential to be set to nil' do
113
+ @client.client_credential_key = "12345"
114
+ @client.client_credential_secret = "54321"
115
+ @client.client_credential_key.should == "12345"
116
+ @client.client_credential_secret.should == "54321"
117
+ @client.client_credential = nil
118
+ @client.client_credential.should == nil
119
+ @client.client_credential_key.should == nil
120
+ @client.client_credential_secret.should == nil
121
+ end
122
+
123
+ it 'should not allow the client_credential to be set to a bogus value' do
124
+ (lambda do
125
+ @client.client_credential = 42
126
+ end).should raise_error(TypeError)
127
+ end
128
+
129
+ it 'should have no client_credential_key' do
130
+ @client.client_credential_key.should == nil
131
+ end
132
+
133
+ it 'should allow the client_credential_key to be set to a String' do
134
+ @client.client_credential_key = "12345"
135
+ @client.client_credential_key.should == "12345"
136
+ end
137
+
138
+ it 'should not allow the client_credential_key to be set to a non-String' do
139
+ (lambda do
140
+ @client.client_credential_key = 12345
141
+ end).should raise_error(TypeError)
142
+ end
143
+
144
+ it 'should have no client_credential_secret' do
145
+ @client.client_credential_secret.should == nil
146
+ end
147
+
148
+ it 'should allow the client_credential_secret to be set to a String' do
149
+ @client.client_credential_secret = "54321"
150
+ @client.client_credential_secret.should === "54321"
151
+ end
152
+
153
+ it 'should not allow the client_credential_secret ' +
154
+ 'to be set to a non-String' do
155
+ (lambda do
156
+ @client.client_credential_secret = 54321
157
+ end).should raise_error(TypeError)
158
+ end
159
+
160
+ it 'should have an out-of-band callback' do
161
+ @client.callback.should == ::Signet::OAuth1::OUT_OF_BAND
162
+ end
163
+
164
+ it 'should allow the callback to be set to a String' do
165
+ @client.callback = "http://example.com/callback"
166
+ @client.callback.should == "http://example.com/callback"
167
+ end
168
+
169
+ it 'should allow the callback to be set to a URI' do
170
+ @client.callback =
171
+ Addressable::URI.parse("http://example.com/callback")
172
+ @client.callback.should == "http://example.com/callback"
173
+ end
174
+
175
+ it 'should not allow the callback to be set to a non-String' do
176
+ (lambda do
177
+ @client.callback = 12345
178
+ end).should raise_error(TypeError)
179
+ end
180
+
181
+ it 'should raise an error if the temporary credentials URI is not set' do
182
+ @client.client_credential_key = 'dpf43f3p2l4k3l03'
183
+ @client.client_credential_secret = 'kd94hf93k423kf44'
184
+ (lambda do
185
+ @client.generate_temporary_credential_request
186
+ end).should raise_error(ArgumentError)
187
+ end
188
+
189
+ it 'should raise an error if the client credential key is not set' do
190
+ @client.temporary_credential_uri =
191
+ 'http://example.com/temporary_credentials'
192
+ @client.client_credential_secret = 'kd94hf93k423kf44'
193
+ (lambda do
194
+ @client.generate_temporary_credential_request
195
+ end).should raise_error(ArgumentError)
196
+ end
197
+
198
+ it 'should raise an error if the client credential secret is not set' do
199
+ @client.temporary_credential_uri =
200
+ 'http://example.com/temporary_credentials'
201
+ @client.client_credential_key = 'dpf43f3p2l4k3l03'
202
+ (lambda do
203
+ @client.generate_temporary_credential_request
204
+ end).should raise_error(ArgumentError)
205
+ end
206
+
207
+ it 'should have no temporary_credential' do
208
+ @client.temporary_credential.should == nil
209
+ end
210
+
211
+ it 'should raise an error for partially set temporary credentials' do
212
+ @client.temporary_credential_key = "12345"
213
+ @client.temporary_credential_secret = nil
214
+ (lambda do
215
+ @client.temporary_credential
216
+ end).should raise_error(ArgumentError)
217
+ end
218
+
219
+ it 'should raise an error for partially set temporary credentials' do
220
+ @client.temporary_credential_key = nil
221
+ @client.temporary_credential_secret = "54321"
222
+ (lambda do
223
+ @client.temporary_credential
224
+ end).should raise_error(ArgumentError)
225
+ end
226
+
227
+ it 'should allow the temporary_credential to be set to a ' +
228
+ 'Signet::OAuth1::Credential' do
229
+ @client.temporary_credential =
230
+ Signet::OAuth1::Credential.new("12345", "54321")
231
+ @client.temporary_credential_key.should == "12345"
232
+ @client.temporary_credential_secret.should == "54321"
233
+ @client.temporary_credential.should ==
234
+ Signet::OAuth1::Credential.new("12345", "54321")
235
+ end
236
+
237
+ it 'should allow the temporary_credential to be set to nil' do
238
+ @client.temporary_credential_key = "12345"
239
+ @client.temporary_credential_secret = "54321"
240
+ @client.temporary_credential_key.should == "12345"
241
+ @client.temporary_credential_secret.should == "54321"
242
+ @client.temporary_credential = nil
243
+ @client.temporary_credential.should == nil
244
+ @client.temporary_credential_key.should == nil
245
+ @client.temporary_credential_secret.should == nil
246
+ end
247
+
248
+ it 'should not allow the temporary_credential to be set to a bogus value' do
249
+ (lambda do
250
+ @client.temporary_credential = 42
251
+ end).should raise_error(TypeError)
252
+ end
253
+
254
+ it 'should have no temporary_credential_key' do
255
+ @client.temporary_credential_key.should == nil
256
+ end
257
+
258
+ it 'should allow the temporary_credential_key to be set to a String' do
259
+ @client.temporary_credential_key = "12345"
260
+ @client.temporary_credential_key.should === "12345"
261
+ end
262
+
263
+ it 'should not allow the temporary_credential_key ' +
264
+ 'to be set to a non-String' do
265
+ (lambda do
266
+ @client.temporary_credential_key = 12345
267
+ end).should raise_error(TypeError)
268
+ end
269
+
270
+ it 'should have no temporary_credential_secret' do
271
+ @client.temporary_credential_secret.should == nil
272
+ end
273
+
274
+ it 'should allow the temporary_credential_secret to be set to a String' do
275
+ @client.temporary_credential_secret = "54321"
276
+ @client.temporary_credential_secret.should === "54321"
277
+ end
278
+
279
+ it 'should not allow the temporary_credential_secret ' +
280
+ 'to be set to a non-String' do
281
+ (lambda do
282
+ @client.temporary_credential_secret = 54321
283
+ end).should raise_error(TypeError)
284
+ end
285
+
286
+ it 'should have no token_credential' do
287
+ @client.token_credential.should == nil
288
+ end
289
+
290
+ it 'should raise an error for partially set token credentials' do
291
+ @client.token_credential_key = "12345"
292
+ @client.token_credential_secret = nil
293
+ (lambda do
294
+ @client.token_credential
295
+ end).should raise_error(ArgumentError)
296
+ end
297
+
298
+ it 'should raise an error for partially set token credentials' do
299
+ @client.token_credential_key = nil
300
+ @client.token_credential_secret = "54321"
301
+ (lambda do
302
+ @client.token_credential
303
+ end).should raise_error(ArgumentError)
304
+ end
305
+
306
+ it 'should allow the token_credential to be set to a ' +
307
+ 'Signet::OAuth1::Credential' do
308
+ @client.token_credential =
309
+ Signet::OAuth1::Credential.new("12345", "54321")
310
+ @client.token_credential_key.should == "12345"
311
+ @client.token_credential_secret.should == "54321"
312
+ @client.token_credential.should ==
313
+ Signet::OAuth1::Credential.new("12345", "54321")
314
+ end
315
+
316
+ it 'should allow the token_credential to be set to nil' do
317
+ @client.token_credential_key = "12345"
318
+ @client.token_credential_secret = "54321"
319
+ @client.token_credential_key.should == "12345"
320
+ @client.token_credential_secret.should == "54321"
321
+ @client.token_credential = nil
322
+ @client.token_credential.should == nil
323
+ @client.token_credential_key.should == nil
324
+ @client.token_credential_secret.should == nil
325
+ end
326
+
327
+ it 'should not allow the token_credential to be set to a bogus value' do
328
+ (lambda do
329
+ @client.token_credential = 42
330
+ end).should raise_error(TypeError)
331
+ end
332
+
333
+ it 'should have no token_credential_key' do
334
+ @client.token_credential_key.should == nil
335
+ end
336
+
337
+ it 'should allow the token_credential_key to be set to a String' do
338
+ @client.token_credential_key = "12345"
339
+ @client.token_credential_key.should === "12345"
340
+ end
341
+
342
+ it 'should not allow the token_credential_key ' +
343
+ 'to be set to a non-String' do
344
+ (lambda do
345
+ @client.token_credential_key = 12345
346
+ end).should raise_error(TypeError)
347
+ end
348
+
349
+ it 'should have no token_credential_secret' do
350
+ @client.token_credential_secret.should == nil
351
+ end
352
+
353
+ it 'should allow the token_credential_secret to be set to a String' do
354
+ @client.token_credential_secret = "54321"
355
+ @client.token_credential_secret.should === "54321"
356
+ end
357
+
358
+ it 'should not allow the token_credential_secret ' +
359
+ 'to be set to a non-String' do
360
+ (lambda do
361
+ @client.token_credential_secret = 54321
362
+ end).should raise_error(TypeError)
363
+ end
364
+ end
365
+
366
+ describe Signet::OAuth1::Client, 'configured' do
367
+ before do
368
+ @client = Signet::OAuth1::Client.new
369
+ @client.temporary_credential_uri =
370
+ 'http://example.com/temporary_credentials'
371
+ @client.authorization_uri =
372
+ 'http://example.com/authorize'
373
+ @client.token_credential_uri =
374
+ 'http://example.com/token_credentials'
375
+ @client.callback = 'http://example.com/callback'
376
+ @client.client_credential_key = 'dpf43f3p2l4k3l03'
377
+ @client.client_credential_secret = 'kd94hf93k423kf44'
378
+ @client.temporary_credential_key = 'hh5s93j4hdidpola'
379
+ @client.temporary_credential_secret = 'hdhd0244k9j7ao03'
380
+ @client.token_credential_key = 'nnch734d00sl2jdk'
381
+ @client.token_credential_secret = 'pfkkdhi9sl3r4s00'
382
+ end
383
+
384
+ it 'should generate an authorization URI with a callback' do
385
+ @client.temporary_credential_key = nil
386
+ @client.authorization_uri.should ===
387
+ 'http://example.com/authorize?oauth_callback=http://example.com/callback'
388
+ end
389
+
390
+ it 'should generate an authorization URI with a temporary credential' do
391
+ @client.callback = nil
392
+ @client.authorization_uri.to_s.should include(
393
+ 'oauth_token=hh5s93j4hdidpola'
394
+ )
395
+ end
396
+
397
+ it 'should generate an authorization URI both a callback and ' +
398
+ 'a temporary credential' do
399
+ @client.authorization_uri.to_s.should include(
400
+ 'oauth_callback=http://example.com/callback'
401
+ )
402
+ @client.authorization_uri.to_s.should include(
403
+ 'oauth_token=hh5s93j4hdidpola'
404
+ )
405
+ end
406
+
407
+ it 'should generate an authorization URI with additional parameters' do
408
+ authorization_uri = @client.authorization_uri(
409
+ :additional_parameters => {:domain => 'www.example.com'}
410
+ )
411
+ authorization_uri.to_s.should include(
412
+ 'oauth_callback=http://example.com/callback'
413
+ )
414
+ authorization_uri.to_s.should include(
415
+ 'oauth_token=hh5s93j4hdidpola'
416
+ )
417
+ authorization_uri.to_s.should include(
418
+ 'domain=www.example.com'
419
+ )
420
+ end
421
+
422
+ it 'should raise an error if the verifier is not provided' do
423
+ (lambda do
424
+ @client.generate_token_credential_request
425
+ end).should raise_error(ArgumentError)
426
+ (lambda do
427
+ @client.generate_token_credential_request(:verifier => nil)
428
+ end).should raise_error(ArgumentError)
429
+ end
430
+
431
+ it 'should raise an error if the token credentials URI is not set' do
432
+ @client.token_credential_uri = nil
433
+ (lambda do
434
+ @client.generate_token_credential_request(:verifier => '12345')
435
+ end).should raise_error(ArgumentError)
436
+ end
437
+
438
+ it 'should raise an error if the client credential key is not set' do
439
+ @client.client_credential_key = nil
440
+ (lambda do
441
+ @client.generate_token_credential_request(:verifier => '12345')
442
+ end).should raise_error(ArgumentError)
443
+ end
444
+
445
+ it 'should raise an error if the client credential secret is not set' do
446
+ @client.client_credential_secret = nil
447
+ (lambda do
448
+ @client.generate_token_credential_request(:verifier => '12345')
449
+ end).should raise_error(ArgumentError)
450
+ end
451
+
452
+ it 'should raise an error if the temporary credential key is not set' do
453
+ @client.temporary_credential_key = nil
454
+ (lambda do
455
+ @client.generate_token_credential_request(:verifier => '12345')
456
+ end).should raise_error(ArgumentError)
457
+ end
458
+
459
+ it 'should raise an error if the temporary credential secret is not set' do
460
+ @client.temporary_credential_secret = nil
461
+ (lambda do
462
+ @client.generate_token_credential_request(:verifier => '12345')
463
+ end).should raise_error(ArgumentError)
464
+ end
465
+
466
+ it 'should raise an error if the client credential key is not set' do
467
+ @client.client_credential_key = nil
468
+ (lambda do
469
+ @client.generate_authenticated_request
470
+ end).should raise_error(ArgumentError)
471
+ end
472
+
473
+ it 'should raise an error if the client credential secret is not set' do
474
+ @client.client_credential_secret = nil
475
+ (lambda do
476
+ @client.generate_authenticated_request
477
+ end).should raise_error(ArgumentError)
478
+ end
479
+
480
+ it 'should raise an error if the token credential key is not set' do
481
+ @client.token_credential_key = nil
482
+ (lambda do
483
+ @client.generate_authenticated_request
484
+ end).should raise_error(ArgumentError)
485
+ end
486
+
487
+ it 'should raise an error if the token credential secret is not set' do
488
+ @client.token_credential_secret = nil
489
+ (lambda do
490
+ @client.generate_authenticated_request
491
+ end).should raise_error(ArgumentError)
492
+ end
493
+
494
+ it 'should raise an error if no request is provided' do
495
+ (lambda do
496
+ @client.generate_authenticated_request
497
+ end).should raise_error(ArgumentError)
498
+ end
499
+
500
+ it 'should raise an error if a bogus request is provided' do
501
+ (lambda do
502
+ @client.generate_authenticated_request(
503
+ :request => []
504
+ )
505
+ end).should raise_error(ArgumentError)
506
+ end
507
+
508
+ it 'should raise an error if no URI is provided' do
509
+ (lambda do
510
+ @client.generate_authenticated_request(
511
+ :method => 'GET',
512
+ :headers => [],
513
+ :body => ''
514
+ )
515
+ end).should raise_error(ArgumentError)
516
+ end
517
+
518
+ it 'should not raise an error if a request body is chunked' do
519
+ request = @client.generate_authenticated_request(
520
+ :method => 'POST',
521
+ :uri => 'https://photos.example.net/photos',
522
+ :body => ['A chunked body.']
523
+ )
524
+ method, uri, headers, body = request
525
+ merge_body(body).should == 'A chunked body.'
526
+ end
527
+
528
+ it 'should not raise an error if a request body is chunked' do
529
+ chunked_body = StringIO.new
530
+ chunked_body.write('A chunked body.')
531
+ chunked_body.rewind
532
+ request = @client.generate_authenticated_request(
533
+ :method => 'POST',
534
+ :uri => 'https://photos.example.net/photos',
535
+ :body => chunked_body
536
+ )
537
+ method, uri, headers, body = request
538
+ merge_body(body).should == 'A chunked body.'
539
+ end
540
+
541
+ it 'should raise an error if a request body is of a bogus type' do
542
+ (lambda do
543
+ @client.generate_authenticated_request(
544
+ :method => 'POST',
545
+ :uri => 'https://photos.example.net/photos',
546
+ :body => 42
547
+ )
548
+ end).should raise_error(TypeError)
549
+ end
550
+
551
+ it 'should correctly fetch the temporary credentials' do
552
+ # Repeat this because signatures change from test to test
553
+ 10.times do
554
+ request = @client.generate_temporary_credential_request
555
+ method, uri, headers, body = request
556
+ method.should == 'POST'
557
+ uri.should == 'http://example.com/temporary_credentials'
558
+ authorization_header = nil
559
+ headers.each do |(header, value)|
560
+ authorization_header = value if header == 'Authorization'
561
+ end
562
+ parameters = Hash[::Signet::OAuth1.parse_authorization_header(
563
+ authorization_header
564
+ )]
565
+ parameters.should_not have_key('oauth_client_credential_key')
566
+ parameters.should_not have_key('oauth_temporary_credential_key')
567
+ parameters.should_not have_key('oauth_token')
568
+ parameters['oauth_nonce'].should =~ /^\w+$/
569
+ parameters['oauth_callback'].should == @client.callback
570
+ parameters['oauth_timestamp'].should =~ /^\d+$/
571
+ parameters['oauth_signature_method'].should == 'HMAC-SHA1'
572
+ parameters['oauth_consumer_key'].should == @client.client_credential_key
573
+ parameters['oauth_signature'].should =~ /^[a-zA-Z0-9\=\/\+]+$/
574
+ parameters['oauth_version'].should == '1.0'
575
+ end
576
+ end
577
+
578
+ it 'should correctly fetch the token credentials' do
579
+ # Repeat this because signatures change from test to test
580
+ 10.times do
581
+ request = @client.generate_token_credential_request(
582
+ :verifier => '473f82d3'
583
+ )
584
+ method, uri, headers, body = request
585
+ method.should == 'POST'
586
+ uri.should == 'http://example.com/token_credentials'
587
+ authorization_header = nil
588
+ headers.each do |(header, value)|
589
+ authorization_header = value if header == 'Authorization'
590
+ end
591
+ parameters = Hash[::Signet::OAuth1.parse_authorization_header(
592
+ authorization_header
593
+ )]
594
+ parameters.should_not have_key('oauth_client_credential_key')
595
+ parameters.should_not have_key('oauth_temporary_credential_key')
596
+ parameters.should_not have_key('oauth_callback')
597
+ parameters['oauth_nonce'].should =~ /^\w+$/
598
+ parameters['oauth_timestamp'].should =~ /^\d+$/
599
+ parameters['oauth_signature_method'].should == 'HMAC-SHA1'
600
+ parameters['oauth_consumer_key'].should == @client.client_credential_key
601
+ parameters['oauth_token'].should == @client.temporary_credential_key
602
+ parameters['oauth_signature'].should =~ /^[a-zA-Z0-9\=\/\+]+$/
603
+ parameters['oauth_verifier'].should == '473f82d3'
604
+ parameters['oauth_version'].should == '1.0'
605
+ end
606
+ end
607
+
608
+ it 'should correctly fetch the protected resource' do
609
+ # Repeat this because signatures change from test to test
610
+ 10.times do
611
+ original_request = [
612
+ 'GET',
613
+ 'https://photos.example.net/photos?file=vacation.jpg&size=original',
614
+ [['Host', 'photos.example.net']],
615
+ ['']
616
+ ]
617
+ signed_request = @client.generate_authenticated_request(
618
+ :request => original_request
619
+ )
620
+ method, uri, headers, body = signed_request
621
+ method.should == 'GET'
622
+ uri.should ==
623
+ 'https://photos.example.net/photos?file=vacation.jpg&size=original'
624
+ authorization_header = nil
625
+ headers.each do |(header, value)|
626
+ authorization_header = value if header == 'Authorization'
627
+ end
628
+ merge_body(body).should == ''
629
+ parameters = Hash[::Signet::OAuth1.parse_authorization_header(
630
+ authorization_header
631
+ )]
632
+ parameters.should_not have_key('oauth_client_credential_key')
633
+ parameters.should_not have_key('oauth_temporary_credential_key')
634
+ parameters.should_not have_key('oauth_token_credential_key')
635
+ parameters.should_not have_key('oauth_callback')
636
+ parameters['oauth_nonce'].should =~ /^\w+$/
637
+ parameters['oauth_timestamp'].should =~ /^\d+$/
638
+ parameters['oauth_signature_method'].should == 'HMAC-SHA1'
639
+ parameters['oauth_consumer_key'].should == @client.client_credential_key
640
+ parameters['oauth_token'].should == @client.token_credential_key
641
+ parameters['oauth_signature'].should =~ /^[a-zA-Z0-9\=\/\+]+$/
642
+ parameters['oauth_version'].should == '1.0'
643
+ end
644
+ end
645
+
646
+ it 'should correctly fetch the protected resource' do
647
+ # Repeat this because signatures change from test to test
648
+ 10.times do
649
+ original_request = [
650
+ 'POST',
651
+ 'https://photos.example.net/photos',
652
+ [
653
+ ['Host', 'photos.example.net'],
654
+ ['Content-Type', 'application/x-www-form-urlencoded; charset=utf-8'],
655
+ ['Content-Length', '31'],
656
+ ],
657
+ ['file=vacation.jpg&size=original']
658
+ ]
659
+ signed_request = @client.generate_authenticated_request(
660
+ :request => original_request
661
+ )
662
+ method, uri, headers, body = signed_request
663
+ method.should == 'POST'
664
+ uri.should ==
665
+ 'https://photos.example.net/photos'
666
+ authorization_header = nil
667
+ headers.each do |(header, value)|
668
+ authorization_header = value if header == 'Authorization'
669
+ end
670
+ merge_body(body).should == 'file=vacation.jpg&size=original'
671
+ parameters = Hash[::Signet::OAuth1.parse_authorization_header(
672
+ authorization_header
673
+ )]
674
+ parameters.should_not have_key('oauth_client_credential_key')
675
+ parameters.should_not have_key('oauth_temporary_credential_key')
676
+ parameters.should_not have_key('oauth_token_credential_key')
677
+ parameters.should_not have_key('oauth_callback')
678
+ parameters['oauth_nonce'].should =~ /^\w+$/
679
+ parameters['oauth_timestamp'].should =~ /^\d+$/
680
+ parameters['oauth_signature_method'].should == 'HMAC-SHA1'
681
+ parameters['oauth_consumer_key'].should == @client.client_credential_key
682
+ parameters['oauth_token'].should == @client.token_credential_key
683
+ parameters['oauth_signature'].should =~ /^[a-zA-Z0-9\=\/\+]+$/
684
+ parameters['oauth_version'].should == '1.0'
685
+ end
686
+ end
687
+ end