rack-cerberus 0.1.6 → 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.md ADDED
@@ -0,0 +1,81 @@
1
+ >"For over a thousand generations the Jedi Knights were the guardians of peace and justice in the Old Republic. Before the dark times, before the Empire." -- Obi-Wan Kenoby
2
+
3
+ Cerberus
4
+ ========
5
+
6
+ Cerberus is a Rack middleware for form-based authentication. Its purpose is only
7
+ to offer a nicer (or more actual) replacement for Basic HTTP authentication.
8
+
9
+ Install with:
10
+
11
+ # sudo gem install rack-cerberus
12
+
13
+ You can use it almost the same way you use `Rack::Auth::Basic`:
14
+
15
+ require 'cerberus'
16
+ use Rack::Session::Cookie, :secret => 'change_me'
17
+ use Cerberus do |login, pass|
18
+ pass=='secret'
19
+ end
20
+
21
+ Like in that example, make sure you have a session, because Cerberus use it for
22
+ persistent login.
23
+
24
+ There is an optional hash you can add for customisation it. Options are:
25
+
26
+ - `:company_name`
27
+ - `:fg_color` (foreground color)
28
+ - `:bg_color` (background color)
29
+ - `:text_color`
30
+ - `:icon_url` (for a company logo or any icon)
31
+ - `:css_location`
32
+
33
+ Which is used that way:
34
+
35
+ use Cerberus, {:company_name => 'Nintendo'} do |login, pass|
36
+ pass=='secret'
37
+ end
38
+
39
+ The purpose of Cerberus is to be basic, which is why there are enough options to have
40
+ a page fairly customized with colors and logo (`:icon_url`). The logo can even replace
41
+ the company name if you leave `:company_name` blank. But should you be fussy, this is possible
42
+ to have more control using an external CSS file with the option `:css_location`.
43
+
44
+ Just like `Rack::Auth::Basic`, Cerberus yields login and pass, and delegate authentication
45
+ to the block you send it which should return a boolean.
46
+
47
+ If you want to see a concrete example, go into the Cerberus directory and run:
48
+
49
+ # rackup example.ru
50
+
51
+ It's gonna start the example at http://localhost:9292
52
+
53
+ Logout
54
+ ------
55
+
56
+ Any request to `/logout` on the path where the middleware is mounted will log you out.
57
+ In other words, if you put the middleware at `/admin`, query `/admin/logout` to be
58
+ logged out. Pretty simple.
59
+
60
+ Help
61
+ ----
62
+
63
+ If you want to help me, don't hesitate to fork that project on Github or send patches.
64
+
65
+ Changelog
66
+ ---------
67
+
68
+ 0.0.1 Changed Everything somehow
69
+ 0.1.0 Make it possible to authenticate through GET request (for restful APIs)
70
+ 0.1.1 Documentation improvement
71
+ 0.1.2 Raise message when using without session
72
+ 0.1.3 Don't go to page /logout when signing in after a logout (redirect to / instead)
73
+ 0.1.4 Fix /logout redirect so that it works with mapping
74
+ 0.1.5 Fix CSS and Javascript for IE (Yes I'm too kind)
75
+ 0.1.6 Send an Array instead of a string to Rack so that it works on Ruby 1.9
76
+ 0.2.0 External CSS file + `:text_color` option + keep details after login failure
77
+
78
+ Copyright
79
+ ---------
80
+
81
+ (c) 2010-2011 Mickael Riga - see MIT_LICENCE for details
data/cerberus.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'rack-cerberus'
3
- s.version = "0.1.6"
3
+ s.version = "0.2.0"
4
4
  s.platform = Gem::Platform::RUBY
5
5
  s.summary = "A Rack middleware for form-based authentication"
6
6
  s.description = "A Rack middleware for form-based authentication. Aim is a compromise between fonctionality, beauty and customization."
data/cerberus.rb CHANGED
@@ -1,14 +1,14 @@
1
1
  class Cerberus
2
2
 
3
- class NoSessionError < RuntimeError
4
- end
3
+ class NoSessionError < RuntimeError; end
5
4
 
6
5
  AUTH_PAGE = <<-PAGE
6
+ <!DOCTYPE html>
7
7
  <html><head>
8
8
  <title>%s Authentication</title>
9
9
  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
10
10
  <style type='text/css'>
11
- body { background-color: %s; font-family: sans-serif; text-align: center; }
11
+ body { background-color: %s; font-family: sans-serif; text-align: center; margin: 0px; }
12
12
  h1, p { color: %s; }
13
13
  .err {
14
14
  padding: 5px;
@@ -21,14 +21,18 @@ class Cerberus
21
21
  div {
22
22
  text-align: left;
23
23
  width: 400px;
24
- margin: 30px auto;
24
+ margin: 0px auto;
25
25
  padding: 10px;
26
- border-radius: 5px;
27
- -moz-border-radius: 5px;
28
- -webkit-border-radius: 5px;
26
+ -webkit-border-bottom-left-radius: 10px;
27
+ -moz-border-radius-bottomleft: 10px;
28
+ border-bottom-left-radius: 10px;
29
+ -webkit-border-bottom-right-radius: 10px;
30
+ -moz-border-radius-bottomright: 10px;
31
+ border-bottom-right-radius: 10px;
29
32
  background-color: %s; }
30
33
  input { width: 400px; font-size: 20px; }
31
34
  </style>
35
+ %s
32
36
  </head><body>
33
37
  <div>
34
38
  <h1>%s</h1>
@@ -36,8 +40,8 @@ class Cerberus
36
40
  %s
37
41
  <p>Please Sign In</p>
38
42
  <form action="%s" method="post" accept-charset="utf-8">
39
- <input type="text" name="cerberus_login" value="login" id='login'><br />
40
- <input type="password" name="cerberus_pass" value="pass" id='pass'>
43
+ <input type="text" name="cerberus_login" value="%s" id='login'><br />
44
+ <input type="password" name="cerberus_pass" value="%s" id='pass'>
41
45
  <p><input type="submit" value="SIGN IN &rarr;"></p>
42
46
  </form>
43
47
  <script type="text/javascript" charset="utf-8">
@@ -60,7 +64,13 @@ PAGE
60
64
 
61
65
  def initialize(app, options={}, &block)
62
66
  @app = app
63
- defaults = { :company_name => 'Cerberus', :bg_color => '#333', :fg_color => '#555', :icon_url => nil}
67
+ defaults = {
68
+ :company_name => 'Cerberus',
69
+ :bg_color => '#999',
70
+ :fg_color => '#CCC',
71
+ :text_color => '#FFF',
72
+ :icon_url => nil
73
+ }
64
74
  @options = defaults.merge(options)
65
75
  @block = block
66
76
  end
@@ -87,7 +97,14 @@ PAGE
87
97
  else
88
98
  env['rack.session'].delete('cerberus_user')
89
99
  icon = @options[:icon_url].nil? ? '' : "<img src='#{@options[:icon_url]}' /><br />"
90
- [401, {'Content-Type' => 'text/html'}, [AUTH_PAGE % [@options[:company_name], @options[:bg_color], @options[:bg_color], @options[:fg_color], @options[:company_name], icon, err, env['REQUEST_URI']]]]
100
+ css = @options[:css_location].nil? ? '' : "<link href='#{@options[:css_location]}' rel='stylesheet' type='text/css'>"
101
+ [
102
+ 401, {'Content-Type' => 'text/html'},
103
+ [AUTH_PAGE % [
104
+ @options[:company_name], @options[:bg_color], @options[:text_color], @options[:fg_color], css, @options[:company_name],
105
+ icon, err, env['REQUEST_URI'], req['cerberus_login']||'login', req['cerberus_pass']||'pass'
106
+ ]]
107
+ ]
91
108
  end
92
109
  end
93
110
 
data/example.css ADDED
@@ -0,0 +1 @@
1
+ body { background-color: #CCC; }
data/example.ru CHANGED
@@ -1,5 +1,6 @@
1
1
  require ::File.dirname(__FILE__) + '/cerberus'
2
2
  use Rack::Session::Cookie, :secret => 'change_me'
3
+ F = ::File
3
4
 
4
5
  map '/' do
5
6
  run lambda {|env|
@@ -13,15 +14,22 @@ map '/' do
13
14
  </body>
14
15
  </html>
15
16
  EOB
16
- [200, {'Content-Type' => 'text/html'}, body]
17
+ [200, {'Content-Type' => 'text/html'}, [body]]
17
18
  }
18
19
  end
19
20
 
20
21
  map '/secret' do
21
- use Cerberus, {:company_name => 'Nintendo'} do |login,pass|
22
+ use Cerberus, {:company_name => 'Nintendo', :fg_color => 'red', :css_location => '/css'} do |login,pass|
22
23
  [login,pass]==['mario','bros']
23
24
  end
24
25
  run lambda {|env|
25
- [200, {'Content-Type' => 'text/plain'}, 'Welcome back Mario. Your Credit Card number is: 9292']
26
+ [200, {'Content-Type' => 'text/plain'}, ['Welcome back Mario. Your Credit Card number is: 9292']]
27
+ }
28
+ end
29
+
30
+ map '/css' do
31
+ run lambda {|env|
32
+ path = F.expand_path('./example.css')
33
+ [200, {'Content-Type' => 'text/css', "Last-Modified" => F.mtime(path).httpdate, "Content-Length" => F.size?(path).to_s}, [F.read(path)]]
26
34
  }
27
35
  end
data/spec.rb CHANGED
@@ -11,6 +11,8 @@ describe 'cerberus' do
11
11
  secret_app = lambda {|env| [200, {'Content-Type'=>'text/plain'}, env['rack.session'].inspect] }
12
12
  app = Rack::Session::Cookie.new(Cerberus.new(secret_app, {}) {|login,pass| [login,pass]==['mario','bros']})
13
13
  req = Rack::MockRequest.new(app)
14
+ app_with_css = app = Rack::Session::Cookie.new(Cerberus.new(secret_app, {:css_location=>'/main.css'}) {|login,pass| [login,pass]==['mario','bros']})
15
+ req_with_css = Rack::MockRequest.new(app_with_css)
14
16
  cookie = ''
15
17
 
16
18
  should 'Raise if there is no session' do
@@ -19,12 +21,19 @@ describe 'cerberus' do
19
21
  lambda { no_session_req.get('/') }.should.raise(Cerberus::NoSessionError).message.should=='Cerberus cannot work without Session'
20
22
  end
21
23
 
22
- should 'Stop request if you are not already logged in or currently successfully logging' do
24
+ should 'Stop request if you are not already logged in' do
23
25
  res = req.get('/')
24
26
  res.status.should==401
25
27
  res.body.class==String
26
- res = req.post('/', :params => {'cerberus_login' => 'fake', 'cerberus_pass' => 'fake'})
28
+ res.body.should.match(/name="cerberus_login" value="login"/)
29
+ res.body.should.match(/name="cerberus_pass" value="pass"/)
30
+ end
31
+
32
+ should 'Stop request if you send wrong details and keep query values' do
33
+ res = req.post('/', :params => {'cerberus_login' => 'fake_login', 'cerberus_pass' => 'fake_pass'})
27
34
  res.status.should==401
35
+ res.body.should.match(/name="cerberus_login" value="fake_login"/)
36
+ res.body.should.match(/name="cerberus_pass" value="fake_pass"/)
28
37
  end
29
38
 
30
39
  should 'Give access with the appropriate login and pass' do
@@ -60,4 +69,9 @@ describe 'cerberus' do
60
69
  res['Location'].should=='/backend'
61
70
  end
62
71
 
72
+ should 'Use an external css file only if requested' do
73
+ req.get('/').body.should.not.match(/<link/)
74
+ req_with_css.get('/').body.should.match(/<link/)
75
+ end
76
+
63
77
  end
metadata CHANGED
@@ -2,12 +2,12 @@
2
2
  name: rack-cerberus
3
3
  version: !ruby/object:Gem::Version
4
4
  hash: 23
5
- prerelease: false
5
+ prerelease:
6
6
  segments:
7
7
  - 0
8
- - 1
9
- - 6
10
- version: 0.1.6
8
+ - 2
9
+ - 0
10
+ version: 0.2.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Mickael Riga
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-02-16 00:00:00 +00:00
18
+ date: 2011-07-07 00:00:00 +01:00
19
19
  default_executable:
20
20
  dependencies: []
21
21
 
@@ -30,10 +30,10 @@ extra_rdoc_files: []
30
30
  files:
31
31
  - .gitignore
32
32
  - MIT_LICENCE
33
- - README.rdoc
34
- - Rakefile
33
+ - README.md
35
34
  - cerberus.gemspec
36
35
  - cerberus.rb
36
+ - example.css
37
37
  - example.ru
38
38
  - spec.rb
39
39
  has_rdoc: true
@@ -66,7 +66,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
66
66
  requirements: []
67
67
 
68
68
  rubyforge_project:
69
- rubygems_version: 1.3.7
69
+ rubygems_version: 1.4.2
70
70
  signing_key:
71
71
  specification_version: 3
72
72
  summary: A Rack middleware for form-based authentication
data/README.rdoc DELETED
@@ -1,68 +0,0 @@
1
- "For over a thousand generations the Jedi Knights were the guardians of peace and justice in the Old Republic. Before the dark times, before the Empire." -- Obi-Wan Kenoby
2
-
3
- = Cerberus
4
-
5
- Cerberus is a Rack middleware for form-based authentication. Its purpose is only
6
- to offer a nicer (or more actual) replacement for Basic HTTP authentication.
7
-
8
- Install with:
9
-
10
- # sudo gem install rack-cerberus
11
-
12
- You can use it almost the same way you use <tt>Rack::Auth::Basic</tt>:
13
-
14
- require 'cerberus'
15
- use Rack::Session::Cookie, :secret => 'change_me'
16
- use Cerberus do |login, pass|
17
- pass=='secret'
18
- end
19
-
20
- Like in that example, make sure you have a session, because Cerberus use it for
21
- persistent login.
22
-
23
- There is an optional hash you can add for personalizing it. Options are:
24
-
25
- * <tt>:company_name</tt>
26
- * <tt>:fg_color</tt> (foreground color)
27
- * <tt>:bg_color</tt> (background color)
28
- * <tt>:icon_url</tt> (for a company logo or any icon)
29
-
30
- Which is used that way:
31
-
32
- use Cerberus, {:company_name => 'Nintendo'} do |login, pass|
33
- pass=='secret'
34
- end
35
-
36
- Just like <tt>Rack::Auth::Basic</tt>, Cerberus yields login and pass, and delegate authentication
37
- to the block you send it which should return a boolean.
38
-
39
- If you want to see a concrete example, go into the Cerberus directory and run:
40
-
41
- # rackup example.ru
42
-
43
- It's gonna start the example at http://localhost:9292
44
-
45
- === Logout
46
-
47
- Any request to <tt>/logout</tt> on the path where the middleware is mounted will log you out.
48
- In other words, if you put the middleware at <tt>/admin</tt>, query <tt>/admin/logout</tt> to be
49
- logged out. Pretty simple.
50
-
51
- === Help
52
-
53
- If you want to help me, don't hesitate to fork that project on Github or send patches.
54
-
55
- === Changelog
56
-
57
- 0.0.1 Changed Everything somehow
58
- 0.1.0 Make it possible to authenticate through GET request (for restful APIs)
59
- 0.1.1 Documentation improvement
60
- 0.1.2 Raise message when using without session
61
- 0.1.3 Don't go to page /logout when signing in after a logout (redirect to / instead)
62
- 0.1.4 Fix /logout redirect so that it works with mapping
63
- 0.1.5 Fix CSS and Javascript for IE (Yes I'm too kind)
64
- 0.1.6 Send an Array instead of a string to Rack so that it works on Ruby 1.9
65
-
66
- === Copyright
67
-
68
- (c) 2010-2011 Mickael Riga - see MIT_LICENCE for details
data/Rakefile DELETED
@@ -1 +0,0 @@
1
-