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
|
-
|
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
|
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
|
@@ -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.
|
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:
|
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: &
|
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: *
|
24
|
+
version_requirements: *2152601180
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rspec
|
27
|
-
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: *
|
35
|
+
version_requirements: *2152600560
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: rack-test
|
38
|
-
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: *
|
46
|
+
version_requirements: *2152599640
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: timecop
|
49
|
-
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: *
|
57
|
+
version_requirements: *2152588140
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: rake
|
60
|
-
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: *
|
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:
|
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:
|
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
|