signet 0.1.0

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.
@@ -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