authpwn_rails 0.12.0 → 0.12.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +7 -2
- data/VERSION +1 -1
- data/app/models/credentials/password.rb +16 -8
- data/app/models/credentials/token.rb +8 -0
- data/app/models/tokens/email_verification.rb +3 -0
- data/app/models/tokens/password_reset.rb +5 -2
- data/app/models/tokens/session_uid.rb +54 -0
- data/authpwn_rails.gemspec +8 -2
- data/lib/authpwn_rails.rb +3 -2
- data/lib/authpwn_rails/current_user.rb +1 -10
- data/lib/authpwn_rails/engine.rb +2 -2
- data/lib/authpwn_rails/expires.rb +23 -0
- data/lib/authpwn_rails/generators/all_generator.rb +9 -4
- data/lib/authpwn_rails/generators/templates/credential.rb +1 -1
- data/lib/authpwn_rails/generators/templates/credentials.yml +16 -0
- data/lib/authpwn_rails/generators/templates/initializer.rb +18 -0
- data/lib/authpwn_rails/generators/templates/session/forbidden.html.erb +1 -1
- data/lib/authpwn_rails/generators/templates/session/home.html.erb +1 -1
- data/lib/authpwn_rails/generators/templates/session/new.html.erb +3 -3
- data/lib/authpwn_rails/generators/templates/session/welcome.html.erb +1 -1
- data/lib/authpwn_rails/generators/templates/session_controller.rb +13 -4
- data/lib/authpwn_rails/generators/templates/session_controller_test.rb +12 -2
- data/lib/authpwn_rails/generators/templates/session_mailer.rb +3 -3
- data/lib/authpwn_rails/generators/templates/session_mailer/email_verification_email.html.erb +3 -3
- data/lib/authpwn_rails/generators/templates/session_mailer/reset_password_email.html.erb +3 -3
- data/lib/authpwn_rails/generators/templates/session_mailer_test.rb +4 -4
- data/lib/authpwn_rails/routes.rb +4 -4
- data/lib/authpwn_rails/session.rb +31 -8
- data/lib/authpwn_rails/session_controller.rb +27 -18
- data/lib/authpwn_rails/test_extensions.rb +16 -6
- data/lib/authpwn_rails/user_model.rb +10 -10
- data/test/cookie_controller_test.rb +165 -16
- data/test/credentials/email_verification_token_test.rb +11 -11
- data/test/credentials/password_credential_test.rb +31 -12
- data/test/credentials/session_uid_token_test.rb +98 -0
- data/test/credentials/token_crendential_test.rb +46 -12
- data/test/helpers/db_setup.rb +6 -5
- data/test/helpers/routes.rb +5 -2
- data/test/initializer_test.rb +18 -0
- data/test/session_controller_api_test.rb +127 -53
- data/test/test_extensions_test.rb +41 -0
- data/test/test_helper.rb +3 -0
- data/test/user_test.rb +11 -10
- metadata +9 -3
@@ -6,7 +6,7 @@ module TestExtensions
|
|
6
6
|
# Stubs User#auth_bounce_reason to block a given credential.
|
7
7
|
#
|
8
8
|
# The default implementation of User#auth_bounce_reason always returns nil.
|
9
|
-
# Your application's implementation might differ. Either way, the method is
|
9
|
+
# Your application's implementation might differ. Either way, the method is
|
10
10
|
# replaced for the duration of the block, such that it returns :block if
|
11
11
|
# the credential matches the given argument, and nil otherwise.
|
12
12
|
def with_blocked_credential(blocked_credential, reason = :blocked, &block)
|
@@ -19,7 +19,7 @@ module TestExtensions
|
|
19
19
|
credential == blocked_credential ? reason : nil
|
20
20
|
end
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
begin
|
24
24
|
yield
|
25
25
|
ensure
|
@@ -40,13 +40,23 @@ end
|
|
40
40
|
module ControllerTestExtensions
|
41
41
|
# Sets the authenticated user in the test session.
|
42
42
|
def set_session_current_user(user)
|
43
|
-
|
43
|
+
if user
|
44
|
+
# Avoid database inserts, if at all possible.
|
45
|
+
if token = Tokens::SessionUid.where(:user_id => user.id).first
|
46
|
+
token.spend # Only bump updated_at if necessary.
|
47
|
+
else
|
48
|
+
token = Tokens::SessionUid.random_for user, '127.0.0.1', 'UnitTests'
|
49
|
+
end
|
50
|
+
request.session[:authpwn_suid] = token.suid
|
51
|
+
else
|
52
|
+
request.session.delete :authpwn_suid
|
53
|
+
end
|
44
54
|
end
|
45
|
-
|
55
|
+
|
46
56
|
# The authenticated user in the test session.
|
47
57
|
def session_current_user
|
48
|
-
return nil unless
|
49
|
-
|
58
|
+
return nil unless suid = request.session[:authpwn_suid]
|
59
|
+
Credentials::Token.with_code(suid).user
|
50
60
|
end
|
51
61
|
|
52
62
|
# Sets the HTTP Authentication header.
|
@@ -18,16 +18,16 @@ module UserModel
|
|
18
18
|
# This is decoupled from "id" column to avoid leaking information about
|
19
19
|
# the application's usage.
|
20
20
|
validates :exuid, :presence => true, :length => 1..32, :uniqueness => true
|
21
|
-
|
21
|
+
|
22
22
|
# Credentials used to authenticate the user.
|
23
23
|
has_many :credentials, :dependent => :destroy, :inverse_of => :user
|
24
24
|
validates_associated :credentials
|
25
25
|
# This is safe, because credentials use attr_accessible.
|
26
26
|
accepts_nested_attributes_for :credentials, :allow_destroy => true
|
27
|
-
|
27
|
+
|
28
28
|
# Automatically assign exuid.
|
29
29
|
before_validation :set_default_exuid, :on => :create
|
30
|
-
|
30
|
+
|
31
31
|
# Forms should not be able to touch any attribute.
|
32
32
|
attr_accessible :credentials_attributes
|
33
33
|
end
|
@@ -46,8 +46,8 @@ module UserModel
|
|
46
46
|
# The method's parameter names are an acknowledgement to the email and
|
47
47
|
# password fields on automatically-generated forms.
|
48
48
|
#
|
49
|
-
# The easiest method of accepting other login information is to override
|
50
|
-
# method, locate the user's email, and supply it in a call to super.
|
49
|
+
# The easiest method of accepting other login information is to override
|
50
|
+
# this method, locate the user's email, and supply it in a call to super.
|
51
51
|
#
|
52
52
|
# Returns an authenticated user, or a symbol indicating the reason why the
|
53
53
|
# authentication failed.
|
@@ -55,21 +55,21 @@ module UserModel
|
|
55
55
|
Credentials::Password.authenticate_email email, password
|
56
56
|
end
|
57
57
|
end # module Authpwn::UserModel::ClassMethods
|
58
|
-
|
58
|
+
|
59
59
|
# Checks if a credential is acceptable for authenticating a user.
|
60
60
|
#
|
61
61
|
# Returns nil if the credential is acceptable, or a String containing a
|
62
|
-
# user-visible reason why the credential is not acceptable.
|
62
|
+
# user-visible reason why the credential is not acceptable.
|
63
63
|
def auth_bounce_reason(crdential)
|
64
64
|
nil
|
65
65
|
end
|
66
|
-
|
66
|
+
|
67
67
|
# Use e-mails instead of exposing ActiveRecord IDs.
|
68
68
|
def to_param
|
69
69
|
exuid
|
70
70
|
end
|
71
|
-
|
72
|
-
# :nodoc: sets exuid to a (hopefully) unique value before validations occur.
|
71
|
+
|
72
|
+
# :nodoc: sets exuid to a (hopefully) unique value before validations occur.
|
73
73
|
def set_default_exuid
|
74
74
|
self.exuid ||=
|
75
75
|
SecureRandom.random_bytes(8).unpack('Q').first & 0x7fffffffffffffff
|
@@ -2,8 +2,8 @@ require File.expand_path('../test_helper', __FILE__)
|
|
2
2
|
|
3
3
|
# Mock controller used for testing session handling.
|
4
4
|
class CookieController < ApplicationController
|
5
|
-
authenticates_using_session
|
6
|
-
|
5
|
+
authenticates_using_session :except => :update
|
6
|
+
|
7
7
|
def show
|
8
8
|
if current_user
|
9
9
|
render :text => "User: #{current_user.id}"
|
@@ -11,7 +11,16 @@ class CookieController < ApplicationController
|
|
11
11
|
render :text => "No user"
|
12
12
|
end
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
|
+
def update
|
16
|
+
if params[:exuid].blank?
|
17
|
+
set_session_current_user nil
|
18
|
+
else
|
19
|
+
set_session_current_user User.find_by_param(params[:exuid])
|
20
|
+
end
|
21
|
+
render :text => ''
|
22
|
+
end
|
23
|
+
|
15
24
|
def bouncer
|
16
25
|
bounce_user
|
17
26
|
end
|
@@ -20,32 +29,172 @@ end
|
|
20
29
|
class CookieControllerTest < ActionController::TestCase
|
21
30
|
setup do
|
22
31
|
@user = users(:john)
|
32
|
+
@token = credentials(:john_session_token)
|
23
33
|
end
|
24
34
|
|
25
|
-
test "no
|
35
|
+
test "no suid in session" do
|
26
36
|
get :show
|
27
37
|
assert_response :success
|
28
38
|
assert_nil assigns(:current_user)
|
29
39
|
assert_equal 'No user', response.body
|
30
40
|
end
|
31
|
-
|
32
|
-
test "valid
|
33
|
-
|
41
|
+
|
42
|
+
test "valid suid in session" do
|
43
|
+
request.session[:authpwn_suid] = @token.suid
|
34
44
|
get :show
|
35
45
|
assert_response :success
|
36
46
|
assert_equal @user, assigns(:current_user)
|
37
47
|
assert_equal "User: #{ActiveRecord::Fixtures.identify(:john)}",
|
38
48
|
response.body
|
39
49
|
end
|
40
|
-
|
41
|
-
test "
|
42
|
-
|
50
|
+
|
51
|
+
test "valid suid in session does not refresh very recent session" do
|
52
|
+
request.session[:authpwn_suid] = @token.suid
|
53
|
+
@token.updated_at = Time.now - 5.minutes
|
54
|
+
@token.save!
|
55
|
+
get :show
|
56
|
+
assert_response :success
|
57
|
+
assert_equal @user, assigns(:current_user)
|
58
|
+
assert_operator @token.reload.updated_at, :<=, Time.now - 5.minutes
|
59
|
+
end
|
60
|
+
|
61
|
+
test "valid suid in session refreshes recent session" do
|
62
|
+
request.session[:authpwn_suid] = @token.suid
|
63
|
+
@token.updated_at = Time.now - 5.minutes
|
64
|
+
@token.save!
|
65
|
+
get :show
|
66
|
+
assert_response :success
|
67
|
+
assert_equal @user, assigns(:current_user)
|
68
|
+
assert_operator @token.reload.updated_at, :<=, Time.now - 5.minutes
|
69
|
+
end
|
70
|
+
|
71
|
+
test "valid suid in session is discarded if the session is old" do
|
72
|
+
request.session[:authpwn_suid] = @token.suid
|
73
|
+
@token.updated_at = Time.now - 3.months
|
74
|
+
@token.save!
|
75
|
+
get :show
|
76
|
+
assert_response :success
|
77
|
+
assert_nil assigns(:current_user), 'current_user set'
|
78
|
+
assert_nil Credentials::Token.with_code(@token.suid),
|
79
|
+
'session token not destroyed'
|
80
|
+
end
|
81
|
+
|
82
|
+
test "invalid suid in session" do
|
83
|
+
request.session[:authpwn_suid] = @token.suid
|
84
|
+
@token.destroy
|
85
|
+
get :show
|
43
86
|
assert_response :success
|
44
87
|
assert_nil assigns(:current_user)
|
45
88
|
end
|
46
|
-
|
89
|
+
|
90
|
+
test "set_session_current_user creates new token by default" do
|
91
|
+
assert_difference 'Credential.count', 1 do
|
92
|
+
put :update, :exuid => @user.exuid
|
93
|
+
end
|
94
|
+
assert_response :success
|
95
|
+
assert_not_equal @token.suid, request.session[:authpwn_suid]
|
96
|
+
|
97
|
+
get :show
|
98
|
+
assert_response :success
|
99
|
+
assert_equal @user, assigns(:current_user)
|
100
|
+
end
|
101
|
+
|
102
|
+
test "set_session_current_user reuses existing token when suitable" do
|
103
|
+
request.session[:authpwn_suid] = @token.suid
|
104
|
+
assert_no_difference 'Credential.count', 'existing token not reused' do
|
105
|
+
put :update, :exuid => @user.exuid
|
106
|
+
end
|
107
|
+
assert_response :success
|
108
|
+
assert_equal @token.suid, request.session[:authpwn_suid]
|
109
|
+
|
110
|
+
get :show
|
111
|
+
assert_response :success
|
112
|
+
assert_equal @user, assigns(:current_user)
|
113
|
+
end
|
114
|
+
|
115
|
+
test "set_session_current_user refreshes old token" do
|
116
|
+
@token.updated_at = Time.now - 1.day
|
117
|
+
request.session[:authpwn_suid] = @token.suid
|
118
|
+
assert_no_difference 'Credential.count', 'existing token not reused' do
|
119
|
+
put :update, :exuid => @user.exuid
|
120
|
+
end
|
121
|
+
assert_response :success
|
122
|
+
assert_operator @token.reload.updated_at, :>=, Time.now - 1.hour,
|
123
|
+
'Old token not refreshed'
|
124
|
+
|
125
|
+
get :show
|
126
|
+
assert_response :success
|
127
|
+
assert_equal @user, assigns(:current_user)
|
128
|
+
end
|
129
|
+
|
130
|
+
test "set_session_current_user creates new token if old token is invalid" do
|
131
|
+
@token.destroy
|
132
|
+
request.session[:authpwn_suid] = @token.suid
|
133
|
+
assert_difference 'Credential.count', 1, 'session token not created' do
|
134
|
+
put :update, :exuid => @user.exuid
|
135
|
+
end
|
136
|
+
assert_response :success
|
137
|
+
assert_not_equal @token.suid, request.session[:authpwn_suid]
|
138
|
+
|
139
|
+
get :show
|
140
|
+
assert_response :success
|
141
|
+
assert_equal @user, assigns(:current_user)
|
142
|
+
end
|
143
|
+
|
144
|
+
test "set_session_current_user switches users correctly" do
|
145
|
+
old_token = credentials(:jane_session_token)
|
146
|
+
request.session[:authpwn_suid] = old_token.suid
|
147
|
+
assert_no_difference 'Credential.count',
|
148
|
+
"old user's token not destroyed or no new token created" do
|
149
|
+
put :update, :exuid => @user.exuid
|
150
|
+
end
|
151
|
+
assert_response :success
|
152
|
+
assert_nil Credentials::Token.with_code(old_token.suid),
|
153
|
+
"old user's token not destroyed"
|
154
|
+
assert_not_equal @token.suid, request.session[:authpwn_suid]
|
155
|
+
|
156
|
+
get :show
|
157
|
+
assert_response :success
|
158
|
+
assert_equal @user, assigns(:current_user)
|
159
|
+
end
|
160
|
+
|
161
|
+
test "set_session_current_user reuses token when switching users" do
|
162
|
+
@token.destroy
|
163
|
+
request.session[:authpwn_suid] = credentials(:jane_session_token).suid
|
164
|
+
assert_no_difference 'Credential.count',
|
165
|
+
"old user's token not destroyed or new user's token not created" do
|
166
|
+
put :update, :exuid => @user.exuid
|
167
|
+
end
|
168
|
+
assert_response :success
|
169
|
+
|
170
|
+
get :show
|
171
|
+
assert_response :success
|
172
|
+
assert_equal @user, assigns(:current_user)
|
173
|
+
end
|
174
|
+
|
175
|
+
test "set_session_current_user logs off a user correctly" do
|
176
|
+
request.session[:authpwn_suid] = @token.suid
|
177
|
+
assert_difference 'Credential.count', -1, 'token not destroyed' do
|
178
|
+
put :update, :exuid => ''
|
179
|
+
end
|
180
|
+
assert_response :success
|
181
|
+
assert_nil request.session[:authpwn_suid]
|
182
|
+
|
183
|
+
get :show
|
184
|
+
assert_response :success
|
185
|
+
assert_equal nil, assigns(:current_user)
|
186
|
+
end
|
187
|
+
|
188
|
+
test "set_session_current_user behaves when no user is logged off" do
|
189
|
+
assert_no_difference 'Credential.count' do
|
190
|
+
put :update, :exuid => ''
|
191
|
+
end
|
192
|
+
assert_response :success
|
193
|
+
assert_nil request.session[:authpwn_suid]
|
194
|
+
end
|
195
|
+
|
47
196
|
test "valid user_id bounced" do
|
48
|
-
|
197
|
+
request.session[:authpwn_suid] = @token.suid
|
49
198
|
get :bouncer
|
50
199
|
assert_response :forbidden
|
51
200
|
assert_template 'session/forbidden'
|
@@ -53,19 +202,19 @@ class CookieControllerTest < ActionController::TestCase
|
|
53
202
|
end
|
54
203
|
|
55
204
|
test "valid user_id bounced in json" do
|
56
|
-
|
205
|
+
request.session[:authpwn_suid] = @token.suid
|
57
206
|
get :bouncer, :format => 'json'
|
58
207
|
assert_response :ok
|
59
208
|
data = ActiveSupport::JSON.decode response.body
|
60
209
|
assert_match(/not allowed/i, data['error'])
|
61
210
|
end
|
62
|
-
|
211
|
+
|
63
212
|
test "no user_id bounced" do
|
64
213
|
get :bouncer
|
65
214
|
assert_response :forbidden
|
66
215
|
assert_template 'session/forbidden'
|
67
216
|
assert_equal bouncer_cookie_url, flash[:auth_redirect_url]
|
68
|
-
|
217
|
+
|
69
218
|
assert_select 'script', %r/.*window.location.*#{new_session_path}.*/
|
70
219
|
end
|
71
220
|
|
@@ -75,7 +224,7 @@ class CookieControllerTest < ActionController::TestCase
|
|
75
224
|
data = ActiveSupport::JSON.decode response.body
|
76
225
|
assert_match(/sign in/i, data['error'])
|
77
226
|
end
|
78
|
-
|
227
|
+
|
79
228
|
test "auth_controller? is false" do
|
80
229
|
assert_equal false, @controller.auth_controller?
|
81
230
|
end
|
@@ -1,27 +1,27 @@
|
|
1
1
|
require File.expand_path('../../test_helper', __FILE__)
|
2
2
|
|
3
|
-
class
|
3
|
+
class EmailVerificationTokenTest < ActiveSupport::TestCase
|
4
4
|
def setup
|
5
5
|
@credential = Tokens::EmailVerification.new(
|
6
6
|
:code => 'AyCMIixa5C7BBqU-XFI7l7IaUFJ4zQZPmcK6oNb3FLo',
|
7
7
|
:key => 'jane@gmail.com')
|
8
8
|
@credential.user = users(:jane)
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
test 'setup' do
|
12
12
|
assert @credential.valid?
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
15
|
test 'code required' do
|
16
16
|
@credential.code = nil
|
17
17
|
assert !@credential.valid?
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
test 'code uniqueness' do
|
21
21
|
@credential.code = credentials(:john_token).code
|
22
22
|
assert !@credential.valid?
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
test 'email required' do
|
26
26
|
@credential.email = nil
|
27
27
|
assert !@credential.valid?
|
@@ -31,22 +31,22 @@ class EmailVerificationTokenCredentialTest < ActiveSupport::TestCase
|
|
31
31
|
@credential.user = nil
|
32
32
|
assert !@credential.valid?
|
33
33
|
end
|
34
|
-
|
34
|
+
|
35
35
|
test 'email_credential' do
|
36
36
|
assert_equal credentials(:jane_email), @credential.email_credential
|
37
37
|
assert_equal credentials(:john_email),
|
38
38
|
credentials(:john_email_token).email_credential
|
39
|
-
|
39
|
+
|
40
40
|
@credential.email = 'bill@gmail.com'
|
41
41
|
assert_nil @credential.email_credential
|
42
42
|
end
|
43
|
-
|
43
|
+
|
44
44
|
test 'spend verifies the e-mail and destroys the token' do
|
45
45
|
email_credential = credentials(:john_email)
|
46
46
|
assert !email_credential.verified, 'bad setup'
|
47
47
|
credential = credentials(:john_email_token)
|
48
48
|
assert_equal Tokens::EmailVerification, credential.class, 'bad setup'
|
49
|
-
|
49
|
+
|
50
50
|
assert_difference 'Credential.count', -1 do
|
51
51
|
credential.spend
|
52
52
|
end
|
@@ -58,14 +58,14 @@ class EmailVerificationTokenCredentialTest < ActiveSupport::TestCase
|
|
58
58
|
email_credential = credentials(:john_email)
|
59
59
|
credential = credentials(:john_email_token)
|
60
60
|
credential.email = 'bill@gmail.com'
|
61
|
-
|
61
|
+
|
62
62
|
assert_difference 'Credential.count', -1 do
|
63
63
|
credential.spend
|
64
64
|
end
|
65
65
|
assert credential.frozen?, 'not destroyed'
|
66
66
|
assert !email_credential.reload.verified?, 'e-mail wrongly verified'
|
67
67
|
end
|
68
|
-
|
68
|
+
|
69
69
|
test 'random_for' do
|
70
70
|
token = Tokens::EmailVerification.random_for credentials(:jane_email)
|
71
71
|
assert token.valid?, 'valid token'
|
@@ -1,61 +1,80 @@
|
|
1
1
|
require File.expand_path('../../test_helper', __FILE__)
|
2
2
|
|
3
|
-
class PasswordCredentialTest < ActiveSupport::TestCase
|
3
|
+
class PasswordCredentialTest < ActiveSupport::TestCase
|
4
4
|
def setup
|
5
5
|
@credential = Credentials::Password.new :password => 'awesome',
|
6
6
|
:password_confirmation => 'awesome'
|
7
7
|
@credential.user = users(:bill)
|
8
|
+
@_password_expires = Credentials::Password.expires_after
|
8
9
|
end
|
9
|
-
|
10
|
+
|
11
|
+
def teardown
|
12
|
+
Credentials::Password.expires_after = @_password_expires
|
13
|
+
end
|
14
|
+
|
10
15
|
test 'setup' do
|
11
16
|
assert @credential.valid?
|
12
17
|
end
|
13
|
-
|
18
|
+
|
14
19
|
test 'key not required' do
|
15
20
|
@credential.key = nil
|
16
21
|
assert @credential.valid?
|
17
22
|
end
|
18
|
-
|
23
|
+
|
19
24
|
test 'user presence' do
|
20
25
|
@credential.user = nil
|
21
26
|
assert !@credential.valid?
|
22
27
|
end
|
23
|
-
|
28
|
+
|
24
29
|
test 'user uniqueness' do
|
25
30
|
@credential.user = users(:john)
|
26
31
|
assert !@credential.valid?
|
27
32
|
end
|
28
|
-
|
33
|
+
|
29
34
|
test 'password confirmation' do
|
30
35
|
@credential.password_confirmation = 'not awesome'
|
31
36
|
assert !@credential.valid?
|
32
37
|
end
|
33
|
-
|
38
|
+
|
34
39
|
test 'password required' do
|
35
40
|
@credential.password = @credential.password_confirmation = nil
|
36
41
|
assert !@credential.valid?
|
37
42
|
end
|
38
|
-
|
43
|
+
|
39
44
|
test 'check_password' do
|
40
45
|
assert_equal true, @credential.check_password('awesome')
|
41
46
|
assert_equal false, @credential.check_password('not awesome'),
|
42
47
|
'Bogus password'
|
43
48
|
assert_equal false, @credential.check_password('password'),
|
44
|
-
"Another user's password"
|
49
|
+
"Another user's password"
|
50
|
+
end
|
51
|
+
|
52
|
+
test 'expired?' do
|
53
|
+
@credential.updated_at = Time.now
|
54
|
+
assert_equal false, @credential.expired?
|
55
|
+
@credential.updated_at = Time.now - 2.years
|
56
|
+
assert_equal true, @credential.expired?
|
57
|
+
Credentials::Password.expires_after = nil
|
58
|
+
assert_equal false, @credential.expired?
|
45
59
|
end
|
46
|
-
|
60
|
+
|
47
61
|
test 'authenticate' do
|
62
|
+
@credential.updated_at = Time.now
|
48
63
|
assert_equal users(:bill), @credential.authenticate('awesome')
|
49
64
|
assert_equal :invalid, @credential.authenticate('not awesome')
|
65
|
+
Credentials::Password.expires_after = 1.month
|
66
|
+
@credential.updated_at = Time.now - 1.year
|
67
|
+
assert_equal :expired, @credential.authenticate('awesome')
|
50
68
|
end
|
51
|
-
|
69
|
+
|
52
70
|
test 'authenticate calls User#auth_bounce_reason' do
|
53
71
|
user = @credential.user
|
54
72
|
flexmock(user).should_receive(:auth_bounce_reason).and_return(:reason)
|
73
|
+
@credential.updated_at = Time.now
|
55
74
|
assert_equal :reason, @credential.authenticate('awesome')
|
56
75
|
assert_equal :invalid, @credential.authenticate('not awesome')
|
57
76
|
end
|
58
|
-
|
77
|
+
|
59
78
|
test 'authenticate_email' do
|
60
79
|
assert_equal users(:john),
|
61
80
|
Credentials::Password.authenticate_email('john@gmail.com', 'password')
|