oauthenticator 0.1.4 → 1.0.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,86 @@
1
+ # encoding: utf-8
2
+ proc { |p| $:.unshift(p) unless $:.any? { |lp| File.expand_path(lp) == p } }.call(File.expand_path('.', File.dirname(__FILE__)))
3
+ require 'helper'
4
+
5
+ describe 'OAuthenticator.parse_authorization' do
6
+ let :spec_authorization do
7
+ %q(OAuth realm="Example",
8
+ oauth_consumer_key="9djdj82h48djs9d2",
9
+ oauth_token="kkk9d7dh3k39sjv7",
10
+ oauth_signature_method="HMAC-SHA1",
11
+ oauth_timestamp="137131201",
12
+ oauth_nonce="7d8f3e4a",
13
+ oauth_signature="r6%2FTJjbCOr97%2F%2BUU0NsvSne7s5g%3D"
14
+ )
15
+ end
16
+ let :spec_authorization_hash do
17
+ {
18
+ 'realm' => "Example",
19
+ 'oauth_consumer_key' => "9djdj82h48djs9d2",
20
+ 'oauth_token' => "kkk9d7dh3k39sjv7",
21
+ 'oauth_signature_method' => "HMAC-SHA1",
22
+ 'oauth_timestamp' => "137131201",
23
+ 'oauth_nonce' => "7d8f3e4a",
24
+ 'oauth_signature' => "r6/TJjbCOr97/+UU0NsvSne7s5g=",
25
+ }
26
+ end
27
+
28
+ it 'parses the example in the spec' do
29
+ assert_equal(spec_authorization_hash, OAuthenticator.parse_authorization(spec_authorization))
30
+ end
31
+ it 'parses the authorization SignableRequest calculates' do
32
+ request = OAuthenticator::SignableRequest.new({
33
+ :request_method => 'POST',
34
+ :uri => 'http://example.com/request?b5=%3D%253D&a3=a&c%40=&a2=r%20b',
35
+ :media_type => 'application/x-www-form-urlencoded',
36
+ :body => 'c2&a3=2+q',
37
+ :authorization => spec_authorization_hash,
38
+ :consumer_secret => 'j49sk3j29djd',
39
+ :token_secret => 'dh893hdasih9',
40
+ })
41
+ assert_equal(spec_authorization_hash, OAuthenticator.parse_authorization(request.authorization))
42
+ end
43
+
44
+ describe 'optional linear white space' do
45
+ { :space => %q(OAuth a="b", c="d", e="f"),
46
+ :spaces => %q(OAuth a="b", c="d", e="f" ),
47
+ :tab => %q(OAuth a="b", c="d", e="f"),
48
+ :tabs => %q(OAuth a="b", c="d", e="f"),
49
+ :tabs_and_spaces => %q(OAuth a="b", c="d", e="f"),
50
+ :none => %q(OAuth a="b",c="d",e="f"),
51
+ }.map do |name, authorization|
52
+ it "parses with #{name}" do
53
+ assert_equal({'a' => 'b', 'c' => 'd', 'e' => 'f'}, OAuthenticator.parse_authorization(authorization))
54
+ end
55
+ end
56
+ end
57
+
58
+ it "handles commas inside quoted values" do
59
+ # note that this is invalid according to the spec; commas should be %-encoded, but this is accepted in
60
+ # the interests of robustness and consistency (other characters are accepted when they should really be
61
+ # escaped).
62
+ header_with_commas = 'OAuth oauth_consumer_key="a,bcd", oauth_nonce="o,LKtec51GQy", oauth_signature="efgh%2Cmnop"'
63
+ assert_equal({'oauth_consumer_key' => "a,bcd", 'oauth_nonce' => "o,LKtec51GQy", 'oauth_signature' => "efgh,mnop"},
64
+ OAuthenticator.parse_authorization(header_with_commas))
65
+ end
66
+
67
+ it "raises ParseError on input without a comma between key/value pairs" do
68
+ assert_raises(OAuthenticator::ParseError) do
69
+ OAuthenticator.parse_authorization(%q(OAuth oauth_consumer_key="k" oauth_nonce="n"))
70
+ end
71
+ end
72
+
73
+ it "raises ParseError on malformed input" do
74
+ assert_raises(OAuthenticator::ParseError) { OAuthenticator.parse_authorization(%q(OAuth huh=/)) }
75
+ end
76
+
77
+ it "raises ParseError when the header does not start with 'OAuth '" do
78
+ assert_raises(OAuthenticator::ParseError) { OAuthenticator.parse_authorization(%q(FooAuth foo="baz")) }
79
+ end
80
+
81
+ it "raises DuplicatedParameter when the header contains duplicated parameters" do
82
+ assert_raises(OAuthenticator::DuplicatedParameters) do
83
+ OAuthenticator.parse_authorization(%q(OAuth oauth_nonce="a", oauth_nonce="b"))
84
+ end
85
+ end
86
+ end
@@ -2,77 +2,13 @@
2
2
  proc { |p| $:.unshift(p) unless $:.any? { |lp| File.expand_path(lp) == p } }.call(File.expand_path('.', File.dirname(__FILE__)))
3
3
  require 'helper'
4
4
 
5
- # config methods for testing OAuthenticator. simple
6
- module OAuthenticatorTestConfigMethods
7
- class << self
8
- # a set of nonces
9
- define_method(:nonces) { @nonces ||= Set.new }
10
- # a Hash keyed by consumer keys with values of consumer secrets
11
- define_method(:consumer_secrets) { @consumer_secrets ||= {} }
12
- # a Hash keyed by access tokens with values of access token secrets
13
- define_method(:access_token_secrets) { @access_token_secrets ||= {} }
14
- # a Hash keyed by access tokens with values of consumer keys
15
- define_method(:access_token_consumers) { @access_token_consumers ||= {} }
16
- end
17
-
18
- def nonce_used?
19
- OAuthenticatorTestConfigMethods.nonces.include?(oauth_header_params[:nonce])
20
- end
21
-
22
- def use_nonce!
23
- OAuthenticatorTestConfigMethods.nonces << oauth_header_params[:nonce]
24
- end
25
-
26
- def timestamp_valid_period
27
- 10
28
- end
29
-
30
- def allowed_signature_methods
31
- %w(HMAC-SHA1 RSA-SHA1 PLAINTEXT)
32
- end
33
-
34
- def consumer_secret
35
- OAuthenticatorTestConfigMethods.consumer_secrets[oauth_header_params[:consumer_key]]
36
- end
37
-
38
- def access_token_secret
39
- OAuthenticatorTestConfigMethods.access_token_secrets[oauth_header_params[:token]]
40
- end
41
-
42
- def access_token_belongs_to_consumer?
43
- OAuthenticatorTestConfigMethods.access_token_consumers[oauth_header_params[:token]] == oauth_header_params[:consumer_key]
44
- end
45
- end
46
-
47
- describe OAuthenticator::Middleware do
5
+ describe OAuthenticator::RackAuthenticator do
48
6
  # act like a database cleaner
49
7
  after do
50
- [:nonces, :consumer_secrets, :access_token_secrets, :access_token_consumers].each do |db|
8
+ [:nonces, :consumer_secrets, :token_secrets, :token_consumers].each do |db|
51
9
  OAuthenticatorTestConfigMethods.send(db).clear
52
10
  end
53
-
54
- Timecop.return
55
- end
56
-
57
- let(:simpleapp) { proc { |env| [200, {}, ['☺']] } }
58
- let(:oapp) { OAuthenticator::Middleware.new(simpleapp, :config_methods => OAuthenticatorTestConfigMethods) }
59
-
60
- let(:consumer) do
61
- {:key => "test_client_app_key", :secret => "test_client_app_secret"}.tap do |consumer|
62
- OAuthenticatorTestConfigMethods.consumer_secrets[consumer[:key]] = consumer[:secret]
63
- end
64
- end
65
- let(:consumer_key) { consumer[:key] }
66
- let(:consumer_secret) { consumer[:secret] }
67
-
68
- let(:access_token_hash) do
69
- {:token => 'test_access_token', :secret => 'test_access_token_secret', :consumer_key => consumer_key}.tap do |hash|
70
- OAuthenticatorTestConfigMethods.access_token_secrets[hash[:token]] = hash[:secret]
71
- OAuthenticatorTestConfigMethods.access_token_consumers[hash[:token]] = hash[:consumer_key]
72
- end
73
11
  end
74
- let(:access_token) { access_token_hash[:token] }
75
- let(:access_token_secret) { access_token_hash[:secret] }
76
12
 
77
13
  def assert_response(expected_status, expected_body, actual_status, actual_headers, actual_body)
78
14
  actual_body_s = actual_body.to_enum.to_a.join
@@ -83,27 +19,31 @@ describe OAuthenticator::Middleware do
83
19
 
84
20
  it 'makes a valid two-legged signed request (generated)' do
85
21
  request = Rack::Request.new(Rack::MockRequest.env_for('/', :method => 'GET'))
86
- request.env['HTTP_AUTHORIZATION'] = SimpleOAuth::Header.new(
87
- request.request_method,
88
- request.url,
89
- nil,
90
- {:consumer_key => consumer_key, :consumer_secret => consumer_secret}
91
- ).to_s
22
+ request.env['HTTP_AUTHORIZATION'] = OAuthenticator::SignableRequest.new({
23
+ :request_method => request.request_method,
24
+ :uri => request.url,
25
+ :media_type => request.media_type,
26
+ :body => request.body,
27
+ :signature_method => 'HMAC-SHA1',
28
+ :consumer_key => consumer_key,
29
+ :consumer_secret => consumer_secret,
30
+ }).authorization
92
31
  assert_response(200, '☺', *oapp.call(request.env))
93
32
  end
94
33
 
95
- it 'makes a valid two-legged signed request with a blank access token (generated)' do
34
+ it 'makes a valid two-legged signed request with a blank token (generated)' do
96
35
  request = Rack::Request.new(Rack::MockRequest.env_for('/', :method => 'GET'))
97
- request.env['HTTP_AUTHORIZATION'] = SimpleOAuth::Header.new(
98
- request.request_method,
99
- request.url,
100
- nil,
101
- { :consumer_key => consumer_key,
102
- :consumer_secret => consumer_secret,
103
- :token => '',
104
- :token_secret => '',
105
- }
106
- ).to_s
36
+ request.env['HTTP_AUTHORIZATION'] = OAuthenticator::SignableRequest.new({
37
+ :request_method => request.request_method,
38
+ :uri => request.url,
39
+ :media_type => request.media_type,
40
+ :body => request.body,
41
+ :signature_method => 'HMAC-SHA1',
42
+ :consumer_key => consumer_key,
43
+ :consumer_secret => consumer_secret,
44
+ :token => '',
45
+ :token_secret => '',
46
+ }).authorization
107
47
  assert_response(200, '☺', *oapp.call(request.env))
108
48
  end
109
49
 
@@ -113,27 +53,31 @@ describe OAuthenticator::Middleware do
113
53
  :input => 'a=b&a=c',
114
54
  'CONTENT_TYPE' => 'application/x-www-form-urlencoded; charset=UTF8',
115
55
  ))
116
- request.env['HTTP_AUTHORIZATION'] = SimpleOAuth::Header.new(
117
- request.request_method,
118
- request.url,
119
- [['a', 'b'], ['a', 'c']],
120
- {:consumer_key => consumer_key, :consumer_secret => consumer_secret}
121
- ).to_s
56
+ request.env['HTTP_AUTHORIZATION'] = OAuthenticator::SignableRequest.new({
57
+ :request_method => request.request_method,
58
+ :uri => request.url,
59
+ :media_type => request.media_type,
60
+ :body => request.body,
61
+ :signature_method => 'HMAC-SHA1',
62
+ :consumer_key => consumer_key,
63
+ :consumer_secret => consumer_secret
64
+ }).authorization
122
65
  assert_response(200, '☺', *oapp.call(request.env))
123
66
  end
124
67
 
125
68
  it 'makes a valid three-legged signed request (generated)' do
126
69
  request = Rack::Request.new(Rack::MockRequest.env_for('/', :method => 'GET'))
127
- request.env['HTTP_AUTHORIZATION'] = SimpleOAuth::Header.new(
128
- request.request_method,
129
- request.url,
130
- nil,
131
- { :consumer_key => consumer_key,
132
- :consumer_secret => consumer_secret,
133
- :token => access_token,
134
- :token_secret => access_token_secret,
135
- }
136
- ).to_s
70
+ request.env['HTTP_AUTHORIZATION'] = OAuthenticator::SignableRequest.new({
71
+ :request_method => request.request_method,
72
+ :uri => request.url,
73
+ :media_type => request.media_type,
74
+ :body => request.body,
75
+ :signature_method => 'HMAC-SHA1',
76
+ :consumer_key => consumer_key,
77
+ :consumer_secret => consumer_secret,
78
+ :token => token,
79
+ :token_secret => token_secret,
80
+ }).authorization
137
81
  assert_response(200, '☺', *oapp.call(request.env))
138
82
  end
139
83
 
@@ -156,15 +100,15 @@ describe OAuthenticator::Middleware do
156
100
  it "makes a valid signed three-legged request (static #{i})" do
157
101
  Timecop.travel Time.at 1391021695
158
102
  consumer # cause this to be created
159
- access_token_hash # cause this to be created
103
+ token_hash # cause this to be created
160
104
  request = Rack::Request.new(Rack::MockRequest.env_for('/', :method => 'GET'))
161
105
  request.env['HTTP_AUTHORIZATION'] = %q(OAuth ) +
162
106
  %q(oauth_consumer_key="test_client_app_key", ) +
163
107
  %q(oauth_nonce="6320851a8f4e18b2ac223497b0477f2e", ) +
164
- %q(oauth_signature="B0sJjhfiXajEveqgjaRL3L60sCM%3D", ) +
108
+ %q(oauth_signature="MyfcvCJfiOHCdkdwFOKtfwoOPqE%3D", ) +
165
109
  %q(oauth_signature_method="HMAC-SHA1", ) +
166
110
  %q(oauth_timestamp="1391021695", ) +
167
- %q(oauth_token="test_access_token", ) +
111
+ %q(oauth_token="test_token", ) +
168
112
  %q(oauth_version="1.0")
169
113
  assert_response(200, '☺', *oapp.call(request.env))
170
114
  end
@@ -183,17 +127,16 @@ describe OAuthenticator::Middleware do
183
127
  end
184
128
 
185
129
  describe 'invalid Authorization header' do
186
- if SimpleOAuth.const_defined?(:ParseError)
187
- it 'does not prefix with oauth_' do
188
- assert_response(401, /Could not parse Authorization header/, *oapp.call({'HTTP_AUTHORIZATION' => %q(OAuth client_app_key="test_client_app_key")}))
189
- end
190
- it 'has something unparseable' do
191
- assert_response(401, /Could not parse Authorization header/, *oapp.call({'HTTP_AUTHORIZATION' => %q(OAuth <client-app-key>test_client_app_key</client-app-key>)}))
192
- end
193
- else
194
- it 'has something unparseable' do
195
- assert_response(401, /Authorization header is not a properly-formed OAuth 1.0 header./, *oapp.call({'HTTP_AUTHORIZATION' => %q(OAuth <client-app-key>test_client_app_key</client-app-key>)}))
196
- end
130
+ it 'has duplicate params' do
131
+ assert_response(
132
+ 401,
133
+ /Received multiple instances of Authorization parameter oauth_version/,
134
+ *oapp.call({'HTTP_AUTHORIZATION' => %q(OAuth oauth_version="1.0", oauth_version="1.1")})
135
+ )
136
+ end
137
+
138
+ it 'has something unparseable' do
139
+ assert_response(401, /Could not parse Authorization header/, *oapp.call({'HTTP_AUTHORIZATION' => %q(OAuth <client-app-key>test_client_app_key</client-app-key>)}))
197
140
  end
198
141
  end
199
142
 
@@ -209,6 +152,18 @@ describe OAuthenticator::Middleware do
209
152
  %q(oauth_version="1.0")
210
153
  assert_response(401, /Authorization oauth_timestamp.*is missing/m, *oapp.call(request.env))
211
154
  end
155
+ it 'omits timestamp with PLAINTEXT' do
156
+ Timecop.travel Time.at 1391021695
157
+ consumer # cause this to be created
158
+ request = Rack::Request.new(Rack::MockRequest.env_for('/', :method => 'GET'))
159
+ request.env['HTTP_AUTHORIZATION'] = %q(OAuth oauth_consumer_key="test_client_app_key", ) +
160
+ %q(oauth_nonce="c1c2bd8676d44e48691c8dceffa66a96", ) +
161
+ %q(oauth_signature="test_client_app_secret%26", ) +
162
+ %q(oauth_signature_method="PLAINTEXT", ) +
163
+ #%q(oauth_timestamp="1391021695", ) +
164
+ %q(oauth_version="1.0")
165
+ assert_response(200, '☺', *oapp.call(request.env))
166
+ end
212
167
  it 'has a non-integer timestamp' do
213
168
  Timecop.travel Time.at 1391021695
214
169
  consumer # cause this to be created
@@ -293,25 +248,25 @@ describe OAuthenticator::Middleware do
293
248
  %q(oauth_version="1.0")
294
249
  assert_response(401, /Authorization oauth_consumer_key.*is invalid/m, *oapp.call(request.env))
295
250
  end
296
- it 'has an invalid access token' do
251
+ it 'has an invalid token' do
297
252
  Timecop.travel Time.at 1391021695
298
253
  consumer # cause this to be created
299
- access_token_hash # cause this to be created
254
+ token_hash # cause this to be created
300
255
  request = Rack::Request.new(Rack::MockRequest.env_for('/', :method => 'GET'))
301
256
  request.env['HTTP_AUTHORIZATION'] = %q(OAuth ) +
302
257
  %q(oauth_consumer_key="test_client_app_key", ) +
303
258
  %q(oauth_nonce="6320851a8f4e18b2ac223497b0477f2e", ) +
304
- %q(oauth_signature="B0sJjhfiXajEveqgjaRL3L60sCM%3D", ) +
259
+ %q(oauth_signature="MyfcvCJfiOHCdkdwFOKtfwoOPqE%3D", ) +
305
260
  %q(oauth_signature_method="HMAC-SHA1", ) +
306
261
  %q(oauth_timestamp="1391021695", ) +
307
- %q(oauth_token="nonexistent_access_token", ) +
262
+ %q(oauth_token="nonexistent_token", ) +
308
263
  %q(oauth_version="1.0")
309
264
  assert_response(401, /Authorization oauth_token.*is invalid/m, *oapp.call(request.env))
310
265
  end
311
- it 'has an access token belonging to a different consumer key' do
266
+ it 'has a token belonging to a different consumer key' do
312
267
  Timecop.travel Time.at 1391021695
313
268
  consumer # cause this to be created
314
- access_token_hash # cause this to be created
269
+ token_hash # cause this to be created
315
270
 
316
271
  OAuthenticatorTestConfigMethods.consumer_secrets["different_client_app_key"] = "different_client_app_secret"
317
272
 
@@ -322,7 +277,7 @@ describe OAuthenticator::Middleware do
322
277
  %q(oauth_signature="PVscPDg%2B%2FjAXRiahIggkeBpN5zI%3D", ) +
323
278
  %q(oauth_signature_method="HMAC-SHA1", ) +
324
279
  %q(oauth_timestamp="1391021695", ) +
325
- %q(oauth_token="test_access_token", ) +
280
+ %q(oauth_token="test_token", ) +
326
281
  %q(oauth_version="1.0")
327
282
  assert_response(401, /Authorization oauth_token.*does not belong to the specified consumer/m, *oapp.call(request.env))
328
283
  end
@@ -338,6 +293,18 @@ describe OAuthenticator::Middleware do
338
293
  %q(oauth_version="1.0")
339
294
  assert_response(401, /Authorization oauth_nonce.*is missing/m, *oapp.call(request.env))
340
295
  end
296
+ it 'omits nonce with PLAINTEXT' do
297
+ Timecop.travel Time.at 1391021695
298
+ consumer # cause this to be created
299
+ request = Rack::Request.new(Rack::MockRequest.env_for('/', :method => 'GET'))
300
+ request.env['HTTP_AUTHORIZATION'] = %q(OAuth oauth_consumer_key="test_client_app_key", ) +
301
+ #%q(oauth_nonce="c1c2bd8676d44e48691c8dceffa66a96", ) +
302
+ %q(oauth_signature="test_client_app_secret%26", ) +
303
+ %q(oauth_signature_method="PLAINTEXT", ) +
304
+ %q(oauth_timestamp="1391021695", ) +
305
+ %q(oauth_version="1.0")
306
+ assert_response(200, '☺', *oapp.call(request.env))
307
+ end
341
308
  it 'has an already-used nonce' do
342
309
  Timecop.travel Time.at 1391021695
343
310
  consumer # cause this to be created
@@ -400,29 +367,152 @@ describe OAuthenticator::Middleware do
400
367
  assert_response(401, /Authorization oauth_signature.*is invalid/m, *oapp.call(request.env))
401
368
  end
402
369
 
370
+ describe 'oauth_body_hash' do
371
+ it 'has a valid body hash' do
372
+ Timecop.travel Time.at 1391021695
373
+ consumer # cause this to be created
374
+ request = Rack::Request.new(Rack::MockRequest.env_for('/', :method => 'PUT', :input => 'hello', 'CONTENT_TYPE' => 'text/plain'))
375
+ request.env['HTTP_AUTHORIZATION'] = %q(OAuth oauth_consumer_key="test_client_app_key", ) +
376
+ %q(oauth_nonce="c1c2bd8676d44e48691c8dceffa66a96", ) +
377
+ %q(oauth_signature="RkmgdKV4zUPAlY1%2BkjwPSuCSr%2F8%3D", ) +
378
+ %q(oauth_signature_method="HMAC-SHA1", ) +
379
+ %q(oauth_timestamp="1391021695", ) +
380
+ %q(oauth_version="1.0", ) +
381
+ %q(oauth_body_hash="qvTGHdzF6KLavt4PO0gs2a6pQ00%3D")
382
+ assert_response(200, '☺', *oapp.call(request.env))
383
+ end
384
+
385
+ it 'has an incorrect body hash' do
386
+ Timecop.travel Time.at 1391021695
387
+ consumer # cause this to be created
388
+ request = Rack::Request.new(Rack::MockRequest.env_for('/', :method => 'PUT', :input => 'hello', 'CONTENT_TYPE' => 'text/plain'))
389
+ request.env['HTTP_AUTHORIZATION'] = %q(OAuth oauth_consumer_key="test_client_app_key", ) +
390
+ %q(oauth_nonce="c1c2bd8676d44e48691c8dceffa66a96", ) +
391
+ %q(oauth_signature="RkmgdKV4zUPAlY1%2BkjwPSuCSr%2F8%3D", ) +
392
+ %q(oauth_signature_method="HMAC-SHA1", ) +
393
+ %q(oauth_timestamp="1391021695", ) +
394
+ %q(oauth_version="1.0", ) +
395
+ %q(oauth_body_hash="yes this is authentic")
396
+ assert_response(401, /Authorization oauth_body_hash.*is invalid/m, *oapp.call(request.env))
397
+ end
398
+
399
+ it 'has a body hash when one is not allowed (even if it is correct)' do
400
+ Timecop.travel Time.at 1391021695
401
+ consumer # cause this to be created
402
+ request = Rack::Request.new(Rack::MockRequest.env_for('/', :method => 'PUT', :input => 'hello', 'CONTENT_TYPE' => 'application/x-www-form-urlencoded'))
403
+ request.env['HTTP_AUTHORIZATION'] = %q(OAuth oauth_consumer_key="test_client_app_key", ) +
404
+ %q(oauth_nonce="c1c2bd8676d44e48691c8dceffa66a96", ) +
405
+ %q(oauth_signature="DG9qcuXaMPMx0fOcVFiUEPdYQnY%3D", ) +
406
+ %q(oauth_signature_method="HMAC-SHA1", ) +
407
+ %q(oauth_timestamp="1391021695", ) +
408
+ %q(oauth_version="1.0", ) +
409
+ %q(oauth_body_hash="qvTGHdzF6KLavt4PO0gs2a6pQ00%3D")
410
+ assert_response(401, /Authorization oauth_body_hash.*must not be included with form-encoded requests/m, *oapp.call(request.env))
411
+ end
412
+
413
+ it 'has a body hash with PLAINTEXT' do
414
+ Timecop.travel Time.at 1391021695
415
+ consumer # cause this to be created
416
+ request = Rack::Request.new(Rack::MockRequest.env_for('/', :method => 'PUT', :input => 'hello', 'CONTENT_TYPE' => 'text/plain'))
417
+ request.env['HTTP_AUTHORIZATION'] = %q(OAuth oauth_consumer_key="test_client_app_key", ) +
418
+ %q(oauth_nonce="c1c2bd8676d44e48691c8dceffa66a96", ) +
419
+ %q(oauth_signature="test_client_app_secret%26", ) +
420
+ %q(oauth_signature_method="PLAINTEXT", ) +
421
+ %q(oauth_timestamp="1391021695", ) +
422
+ %q(oauth_version="1.0", ) +
423
+ %q(oauth_body_hash="qvTGHdzF6KLavt4PO0gs2a6pQ00%3D")
424
+ assert_response(200, '☺', *oapp.call(request.env))
425
+ end
426
+
427
+ describe 'body hash is required' do
428
+ let(:hashrequiredapp) do
429
+ hash_required_config = Module.new do
430
+ include OAuthenticatorTestConfigMethods
431
+ define_method(:body_hash_required?) { true }
432
+ end
433
+ OAuthenticator::RackAuthenticator.new(simpleapp, :config_methods => hash_required_config)
434
+ end
435
+
436
+ it 'is missing a body hash, one is not allowed' do
437
+ Timecop.travel Time.at 1391021695
438
+ consumer # cause this to be created
439
+ request = Rack::Request.new(Rack::MockRequest.env_for('/', :method => 'PUT', :input => 'hello', 'CONTENT_TYPE' => 'application/x-www-form-urlencoded'))
440
+ request.env['HTTP_AUTHORIZATION'] = %q(OAuth oauth_consumer_key="test_client_app_key", ) +
441
+ %q(oauth_nonce="c1c2bd8676d44e48691c8dceffa66a96", ) +
442
+ %q(oauth_signature="DG9qcuXaMPMx0fOcVFiUEPdYQnY%3D", ) +
443
+ %q(oauth_signature_method="HMAC-SHA1", ) +
444
+ %q(oauth_timestamp="1391021695", ) +
445
+ %q(oauth_version="1.0")
446
+ assert_response(200, '☺', *hashrequiredapp.call(request.env))
447
+ end
448
+ it 'is missing a body hash, one is allowed' do
449
+ Timecop.travel Time.at 1391021695
450
+ consumer # cause this to be created
451
+ request = Rack::Request.new(Rack::MockRequest.env_for('/', :method => 'PUT', :input => 'hello', 'CONTENT_TYPE' => 'text/plain'))
452
+ request.env['HTTP_AUTHORIZATION'] = %q(OAuth oauth_consumer_key="test_client_app_key", ) +
453
+ %q(oauth_nonce="c1c2bd8676d44e48691c8dceffa66a96", ) +
454
+ %q(oauth_signature="czC%2F9Z8tE1H4AJaT8lOKLokrWRE%3D", ) +
455
+ %q(oauth_signature_method="HMAC-SHA1", ) +
456
+ %q(oauth_timestamp="1391021695", ) +
457
+ %q(oauth_version="1.0")
458
+ assert_response(401, /Authorization oauth_body_hash.*is required \(on non-form-encoded requests\)/m, *hashrequiredapp.call(request.env))
459
+ end
460
+ end
461
+
462
+ describe 'body hash not required' do
463
+ it 'is missing a body hash, one is not allowed' do
464
+ Timecop.travel Time.at 1391021695
465
+ consumer # cause this to be created
466
+ request = Rack::Request.new(Rack::MockRequest.env_for('/', :method => 'PUT', :input => 'hello', 'CONTENT_TYPE' => 'application/x-www-form-urlencoded'))
467
+ request.env['HTTP_AUTHORIZATION'] = %q(OAuth oauth_consumer_key="test_client_app_key", ) +
468
+ %q(oauth_nonce="c1c2bd8676d44e48691c8dceffa66a96", ) +
469
+ %q(oauth_signature="DG9qcuXaMPMx0fOcVFiUEPdYQnY%3D", ) +
470
+ %q(oauth_signature_method="HMAC-SHA1", ) +
471
+ %q(oauth_timestamp="1391021695", ) +
472
+ %q(oauth_version="1.0")
473
+ assert_response(200, '☺', *oapp.call(request.env))
474
+ end
475
+ it 'is missing a body hash, one is allowed' do
476
+ Timecop.travel Time.at 1391021695
477
+ consumer # cause this to be created
478
+ request = Rack::Request.new(Rack::MockRequest.env_for('/', :method => 'PUT', :input => 'hello', 'CONTENT_TYPE' => 'text/plain'))
479
+ request.env['HTTP_AUTHORIZATION'] = %q(OAuth oauth_consumer_key="test_client_app_key", ) +
480
+ %q(oauth_nonce="c1c2bd8676d44e48691c8dceffa66a96", ) +
481
+ %q(oauth_signature="czC%2F9Z8tE1H4AJaT8lOKLokrWRE%3D", ) +
482
+ %q(oauth_signature_method="HMAC-SHA1", ) +
483
+ %q(oauth_timestamp="1391021695", ) +
484
+ %q(oauth_version="1.0")
485
+ assert_response(200, '☺', *oapp.call(request.env))
486
+ end
487
+ end
488
+ end
489
+
403
490
  describe :bypass do
404
491
  it 'bypasses with invalid request' do
405
- oapp = OAuthenticator::Middleware.new(simpleapp, :bypass => proc { true }, :config_methods => OAuthenticatorTestConfigMethods)
492
+ oapp = OAuthenticator::RackAuthenticator.new(simpleapp, :bypass => proc { true }, :config_methods => OAuthenticatorTestConfigMethods)
406
493
  env = Rack::MockRequest.env_for('/', :method => 'GET').merge({'HTTP_AUTHORIZATION' => 'oauth ?'})
407
494
  assert_response(200, '☺', *oapp.call(env))
408
495
  end
409
496
 
410
497
  it 'does not bypass with invalid request' do
411
- oapp = OAuthenticator::Middleware.new(simpleapp, :bypass => proc { false }, :config_methods => OAuthenticatorTestConfigMethods)
498
+ oapp = OAuthenticator::RackAuthenticator.new(simpleapp, :bypass => proc { false }, :config_methods => OAuthenticatorTestConfigMethods)
412
499
  assert_equal(401, oapp.call({}).first)
413
500
  end
414
501
 
415
502
  it 'bypasses with valid request' do
416
503
  was_authenticated = nil
417
504
  bapp = proc { |env| was_authenticated = env['oauth.authenticated']; [200, {}, ['☺']] }
418
- boapp = OAuthenticator::Middleware.new(bapp, :bypass => proc { true }, :config_methods => OAuthenticatorTestConfigMethods)
505
+ boapp = OAuthenticator::RackAuthenticator.new(bapp, :bypass => proc { true }, :config_methods => OAuthenticatorTestConfigMethods)
419
506
  request = Rack::Request.new(Rack::MockRequest.env_for('/', :method => 'GET'))
420
- request.env['HTTP_AUTHORIZATION'] = SimpleOAuth::Header.new(
421
- request.request_method,
422
- request.url,
423
- nil,
424
- {:consumer_key => consumer_key, :consumer_secret => consumer_secret}
425
- ).to_s
507
+ request.env['HTTP_AUTHORIZATION'] = OAuthenticator::SignableRequest.new({
508
+ :request_method => request.request_method,
509
+ :uri => request.url,
510
+ :media_type => request.media_type,
511
+ :body => request.body,
512
+ :signature_method => 'HMAC-SHA1',
513
+ :consumer_key => consumer_key,
514
+ :consumer_secret => consumer_secret
515
+ }).authorization
426
516
  assert_response(200, '☺', *boapp.call(request.env))
427
517
  assert(was_authenticated == false)
428
518
  end
@@ -430,16 +520,54 @@ describe OAuthenticator::Middleware do
430
520
  it 'does not bypass with valid request' do
431
521
  was_authenticated = nil
432
522
  bapp = proc { |env| was_authenticated = env['oauth.authenticated']; [200, {}, ['☺']] }
433
- boapp = OAuthenticator::Middleware.new(bapp, :bypass => proc { false }, :config_methods => OAuthenticatorTestConfigMethods)
523
+ boapp = OAuthenticator::RackAuthenticator.new(bapp, :bypass => proc { false }, :config_methods => OAuthenticatorTestConfigMethods)
434
524
  request = Rack::Request.new(Rack::MockRequest.env_for('/', :method => 'GET'))
435
- request.env['HTTP_AUTHORIZATION'] = SimpleOAuth::Header.new(
436
- request.request_method,
437
- request.url,
438
- nil,
439
- {:consumer_key => consumer_key, :consumer_secret => consumer_secret}
440
- ).to_s
525
+ request.env['HTTP_AUTHORIZATION'] = OAuthenticator::SignableRequest.new({
526
+ :request_method => request.request_method,
527
+ :uri => request.url,
528
+ :media_type => request.media_type,
529
+ :body => request.body,
530
+ :signature_method => 'HMAC-SHA1',
531
+ :consumer_key => consumer_key,
532
+ :consumer_secret => consumer_secret
533
+ }).authorization
441
534
  assert_response(200, '☺', *boapp.call(request.env))
442
535
  assert(was_authenticated == true)
443
536
  end
444
537
  end
538
+
539
+ describe 'rack env variables' do
540
+ let :request do
541
+ Rack::Request.new(Rack::MockRequest.env_for('/', :method => 'GET')).tap do |request|
542
+ request.env['HTTP_AUTHORIZATION'] = OAuthenticator::SignableRequest.new({
543
+ :request_method => request.request_method,
544
+ :uri => request.url,
545
+ :media_type => request.media_type,
546
+ :body => request.body,
547
+ :signature_method => 'HMAC-SHA1',
548
+ :consumer_key => consumer_key,
549
+ :consumer_secret => consumer_secret,
550
+ :token => token,
551
+ :token_secret => token_secret,
552
+ }).authorization
553
+ end
554
+ end
555
+
556
+ it 'sets oauth.authenticated, oauth.token, oauth.consumer_key' do
557
+ oauth_authenticated = nil
558
+ oauth_token = nil
559
+ oauth_consumer_key = nil
560
+ testapp = proc do |env|
561
+ oauth_authenticated = env['oauth.authenticated']
562
+ oauth_token = env['oauth.token']
563
+ oauth_consumer_key = env['oauth.consumer_key']
564
+ [200, {}, ['☺']]
565
+ end
566
+ otestapp = OAuthenticator::RackAuthenticator.new(testapp, :config_methods => OAuthenticatorTestConfigMethods)
567
+ assert_response(200, '☺', *otestapp.call(request.env))
568
+ assert_equal(token, oauth_token)
569
+ assert_equal(consumer_key, oauth_consumer_key)
570
+ assert_equal(true, oauth_authenticated)
571
+ end
572
+ end
445
573
  end