rack-cerberus 0.1.6 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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
-