rack_staging 0.1.1 → 0.2.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/README.mdown +31 -2
- data/Rakefile +2 -0
- data/lib/rack_staging.rb +24 -37
- data/test/staging_test.rb +5 -5
- metadata +22 -30
data/README.mdown
CHANGED
@@ -1,18 +1,47 @@
|
|
1
|
-
# Rack
|
1
|
+
# Rack::Staging
|
2
|
+
|
3
|
+
Don't let users accidentally stumble upon your staging servers, make sure
|
4
|
+
they're password protected.
|
2
5
|
|
3
6
|
## Usage
|
4
7
|
|
8
|
+
Include the `Rack::Staging` middleware into your `config.ru` like so:
|
9
|
+
|
10
|
+
use Rack::Staging
|
11
|
+
run MyApp.new
|
12
|
+
|
13
|
+
By default `Rack::Staging` will assume it's in a staging environment if the
|
14
|
+
hostname for the request contains the string "staging", or if an environment
|
15
|
+
variable of "STAGING" is set.
|
16
|
+
|
17
|
+
Username and password for authentication should be set to "STAGING_USER" and
|
18
|
+
"STAGING_PASS" environment variables respectively.
|
19
|
+
|
20
|
+
Alternatively `Rack::Staging` accepts a `Proc` as a parameter which will be
|
21
|
+
evaluated to determine whether an app is in your staging environment or not.
|
22
|
+
Use this method to override the default behaviour:
|
23
|
+
|
24
|
+
use Rack::Staging, Proc.new{|env| env["HTTP_HOST"] == "foobar.example.org" }
|
25
|
+
run MyApp.new
|
26
|
+
|
5
27
|
## Why would I want to use this?
|
6
28
|
|
29
|
+
Because it's easy to forget to make your staging server just *slightly*
|
30
|
+
different from your production box by restricting access to it. Hopefully
|
31
|
+
remembering to include this in your `Gemfile` is easier (I'll soon make it
|
32
|
+
insert itself automatically into the middleware stack for Rails >= 3.x.x apps).
|
33
|
+
|
7
34
|
## Compatibility
|
8
35
|
|
36
|
+
Only tested on Ruby 1.9.2
|
37
|
+
|
9
38
|
## Contributions
|
10
39
|
|
11
40
|
* Glenn Gillen
|
12
41
|
|
13
42
|
## Status
|
14
43
|
|
15
|
-
|
44
|
+
Production Ready
|
16
45
|
|
17
46
|
## Bugs, Feature Requests, etc.
|
18
47
|
|
data/Rakefile
CHANGED
data/lib/rack_staging.rb
CHANGED
@@ -1,51 +1,38 @@
|
|
1
1
|
require 'rack'
|
2
2
|
module Rack
|
3
|
-
class Staging
|
4
|
-
|
5
|
-
def initialize(app, staging_test = nil)
|
3
|
+
class Staging < Rack::Auth::Basic
|
4
|
+
def initialize(app, detect_proc = nil)
|
6
5
|
@app = app
|
7
|
-
@staging_test = staging_test
|
8
|
-
end
|
9
|
-
|
10
|
-
def call(env)
|
11
|
-
return @app.call(env) unless staging?(env)
|
12
|
-
return robots_txt if robots_txt?(env)
|
13
|
-
return unauthorized unless authorized?(env)
|
14
|
-
@app.call(env)
|
15
|
-
end
|
16
6
|
|
17
|
-
|
18
|
-
def staging?(env)
|
19
|
-
return @staging_test.call(env) if @staging_test
|
7
|
+
@staging_detect = detect_proc || lambda do |env|
|
20
8
|
env["HTTP_HOST"] =~ /staging/ || ENV["STAGING"]
|
21
9
|
end
|
22
10
|
|
23
|
-
|
24
|
-
|
11
|
+
super app, 'staging' do |username, password|
|
12
|
+
[username, password] == [ENV["STAGING_USER"], ENV["STAGING_PASS"]]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def call(env)
|
17
|
+
@env = env
|
18
|
+
if @staging_detect.call(@env)
|
19
|
+
return robots_txt if robots_txt?(env)
|
20
|
+
super
|
21
|
+
else
|
22
|
+
@app.call(env)
|
25
23
|
end
|
24
|
+
end
|
26
25
|
|
27
|
-
|
28
|
-
|
26
|
+
def robots_txt?(env)
|
27
|
+
env["PATH_INFO"] == "/robots.txt"
|
28
|
+
end
|
29
|
+
|
30
|
+
def robots_txt
|
31
|
+
body = <<-EOF
|
29
32
|
User-agent: *
|
30
33
|
Disallow: /
|
31
34
|
EOF
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
def authorized?(env)
|
36
|
-
@auth ||= Rack::Auth::Basic::Request.new(env)
|
37
|
-
@auth.provided? &&
|
38
|
-
@auth.basic? &&
|
39
|
-
@auth.credentials &&
|
40
|
-
@auth.credentials == [ENV["STAGING_USER"], ENV["STAGING_PASS"]]
|
41
|
-
end
|
42
|
-
|
43
|
-
def unauthorized
|
44
|
-
[ 401,
|
45
|
-
{'Content-Type' => 'text/plain',
|
46
|
-
"WWW-Authenticate" => 'Basic realm="staging"' },
|
47
|
-
["Unauthorized"] ]
|
48
|
-
end
|
49
|
-
|
35
|
+
[ 200, {'Content-Type' => 'text/plain'}, [body] ]
|
36
|
+
end
|
50
37
|
end
|
51
38
|
end
|
data/test/staging_test.rb
CHANGED
@@ -24,7 +24,7 @@ class RackStagingTest < Test::Unit::TestCase
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def test_robots_txt_if_staging
|
27
|
-
header "
|
27
|
+
header "Host", "staging.example.org"
|
28
28
|
get "/robots.txt"
|
29
29
|
expected = <<-EOF
|
30
30
|
User-agent: *
|
@@ -34,7 +34,7 @@ EOF
|
|
34
34
|
end
|
35
35
|
|
36
36
|
def test_requires_authentication_if_staging
|
37
|
-
header "
|
37
|
+
header "Host", "staging.example.org"
|
38
38
|
get "/"
|
39
39
|
assert_equal 401, last_response.status
|
40
40
|
end
|
@@ -52,11 +52,11 @@ EOF
|
|
52
52
|
use Rack::Staging, Proc.new{|env| env["HTTP_HOST"] =~ /foobar/ }
|
53
53
|
run DummyApp.new
|
54
54
|
end
|
55
|
-
header "
|
55
|
+
header "Host", "staging.example.org"
|
56
56
|
get "/"
|
57
57
|
assert_equal 200, last_response.status
|
58
58
|
|
59
|
-
header "
|
59
|
+
header "Host", "foobar.org"
|
60
60
|
get "/"
|
61
61
|
assert_equal 401, last_response.status
|
62
62
|
end
|
@@ -65,7 +65,7 @@ EOF
|
|
65
65
|
ENV["STAGING_USER"] = "top"
|
66
66
|
ENV["STAGING_PASS"] = "seecrets"
|
67
67
|
|
68
|
-
header "
|
68
|
+
header "Host", "staging.example.org"
|
69
69
|
get "/"
|
70
70
|
assert_equal 401, last_response.status
|
71
71
|
authorize "top", "seecrets"
|
metadata
CHANGED
@@ -1,62 +1,54 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack_staging
|
3
|
-
version: !ruby/object:Gem::Version
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
4
5
|
prerelease:
|
5
|
-
version: 0.1.1
|
6
6
|
platform: ruby
|
7
|
-
authors:
|
7
|
+
authors:
|
8
8
|
- Glenn Gillen
|
9
|
+
- Chris Continanza
|
9
10
|
autorequire:
|
10
11
|
bindir: bin
|
11
12
|
cert_chain: []
|
12
|
-
|
13
|
-
date: 2011-08-15 00:00:00 +01:00
|
14
|
-
default_executable:
|
13
|
+
date: 2011-10-08 00:00:00.000000000Z
|
15
14
|
dependencies: []
|
16
|
-
|
17
|
-
|
15
|
+
description: Automatically protects your staging app from web crawlers and casual
|
16
|
+
visitors.
|
18
17
|
email: me@glenngillen.com
|
19
18
|
executables: []
|
20
|
-
|
21
19
|
extensions: []
|
22
|
-
|
23
20
|
extra_rdoc_files: []
|
24
|
-
|
25
|
-
files:
|
21
|
+
files:
|
26
22
|
- README.mdown
|
27
23
|
- Rakefile
|
28
24
|
- lib/rack_staging.rb
|
29
25
|
- test/staging_test.rb
|
30
26
|
- test/test_helper.rb
|
31
|
-
has_rdoc: true
|
32
27
|
homepage: http://github.com/glenngillen/rack_staging
|
33
28
|
licenses: []
|
34
|
-
|
35
29
|
post_install_message:
|
36
30
|
rdoc_options: []
|
37
|
-
|
38
|
-
require_paths:
|
31
|
+
require_paths:
|
39
32
|
- .
|
40
33
|
- lib
|
41
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
34
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
42
35
|
none: false
|
43
|
-
requirements:
|
44
|
-
- -
|
45
|
-
- !ruby/object:Gem::Version
|
46
|
-
version:
|
47
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ! '>='
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
48
41
|
none: false
|
49
|
-
requirements:
|
50
|
-
- -
|
51
|
-
- !ruby/object:Gem::Version
|
52
|
-
version:
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
53
46
|
requirements: []
|
54
|
-
|
55
47
|
rubyforge_project:
|
56
|
-
rubygems_version: 1.
|
48
|
+
rubygems_version: 1.8.10
|
57
49
|
signing_key:
|
58
50
|
specification_version: 2
|
59
51
|
summary: Rack::Staging - Protects your staging apps from prying eyes.
|
60
|
-
test_files:
|
52
|
+
test_files:
|
61
53
|
- test/staging_test.rb
|
62
54
|
- test/test_helper.rb
|