shield 0.0.0 → 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,36 @@
1
1
  # Shield
2
2
 
3
- See the [one file tutorial][tut] for info on getting started.
3
+ Shield
4
4
 
5
- [tut]: http://cyx.github.com/shield
5
+ _n. A solid piece of metal code used to protect your application._
6
+
7
+ ## Why another authentication library?
8
+
9
+ 1. Because most of the other libraries are too huge.
10
+ 2. Extending other libraries is a pain.
11
+ 3. Writing code is fun :-)
12
+
13
+ ## Description of Shield
14
+
15
+ 1. Simple
16
+ 2. Doesn't get in the way
17
+ 3. Extensible (see [shield-contrib][shield-contrib]).
18
+
19
+ ## Getting started
20
+
21
+ The fastest way to get started is by using one of the drop-in solutions
22
+ in [shield-contrib][shield-contrib].
23
+
24
+ ## Tutorials
25
+
26
+ You can learn more by reading through some of our tutorials:
27
+
28
+ 1. [Sinatra & OHM][sin-ohm]
29
+ 2. [Sinatra & Sequel][sin-sequel]
30
+
31
+
32
+ [sin]: http://sinatrarb.com
33
+ [ohm]: http://ohm.keyvalue.org
34
+ [shield-contrib]: http://github.com/cyx/shield-contrib
35
+ [sin-ohm]: http://cyx.github.com/shield/sinatra-ohm.html
36
+ [sin-sequel]: http://cyx.github.com/shield/sinatra-sequel.html
@@ -1,18 +1,7 @@
1
1
  module Shield
2
- VERSION = "0.0.0"
2
+ VERSION = "0.0.1"
3
3
 
4
- autoload :BasicUser, "shield/template/basic_user"
5
- autoload :User, "shield/template/user"
6
- autoload :FlexiUser, "shield/template/flexi_user"
7
4
  autoload :Password, "shield/password"
8
- autoload :Login, "shield/login"
9
5
  autoload :Helpers, "shield/helpers"
10
-
11
- def self.registered(app)
12
- app.helpers Helpers
13
-
14
- app.use Login do |m|
15
- m.settings.set :views, app.views if app.views
16
- end
17
- end
18
- end
6
+ autoload :Model, "shield/model"
7
+ end
@@ -1,22 +1,41 @@
1
1
  module Shield
2
2
  module Helpers
3
- def ensure_authenticated
4
- return if logged_in?
3
+ def ensure_authenticated(model)
4
+ return if authenticated(model)
5
5
 
6
6
  session[:return_to] = request.fullpath
7
- redirect "/login"
7
+ redirect_to_login
8
8
  end
9
9
 
10
- def logged_in?
11
- !! current_user
10
+ def authenticated(model)
11
+ @_authenticated ||= {}
12
+ @_authenticated[model] ||= model[session[model.to_s]]
12
13
  end
13
14
 
14
- def current_user
15
- @_current_user ||= ::User[session[:user]]
15
+ def redirect_to_login
16
+ redirect "/login"
16
17
  end
17
18
 
18
19
  def redirect_to_stored(default = "/")
19
20
  redirect(session.delete(:return_to) || default)
20
21
  end
22
+
23
+ def login(model, username, password)
24
+ instance = model.authenticate(username, password)
25
+
26
+ if instance
27
+ session[model.to_s] = instance.id
28
+ return true
29
+ else
30
+ return false
31
+ end
32
+ end
33
+
34
+ def logout(model)
35
+ session.delete(model.to_s)
36
+ session.delete(:return_to)
37
+
38
+ @_authenticated.delete(model) if defined?(@_authenticated)
39
+ end
21
40
  end
22
41
  end
@@ -0,0 +1,35 @@
1
+ module Shield
2
+ module Model
3
+ def authenticate(username, password)
4
+ user = fetch(username)
5
+
6
+ if user and is_valid_password?(user, password)
7
+ return user
8
+ end
9
+ end
10
+
11
+ def fetch(login)
12
+ raise FetchMissing
13
+ end
14
+
15
+ def is_valid_password?(user, password)
16
+ Shield::Password.check(password, user.crypted_password)
17
+ end
18
+
19
+ class FetchMissing < Class.new(StandardError)
20
+ def message
21
+ %{
22
+ !! You need to implement `fetch`.
23
+ Below is a quick example implementation (in Ohm):
24
+
25
+ def fetch(email)
26
+ find(:email => email).first
27
+ end
28
+
29
+ For more example implementations, check out
30
+ http://github.com/cyx/shield-contrib
31
+ }.gsub(/^ {10}/, "")
32
+ end
33
+ end
34
+ end
35
+ end
@@ -4,12 +4,6 @@ require "shield"
4
4
  require "cutest"
5
5
  require "rack/test"
6
6
  require "sinatra/base"
7
- require "nokogiri"
8
- require "haml"
9
- require "ohm"
10
- require "ohm/contrib"
11
-
12
- prepare { Ohm.flush }
13
7
 
14
8
  class Cutest::Scope
15
9
  include Rack::Test::Methods
@@ -0,0 +1,45 @@
1
+ require File.expand_path("helper", File.dirname(__FILE__))
2
+
3
+ class User < Struct.new(:crypted_password)
4
+ extend Shield::Model
5
+ end
6
+
7
+ test "fetch" do
8
+ ex = nil
9
+
10
+ begin
11
+ User.fetch("quentin")
12
+ rescue Exception => e
13
+ ex = e
14
+ end
15
+
16
+ assert ex.kind_of?(Shield::Model::FetchMissing)
17
+ assert Shield::Model::FetchMissing.new.message == ex.message
18
+ end
19
+
20
+ test "is_valid_password?" do
21
+ user = User.new(Shield::Password.encrypt("password"))
22
+
23
+ assert User.is_valid_password?(user, "password")
24
+ assert ! User.is_valid_password?(user, "password1")
25
+ end
26
+
27
+ class User
28
+ class << self
29
+ attr_accessor :fetched
30
+ end
31
+
32
+ def self.fetch(username)
33
+ return fetched if username == "quentin"
34
+ end
35
+ end
36
+
37
+ test "authenticate" do
38
+ user = User.new(Shield::Password.encrypt("pass"))
39
+
40
+ User.fetched = user
41
+
42
+ assert user == User.authenticate("quentin", "pass")
43
+ assert nil == User.authenticate("unknown", "pass")
44
+ assert nil == User.authenticate("quentin", "wrongpass")
45
+ end
@@ -1 +1,114 @@
1
- require File.expand_path("helper", File.dirname(__FILE__))
1
+ require File.expand_path("helper", File.dirname(__FILE__))
2
+
3
+ class User < Struct.new(:id)
4
+ extend Shield::Model
5
+
6
+ def self.[](id)
7
+ User.new(1) unless id.to_s.empty?
8
+ end
9
+
10
+ def self.authenticate(username, password)
11
+ User.new(1001) if username == "quentin" && password == "password"
12
+ end
13
+ end
14
+
15
+ class Context
16
+ def initialize(path)
17
+ @path = path
18
+ end
19
+
20
+ def session
21
+ @session ||= {}
22
+ end
23
+
24
+ class Request < Struct.new(:fullpath)
25
+ end
26
+
27
+ def request
28
+ Request.new(@path)
29
+ end
30
+
31
+ def redirect(redirect = nil)
32
+ @redirect = redirect if redirect
33
+ @redirect
34
+ end
35
+
36
+ include Shield::Helpers
37
+ end
38
+
39
+ setup do
40
+ Context.new("/events/1")
41
+ end
42
+
43
+ test "ensure_authenticated when logged out" do |context|
44
+ context.ensure_authenticated(User)
45
+ assert "/events/1" == context.session[:return_to]
46
+ assert "/login" == context.redirect
47
+ end
48
+
49
+ test "ensure_authenticated when logged in" do |context|
50
+ context.session["User"] = 1
51
+ assert nil == context.ensure_authenticated(User)
52
+ assert nil == context.redirect
53
+ assert nil == context.session[:return_to]
54
+ end
55
+
56
+ class Admin < Struct.new(:id)
57
+ def self.[](id)
58
+ new(id) unless id.to_s.empty?
59
+ end
60
+ end
61
+
62
+ test "authenticated" do |context|
63
+ context.session["User"] = 1
64
+
65
+ assert User.new(1) == context.authenticated(User)
66
+ assert nil == context.authenticated(Admin)
67
+ end
68
+
69
+ test "caches authenticated in @_authenticated" do |context|
70
+ context.session["User"] = 1
71
+ context.authenticated(User)
72
+
73
+ assert User.new(1) == context.instance_variable_get(:@_authenticated)[User]
74
+ end
75
+
76
+ test "redirect to stored when :return_to is set" do |context|
77
+ context.session[:return_to] = "/private"
78
+ context.redirect_to_stored
79
+
80
+ assert "/private" == context.redirect
81
+ assert nil == context.session[:return_to]
82
+ end
83
+
84
+ test "redirect to stored when no return to" do |context|
85
+ context.redirect_to_stored
86
+ assert "/" == context.redirect
87
+
88
+ context.redirect_to_stored("/custom")
89
+ assert "/custom" == context.redirect
90
+ end
91
+
92
+ test "login success" do |context|
93
+ assert context.login(User, "quentin", "password")
94
+ assert 1001 == context.session["User"]
95
+ end
96
+
97
+ test "login failure" do |context|
98
+ assert false == context.login(User, "wrong", "creds")
99
+ assert nil == context.session["User"]
100
+ end
101
+
102
+ test "logout" do |context|
103
+ context.session["User"] = 1001
104
+ context.session[:return_to] = "/foo"
105
+
106
+ # Now let's make it memoize the User
107
+ context.authenticated(User)
108
+
109
+ context.logout(User)
110
+
111
+ assert nil == context.session["User"]
112
+ assert nil == context.session[:return_to]
113
+ assert nil == context.authenticated(User)
114
+ end
@@ -1,21 +1,47 @@
1
1
  require File.expand_path("helper", File.dirname(__FILE__))
2
2
 
3
- class User < Shield::User
3
+ class User < Struct.new(:id)
4
+ extend Shield::Model
5
+
6
+ def self.[](id)
7
+ User.new(1) unless id.to_s.empty?
8
+ end
9
+
10
+ def self.authenticate(username, password)
11
+ User.new(1001) if username == "quentin" && password == "password"
12
+ end
4
13
  end
5
14
 
6
15
  class SinatraApp < Sinatra::Base
7
16
  enable :sessions
8
- register Shield
17
+ helpers Shield::Helpers
9
18
 
10
19
  get "/public" do
11
20
  "Public"
12
21
  end
13
22
 
14
23
  get "/private" do
15
- ensure_authenticated
24
+ ensure_authenticated(User)
16
25
 
17
26
  "Private"
18
27
  end
28
+
29
+ get "/login" do
30
+ "Login"
31
+ end
32
+
33
+ post "/login" do
34
+ if login(User, params[:login], params[:password])
35
+ redirect_to_stored
36
+ else
37
+ redirect_to_login
38
+ end
39
+ end
40
+
41
+ get "/logout" do
42
+ logout(User)
43
+ redirect "/"
44
+ end
19
45
  end
20
46
 
21
47
  scope do
@@ -24,9 +50,7 @@ scope do
24
50
  end
25
51
 
26
52
  setup do
27
- User.create(:email => "quentin@test.com",
28
- :password => "password",
29
- :password_confirmation => "password")
53
+ clear_cookies
30
54
  end
31
55
 
32
56
  test "public" do
@@ -34,40 +58,30 @@ scope do
34
58
  assert "Public" == last_response.body
35
59
  end
36
60
 
37
- test "private" do
61
+ test "successful logging in" do
38
62
  get "/private"
39
63
  assert_redirected_to "/login"
40
64
  assert "/private" == session[:return_to]
41
65
 
42
- post "/login", :login => "quentin@test.com", :password => "password"
66
+ post "/login", :login => "quentin", :password => "password"
43
67
  assert_redirected_to "/private"
44
- end
45
68
 
46
- test "GET /login response" do
47
- get "/login"
48
-
49
- doc = Nokogiri(%{<div>#{last_response.body}</div>})
50
-
51
- assert 2 == doc.search("form > fieldset > label > input").size
52
- assert 1 == doc.search("form > fieldset > button").size
69
+ assert 1001 == session["User"]
53
70
  end
54
- end
55
-
56
- class LoginCustomized < Sinatra::Base
57
- enable :sessions
58
- set :views, File.join(File.dirname(__FILE__), "fixtures", "views")
59
71
 
60
- register Shield
61
- end
72
+ test "failed login" do
73
+ post "/login", :login => "q", :password => "p"
74
+ assert_redirected_to "/login"
62
75
 
63
- scope do
64
- def app
65
- LoginCustomized.new
76
+ assert nil == session["User"]
66
77
  end
67
78
 
68
- test "login response" do
69
- get "/login"
79
+ test "logging out" do
80
+ post "/login", :login => "quentin", :password => "password"
81
+
82
+ get "/logout"
70
83
 
71
- assert "<h1>Login</h1>" == last_response.body.strip
84
+ assert nil == session["User"]
85
+ assert nil == session[:return_to]
72
86
  end
73
87
  end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 0
9
- version: 0.0.0
8
+ - 1
9
+ version: 0.0.1
10
10
  platform: ruby
11
11
  authors:
12
12
  - Michel Martens
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2010-10-15 00:00:00 +08:00
19
+ date: 2010-10-21 00:00:00 +08:00
20
20
  default_executable:
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency
@@ -46,7 +46,7 @@ dependencies:
46
46
  type: :development
47
47
  version_requirements: *id002
48
48
  - !ruby/object:Gem::Dependency
49
- name: haml
49
+ name: rack-test
50
50
  prerelease: false
51
51
  requirement: &id003 !ruby/object:Gem::Requirement
52
52
  none: false
@@ -58,59 +58,7 @@ dependencies:
58
58
  version: "0"
59
59
  type: :development
60
60
  version_requirements: *id003
61
- - !ruby/object:Gem::Dependency
62
- name: rack-test
63
- prerelease: false
64
- requirement: &id004 !ruby/object:Gem::Requirement
65
- none: false
66
- requirements:
67
- - - ">="
68
- - !ruby/object:Gem::Version
69
- segments:
70
- - 0
71
- version: "0"
72
- type: :development
73
- version_requirements: *id004
74
- - !ruby/object:Gem::Dependency
75
- name: ohm
76
- prerelease: false
77
- requirement: &id005 !ruby/object:Gem::Requirement
78
- none: false
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- segments:
83
- - 0
84
- version: "0"
85
- type: :development
86
- version_requirements: *id005
87
- - !ruby/object:Gem::Dependency
88
- name: ohm-contrib
89
- prerelease: false
90
- requirement: &id006 !ruby/object:Gem::Requirement
91
- none: false
92
- requirements:
93
- - - ">="
94
- - !ruby/object:Gem::Version
95
- segments:
96
- - 0
97
- version: "0"
98
- type: :development
99
- version_requirements: *id006
100
- - !ruby/object:Gem::Dependency
101
- name: nokogiri
102
- prerelease: false
103
- requirement: &id007 !ruby/object:Gem::Requirement
104
- none: false
105
- requirements:
106
- - - ">="
107
- - !ruby/object:Gem::Version
108
- segments:
109
- - 0
110
- version: "0"
111
- type: :development
112
- version_requirements: *id007
113
- description: "\n Gets you 80-90% of the way regarding your authentication\n requirements. Provides convenience helper functions which you can\n use with your favorite web framework of choice.\n "
61
+ description: "\n Provides all the protocol you need in order to do authentication on\n your rack application. The implementation specifics can be found in\n http://github.com/cyx/shield-contrib\n "
114
62
  email:
115
63
  - michel@soveran.com
116
64
  - djanowski@dimaion.com
@@ -123,26 +71,17 @@ extra_rdoc_files: []
123
71
 
124
72
  files:
125
73
  - lib/shield/helpers.rb
126
- - lib/shield/login.rb
74
+ - lib/shield/model.rb
127
75
  - lib/shield/password.rb
128
- - lib/shield/template/basic_user.rb
129
- - lib/shield/template/flexi_user.rb
130
- - lib/shield/template/user.rb
131
76
  - lib/shield.rb
132
77
  - README.markdown
133
- - README.rb
134
78
  - LICENSE
135
79
  - Rakefile
136
- - test/basic_user_test.rb
137
- - test/flexi_user_test.rb
138
80
  - test/helper.rb
139
- - test/login_middleware_test.rb
140
- - test/login_rack_mounting_test.rb
141
- - test/mounted_middleware_test.rb
81
+ - test/model_test.rb
142
82
  - test/password_hash_test.rb
143
83
  - test/shield_test.rb
144
84
  - test/sinatra_test.rb
145
- - test/user_test.rb
146
85
  has_rdoc: true
147
86
  homepage: http://github.com/cyx/shield
148
87
  licenses: []
@@ -174,6 +113,6 @@ rubyforge_project: shield
174
113
  rubygems_version: 1.3.7
175
114
  signing_key:
176
115
  specification_version: 3
177
- summary: Ohm specific authentication solution.
116
+ summary: Generic authentication protocol for rack applications.
178
117
  test_files: []
179
118
 
data/README.rb DELETED
@@ -1,73 +0,0 @@
1
- ## Shield
2
-
3
- # A simple authentication framework for use with a basic Rack application.
4
- # It doesn't try to be generic and instead has the following assertions:
5
-
6
- # 1. You use [Ohm][ohm] for your persistence layer.
7
- # 2. That your app has some form of a Helper plugin system.
8
-
9
- ## Usage
10
-
11
- # The fastest way to get started with `Shield` is to use it as a [Sinatra][sin]
12
- # extension on top of your main application.
13
-
14
- # We simply have to require sinatra, shield, and [Ohm][ohm].
15
- require "sinatra/base"
16
- require "shield"
17
- require "ohm"
18
-
19
- # We then define a `User` class on the top-level namespace:
20
- class User < Shield::User
21
- end
22
-
23
- # Our sinatra application can be a classic style, but for this example,
24
- # we'll use the more modular style extending from `Sinatra::Base`.
25
- class App < Sinatra::Base
26
- # One very very important detail to remember is that you need to
27
- # have session support for all of Shield to work.
28
- enable :sessions
29
-
30
- # Now for the main highlight: This line simply does two things:
31
- #
32
- # 1. It adds `Shield::Helpers` to your Sinatra app's helpers.
33
- # 2. It adds `Shield::Login` as a middleware for your application.
34
- #
35
- register Shield
36
-
37
- # This is a normal Sinatra route. No authentication is needed here.
38
- get "/public" do
39
- "Public"
40
- end
41
-
42
- # This is a private Sinatra route, which we enforce using
43
- # `ensure_authenticated`. This method comes from `Shield::Helpers` along
44
- # with some other helper methods:
45
- #
46
- # 1. `current_user` - ain't this the standard nowadays?
47
- # 2. `logged_in?` - simple sugar to verify if the user is logged in.
48
- # 3. `ensure_authenticated` - as shown here.
49
- # 4. `redirect_to_stored` - redirects to the previous url the user was
50
- # trying to access prior to authenticating.
51
- get "/private" do
52
- ensure_authenticated
53
-
54
- "Private"
55
- end
56
- end
57
-
58
- # If this file was run directly i.e. ruby README.rb.
59
- if __FILE__ == $0
60
- # For the purposes of this quick script, let's create a User. You'll use that
61
- # to quickly verify that you can indeed login to the application.
62
- if User.all.size == 0
63
- User.create(:email => "quentin@test.com",
64
- :password => "password",
65
- :password_confirmation => "password")
66
- end
67
-
68
- # Let Sinatra take the stage.
69
- App.run!
70
- end
71
-
72
- # [ohm]: http://ohm.keyvalue.org
73
- # [sin]: http://sinatrarb.com
@@ -1,38 +0,0 @@
1
- require "sinatra/base"
2
-
3
- module Shield
4
- class Login < Sinatra::Base
5
- enable :sessions
6
- helpers Helpers
7
-
8
- set :views, File.join(File.dirname(__FILE__), "..", "..", "views")
9
-
10
- set :auth_success_message, "You have successfully logged in."
11
- set :auth_failure_message, "Wrong Username and/or Password combination."
12
-
13
- get "/login/?" do
14
- haml :login
15
- end
16
-
17
- post "/login/?" do
18
- user = ::User.authenticate(params[:login], params[:password])
19
-
20
- if user
21
- session[:success] = settings.auth_success_message
22
- session[:user] = user.id
23
-
24
- redirect_to_stored
25
- else
26
- session[:error] = settings.auth_failure_message
27
- redirect "/login"
28
- end
29
- end
30
-
31
- get "/logout/?" do
32
- session.delete(:user)
33
- session.delete(:return_to)
34
-
35
- redirect "/"
36
- end
37
- end
38
- end
@@ -1,37 +0,0 @@
1
- module Shield
2
- class BasicUser < Ohm::Model
3
- Unimplemented = Class.new(StandardError)
4
-
5
- def self.inherited(model)
6
- model.attribute :crypted_password
7
- end
8
-
9
- # TODO : change this if Ohm decides on implementing subclassing.
10
- def self._copy_attributes_indices_counters(model)
11
- attributes.each { |att| model.attribute(att) }
12
- indices.each { |att| model.index(att) }
13
- counters.each { |att| model.counter(att) }
14
- end
15
-
16
- attr_reader :password, :password_confirmation
17
- attr_writer :password_confirmation
18
-
19
- def self.authenticate(login, password)
20
- user = find_by_login(login)
21
-
22
- if user && Shield::Password.check(password, user.crypted_password)
23
- return user
24
- end
25
- end
26
-
27
- def self.find_by_login(login)
28
- raise Unimplemented
29
- end
30
-
31
- def password=(password)
32
- write_local :crypted_password, Shield::Password.encrypt(password)
33
-
34
- @password = password
35
- end
36
- end
37
- end
@@ -1,22 +0,0 @@
1
- module Shield
2
- class FlexiUser < User
3
- def self.inherited(model)
4
- model.attribute :username
5
- model.index :username
6
-
7
- _copy_attributes_indices_counters(model)
8
- end
9
-
10
- def self.find_by_login(login)
11
- super or find(:username => login).first
12
- end
13
-
14
- def validate
15
- super
16
-
17
- assert_present(:username) &&
18
- assert_format(:username, /\A[a-z][a-z0-9\-\_\.]{2,}\z/) &&
19
- assert_unique(:username)
20
- end
21
- end
22
- end
@@ -1,32 +0,0 @@
1
- require "ohm/contrib"
2
-
3
- module Shield
4
- class User < BasicUser
5
- include Ohm::WebValidations
6
-
7
- def self.inherited(model)
8
- model.attribute :email
9
- model.index :email
10
-
11
- _copy_attributes_indices_counters(model)
12
- end
13
-
14
- def self.find_by_login(login)
15
- find(:email => login).first
16
- end
17
-
18
- def validate
19
- super
20
-
21
- assert_present(:email) && assert_email(:email) && assert_unique(:email)
22
-
23
- if new?
24
- assert_present :password
25
- end
26
-
27
- unless password.to_s.empty?
28
- assert password == password_confirmation, [:password, :not_confirmed]
29
- end
30
- end
31
- end
32
- end
@@ -1,37 +0,0 @@
1
- require File.expand_path("helper", File.dirname(__FILE__))
2
-
3
- class BasicUser < Shield::BasicUser
4
- end
5
-
6
- setup do
7
- BasicUser.create(:password => "password")
8
- end
9
-
10
- test "allows password checks at the minimum" do |u|
11
- assert Shield::Password.check("password", u.crypted_password)
12
- end
13
-
14
- test "no find_by_login" do
15
- assert_raise Shield::BasicUser::Unimplemented do
16
- BasicUser.authenticate("quentin", "password")
17
- end
18
-
19
- assert_raise Shield::BasicUser::Unimplemented do
20
- BasicUser.find_by_login("quentin")
21
- end
22
- end
23
-
24
- test "has password confirmation accesors" do |u|
25
- u.password_confirmation = "pass"
26
-
27
- assert "pass" == u.password_confirmation
28
- end
29
-
30
- test "writes the new crypted password on set" do
31
- u = BasicUser.new(:password => "mypass")
32
- assert Shield::Password.check("mypass", u.crypted_password)
33
-
34
- u.save
35
- u = BasicUser[u.id]
36
- assert Shield::Password.check("mypass", u.crypted_password)
37
- end
@@ -1,40 +0,0 @@
1
- require File.expand_path("helper", File.dirname(__FILE__))
2
-
3
- class FlexiUser < Shield::FlexiUser
4
- end
5
-
6
- setup do
7
- FlexiUser.create(:email => "quentin@test.com",
8
- :username => "quentin",
9
- :password => "password",
10
- :password_confirmation => "password")
11
- end
12
-
13
- test "find_by_login" do |u|
14
- assert u == FlexiUser.find_by_login("quentin@test.com")
15
- assert u == FlexiUser.find_by_login("quentin")
16
- end
17
-
18
- test "authenticate" do |u|
19
- assert u == FlexiUser.authenticate("quentin", "password")
20
- assert u == FlexiUser.authenticate("quentin@test.com", "password")
21
- end
22
-
23
- test "username validation" do |u|
24
- u.username = nil
25
- assert ! u.valid?
26
- assert u.errors.include?([:username, :not_present])
27
-
28
- ["1foo", "fo", "foo^", "foo&", "foo#"].each do |username|
29
- u.username = username
30
- assert ! u.valid?
31
- assert u.errors.include?([:username, :format])
32
- end
33
-
34
- u.username = "foo"
35
- assert u.valid?
36
-
37
- newuser = FlexiUser.new(:username => "quentin")
38
- assert ! newuser.valid?
39
- assert newuser.errors.include?([:username, :not_unique])
40
- end
@@ -1,59 +0,0 @@
1
- require File.expand_path("helper", File.dirname(__FILE__))
2
-
3
- class User < Shield::User
4
- end
5
-
6
- class Main < Sinatra::Base
7
- enable :sessions
8
- helpers Shield::Helpers
9
-
10
- get "/public" do
11
- "Public"
12
- end
13
-
14
- get "/private" do
15
- ensure_authenticated
16
-
17
- "Private"
18
- end
19
-
20
- use Shield::Login do |login|
21
- login.settings.auth_success_message = "Booya!"
22
- login.settings.auth_failure_message = "BOOM!"
23
- end
24
- end
25
-
26
- scope do
27
- def app
28
- Main.new
29
- end
30
-
31
- setup do
32
- clear_cookies
33
-
34
- User.create(:email => "quentin@test.com",
35
- :password => "password",
36
- :password_confirmation => "password")
37
- end
38
-
39
- test "public" do
40
- get "/public"
41
- assert "Public" == last_response.body
42
- end
43
-
44
- test "logging in" do
45
- post "/login", :login => "quentin@test.com", :password => "password"
46
-
47
- get "/private"
48
- assert "Private" == last_response.body
49
- assert "Booya!" == session[:success]
50
- end
51
-
52
- test "login, logout, login failure" do
53
- post "/login", :login => "quentin@test.com", :password => "password"
54
- get "/logout"
55
-
56
- post "/login"
57
- assert "BOOM!" == session[:error]
58
- end
59
- end
@@ -1,63 +0,0 @@
1
- require File.expand_path("helper", File.dirname(__FILE__))
2
-
3
- class User < Shield::User
4
- end
5
-
6
- class Main < Sinatra::Base
7
- enable :sessions
8
- helpers Shield::Helpers
9
-
10
- get "/public" do
11
- "Public"
12
- end
13
-
14
- get "/private" do
15
- ensure_authenticated
16
-
17
- "Private"
18
- end
19
- end
20
-
21
- $app = Rack::Builder.app {
22
- use Shield::Login
23
-
24
- map "/" do
25
- run Main
26
- end
27
- }
28
-
29
- scope do
30
- def app
31
- $app
32
- end
33
-
34
- setup do
35
- clear_cookies
36
-
37
- User.create(:email => "quentin@test.com",
38
- :password => "password",
39
- :password_confirmation => "password")
40
- end
41
-
42
- test "public" do
43
- get "/public"
44
-
45
- assert "Public" == last_response.body
46
- end
47
-
48
- test "logging in" do
49
- post "/login", :login => "quentin@test.com",
50
- :password => "password"
51
-
52
- get "/private"
53
- assert "Private" == last_response.body
54
- end
55
-
56
- test "being redirected and then logging in" do
57
- get "/private"
58
- assert_redirected_to "/login"
59
-
60
- post "/login", :login => "quentin@test.com", :password => "password"
61
- assert_redirected_to "/private"
62
- end
63
- end
@@ -1,96 +0,0 @@
1
- require File.expand_path("helper", File.dirname(__FILE__))
2
-
3
- class User < Shield::User
4
- end
5
-
6
- class App < Sinatra::Base
7
- enable :sessions
8
-
9
- helpers Shield::Helpers
10
- end
11
-
12
- class Main < App
13
- get "/public" do
14
- "Public"
15
- end
16
-
17
- get "/private" do
18
- ensure_authenticated
19
-
20
- "Private"
21
- end
22
- end
23
-
24
- class Admin < App
25
- before do
26
- ensure_authenticated unless request.fullpath == "/admin/login"
27
- end
28
-
29
- get "/events" do
30
- "Events"
31
- end
32
-
33
- get "/sponsors" do
34
- "Sponsors"
35
- end
36
-
37
- post "/login" do
38
- user = User.authenticate(params[:login], params[:password])
39
-
40
- if user
41
- session[:success] = "Success"
42
- session[:user] = user.id
43
-
44
- redirect_to_stored
45
- else
46
- session[:error] = "Failure"
47
- redirect "/login"
48
- end
49
- end
50
- end
51
-
52
- $app = Rack::Builder.app {
53
- map "/" do
54
- run Main
55
- end
56
-
57
- map "/admin" do
58
- run Admin
59
- end
60
- }
61
-
62
- scope do
63
- def app
64
- $app
65
- end
66
-
67
- setup do
68
- User.create(:email => "quentin@test.com",
69
- :password => "password",
70
- :password_confirmation => "password")
71
- end
72
-
73
- test "public" do
74
- get "/public"
75
-
76
- assert "Public" == last_response.body
77
- end
78
-
79
- test "all admin routes" do
80
- get "/admin/events"
81
- assert_redirected_to "/login"
82
- assert "/admin/events" == session[:return_to]
83
-
84
- get "/admin/sponsors"
85
- assert_redirected_to "/login"
86
- assert "/admin/sponsors" == session[:return_to]
87
- end
88
-
89
- test "single sign on" do
90
- post "/admin/login", :login => "quentin@test.com",
91
- :password => "password"
92
-
93
- get "/private"
94
- assert "Private" == last_response.body
95
- end
96
- end
@@ -1,33 +0,0 @@
1
- require File.expand_path("helper", File.dirname(__FILE__))
2
-
3
- class User < Shield::User
4
- end
5
-
6
- setup do
7
- User.create(:email => "quentin@email.com", :password => "password",
8
- :password_confirmation => "password")
9
- end
10
-
11
- test "authentication default" do |u|
12
- assert u == User.authenticate("quentin@email.com", "password")
13
-
14
- assert nil == User.authenticate("quentin@email.com", "pass")
15
- assert nil == User.authenticate("quentin@email.co.uk", "password")
16
- end
17
-
18
- test "email validation" do |u|
19
- u.email = nil
20
- assert ! u.valid?
21
- assert u.errors.include?([:email, :not_present])
22
-
23
- u.email = "foobar"
24
- assert ! u.valid?
25
- assert u.errors.include?([:email, :not_email])
26
-
27
- u.email = "foo@bar.com"
28
- u.save
29
-
30
- foo = User.new(:email => "foo@bar.com")
31
- assert ! foo.valid?
32
- assert foo.errors.include?([:email, :not_unique])
33
- end