oauthenticator 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
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