rack-authenticate 0.3.0 → 0.4.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.
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use 1.9.2
@@ -0,0 +1,45 @@
1
+ module Rack
2
+ module Authenticate
3
+ class CORSMiddleware
4
+ ACCESS_CONTROL_MAX_AGE = 60 * 60 * 48 # 48 hours
5
+
6
+ def initialize(app)
7
+ @app = app
8
+ end
9
+
10
+ def call(env)
11
+ status, headers, body = if cors_preflight_request?(env)
12
+ cors_allowances(env)
13
+ else
14
+ @app.call(env)
15
+ end
16
+
17
+ headers['Access-Control-Allow-Origin'] = env['HTTP_ORIGIN'] if env.has_key?('HTTP_ORIGIN')
18
+
19
+ [status, headers, body]
20
+ end
21
+
22
+ def cors_preflight_request?(env)
23
+ env['REQUEST_METHOD'] == 'OPTIONS' &&
24
+ %w[ HTTP_ACCESS_CONTROL_REQUEST_METHOD HTTP_ORIGIN ].all? { |k| env.has_key?(k) }
25
+ end
26
+
27
+ def cors_allowances(env)
28
+ headers = {
29
+ 'Access-Control-Allow-Origin' => env['HTTP_ORIGIN'],
30
+ 'Access-Control-Allow-Methods' => env['HTTP_ACCESS_CONTROL_REQUEST_METHOD'],
31
+ 'Access-Control-Allow-Credentials' => 'true',
32
+ 'Access-Control-Max-Age' => ACCESS_CONTROL_MAX_AGE.to_s,
33
+ 'Content-Type' => 'text/plain'
34
+ }
35
+
36
+ if env.has_key?('HTTP_ACCESS_CONTROL_REQUEST_HEADERS')
37
+ headers['Access-Control-Allow-Headers'] = env['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']
38
+ end
39
+
40
+ [200, headers, []]
41
+ end
42
+ end
43
+ end
44
+ end
45
+
@@ -5,8 +5,6 @@ require 'time'
5
5
  module Rack
6
6
  module Authenticate
7
7
  class Middleware < ::Rack::Auth::Basic
8
- ACCESS_CONTROL_MAX_AGE = 60 * 60 * 24 # 24 hours
9
-
10
8
  class Configuration
11
9
  def initialize(*args)
12
10
  self.timestamp_minute_tolerance ||= 30
@@ -112,12 +110,6 @@ module Rack
112
110
  calculated_digest == given_digest
113
111
  end
114
112
 
115
- def supported_cors_preflight_request?
116
- @configuration.support_cross_origin_resource_sharing? &&
117
- request.request_method == 'OPTIONS' &&
118
- %w[ HTTP_ACCESS_CONTROL_REQUEST_METHOD HTTP_ORIGIN ].all? { |k| request.env.has_key?(k) }
119
- end
120
-
121
113
  private
122
114
 
123
115
  def date
@@ -135,47 +127,36 @@ module Rack
135
127
  def initialize(app)
136
128
  @configuration = Configuration.new
137
129
  yield @configuration
130
+
131
+ @middleware_stack = lambda do |env|
132
+ auth = Auth.new(env, @configuration)
133
+ _call(env, auth)
134
+ end
135
+
136
+ if @configuration.support_cross_origin_resource_sharing?
137
+ require 'rack/authenticate/cors_middleware'
138
+ @middleware_stack = ::Rack::Authenticate::CORSMiddleware.new(@middleware_stack)
139
+ end
140
+
138
141
  super(app, &@configuration.basic_auth_validation_block)
139
142
  end
140
143
 
144
+ alias basic_auth_call call
141
145
  def call(env)
142
- auth = Auth.new(env, @configuration)
143
- return cors_allowances(env) if auth.supported_cors_preflight_request?
144
-
145
- _call(env, auth) { super }.tap do |(status, headers, body)|
146
- if @configuration.support_cross_origin_resource_sharing? && env.has_key?('HTTP_ORIGIN')
147
- headers['Access-Control-Allow-Origin'] = env['HTTP_ORIGIN']
148
- end
149
- end
146
+ @middleware_stack.call(env)
150
147
  end
151
148
 
152
149
  private
153
150
 
154
151
  def _call(env, auth)
155
152
  return unauthorized unless auth.provided?
156
- return yield if auth.basic?
153
+ return basic_auth_call(env) if auth.basic?
157
154
  return bad_request unless auth.hmac?
158
155
  return bad_request unless auth.has_all_required_parts?
159
156
  return unauthorized unless auth.valid?
160
157
 
161
158
  @app.call(env)
162
159
  end
163
-
164
- def cors_allowances(env)
165
- headers = {
166
- 'Access-Control-Allow-Origin' => env['HTTP_ORIGIN'],
167
- 'Access-Control-Allow-Methods' => env['HTTP_ACCESS_CONTROL_REQUEST_METHOD'],
168
- 'Access-Control-Allow-Credentials' => 'true',
169
- 'Access-Control-Max-Age' => ACCESS_CONTROL_MAX_AGE.to_s,
170
- 'Content-Type' => 'text/plain'
171
- }
172
-
173
- if env.has_key?('HTTP_ACCESS_CONTROL_REQUEST_HEADERS')
174
- headers['Access-Control-Allow-Headers'] = env['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']
175
- end
176
-
177
- [200, headers, []]
178
- end
179
160
  end
180
161
  end
181
162
  end
@@ -1,5 +1,5 @@
1
1
  module Rack
2
2
  module Authenticate
3
- VERSION = "0.3.0"
3
+ VERSION = "0.4.0"
4
4
  end
5
5
  end
@@ -0,0 +1,69 @@
1
+ require 'rack/authenticate/cors_middleware'
2
+ require 'rack/test'
3
+
4
+ RSpec.configure do |c|
5
+ c.treat_symbols_as_metadata_keys_with_true_values = true
6
+ c.filter_run :f
7
+ c.run_all_when_everything_filtered = true
8
+ end
9
+
10
+ module Rack
11
+ module Authenticate
12
+ describe CORSMiddleware do
13
+ include Rack::Test::Methods
14
+
15
+ let(:app) do
16
+ Rack::Builder.new do
17
+ use Rack::ContentLength
18
+ use Rack::Authenticate::CORSMiddleware
19
+ run lambda { |env| [200, {}, ['OK']] }
20
+ end
21
+ end
22
+
23
+ let(:headers) { 'X-Authorization-Date, Content-MD5, Authorization, Content-Type' }
24
+ let(:origin) { 'http://foo.example.com' }
25
+
26
+ let(:expected_response_headers) do {
27
+ 'Content-Type' => 'text/plain',
28
+ 'Access-Control-Allow-Origin' => origin,
29
+ 'Access-Control-Allow-Methods' => 'PUT',
30
+ 'Access-Control-Allow-Credentials' => 'true',
31
+ 'Access-Control-Max-Age' => CORSMiddleware::ACCESS_CONTROL_MAX_AGE.to_s
32
+ } end
33
+
34
+ it 'responds to a CORS OPTIONS request with all of the correct headers' do
35
+ header 'Origin', origin
36
+ header 'Access-Control-Request-Method', 'PUT'
37
+ options '/'
38
+
39
+ last_response.status.should eq(200)
40
+ last_response.headers.should include(expected_response_headers)
41
+ last_response.headers.should_not have_key('Access-Control-Allow-Headers')
42
+ end
43
+
44
+ it 'includes Access-Control-Allow-Headers when they the request asks about them' do
45
+ header 'Origin', origin
46
+ header 'Access-Control-Request-Method', 'PUT'
47
+ header 'Access-Control-Request-Headers', headers
48
+ options '/'
49
+
50
+ last_response.status.should eq(200)
51
+ last_response.headers.should include(expected_response_headers.merge(
52
+ 'Access-Control-Allow-Headers' => headers
53
+ ))
54
+ end
55
+
56
+ it 'appends the Access-Control-Allow-Origin header to every response to a request with an Origin header' do
57
+ header 'Origin', origin
58
+ get '/'
59
+ last_response.headers.should include('Access-Control-Allow-Origin' => origin)
60
+ end
61
+
62
+ it 'does not append a Access-Control-Allow-Origin header to a request without an Origin header' do
63
+ get '/'
64
+ last_response.headers.keys.should_not include('Access-Control-Allow-Origin')
65
+ end
66
+ end
67
+ end
68
+ end
69
+
@@ -370,7 +370,7 @@ module Rack
370
370
  'Access-Control-Allow-Origin' => origin,
371
371
  'Access-Control-Allow-Methods' => 'PUT',
372
372
  'Access-Control-Allow-Credentials' => 'true',
373
- 'Access-Control-Max-Age' => ACCESS_CONTROL_MAX_AGE.to_s
373
+ 'Access-Control-Max-Age' => CORSMiddleware::ACCESS_CONTROL_MAX_AGE.to_s
374
374
  } end
375
375
 
376
376
  it 'responds to a CORS OPTIONS request with all of the correct headers' do
@@ -382,29 +382,6 @@ module Rack
382
382
  last_response.headers.should include(expected_response_headers)
383
383
  last_response.headers.should_not have_key('Access-Control-Allow-Headers')
384
384
  end
385
-
386
- it 'includes Access-Control-Allow-Headers when they the request asks about them' do
387
- header 'Origin', origin
388
- header 'Access-Control-Request-Method', 'PUT'
389
- header 'Access-Control-Request-Headers', headers
390
- options '/'
391
-
392
- last_response.status.should eq(200)
393
- last_response.headers.should include(expected_response_headers.merge(
394
- 'Access-Control-Allow-Headers' => headers
395
- ))
396
- end
397
-
398
- it 'appends the Access-Control-Allow-Origin header to every response to a request with an Origin header' do
399
- header 'Origin', origin
400
- get '/'
401
- last_response.headers.should include('Access-Control-Allow-Origin' => origin)
402
- end
403
-
404
- it 'does not append a Access-Control-Allow-Origin header to a request without an Origin header' do
405
- get '/'
406
- last_response.headers.keys.should_not include('Access-Control-Allow-Origin')
407
- end
408
385
  end
409
386
 
410
387
  context 'when cross origin resource sharing is not supported' do
@@ -418,12 +395,6 @@ module Rack
418
395
  last_response.status.should eq(401)
419
396
  last_response.headers.keys.select { |k| k.include?('Access-Control') }.should eq([])
420
397
  end
421
-
422
- it 'does not append the Access-Control-Allow-Origin header to every response' do
423
- header 'Origin', 'http://foo.example.com'
424
- get '/'
425
- last_response.headers.keys.should_not include('Access-Control-Allow-Origin')
426
- end
427
398
  end
428
399
  end
429
400
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-authenticate
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-12-19 00:00:00.000000000Z
12
+ date: 2012-02-14 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: ruby-hmac
16
- requirement: &2156269640 !ruby/object:Gem::Requirement
16
+ requirement: &2152601180 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 0.4.0
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *2156269640
24
+ version_requirements: *2152601180
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rspec
27
- requirement: &2156267980 !ruby/object:Gem::Requirement
27
+ requirement: &2152600560 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 2.8.0.rc1
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *2156267980
35
+ version_requirements: *2152600560
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rack-test
38
- requirement: &2156267060 !ruby/object:Gem::Requirement
38
+ requirement: &2152599640 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: 0.6.1
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *2156267060
46
+ version_requirements: *2152599640
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: timecop
49
- requirement: &2156266080 !ruby/object:Gem::Requirement
49
+ requirement: &2152588140 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ~>
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: 0.3.5
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *2156266080
57
+ version_requirements: *2152588140
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: rake
60
- requirement: &2156265000 !ruby/object:Gem::Requirement
60
+ requirement: &2152586640 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ~>
@@ -65,7 +65,7 @@ dependencies:
65
65
  version: 0.9.2.2
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *2156265000
68
+ version_requirements: *2152586640
69
69
  description: A rack middleware that authenticates requests either using basic auth
70
70
  or via signed HMAC.
71
71
  email:
@@ -76,6 +76,7 @@ extra_rdoc_files: []
76
76
  files:
77
77
  - .gitignore
78
78
  - .rspec
79
+ - .rvmrc
79
80
  - .travis.yml
80
81
  - Appraisals
81
82
  - Gemfile
@@ -90,10 +91,12 @@ files:
90
91
  - lib/rack-authenticate.rb
91
92
  - lib/rack/authenticate.rb
92
93
  - lib/rack/authenticate/client.rb
94
+ - lib/rack/authenticate/cors_middleware.rb
93
95
  - lib/rack/authenticate/middleware.rb
94
96
  - lib/rack/authenticate/version.rb
95
97
  - rack-authenticate.gemspec
96
98
  - spec/rack/authenticate/client_spec.rb
99
+ - spec/rack/authenticate/cors_middleware_spec.rb
97
100
  - spec/rack/authenticate/middleware_spec.rb
98
101
  - spec/rack/authenticate_spec.rb
99
102
  homepage: ''
@@ -110,7 +113,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
110
113
  version: '0'
111
114
  segments:
112
115
  - 0
113
- hash: 496392540953768214
116
+ hash: -359603919774236080
114
117
  required_rubygems_version: !ruby/object:Gem::Requirement
115
118
  none: false
116
119
  requirements:
@@ -119,7 +122,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
119
122
  version: '0'
120
123
  segments:
121
124
  - 0
122
- hash: 496392540953768214
125
+ hash: -359603919774236080
123
126
  requirements: []
124
127
  rubyforge_project: rack-authenticate
125
128
  rubygems_version: 1.8.6
@@ -129,5 +132,6 @@ summary: A rack middleware that authenticates requests either using basic auth o
129
132
  via signed HMAC.
130
133
  test_files:
131
134
  - spec/rack/authenticate/client_spec.rb
135
+ - spec/rack/authenticate/cors_middleware_spec.rb
132
136
  - spec/rack/authenticate/middleware_spec.rb
133
137
  - spec/rack/authenticate_spec.rb