rack-wwwhisper 1.1.2 → 1.1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/rack/wwwhisper.rb +40 -29
- data/test/test_wwwhisper.rb +13 -2
- metadata +4 -4
data/lib/rack/wwwhisper.rb
CHANGED
@@ -7,37 +7,10 @@
|
|
7
7
|
require 'addressable/uri'
|
8
8
|
require 'net/http/persistent'
|
9
9
|
require 'rack/utils'
|
10
|
+
require 'rack/wwwhisper_version'
|
10
11
|
|
11
12
|
module Rack
|
12
13
|
|
13
|
-
# An internal middleware used by Rack::WWWhisper to change directives
|
14
|
-
# that enable public caching into directives that enable private
|
15
|
-
# caching.
|
16
|
-
#
|
17
|
-
# To be on a safe side, all wwwhisper protected content is treated as
|
18
|
-
# sensitive and not publicly cacheable.
|
19
|
-
class NoPublicCache
|
20
|
-
def initialize(app)
|
21
|
-
@app = app
|
22
|
-
end
|
23
|
-
|
24
|
-
# If a response enables caching, makes sure it is private.
|
25
|
-
def call(env)
|
26
|
-
status, headers, body = @app.call(env)
|
27
|
-
if cache_control = headers['Cache-Control']
|
28
|
-
cache_control = cache_control.gsub(/public/, 'private')
|
29
|
-
if (not cache_control.include? 'private' and
|
30
|
-
cache_control.index(/max-age\s*=\s*0*[1-9]/))
|
31
|
-
# max-age > 0 without 'public' or 'private' directive is
|
32
|
-
# treated as 'public', so 'private' needs to be prepended.
|
33
|
-
cache_control.insert(0, 'private, ')
|
34
|
-
end
|
35
|
-
headers['Cache-Control'] = cache_control
|
36
|
-
end
|
37
|
-
[status, headers, body]
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
14
|
# Communicates with the wwwhisper service to authorize each incomming
|
42
15
|
# request. Acts as a proxy for requests to locations handled by
|
43
16
|
# wwwhisper (/wwwhisper/auth and /wwwhisper/admin)
|
@@ -56,9 +29,17 @@ class WWWhisper
|
|
56
29
|
@@WWWHISPER_PREFIX = '/wwwhisper/'
|
57
30
|
# Name prefix of cookies that are passed to wwwhisper.
|
58
31
|
@@AUTH_COOKIES_PREFIX = 'wwwhisper'
|
32
|
+
|
59
33
|
# Headers that are passed to wwwhisper ('Cookie' is handled
|
60
34
|
# in a special way: only wwwhisper related cookies are passed).
|
61
|
-
#
|
35
|
+
#
|
36
|
+
# In addition, the current site URL is passed in the Site-Url header.
|
37
|
+
# This is needed to perform URL verification of Persona assertions and to
|
38
|
+
# construct Location headers in redirects.
|
39
|
+
#
|
40
|
+
# wwwhisper library version is passed in the User-Agent header. This
|
41
|
+
# is to warn the site owner if a vulnerability in the library is
|
42
|
+
# discovered and the library needs to be updated.
|
62
43
|
@@FORWARDED_HEADERS = ['Accept', 'Accept-Language', 'Cookie', 'Origin',
|
63
44
|
'X-CSRFToken', 'X-Requested-With']
|
64
45
|
@@DEFAULT_IFRAME = %Q[<script type="text/javascript" src="%s"> </script>
|
@@ -174,6 +155,7 @@ class WWWhisper
|
|
174
155
|
copy_headers(rack_req.env, sub_req)
|
175
156
|
scheme = rack_req.env['HTTP_X_FORWARDED_PROTO'] ||= rack_req.scheme
|
176
157
|
sub_req['Site-Url'] = "#{scheme}://#{rack_req.env['HTTP_HOST']}"
|
158
|
+
sub_req['User-Agent'] = "Ruby-#{Rack::WWWHISPER_VERSION}"
|
177
159
|
if @wwwhisper_uri.user and @wwwhisper_uri.password
|
178
160
|
sub_req.basic_auth(@wwwhisper_uri.user, @wwwhisper_uri.password)
|
179
161
|
end
|
@@ -280,6 +262,35 @@ class WWWhisper
|
|
280
262
|
end
|
281
263
|
end
|
282
264
|
|
265
|
+
|
266
|
+
# An internal middleware used by Rack::WWWhisper to change directives
|
267
|
+
# that enable public caching into directives that enable private
|
268
|
+
# caching.
|
269
|
+
#
|
270
|
+
# To be on a safe side, all wwwhisper protected content is treated as
|
271
|
+
# sensitive and not publicly cacheable.
|
272
|
+
class NoPublicCache
|
273
|
+
def initialize(app)
|
274
|
+
@app = app
|
275
|
+
end
|
276
|
+
|
277
|
+
# If a response enables caching, makes sure it is private.
|
278
|
+
def call(env)
|
279
|
+
status, headers, body = @app.call(env)
|
280
|
+
if cache_control = headers['Cache-Control']
|
281
|
+
cache_control = cache_control.gsub(/public/, 'private')
|
282
|
+
if (not cache_control.include? 'private' and
|
283
|
+
cache_control.index(/max-age\s*=\s*0*[1-9]/))
|
284
|
+
# max-age > 0 without 'public' or 'private' directive is
|
285
|
+
# treated as 'public', so 'private' needs to be prepended.
|
286
|
+
cache_control.insert(0, 'private, ')
|
287
|
+
end
|
288
|
+
headers['Cache-Control'] = cache_control
|
289
|
+
end
|
290
|
+
[status, headers, body]
|
291
|
+
end
|
292
|
+
end # class NoPublicCache
|
293
|
+
|
283
294
|
end # class WWWhisper
|
284
295
|
|
285
296
|
end # module
|
data/test/test_wwwhisper.rb
CHANGED
@@ -8,6 +8,7 @@ require 'rack/test'
|
|
8
8
|
require 'test/unit'
|
9
9
|
require 'webmock/test_unit'
|
10
10
|
require 'rack/wwwhisper'
|
11
|
+
require 'rack/wwwhisper_version'
|
11
12
|
|
12
13
|
ENV['RACK_ENV'] = 'test'
|
13
14
|
|
@@ -196,6 +197,16 @@ class TestWWWhisper < Test::Unit::TestCase
|
|
196
197
|
assert_requested :get, full_url(@wwwhisper.auth_query(path))
|
197
198
|
end
|
198
199
|
|
200
|
+
def test_library_version_passed_to_wwwhisper
|
201
|
+
path = '/foo/bar'
|
202
|
+
stub_request(:get, full_url(@wwwhisper.auth_query(path))).
|
203
|
+
with(:headers => {'User-Agent' => "Ruby-#{Rack::WWWHISPER_VERSION}"}).
|
204
|
+
to_return(granted())
|
205
|
+
|
206
|
+
get path
|
207
|
+
assert last_response.ok?
|
208
|
+
end
|
209
|
+
|
199
210
|
def assert_path_normalized(normalized, requested, script_name=nil)
|
200
211
|
stub_request(:get, full_url(@wwwhisper.auth_query(normalized))).
|
201
212
|
to_return(granted())
|
@@ -266,11 +277,11 @@ class TestWWWhisper < Test::Unit::TestCase
|
|
266
277
|
# X-Forwarded headers must be sent to wwwhisper backend.
|
267
278
|
stub_request(:get, full_url(@wwwhisper.auth_query(path))).
|
268
279
|
with(:headers => {
|
269
|
-
'Site-
|
280
|
+
'Site-Url' => "#{SITE_PROTO}://#{SITE_HOST}"
|
270
281
|
}).
|
271
282
|
to_return(granted())
|
272
283
|
stub_request(:get, full_url(path)).
|
273
|
-
with(:headers => {'Site-
|
284
|
+
with(:headers => {'Site-Url' => "#{SITE_PROTO}://#{SITE_HOST}"}).
|
274
285
|
to_return(:status => 200, :body => 'Admin page', :headers => {})
|
275
286
|
|
276
287
|
get path
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-wwwhisper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-03-18 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rack
|
@@ -131,7 +131,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
131
131
|
version: '0'
|
132
132
|
segments:
|
133
133
|
- 0
|
134
|
-
hash:
|
134
|
+
hash: -2256402036579086807
|
135
135
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
136
136
|
none: false
|
137
137
|
requirements:
|
@@ -140,7 +140,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
140
140
|
version: '0'
|
141
141
|
segments:
|
142
142
|
- 0
|
143
|
-
hash:
|
143
|
+
hash: -2256402036579086807
|
144
144
|
requirements: []
|
145
145
|
rubyforge_project:
|
146
146
|
rubygems_version: 1.8.24
|