auth 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,9 @@
1
+ *0.0.7*
2
+
3
+ * Added handling of access_token as query parameter in Auth::Middleware
4
+ * Add option for allowing unauthenticated access in Auth::Middleware
5
+ * Uses SecureRandom when possible
6
+
1
7
  *0.0.6*
2
8
 
3
9
  * Added a Rack middleware
@@ -1,14 +1,23 @@
1
1
  require 'base64'
2
2
  require 'digest/sha2'
3
3
 
4
+ begin
5
+ require 'securerandom'
6
+ rescue LoadError
7
+ end
8
+
4
9
  module Auth
5
10
  module Helpers
6
11
 
7
12
  # Generate a unique cryptographically secure secret
8
13
  def generate_secret
9
- Base64.encode64(
10
- Digest::SHA256.digest("#{Time.now}-#{rand}")
11
- ).gsub('/','x').gsub('+','y').gsub('=','').strip
14
+ if defined?(SecureRandom)
15
+ SecureRandom.urlsafe_base64(32)
16
+ else
17
+ Base64.encode64(
18
+ Digest::SHA256.digest("#{Time.now}-#{Time.now.usec}-#{$$}-#{rand}")
19
+ ).gsub('/','-').gsub('+','_').gsub('=','').strip
20
+ end
12
21
  end
13
22
 
14
23
  # Obfuscate a password using a salt and a cryptographic hash function
@@ -7,18 +7,32 @@ require 'auth'
7
7
  module Auth
8
8
  class Middleware < Rack::Auth::AbstractHandler
9
9
 
10
+ def initialize(app, realm=nil, options={}, &authenticator)
11
+ super(app, realm, &authenticator)
12
+ @options = options
13
+ end
14
+
10
15
  def call(env)
11
16
  auth = Request.new(env)
12
17
 
13
- return unauthorized unless auth.provided?
14
- return bad_request unless auth.bearer?
18
+ unless @options[:allow_unauthenticated]
19
+ return unauthorized unless auth.provided?
20
+ return bad_request unless auth.bearer?
21
+ end
15
22
 
16
- if valid?(auth)
23
+ if auth.provided? && valid?(auth)
17
24
  env['REMOTE_USER'] = auth.account_id
18
25
  return @app.call(env)
19
26
  end
20
27
 
21
- unauthorized
28
+ if @options[:allow_unauthenticated]
29
+ res = @app.call(env)
30
+ return [res[0],
31
+ res[1].merge('WWW-Authenticate' => challenge),
32
+ res[2]]
33
+ else
34
+ unauthorized
35
+ end
22
36
  end
23
37
 
24
38
  private
@@ -36,8 +50,17 @@ module Auth
36
50
  :bearer == scheme
37
51
  end
38
52
 
53
+ def provided?
54
+ super || request.params['access_token']
55
+ end
56
+
57
+ def parts
58
+ authorization_key ? super : ['Bearer', nil]
59
+ end
60
+
39
61
  def access_token
40
- @access_token ||= params.unpack("m*").first
62
+ @access_token ||= params ? params.unpack("m*").first :
63
+ request.params['access_token']
41
64
  end
42
65
 
43
66
  def account_id
@@ -10,7 +10,7 @@ module Auth
10
10
  dir = File.dirname(File.expand_path(__FILE__))
11
11
 
12
12
  set :views, "#{dir}/server/views"
13
- set :public, "#{dir}/server/public"
13
+ set :public_folder, "#{dir}/server/public"
14
14
  set :static, true
15
15
  set :raise_errors, true
16
16
  set :show_exceptions, true if development?
@@ -1,3 +1,3 @@
1
1
  module Auth
2
- Version = VERSION = '0.0.6'
2
+ Version = VERSION = '0.0.7'
3
3
  end
@@ -4,11 +4,18 @@ require 'auth/middleware'
4
4
  class MiddlewareTest < Test::Unit::TestCase
5
5
  include Rack::Test::Methods
6
6
 
7
+ def inner_app
8
+ lambda { |env| [200, {'Content-Type' => 'text/plain'}, [env['REMOTE_USER']]] }
9
+ end
10
+
7
11
  def app
8
- inner_app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, [env['REMOTE_USER']]] }
9
12
  Auth::Middleware.new(inner_app, 'Test realm')
10
13
  end
11
14
 
15
+ def unprotected_app
16
+ Auth::Middleware.new(inner_app, 'Test realm', :allow_unauthenticated => true)
17
+ end
18
+
12
19
  def setup
13
20
  Auth.redis.flushall
14
21
  end
@@ -49,4 +56,31 @@ class MiddlewareTest < Test::Unit::TestCase
49
56
  assert_empty res[2]
50
57
  end
51
58
 
59
+ def test_unauthenticated_request_on_unprotected_app
60
+ env = Rack::MockRequest.env_for('/test')
61
+ res = unprotected_app.call(env)
62
+ assert_equal 200, res[0]
63
+ assert_equal 'Bearer realm="Test realm"', res[1]['WWW-Authenticate']
64
+ assert_equal [nil], res[2]
65
+ end
66
+
67
+ def test_authenticated_request_on_unprotected_app
68
+ token = Auth.issue_token('test-user')
69
+ env = Rack::MockRequest.env_for('/test',
70
+ 'HTTP_AUTHORIZATION' => "Bearer #{Base64.encode64(token)}")
71
+ res = unprotected_app.call(env)
72
+ assert_equal 200, res[0]
73
+ assert_equal nil, res[1]['WWW-Authenticate']
74
+ assert_equal ['test-user'], res[2]
75
+ end
76
+
77
+ def test_authenticated_request_with_query_parameter
78
+ token = Auth.issue_token('test-user')
79
+ env = Rack::MockRequest.env_for("/test?access_token=#{CGI.escape(token)}")
80
+ res = app.call(env)
81
+ assert_equal 200, res[0]
82
+ assert_equal nil, res[1]['WWW-Authenticate']
83
+ assert_equal ['test-user'], res[2]
84
+ end
85
+
52
86
  end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: auth
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.0.6
5
+ version: 0.0.7
6
6
  platform: ruby
7
7
  authors:
8
8
  - Niklas Holmgren
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-12-19 00:00:00 Z
13
+ date: 2012-01-23 00:00:00 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: json