quo_vadis 1.0.2 → 1.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/README.md +40 -8
- data/Rakefile +9 -0
- data/app/controllers/controller_mixin.rb +38 -2
- data/app/controllers/quo_vadis/sessions_controller.rb +12 -3
- data/app/mailers/quo_vadis/notifier.rb +2 -0
- data/app/models/model_mixin.rb +35 -5
- data/config/initializers/quo_vadis.rb +13 -9
- data/lib/quo_vadis/version.rb +1 -1
- data/lib/quo_vadis.rb +21 -14
- data/test/dummy/config/locales/quo_vadis.en.yml +4 -3
- data/test/integration/cookie_test.rb +97 -0
- data/test/test_helper.rb +1 -0
- metadata +6 -4
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -8,14 +8,13 @@ Features:
|
|
8
8
|
* No surprises: it does what you expect.
|
9
9
|
* Easy to customise.
|
10
10
|
* Uses BCrypt to encrypt passwords.
|
11
|
-
* Sign in, sign out, forgotten password, authenticate actions.
|
11
|
+
* Sign in, sign out, forgotten password, authenticate actions, remember user between browser sessions.
|
12
12
|
|
13
13
|
Forthcoming features:
|
14
14
|
|
15
|
-
* Generate the views for you.
|
15
|
+
* Generate the views for you (for now, copy the examples given below).
|
16
16
|
* Let you choose which model(s) to authenticate (currently `User`).
|
17
17
|
* Let you choose the identification field (currently `username`).
|
18
|
-
* Remember authenticated user across browser sessions.
|
19
18
|
* HTTP basic/digest authentication (probably).
|
20
19
|
* Generate (User) model plus migration if it doesn't exist.
|
21
20
|
* Detect presence of `has_secure_password` (see below) and adapt appropriately.
|
@@ -58,7 +57,7 @@ Write the sign-in view. Your sign-in form must:
|
|
58
57
|
* be in `app/views/sessions/new.html.:format`
|
59
58
|
* POST the parameters `:username` and `:password` to `sign_in_url`
|
60
59
|
|
61
|
-
You have to write the view yourself because you'd inevitably want to change whatever markup I generated for you.
|
60
|
+
You have to write the view yourself because you'd inevitably want to change whatever markup I generated for you. You can find an example in the [test app](https://github.com/airblade/quo_vadis/blob/master/test/dummy/app/views/sessions/new.html.erb).
|
62
61
|
|
63
62
|
Remember to serve your sign in form over HTTPS -- to avoid [the credentials being stolen](http://blog.jgc.org/2011/01/code-injected-to-steal-passwords-in.html).
|
64
63
|
|
@@ -80,12 +79,12 @@ It'll take you about 5 minutes to implement this.
|
|
80
79
|
|
81
80
|
On your sign-in page, link to the forgotten-password view at `forgotten_sign_in_url`.
|
82
81
|
|
83
|
-
Write the forgotten-password view. The form must:
|
82
|
+
Write the forgotten-password view ([example](https://github.com/airblade/quo_vadis/blob/master/test/dummy/app/views/sessions/forgotten.html.erb)). The form must:
|
84
83
|
|
85
84
|
* be in `app/views/sessions/forgotten.html.:format`
|
86
85
|
* POST the parameter `:username` to `forgotten_sign_in_url`
|
87
86
|
|
88
|
-
Now write the mailer view, i.e. the email which will be sent to your forgetful users. The view must:
|
87
|
+
Now write the mailer view, i.e. the email which will be sent to your forgetful users ([example](https://github.com/airblade/quo_vadis/blob/master/test/dummy/app/views/quo_vadis/notifier/change_password.text.erb)). The view must:
|
89
88
|
|
90
89
|
* be at `app/views/quo_vadis/notifier/change_password.text.erb`
|
91
90
|
* render `@url` somewhere (this is the link the user clicks to go to the change-password page)
|
@@ -98,7 +97,7 @@ Configure the default host so ActionMailer can generate the URL. In `config/env
|
|
98
97
|
|
99
98
|
config.action_mailer.default_url_options = {:host => 'yourdomain.com'}
|
100
99
|
|
101
|
-
Finally, write the change-password page. The form must:
|
100
|
+
Finally, write the change-password page ([example](https://github.com/airblade/quo_vadis/blob/master/test/dummy/app/views/sessions/edit.html.erb)). The form must:
|
102
101
|
|
103
102
|
* be in `app/views/sessions/edit.html.:format`
|
104
103
|
* PUT the parameter `:password` to `change_password_url(params[:token])`
|
@@ -106,13 +105,34 @@ Finally, write the change-password page. The form must:
|
|
106
105
|
|
107
106
|
## Customisation
|
108
107
|
|
109
|
-
You can customise the flash messages in `config/locales/quo_vadis.en.yml`.
|
108
|
+
You can customise the flash messages and mailer from/subject in `config/locales/quo_vadis.en.yml`.
|
110
109
|
|
111
110
|
You can customise the sign-in and sign-out redirects in `config/initializers/quo_vadis.rb`; they both default to the root route. You can also hook into the sign-in and sign-out process if you need to run any other code.
|
112
111
|
|
113
112
|
If you want to add other session management type features, go right ahead: create a `SessionsController` as normal and carry on.
|
114
113
|
|
115
114
|
|
115
|
+
## Sign up / user registration
|
116
|
+
|
117
|
+
Quo Vadis doesn't offer sign-up because that's user management, not authentication.
|
118
|
+
|
119
|
+
However if you have implemented user sign-up yourself, you need to be able to sign in a newly created user. Do this by calling `sign_in(user)` in your controller. For example:
|
120
|
+
|
121
|
+
# In your app
|
122
|
+
class UsersController < ApplicationController
|
123
|
+
def create
|
124
|
+
@user = User.new params[:user]
|
125
|
+
if @user.save
|
126
|
+
sign_in @user # <-- NOTE: sign in your user here
|
127
|
+
else
|
128
|
+
render 'new'
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
The `sign_in(user)` method will redirect the user appropriately (you can configure this in `config/initializers/quo_vadis.rb`), as well as running any sign-in hook you may have defined in the initializer.
|
134
|
+
|
135
|
+
|
116
136
|
## See also
|
117
137
|
|
118
138
|
* Rails 3 edge's [ActiveModel::SecurePassword](https://github.com/rails/rails/blob/master/activemodel/lib/active_model/secure_password.rb). It's `has_secure_password` class method is similar to Quo Vadis's `authenticates` class method.
|
@@ -122,3 +142,15 @@ If you want to add other session management type features, go right ahead: creat
|
|
122
142
|
## What's up with the name?
|
123
143
|
|
124
144
|
Roman sentries used to challenge intruders with, "Halt! Who goes there?"; quo vadis is Latin for "Who goes there?". At least that's what my Latin teacher told us, but I was 8 years old then so I may not be remembering this entirely accurately.
|
145
|
+
|
146
|
+
|
147
|
+
## Questions, Problems, Feedback
|
148
|
+
|
149
|
+
Please use the GitHub [issue tracker](https://github.com/airblade/quo_vadis/issues) or email me.
|
150
|
+
|
151
|
+
|
152
|
+
## Intellectual property
|
153
|
+
|
154
|
+
Copyright 2011 Andy Stewart (boss@airbladesoftware.com).
|
155
|
+
|
156
|
+
Released under the MIT licence.
|
data/Rakefile
CHANGED
@@ -2,6 +2,7 @@ require 'bundler'
|
|
2
2
|
Bundler::GemHelper.install_tasks
|
3
3
|
|
4
4
|
require 'rake/testtask'
|
5
|
+
require 'rake/rdoctask'
|
5
6
|
|
6
7
|
Rake::TestTask.new(:test) do |t|
|
7
8
|
t.libs << 'lib'
|
@@ -10,4 +11,12 @@ Rake::TestTask.new(:test) do |t|
|
|
10
11
|
t.verbose = false
|
11
12
|
end
|
12
13
|
|
14
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
15
|
+
rdoc.rdoc_dir = 'rdoc'
|
16
|
+
rdoc.title = 'Quo Vadis'
|
17
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
18
|
+
rdoc.rdoc_files.include('README.md')
|
19
|
+
rdoc.rdoc_files.include('app/**/*.rb')
|
20
|
+
end
|
21
|
+
|
13
22
|
task :default => :test
|
@@ -5,14 +5,22 @@ module ControllerMixin
|
|
5
5
|
|
6
6
|
private
|
7
7
|
|
8
|
+
# Remembers the authenticated <tt>user</tt> (in this session and future sessions).
|
9
|
+
#
|
10
|
+
# If you want to sign in a <tt>user</tt>, call <tt>QuoVadis::SessionsController#sign_in</tt>
|
11
|
+
# instead.
|
8
12
|
def current_user=(user)
|
9
|
-
|
13
|
+
remember_user_in_session user
|
14
|
+
remember_user_between_sessions user
|
10
15
|
end
|
11
16
|
|
17
|
+
# Returns the authenticated user.
|
12
18
|
def current_user
|
13
|
-
@current_user ||=
|
19
|
+
@current_user ||= find_authenticated_user
|
14
20
|
end
|
15
21
|
|
22
|
+
# Does nothing if we already have an authenticated user. If we don't have an
|
23
|
+
# authenticated user, it stores the desired URL and redirects to the sign in URL.
|
16
24
|
def authenticate
|
17
25
|
unless current_user
|
18
26
|
session[:quo_vadis_original_url] = request.fullpath
|
@@ -20,4 +28,32 @@ module ControllerMixin
|
|
20
28
|
redirect_to sign_in_url
|
21
29
|
end
|
22
30
|
end
|
31
|
+
|
32
|
+
def remember_user_in_session(user) # :nodoc:
|
33
|
+
session[:current_user_id] = user ? user.id : nil
|
34
|
+
end
|
35
|
+
|
36
|
+
def remember_user_between_sessions(user) # :nodoc:
|
37
|
+
if user && QuoVadis.remember_for
|
38
|
+
cookies.signed[:remember_me] = {
|
39
|
+
:value => [user.id, user.password_salt],
|
40
|
+
:expires => QuoVadis.remember_for.from_now,
|
41
|
+
:httponly => true
|
42
|
+
}
|
43
|
+
else
|
44
|
+
cookies.delete :remember_me
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def find_authenticated_user # :nodoc:
|
49
|
+
find_user_by_session || find_user_by_cookie
|
50
|
+
end
|
51
|
+
|
52
|
+
def find_user_by_cookie # :nodoc:
|
53
|
+
User.find_by_salt(*cookies.signed[:remember_me]) if cookies.signed[:remember_me]
|
54
|
+
end
|
55
|
+
|
56
|
+
def find_user_by_session # :nodoc:
|
57
|
+
User.find(session[:current_user_id]) if session[:current_user_id]
|
58
|
+
end
|
23
59
|
end
|
@@ -74,26 +74,35 @@ class QuoVadis::SessionsController < ApplicationController
|
|
74
74
|
end
|
75
75
|
end
|
76
76
|
|
77
|
-
|
77
|
+
protected
|
78
78
|
|
79
|
+
# Signs in a user, i.e. remembers them in the session, runs the sign-in hook,
|
80
|
+
# and redirects appropriately.
|
81
|
+
#
|
82
|
+
# This method should be called when you have just authenticated <tt>user</tt>
|
83
|
+
# and you need to sign them in. For example, if a new user has just signed up,
|
84
|
+
# you should call this method to sign them in.
|
79
85
|
def sign_in(user)
|
80
86
|
self.current_user = user
|
81
87
|
QuoVadis.signed_in_hook user, self
|
82
88
|
redirect_to QuoVadis.signed_in_url(user, original_url)
|
83
89
|
end
|
84
90
|
|
91
|
+
private
|
92
|
+
|
93
|
+
# Returns the URL if any which the user tried to visit before being forced to authenticate.
|
85
94
|
def original_url
|
86
95
|
url = session[:quo_vadis_original_url]
|
87
96
|
session[:quo_vadis_original_url] = nil
|
88
97
|
url
|
89
98
|
end
|
90
99
|
|
91
|
-
def invalid_token
|
100
|
+
def invalid_token # :nodoc:
|
92
101
|
flash[:alert] = t('quo_vadis.flash.forgotten.invalid_token') unless t('quo_vadis.flash.forgotten.invalid_token').blank?
|
93
102
|
redirect_to forgotten_sign_in_url
|
94
103
|
end
|
95
104
|
|
96
|
-
def quo_vadis_layout
|
105
|
+
def quo_vadis_layout # :nodoc:
|
97
106
|
QuoVadis.layout
|
98
107
|
end
|
99
108
|
|
data/app/models/model_mixin.rb
CHANGED
@@ -7,6 +7,9 @@ module ModelMixin
|
|
7
7
|
end
|
8
8
|
|
9
9
|
module ClassMethods
|
10
|
+
# Adds methods to set and authenticate against a password stored encrypted by BCrypt.
|
11
|
+
# Also adds methods to generate and clear a token, used to retrieve the record of a
|
12
|
+
# user who has forgotten their password.
|
10
13
|
def authenticates
|
11
14
|
send :include, InstanceMethodsOnActivation
|
12
15
|
|
@@ -20,6 +23,8 @@ module ModelMixin
|
|
20
23
|
scope :valid_token, lambda { |token| where("token = ? AND token_created_at > ?", token, 3.hours.ago) }
|
21
24
|
|
22
25
|
instance_eval <<-END
|
26
|
+
# Returns the user with the given <tt>username</tt> if the given password is
|
27
|
+
# correct, and <tt>nil</tt> otherwise.
|
23
28
|
def authenticate(username, plain_text_password)
|
24
29
|
user = where(:username => username).first
|
25
30
|
if user && user.has_matching_password?(plain_text_password)
|
@@ -28,17 +33,28 @@ module ModelMixin
|
|
28
33
|
nil
|
29
34
|
end
|
30
35
|
end
|
36
|
+
|
37
|
+
def find_by_salt(id, salt) # :nodoc:
|
38
|
+
user = User.find_by_id id
|
39
|
+
if user && user.has_matching_salt?(salt)
|
40
|
+
user
|
41
|
+
else
|
42
|
+
nil
|
43
|
+
end
|
44
|
+
end
|
31
45
|
END
|
32
46
|
end
|
33
47
|
end
|
34
48
|
|
35
49
|
module InstanceMethodsOnActivation
|
36
|
-
def password=(plain_text_password)
|
50
|
+
def password=(plain_text_password) # :nodoc:
|
37
51
|
@password = plain_text_password
|
38
52
|
self.password_digest = BCrypt::Password.create plain_text_password
|
39
53
|
end
|
40
54
|
|
41
|
-
|
55
|
+
# Generates a unique, timestamped token which can be used in URLs, and
|
56
|
+
# saves the record. This is part of the forgotten-password workflow.
|
57
|
+
def generate_token # :nodoc:
|
42
58
|
begin
|
43
59
|
self.token = url_friendly_token
|
44
60
|
end while self.class.exists?(:token => token)
|
@@ -46,17 +62,31 @@ module ModelMixin
|
|
46
62
|
save
|
47
63
|
end
|
48
64
|
|
49
|
-
|
65
|
+
# Clears the user's timestamped token and saves the record.
|
66
|
+
# This is part of the forgotten-password workflow.
|
67
|
+
def clear_token # :nodoc:
|
50
68
|
update_attributes :token => nil, :token_created_at => nil
|
51
69
|
end
|
52
70
|
|
53
|
-
|
71
|
+
# Returns true if the given <tt>plain_text_password</tt> is the user's
|
72
|
+
# password, and false otherwise.
|
73
|
+
def has_matching_password?(plain_text_password) # :nodoc:
|
54
74
|
BCrypt::Password.new(password_digest) == plain_text_password
|
55
75
|
end
|
56
76
|
|
77
|
+
# Returns true if the given <tt>salt</tt> is the user's salt,
|
78
|
+
# and false otherwise.
|
79
|
+
def has_matching_salt?(salt) # :nodoc:
|
80
|
+
password_salt == salt
|
81
|
+
end
|
82
|
+
|
83
|
+
def password_salt # :nodoc:
|
84
|
+
BCrypt::Password.new(password_digest).salt
|
85
|
+
end
|
86
|
+
|
57
87
|
private
|
58
88
|
|
59
|
-
def url_friendly_token
|
89
|
+
def url_friendly_token # :nodoc:
|
60
90
|
ActiveSupport::SecureRandom.base64(10).tr('+/=', 'xyz')
|
61
91
|
end
|
62
92
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
QuoVadis.configure do |config|
|
2
2
|
|
3
3
|
#
|
4
|
-
#
|
4
|
+
# Sign in
|
5
5
|
#
|
6
6
|
|
7
7
|
# The URL to redirect the user to after s/he signs in.
|
@@ -18,14 +18,6 @@ QuoVadis.configure do |config|
|
|
18
18
|
# to reach when they were made to authenticate.
|
19
19
|
config.override_original_url = false
|
20
20
|
|
21
|
-
# The URL to redirect the user to after s/he signs out.
|
22
|
-
config.signed_out_url = :root
|
23
|
-
|
24
|
-
|
25
|
-
#
|
26
|
-
# Hooks
|
27
|
-
#
|
28
|
-
|
29
21
|
# Code to run when the user has signed in. E.g.:
|
30
22
|
#
|
31
23
|
# config.signed_in_hook = Proc.new do |user, controller|
|
@@ -40,6 +32,18 @@ QuoVadis.configure do |config|
|
|
40
32
|
# end
|
41
33
|
config.failed_sign_in_hook = nil
|
42
34
|
|
35
|
+
# How long to remember user across browser sessions.
|
36
|
+
# Set to <tt>nil</tt> to never remember user.
|
37
|
+
config.remember_for = 2.weeks
|
38
|
+
|
39
|
+
|
40
|
+
#
|
41
|
+
# Sign out
|
42
|
+
#
|
43
|
+
|
44
|
+
# The URL to redirect the user to after s/he signs out.
|
45
|
+
config.signed_out_url = :root
|
46
|
+
|
43
47
|
# Code to run just before the user has signed out. E.g.:
|
44
48
|
#
|
45
49
|
# config.signed_out_hook = Proc.new do |user, controller|
|
data/lib/quo_vadis/version.rb
CHANGED
data/lib/quo_vadis.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
require 'quo_vadis/engine'
|
2
|
+
require 'active_support/core_ext/numeric/time'
|
2
3
|
|
3
4
|
module QuoVadis
|
4
5
|
|
5
6
|
#
|
6
|
-
#
|
7
|
+
# Sign in
|
7
8
|
#
|
8
9
|
|
9
10
|
# The URL to redirect the user to after s/he signs in.
|
@@ -15,7 +16,7 @@ module QuoVadis
|
|
15
16
|
mattr_accessor :override_original_url
|
16
17
|
@@override_original_url = false
|
17
18
|
|
18
|
-
def self.signed_in_url(user, original_url)
|
19
|
+
def self.signed_in_url(user, original_url) # :nodoc:
|
19
20
|
if original_url && !@@override_original_url
|
20
21
|
original_url
|
21
22
|
else
|
@@ -23,20 +24,11 @@ module QuoVadis
|
|
23
24
|
end
|
24
25
|
end
|
25
26
|
|
26
|
-
# The URL to redirect the user to after s/he signs out.
|
27
|
-
mattr_accessor :signed_out_url
|
28
|
-
@@signed_in_url = :root
|
29
|
-
|
30
|
-
|
31
|
-
#
|
32
|
-
# Hooks
|
33
|
-
#
|
34
|
-
|
35
27
|
# Code to run when the user has signed in.
|
36
28
|
mattr_accessor :signed_in_hook
|
37
29
|
@@signed_in_hook = nil
|
38
30
|
|
39
|
-
def self.signed_in_hook(user, controller)
|
31
|
+
def self.signed_in_hook(user, controller) # :nodoc:
|
40
32
|
@@signed_in_hook.call(user, controller) if @@signed_in_hook
|
41
33
|
end
|
42
34
|
|
@@ -44,15 +36,29 @@ module QuoVadis
|
|
44
36
|
mattr_accessor :failed_sign_in_hook
|
45
37
|
@@failed_sign_in_hook = nil
|
46
38
|
|
47
|
-
def self.failed_sign_in_hook(controller)
|
39
|
+
def self.failed_sign_in_hook(controller) # :nodoc:
|
48
40
|
@@failed_sign_in_hook.call(controller) if @@failed_sign_in_hook
|
49
41
|
end
|
50
42
|
|
43
|
+
# How long to remember user across browser sessions.
|
44
|
+
mattr_accessor :remember_for
|
45
|
+
@@remember_for = 2.weeks
|
46
|
+
|
47
|
+
|
48
|
+
#
|
49
|
+
# Sign out
|
50
|
+
#
|
51
|
+
|
52
|
+
# The URL to redirect the user to after s/he signs out.
|
53
|
+
mattr_accessor :signed_out_url
|
54
|
+
@@signed_in_url = :root
|
55
|
+
|
56
|
+
|
51
57
|
# Code to run just before the user has signed out.
|
52
58
|
mattr_accessor :signed_out_hook
|
53
59
|
@@signed_out_hook = nil
|
54
60
|
|
55
|
-
def self.signed_out_hook(user, controller)
|
61
|
+
def self.signed_out_hook(user, controller) # :nodoc:
|
56
62
|
@@signed_out_hook.call(user, controller) if @@signed_out_hook
|
57
63
|
end
|
58
64
|
|
@@ -70,6 +76,7 @@ module QuoVadis
|
|
70
76
|
@@subject = 'Change your password.'
|
71
77
|
|
72
78
|
|
79
|
+
|
73
80
|
#
|
74
81
|
# Miscellaneous
|
75
82
|
#
|
@@ -1,7 +1,8 @@
|
|
1
1
|
en:
|
2
2
|
quo_vadis:
|
3
3
|
flash:
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
sign_in:
|
5
|
+
before: 'Please sign in first.'
|
6
|
+
after: 'You have successfully signed in.'
|
7
|
+
failed: 'Sorry, we did not recognise you.'
|
7
8
|
sign_out: 'You have successfully signed out.'
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class CookieTest < ActiveSupport::IntegrationCase
|
4
|
+
|
5
|
+
teardown do
|
6
|
+
Capybara.reset_sessions!
|
7
|
+
reset_quo_vadis_configuration
|
8
|
+
end
|
9
|
+
|
10
|
+
test 'authenticated user is remembered between browser sessions' do
|
11
|
+
user_factory 'Bob', 'bob', 'secret'
|
12
|
+
sign_in_as 'bob', 'secret'
|
13
|
+
close_browser
|
14
|
+
visit root_path
|
15
|
+
within '#topnav' do
|
16
|
+
assert page.has_content?('You are signed in as Bob.')
|
17
|
+
end
|
18
|
+
assert page.has_no_css?('div.flash')
|
19
|
+
end
|
20
|
+
|
21
|
+
test "signing in updates the remember-me cookie's expiry time" do
|
22
|
+
user_factory 'Bob', 'bob', 'secret'
|
23
|
+
sign_in_as 'bob', 'secret'
|
24
|
+
cookie_a = get_cookie('remember_me')
|
25
|
+
assert_equal 2.weeks.from_now.httpdate, cookie_a.expires.httpdate
|
26
|
+
close_browser
|
27
|
+
sleep 1 # cookie expiry times are accurate to 1 second.
|
28
|
+
|
29
|
+
sign_in_as 'bob', 'secret'
|
30
|
+
cookie_b = get_cookie('remember_me')
|
31
|
+
assert cookie_b.expires > cookie_a.expires
|
32
|
+
assert_equal cookie_a.value, cookie_b.value
|
33
|
+
end
|
34
|
+
|
35
|
+
test 'signing out prevents the user being remembered in the next browser session' do
|
36
|
+
user_factory 'Bob', 'bob', 'secret'
|
37
|
+
sign_in_as 'bob', 'secret'
|
38
|
+
visit sign_out_path
|
39
|
+
close_browser
|
40
|
+
visit new_article_path
|
41
|
+
assert_equal sign_in_path, current_path
|
42
|
+
end
|
43
|
+
|
44
|
+
test "changing user's password prevents user being remembered in the next browser session" do
|
45
|
+
user_factory 'Bob', 'bob', 'secret'
|
46
|
+
sign_in_as 'bob', 'secret'
|
47
|
+
cookie = get_cookie('remember_me')
|
48
|
+
User.last.update_attributes! :password => 'topsecret'
|
49
|
+
close_browser
|
50
|
+
visit new_article_path
|
51
|
+
assert_equal sign_in_path, current_path
|
52
|
+
end
|
53
|
+
|
54
|
+
test 'length of time user is remembered can be configured' do
|
55
|
+
QuoVadis.remember_for = 1.second
|
56
|
+
user_factory 'Bob', 'bob', 'secret'
|
57
|
+
sign_in_as 'bob', 'secret'
|
58
|
+
close_browser
|
59
|
+
sleep 2
|
60
|
+
visit new_article_path
|
61
|
+
assert_equal sign_in_path, current_path
|
62
|
+
end
|
63
|
+
|
64
|
+
test 'remembering user between sessions can be turned off' do
|
65
|
+
QuoVadis.remember_for = nil
|
66
|
+
user_factory 'Bob', 'bob', 'secret'
|
67
|
+
sign_in_as 'bob', 'secret'
|
68
|
+
close_browser
|
69
|
+
visit new_article_path
|
70
|
+
assert_equal sign_in_path, current_path
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
#
|
75
|
+
# Code below from https://github.com/nruth/show_me_the_cookies
|
76
|
+
#
|
77
|
+
|
78
|
+
def delete_cookie(cookie_name)
|
79
|
+
cookie_jar.instance_variable_get(:@cookies).reject! do |existing_cookie|
|
80
|
+
existing_cookie.name.downcase == cookie_name
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def get_cookie(cookie_name)
|
85
|
+
cookie_jar.instance_variable_get(:@cookies).select do |existing_cookie|
|
86
|
+
existing_cookie.name.downcase == cookie_name
|
87
|
+
end.first
|
88
|
+
end
|
89
|
+
|
90
|
+
def cookie_jar
|
91
|
+
Capybara.current_session.driver.current_session.instance_variable_get(:@rack_mock_session).cookie_jar
|
92
|
+
end
|
93
|
+
|
94
|
+
def close_browser
|
95
|
+
delete_cookie Rails.application.config.session_options[:key]
|
96
|
+
end
|
97
|
+
end
|
data/test/test_helper.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: quo_vadis
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 17
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 1.0.
|
9
|
+
- 3
|
10
|
+
version: 1.0.3
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Andy Stewart
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
18
|
+
date: 2011-02-07 00:00:00 +00:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -177,6 +177,7 @@ files:
|
|
177
177
|
- test/dummy/tmp/capybara/capybara-20110124135435.html
|
178
178
|
- test/integration/authenticate_test.rb
|
179
179
|
- test/integration/config_test.rb
|
180
|
+
- test/integration/cookie_test.rb
|
180
181
|
- test/integration/forgotten_test.rb
|
181
182
|
- test/integration/helper_test.rb
|
182
183
|
- test/integration/locale_test.rb
|
@@ -278,6 +279,7 @@ test_files:
|
|
278
279
|
- test/dummy/tmp/capybara/capybara-20110124135435.html
|
279
280
|
- test/integration/authenticate_test.rb
|
280
281
|
- test/integration/config_test.rb
|
282
|
+
- test/integration/cookie_test.rb
|
281
283
|
- test/integration/forgotten_test.rb
|
282
284
|
- test/integration/helper_test.rb
|
283
285
|
- test/integration/locale_test.rb
|