shield 0.0.0 → 0.0.1

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,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