rack-wwwhisper 1.1.2 → 1.1.3
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/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
|