oauthenticator 1.0.0 → 1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7006ebe89c4cd63acc4c40c404a81cd1d435c671
4
- data.tar.gz: 54399c9d2d96645797f5bf0c179a46ac3aa0e47d
3
+ metadata.gz: 827942505f6a7a7454a54fec370230998566b31d
4
+ data.tar.gz: a2b80c738be4320eec657fea5b16d3b53ea06050
5
5
  SHA512:
6
- metadata.gz: 85859997c9cba4592b097443e643528c6ccc479542eb0410e64a57611c6226a0988314d0b8adb3a17e3e0ae08b823d45a6bbeb75f0f15ca6c298c4b5581859ab
7
- data.tar.gz: b1776d367f14799e6fcf5da5e09ed4c6c97cc932d86969c19c06bdcb99ac81827396c8d227fd445a64cbb8ae71f561a9ae4d7da9d65c6dfef67b3b788ce2c142
6
+ metadata.gz: ce622ff45391f968819261955cfabf0f1a8f73a7d0956b1e63011b7e342d83259f198a2f4b0d3f3895dcb119e8e89e0bc78e6fbc02c36fa54dc2eecd01b545a7
7
+ data.tar.gz: 42c979625cb2411ecb257e2010c7038f346c0b839cd2d57c079f09db4cefb7f04eddceff664e78b9fe5a8529e1ab93a0841b0f9cffcfac71dbb356d6611d77b0
@@ -0,0 +1,8 @@
1
+ # 1.1.0
2
+
3
+ - added OAuthenticator::NonceUsedError to address race condition between `#nonce_used?` and `#use_nonce!`
4
+ - minor fixes for ruby 1.8.7 compatibility
5
+
6
+ # 1.0.0
7
+
8
+ - initial stable release
@@ -98,6 +98,10 @@ module OAuthenticator
98
98
  # it's worth noting that if this ever returns true, it may indicate a replay attack under way against your
99
99
  # application. the replay attack will fail due to OAuth, but you may wish to log the event.
100
100
  #
101
+ # this method MAY simply return false IF the method #use_nonce! is implemented to raise
102
+ # OAuthenticator::NonceUsedError when it encounters an already-used nonce. this may be preferable - see
103
+ # the #use_nonce! documentation.
104
+ #
101
105
  # @return [Boolean] whether the request's nonce has already been used.
102
106
  def nonce_used?
103
107
  config_method_not_implemented
@@ -106,7 +110,18 @@ module OAuthenticator
106
110
  # cause the nonce, available via the `#nonce` method, to be marked as used. you may wish to use this in
107
111
  # conjunction with the timestamp (`#timestamp`).
108
112
  #
113
+ # although this will only be called when #nonce_used? has returned false, since a nonzero amount of time
114
+ # does elapse between that being called and this, a race condition may occur. therefore, if the
115
+ # implementation is able to perform an atomic test-and-set (e.g. with SETNX in redis, or with a
116
+ # uniqueness-ensuring index in SQL) when it is using the nonce, then it SHOULD do so in this method,
117
+ # and if the test-and-set indicates the nonce has been used, SHOULD raise OAuthenticator::NonceUsedError.
118
+ #
119
+ # if it is more performant for the implementation to only check whether the nonce is used once, when
120
+ # setting, then the method #nonce_used? MAY simply return false, and raising
121
+ # OAuthenticator::NonceUsedError from this method may be the only method of indicating a used nonce.
122
+ #
109
123
  # @return [Void] (return value is ignored / unused)
124
+ # @raise [OAuthenticator::NonceUsedError] if the nonce (with the timestamp, optionally) has already been used
110
125
  def use_nonce!
111
126
  config_method_not_implemented
112
127
  end
@@ -4,7 +4,7 @@ module OAuthenticator
4
4
  class Error < StandardError
5
5
  # @param message [String]
6
6
  # @param errors [Hash<String, Array<String>>]
7
- def initialize(message, errors=nil)
7
+ def initialize(message=nil, errors=nil)
8
8
  super(message)
9
9
  @errors = errors
10
10
  end
@@ -47,7 +47,7 @@ module OAuthenticator
47
47
  unless scanner.eos?
48
48
  auth_parse_error.call("Could not parse Authorization header: #{header}\naround or after character #{scanner.pos}: #{scanner.rest}")
49
49
  end
50
- duplicates = attributes.select { |k,v| v.size > 1 }
50
+ duplicates = attributes.reject { |k,v| v.size <= 1 }
51
51
  if duplicates.any?
52
52
  errors = duplicates.map do |k,vs|
53
53
  {k => "Received multiple instances of Authorization parameter #{k}. Received values were: #{vs.inspect}"}
@@ -2,6 +2,10 @@ require 'oauthenticator/signable_request'
2
2
  require 'oauthenticator/parse_authorization'
3
3
 
4
4
  module OAuthenticator
5
+ # an error which is to be raised when an attempt is made to use a nonce which has already been used.
6
+ class NonceUsedError < Error
7
+ end
8
+
5
9
  # this class represents an OAuth signed request. its primary user-facing method is {#errors}, which returns
6
10
  # nil if the request is valid and authentic, or a helpful object of error messages describing what was
7
11
  # invalid if not.
@@ -215,7 +219,12 @@ module OAuthenticator
215
219
  throw(:errors, {'Authorization oauth_signature' => ['is invalid']})
216
220
  end
217
221
 
218
- use_nonce!
222
+ begin
223
+ use_nonce!
224
+ rescue NonceUsedError
225
+ throw(:errors, {'Authorization oauth_nonce' => ['has already been used']})
226
+ end
227
+
219
228
  nil
220
229
  end
221
230
  end
@@ -1,5 +1,5 @@
1
1
  # OAuthenticator
2
2
  module OAuthenticator
3
3
  # OAuthenticator::VERSION
4
- VERSION = "1.0.0"
4
+ VERSION = "1.1.0"
5
5
  end
@@ -36,7 +36,7 @@ describe OAuthenticator::SignedRequest do
36
36
  assert_equal 2, called
37
37
  end
38
38
  it 'uses the default value for allowed signature methods' do
39
- assert_equal %w(RSA-SHA1 HMAC-SHA1 PLAINTEXT), OAuthenticator::SignedRequest.new({}).allowed_signature_methods
39
+ assert_equal %w(RSA-SHA1 HMAC-SHA1 PLAINTEXT).sort, OAuthenticator::SignedRequest.new({}).allowed_signature_methods.sort
40
40
  end
41
41
  it 'uses default value for body_hash_required?' do
42
42
  assert_equal false, OAuthenticator::SignedRequest.new({}).body_hash_required?
@@ -51,7 +51,7 @@ describe OAuthenticator::RackAuthenticator do
51
51
  request = Rack::Request.new(Rack::MockRequest.env_for('/',
52
52
  :method => 'GET',
53
53
  :input => 'a=b&a=c',
54
- 'CONTENT_TYPE' => 'application/x-www-form-urlencoded; charset=UTF8',
54
+ 'CONTENT_TYPE' => 'application/x-www-form-urlencoded; charset=UTF8'
55
55
  ))
56
56
  request.env['HTTP_AUTHORIZATION'] = OAuthenticator::SignableRequest.new({
57
57
  :request_method => request.request_method,
@@ -318,6 +318,26 @@ describe OAuthenticator::RackAuthenticator do
318
318
  assert_response(200, '☺', *oapp.call(request.env))
319
319
  assert_response(401, /Authorization oauth_nonce.*has already been used/m, *oapp.call(request.env))
320
320
  end
321
+ it 'has an already-used nonce, via use_nonce!' do
322
+ Timecop.travel Time.at 1391021695
323
+ consumer # cause this to be created
324
+ request = Rack::Request.new(Rack::MockRequest.env_for('/', :method => 'GET'))
325
+ request.env['HTTP_AUTHORIZATION'] = %q(OAuth oauth_consumer_key="test_client_app_key", ) +
326
+ %q(oauth_nonce="c1c2bd8676d44e48691c8dceffa66a96", ) +
327
+ %q(oauth_signature="Xy1s5IUn8x0U2KPyHBw4B2cHZMo%3D", ) +
328
+ %q(oauth_signature_method="HMAC-SHA1", ) +
329
+ %q(oauth_timestamp="1391021695", ) +
330
+ %q(oauth_version="1.0")
331
+ test_config_methods_nonce_used_false = Module.new do
332
+ include OAuthenticatorTestConfigMethods
333
+ def nonce_used?
334
+ false
335
+ end
336
+ end
337
+ app = OAuthenticator::RackAuthenticator.new(simpleapp, :config_methods => test_config_methods_nonce_used_false)
338
+ assert_response(200, '☺', *app.call(request.env))
339
+ assert_response(401, /Authorization oauth_nonce.*has already been used/m, *app.call(request.env))
340
+ end
321
341
  it 'omits signature' do
322
342
  Timecop.travel Time.at 1391021695
323
343
  consumer # cause this to be created
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  # config methods for testing OAuthenticator. simple
2
4
  module OAuthenticatorTestConfigMethods
3
5
  class << self
@@ -16,7 +18,12 @@ module OAuthenticatorTestConfigMethods
16
18
  end
17
19
 
18
20
  def use_nonce!
19
- OAuthenticatorTestConfigMethods.nonces << nonce
21
+ if OAuthenticatorTestConfigMethods.nonces.include?(nonce)
22
+ # checking the same thing as #nonce_used? lets #nonce_used? be overridden to return false and things still work
23
+ raise OAuthenticator::NonceUsedError
24
+ else
25
+ OAuthenticatorTestConfigMethods.nonces << nonce
26
+ end
20
27
  end
21
28
 
22
29
  def timestamp_valid_period
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oauthenticator
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ethan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-04-22 00:00:00.000000000 Z
11
+ date: 2014-05-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -201,6 +201,7 @@ extra_rdoc_files: []
201
201
  files:
202
202
  - ".simplecov"
203
203
  - ".yardopts"
204
+ - CHANGELOG.md
204
205
  - LICENSE.txt
205
206
  - README.md
206
207
  - Rakefile.rb