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.
@@ -1,18 +1,47 @@
1
- # Rack Staging
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
- In Development
44
+ Production Ready
16
45
 
17
46
  ## Bugs, Feature Requests, etc.
18
47
 
data/Rakefile CHANGED
@@ -2,6 +2,8 @@ require 'rake'
2
2
  require 'rake/testtask'
3
3
  require 'rubygems'
4
4
  require 'rubygems/package_task'
5
+ require 'bundler'
6
+ Bundler::GemHelper.install_tasks
5
7
 
6
8
  desc 'Default: run unit tests.'
7
9
  task :default => :test
@@ -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
- private
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
- def robots_txt?(env)
24
- env["PATH_INFO"] == "/robots.txt"
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
- def robots_txt
28
- body = <<-EOF
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
- [ 200, {'Content-Type' => 'text/plain'}, [body] ]
33
- end
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
@@ -24,7 +24,7 @@ class RackStagingTest < Test::Unit::TestCase
24
24
  end
25
25
 
26
26
  def test_robots_txt_if_staging
27
- header "HOST", "staging.example.org"
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 "HOST", "staging.example.org"
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 "HOST", "staging.example.org"
55
+ header "Host", "staging.example.org"
56
56
  get "/"
57
57
  assert_equal 200, last_response.status
58
58
 
59
- header "HOST", "foobar.org"
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 "HOST", "staging.example.org"
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
- description: Automatically protects your staging app from web crawlers and casual visitors.
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: "0"
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: "0"
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
53
46
  requirements: []
54
-
55
47
  rubyforge_project:
56
- rubygems_version: 1.6.0
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