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