##// END OF EJS Templates
Keep track of valid user sessions (#21058)....
Jean-Philippe Lang -
r14353:4cd22dcc5595
parent child
Show More
@@ -0,0 +1,10
1 class AddTokensUpdatedOn < ActiveRecord::Migration
2 def self.up
3 add_column :tokens, :updated_on, :timestamp
4 Token.update_all("updated_on = created_on")
5 end
6
7 def self.down
8 remove_column :tokens, :updated_on
9 end
10 end
@@ -0,0 +1,97
1 # Redmine - project management software
2 # Copyright (C) 2006-2015 Jean-Philippe Lang
3 #
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
18 require File.expand_path('../../test_helper', __FILE__)
19
20 class SessionsTest < Redmine::IntegrationTest
21 fixtures :users, :email_addresses, :roles
22
23 def setup
24 Rails.application.config.redmine_verify_sessions = true
25 end
26
27 def teardown
28 Rails.application.config.redmine_verify_sessions = false
29 end
30
31 def test_change_password_kills_sessions
32 log_user('jsmith', 'jsmith')
33
34 jsmith = User.find(2)
35 jsmith.password = "somenewpassword"
36 jsmith.save!
37
38 get '/my/account'
39 assert_response 302
40 assert flash[:error].match(/Your session has expired/)
41 end
42
43 def test_lock_user_kills_sessions
44 log_user('jsmith', 'jsmith')
45
46 jsmith = User.find(2)
47 assert jsmith.lock!
48 assert jsmith.activate!
49
50 get '/my/account'
51 assert_response 302
52 assert flash[:error].match(/Your session has expired/)
53 end
54
55 def test_update_user_does_not_kill_sessions
56 log_user('jsmith', 'jsmith')
57
58 jsmith = User.find(2)
59 jsmith.firstname = 'Robert'
60 jsmith.save!
61
62 get '/my/account'
63 assert_response 200
64 end
65
66 def test_change_password_generates_a_new_token_for_current_session
67 log_user('jsmith', 'jsmith')
68 assert_not_nil token = session[:tk]
69
70 get '/my/password'
71 assert_response 200
72 post '/my/password', :password => 'jsmith',
73 :new_password => 'secret123',
74 :new_password_confirmation => 'secret123'
75 assert_response 302
76 assert_not_equal token, session[:tk]
77
78 get '/my/account'
79 assert_response 200
80 end
81
82 def test_simultaneous_sessions_should_be_valid
83 first = open_session do |session|
84 session.post "/login", :username => 'jsmith', :password => 'jsmith'
85 end
86 other = open_session do |session|
87 session.post "/login", :username => 'jsmith', :password => 'jsmith'
88 end
89
90 first.get '/my/account'
91 assert_equal 200, first.response.response_code
92 first.post '/logout'
93
94 other.get '/my/account'
95 assert_equal 200, other.response.response_code
96 end
97 end
@@ -51,7 +51,7 class ApplicationController < ActionController::Base
51 end
51 end
52 end
52 end
53
53
54 before_filter :session_expiration, :user_setup, :force_logout_if_password_changed, :check_if_login_required, :check_password_change, :set_localization
54 before_filter :session_expiration, :user_setup, :check_if_login_required, :check_password_change, :set_localization
55
55
56 rescue_from ::Unauthorized, :with => :deny_access
56 rescue_from ::Unauthorized, :with => :deny_access
57 rescue_from ::ActionView::MissingTemplate, :with => :missing_template
57 rescue_from ::ActionView::MissingTemplate, :with => :missing_template
@@ -63,36 +63,23 class ApplicationController < ActionController::Base
63 include Redmine::SudoMode::Controller
63 include Redmine::SudoMode::Controller
64
64
65 def session_expiration
65 def session_expiration
66 if session[:user_id]
66 if session[:user_id] && Rails.application.config.redmine_verify_sessions != false
67 if session_expired? && !try_to_autologin
67 if session_expired? && !try_to_autologin
68 set_localization(User.active.find_by_id(session[:user_id]))
68 set_localization(User.active.find_by_id(session[:user_id]))
69 self.logged_user = nil
69 self.logged_user = nil
70 flash[:error] = l(:error_session_expired)
70 flash[:error] = l(:error_session_expired)
71 require_login
71 require_login
72 else
73 session[:atime] = Time.now.utc.to_i
74 end
72 end
75 end
73 end
76 end
74 end
77
75
78 def session_expired?
76 def session_expired?
79 if Setting.session_lifetime?
77 ! User.verify_session_token(session[:user_id], session[:tk])
80 unless session[:ctime] && (Time.now.utc.to_i - session[:ctime].to_i <= Setting.session_lifetime.to_i * 60)
81 return true
82 end
83 end
84 if Setting.session_timeout?
85 unless session[:atime] && (Time.now.utc.to_i - session[:atime].to_i <= Setting.session_timeout.to_i * 60)
86 return true
87 end
88 end
89 false
90 end
78 end
91
79
92 def start_user_session(user)
80 def start_user_session(user)
93 session[:user_id] = user.id
81 session[:user_id] = user.id
94 session[:ctime] = Time.now.utc.to_i
82 session[:tk] = user.generate_session_token
95 session[:atime] = Time.now.utc.to_i
96 if user.must_change_password?
83 if user.must_change_password?
97 session[:pwd] = '1'
84 session[:pwd] = '1'
98 end
85 end
@@ -149,18 +136,6 class ApplicationController < ActionController::Base
149 user
136 user
150 end
137 end
151
138
152 def force_logout_if_password_changed
153 passwd_changed_on = User.current.passwd_changed_on || Time.at(0)
154 # Make sure we force logout only for web browser sessions, not API calls
155 # if the password was changed after the session creation.
156 if session[:user_id] && passwd_changed_on.utc.to_i > session[:ctime].to_i
157 reset_session
158 set_localization
159 flash[:error] = l(:error_session_expired)
160 redirect_to signin_url
161 end
162 end
163
164 def autologin_cookie_name
139 def autologin_cookie_name
165 Redmine::Configuration['autologin_cookie_name'].presence || 'autologin'
140 Redmine::Configuration['autologin_cookie_name'].presence || 'autologin'
166 end
141 end
@@ -193,6 +168,7 class ApplicationController < ActionController::Base
193 if User.current.logged?
168 if User.current.logged?
194 cookies.delete(autologin_cookie_name)
169 cookies.delete(autologin_cookie_name)
195 Token.delete_all(["user_id = ? AND action = ?", User.current.id, 'autologin'])
170 Token.delete_all(["user_id = ? AND action = ?", User.current.id, 'autologin'])
171 Token.delete_all(["user_id = ? AND action = ? AND value = ?", User.current.id, 'session', session[:tk]])
196 self.logged_user = nil
172 self.logged_user = nil
197 end
173 end
198 end
174 end
@@ -103,9 +103,8 class MyController < ApplicationController
103 @user.password, @user.password_confirmation = params[:new_password], params[:new_password_confirmation]
103 @user.password, @user.password_confirmation = params[:new_password], params[:new_password_confirmation]
104 @user.must_change_passwd = false
104 @user.must_change_passwd = false
105 if @user.save
105 if @user.save
106 # Reset the session creation time to not log out this session on next
106 # The session token was destroyed by the password change, generate a new one
107 # request due to ApplicationController#force_logout_if_password_changed
107 session[:tk] = @user.generate_session_token
108 session[:ctime] = User.current.passwd_changed_on.utc.to_i
109 flash[:notice] = l(:notice_account_password_updated)
108 flash[:notice] = l(:notice_account_password_updated)
110 redirect_to my_account_path
109 redirect_to my_account_path
111 end
110 end
@@ -36,7 +36,7 class Token < ActiveRecord::Base
36
36
37 # Delete all expired tokens
37 # Delete all expired tokens
38 def self.destroy_expired
38 def self.destroy_expired
39 Token.where("action NOT IN (?) AND created_on < ?", ['feeds', 'api'], Time.now - validity_time).delete_all
39 Token.where("action NOT IN (?) AND created_on < ?", ['feeds', 'api', 'session'], Time.now - validity_time).delete_all
40 end
40 end
41
41
42 # Returns the active user who owns the key for the given action
42 # Returns the active user who owns the key for the given action
@@ -79,7 +79,15 class Token < ActiveRecord::Base
79 # Removes obsolete tokens (same user and action)
79 # Removes obsolete tokens (same user and action)
80 def delete_previous_tokens
80 def delete_previous_tokens
81 if user
81 if user
82 Token.where(:user_id => user.id, :action => action).delete_all
82 scope = Token.where(:user_id => user.id, :action => action)
83 if action == 'session'
84 ids = scope.order(:updated_on => :desc).offset(9).ids
85 if ids.any?
86 Token.delete(ids)
87 end
88 else
89 scope.delete_all
90 end
83 end
91 end
84 end
92 end
85 end
93 end
@@ -394,6 +394,26 class User < Principal
394 api_token.value
394 api_token.value
395 end
395 end
396
396
397 # Generates a new session token and returns its value
398 def generate_session_token
399 token = Token.create!(:user_id => id, :action => 'session')
400 token.value
401 end
402
403 # Returns true if token is a valid session token for the user whose id is user_id
404 def self.verify_session_token(user_id, token)
405 return false if user_id.blank? || token.blank?
406
407 scope = Token.where(:user_id => user_id, :value => token.to_s, :action => 'session')
408 if Setting.session_lifetime?
409 scope = scope.where("created_on > ?", Setting.session_lifetime.to_i.minutes.ago)
410 end
411 if Setting.session_timeout?
412 scope = scope.where("updated_on > ?", Setting.session_timeout.to_i.minutes.ago)
413 end
414 scope.update_all(:updated_on => Time.now) == 1
415 end
416
397 # Return an array of project ids for which the user has explicitly turned mail notifications on
417 # Return an array of project ids for which the user has explicitly turned mail notifications on
398 def notified_projects_ids
418 def notified_projects_ids
399 @notified_projects_ids ||= memberships.select {|m| m.mail_notification?}.collect(&:project_id)
419 @notified_projects_ids ||= memberships.select {|m| m.mail_notification?}.collect(&:project_id)
@@ -764,8 +784,8 class User < Principal
764 # This helps to keep the account secure in case the associated email account
784 # This helps to keep the account secure in case the associated email account
765 # was compromised.
785 # was compromised.
766 def destroy_tokens
786 def destroy_tokens
767 if hashed_password_changed?
787 if hashed_password_changed? || (status_changed? && !active?)
768 tokens = ['recovery', 'autologin']
788 tokens = ['recovery', 'autologin', 'session']
769 Token.where(:user_id => id, :action => tokens).delete_all
789 Token.where(:user_id => id, :action => tokens).delete_all
770 end
790 end
771 end
791 end
@@ -26,6 +26,9 Rails.application.configure do
26 # Disable request forgery protection in test environment.
26 # Disable request forgery protection in test environment.
27 config.action_controller.allow_forgery_protection = false
27 config.action_controller.allow_forgery_protection = false
28
28
29 # Disable sessions verifications in test environment.
30 config.redmine_verify_sessions = false
31
29 # Print deprecation notices to stderr and the Rails logger.
32 # Print deprecation notices to stderr and the Rails logger.
30 config.active_support.deprecation = [:stderr, :log]
33 config.active_support.deprecation = [:stderr, :log]
31
34
@@ -185,18 +185,6 class MyControllerTest < ActionController::TestCase
185 assert User.try_to_login('jsmith', 'secret123')
185 assert User.try_to_login('jsmith', 'secret123')
186 end
186 end
187
187
188 def test_change_password_kills_other_sessions
189 @request.session[:ctime] = (Time.now - 30.minutes).utc.to_i
190
191 jsmith = User.find(2)
192 jsmith.passwd_changed_on = Time.now
193 jsmith.save!
194
195 get 'account'
196 assert_response 302
197 assert flash[:error].match(/Your session has expired/)
198 end
199
200 def test_change_password_should_redirect_if_user_cannot_change_its_password
188 def test_change_password_should_redirect_if_user_cannot_change_its_password
201 User.find(2).update_attribute(:auth_source_id, 1)
189 User.find(2).update_attribute(:auth_source_id, 1)
202
190
@@ -17,95 +17,99
17
17
18 require File.expand_path('../../test_helper', __FILE__)
18 require File.expand_path('../../test_helper', __FILE__)
19
19
20 class SessionStartTest < ActionController::TestCase
20 class SessionsControllerTest < ActionController::TestCase
21 tests AccountController
21 include Redmine::I18n
22 tests WelcomeController
22
23
23 fixtures :users
24 fixtures :users, :email_addresses
24
25
25 def test_login_should_set_session_timestamps
26 def setup
26 post :login, :username => 'jsmith', :password => 'jsmith'
27 Rails.application.config.redmine_verify_sessions = true
27 assert_response 302
28 assert_equal 2, session[:user_id]
29 assert_not_nil session[:ctime]
30 assert_not_nil session[:atime]
31 end
28 end
32 end
33
29
34 class SessionsTest < ActionController::TestCase
30 def teardown
35 include Redmine::I18n
31 Rails.application.config.redmine_verify_sessions = false
36 tests WelcomeController
32 end
37
33
38 fixtures :users, :email_addresses
34 def test_session_token_should_be_updated
35 created = 10.hours.ago
36 token = Token.create!(:user_id => 2, :action => 'session', :created_on => created, :updated_on => created)
39
37
40 def test_atime_from_user_session_should_be_updated
38 get :index, {}, {:user_id => 2, :tk => token.value}
41 created = 2.hours.ago.utc.to_i
42 get :index, {}, {:user_id => 2, :ctime => created, :atime => created}
43 assert_response :success
39 assert_response :success
44 assert_equal created, session[:ctime]
40 token.reload
45 assert_not_equal created, session[:atime]
41 assert_equal created, token.created_on
46 assert session[:atime] > created
42 assert_not_equal created, token.updated_on
43 assert token.updated_on > created
47 end
44 end
48
45
49 def test_user_session_should_not_be_reset_if_lifetime_and_timeout_disabled
46 def test_user_session_should_not_be_reset_if_lifetime_and_timeout_disabled
47 created = 2.years.ago
48 token = Token.create!(:user_id => 2, :action => 'session', :created_on => created, :updated_on => created)
49
50 with_settings :session_lifetime => '0', :session_timeout => '0' do
50 with_settings :session_lifetime => '0', :session_timeout => '0' do
51 get :index, {}, {:user_id => 2}
51 get :index, {}, {:user_id => 2, :tk => token.value}
52 assert_response :success
52 assert_response :success
53 end
53 end
54 end
54 end
55
55
56 def test_user_session_without_ctime_should_be_reset_if_lifetime_enabled
56 def test_user_session_without_token_should_be_reset
57 with_settings :session_lifetime => '720' do
57 get :index, {}, {:user_id => 2}
58 get :index, {}, {:user_id => 2}
58 assert_redirected_to 'http://test.host/login?back_url=http%3A%2F%2Ftest.host%2F'
59 assert_redirected_to 'http://test.host/login?back_url=http%3A%2F%2Ftest.host%2F'
60 end
61 end
59 end
62
60
63 def test_user_session_with_expired_ctime_should_be_reset_if_lifetime_enabled
61 def test_expired_user_session_should_be_reset_if_lifetime_enabled
62 created = 2.days.ago
63 token = Token.create!(:user_id => 2, :action => 'session', :created_on => created, :updated_on => created)
64
64 with_settings :session_timeout => '720' do
65 with_settings :session_timeout => '720' do
65 get :index, {}, {:user_id => 2, :atime => 2.days.ago.utc.to_i}
66 get :index, {}, {:user_id => 2, :tk => token.value}
66 assert_redirected_to 'http://test.host/login?back_url=http%3A%2F%2Ftest.host%2F'
67 assert_redirected_to 'http://test.host/login?back_url=http%3A%2F%2Ftest.host%2F'
67 end
68 end
68 end
69 end
69
70
70 def test_user_session_with_valid_ctime_should_not_be_reset_if_lifetime_enabled
71 def test_valid_user_session_should_not_be_reset_if_lifetime_enabled
72 created = 3.hours.ago
73 token = Token.create!(:user_id => 2, :action => 'session', :created_on => created, :updated_on => created)
74
71 with_settings :session_timeout => '720' do
75 with_settings :session_timeout => '720' do
72 get :index, {}, {:user_id => 2, :atime => 3.hours.ago.utc.to_i}
76 get :index, {}, {:user_id => 2, :tk => token.value}
73 assert_response :success
77 assert_response :success
74 end
78 end
75 end
79 end
76
80
77 def test_user_session_without_atime_should_be_reset_if_timeout_enabled
81 def test_expired_user_session_should_be_reset_if_timeout_enabled
78 with_settings :session_timeout => '60' do
82 created = 4.hours.ago
79 get :index, {}, {:user_id => 2}
83 token = Token.create!(:user_id => 2, :action => 'session', :created_on => created, :updated_on => created)
80 assert_redirected_to 'http://test.host/login?back_url=http%3A%2F%2Ftest.host%2F'
81 end
82 end
83
84
84 def test_user_session_with_expired_atime_should_be_reset_if_timeout_enabled
85 with_settings :session_timeout => '60' do
85 with_settings :session_timeout => '60' do
86 get :index, {}, {:user_id => 2, :atime => 4.hours.ago.utc.to_i}
86 get :index, {}, {:user_id => 2, :tk => token.value}
87 assert_redirected_to 'http://test.host/login?back_url=http%3A%2F%2Ftest.host%2F'
87 assert_redirected_to 'http://test.host/login?back_url=http%3A%2F%2Ftest.host%2F'
88 end
88 end
89 end
89 end
90
90
91 def test_user_session_with_valid_atime_should_not_be_reset_if_timeout_enabled
91 def test_valid_user_session_should_not_be_reset_if_timeout_enabled
92 created = 10.minutes.ago
93 token = Token.create!(:user_id => 2, :action => 'session', :created_on => created, :updated_on => created)
94
92 with_settings :session_timeout => '60' do
95 with_settings :session_timeout => '60' do
93 get :index, {}, {:user_id => 2, :atime => 10.minutes.ago.utc.to_i}
96 get :index, {}, {:user_id => 2, :tk => token.value}
94 assert_response :success
97 assert_response :success
95 end
98 end
96 end
99 end
97
100
98 def test_expired_user_session_should_be_restarted_if_autologin
101 def test_expired_user_session_should_be_restarted_if_autologin
102 created = 2.hours.ago
103 token = Token.create!(:user_id => 2, :action => 'session', :created_on => created, :updated_on => created)
104
99 with_settings :session_lifetime => '720', :session_timeout => '60', :autologin => 7 do
105 with_settings :session_lifetime => '720', :session_timeout => '60', :autologin => 7 do
100 token = Token.create!(:user_id => 2, :action => 'autologin', :created_on => 1.day.ago)
106 autologin_token = Token.create!(:user_id => 2, :action => 'autologin', :created_on => 1.day.ago)
101 @request.cookies['autologin'] = token.value
107 @request.cookies['autologin'] = autologin_token.value
102 created = 2.hours.ago.utc.to_i
103
108
104 get :index, {}, {:user_id => 2, :ctime => created, :atime => created}
109 get :index, {}, {:user_id => 2, :tk => token.value}
105 assert_equal 2, session[:user_id]
110 assert_equal 2, session[:user_id]
106 assert_response :success
111 assert_response :success
107 assert_not_equal created, session[:ctime]
112 assert_not_equal token.value, session[:tk]
108 assert session[:ctime] >= created
109 end
113 end
110 end
114 end
111
115
@@ -114,9 +118,11 class SessionsTest < ActionController::TestCase
114 user = User.find(2)
118 user = User.find(2)
115 user.language = 'fr'
119 user.language = 'fr'
116 user.save!
120 user.save!
121 created = 4.hours.ago
122 token = Token.create!(:user_id => 2, :action => 'session', :created_on => created, :updated_on => created)
117
123
118 with_settings :session_timeout => '60' do
124 with_settings :session_timeout => '60' do
119 get :index, {}, {:user_id => user.id, :atime => 4.hours.ago.utc.to_i}
125 get :index, {}, {:user_id => user.id, :tk => token.value}
120 assert_redirected_to 'http://test.host/login?back_url=http%3A%2F%2Ftest.host%2F'
126 assert_redirected_to 'http://test.host/login?back_url=http%3A%2F%2Ftest.host%2F'
121 assert_include "Veuillez vous reconnecter", flash[:error]
127 assert_include "Veuillez vous reconnecter", flash[:error]
122 assert_equal :fr, current_language
128 assert_equal :fr, current_language
@@ -30,35 +30,47 class AccountTest < Redmine::IntegrationTest
30 assert_template "my/account"
30 assert_template "my/account"
31 end
31 end
32
32
33 def test_login_should_set_session_token
34 assert_difference 'Token.count' do
35 log_user('jsmith', 'jsmith')
36
37 assert_equal 2, session[:user_id]
38 assert_not_nil session[:tk]
39 end
40 end
41
33 def test_autologin
42 def test_autologin
34 user = User.find(1)
43 user = User.find(1)
35 Setting.autologin = "7"
36 Token.delete_all
44 Token.delete_all
37
45
38 # User logs in with 'autologin' checked
46 with_settings :autologin => '7' do
39 post '/login', :username => user.login, :password => 'admin', :autologin => 1
47 assert_difference 'Token.count', 2 do
40 assert_redirected_to '/my/page'
48 # User logs in with 'autologin' checked
41 token = Token.first
49 post '/login', :username => user.login, :password => 'admin', :autologin => 1
42 assert_not_nil token
50 assert_redirected_to '/my/page'
43 assert_equal user, token.user
51 end
44 assert_equal 'autologin', token.action
52 token = Token.where(:action => 'autologin').order(:id => :desc).first
45 assert_equal user.id, session[:user_id]
53 assert_not_nil token
46 assert_equal token.value, cookies['autologin']
54 assert_equal user, token.user
47
55 assert_equal 'autologin', token.action
48 # Session is cleared
56 assert_equal user.id, session[:user_id]
49 reset!
57 assert_equal token.value, cookies['autologin']
50 User.current = nil
58
51 # Clears user's last login timestamp
59 # Session is cleared
52 user.update_attribute :last_login_on, nil
60 reset!
53 assert_nil user.reload.last_login_on
61 User.current = nil
54
62 # Clears user's last login timestamp
55 # User comes back with user's autologin cookie
63 user.update_attribute :last_login_on, nil
56 cookies[:autologin] = token.value
64 assert_nil user.reload.last_login_on
57 get '/my/page'
65
58 assert_response :success
66 # User comes back with user's autologin cookie
59 assert_template 'my/page'
67 cookies[:autologin] = token.value
60 assert_equal user.id, session[:user_id]
68 get '/my/page'
61 assert_not_nil user.reload.last_login_on
69 assert_response :success
70 assert_template 'my/page'
71 assert_equal user.id, session[:user_id]
72 assert_not_nil user.reload.last_login_on
73 end
62 end
74 end
63
75
64 def test_autologin_should_use_autologin_cookie_name
76 def test_autologin_should_use_autologin_cookie_name
@@ -69,7 +81,7 class AccountTest < Redmine::IntegrationTest
69 Redmine::Configuration.stubs(:[]).with('sudo_mode_timeout').returns(15)
81 Redmine::Configuration.stubs(:[]).with('sudo_mode_timeout').returns(15)
70
82
71 with_settings :autologin => '7' do
83 with_settings :autologin => '7' do
72 assert_difference 'Token.count' do
84 assert_difference 'Token.count', 2 do
73 post '/login', :username => 'admin', :password => 'admin', :autologin => 1
85 post '/login', :username => 'admin', :password => 'admin', :autologin => 1
74 assert_response 302
86 assert_response 302
75 end
87 end
@@ -82,7 +94,7 class AccountTest < Redmine::IntegrationTest
82 get '/my/page'
94 get '/my/page'
83 assert_response :success
95 assert_response :success
84
96
85 assert_difference 'Token.count', -1 do
97 assert_difference 'Token.count', -2 do
86 post '/logout'
98 post '/logout'
87 end
99 end
88 assert cookies['custom_autologin'].blank?
100 assert cookies['custom_autologin'].blank?
@@ -119,7 +131,7 class AccountTest < Redmine::IntegrationTest
119 assert_equal 'Password was successfully updated.', flash[:notice]
131 assert_equal 'Password was successfully updated.', flash[:notice]
120
132
121 log_user('jsmith', 'newpass123')
133 log_user('jsmith', 'newpass123')
122 assert_equal 0, Token.count
134 assert_equal false, Token.exists?(token.id), "Password recovery token was not deleted"
123 end
135 end
124
136
125 def test_user_with_must_change_passwd_should_be_forced_to_change_its_password
137 def test_user_with_must_change_passwd_should_be_forced_to_change_its_password
@@ -36,6 +36,19 class TokenTest < ActiveSupport::TestCase
36 assert Token.exists?(t2.id)
36 assert Token.exists?(t2.id)
37 end
37 end
38
38
39 def test_create_session_token_should_keep_last_10_tokens
40 Token.delete_all
41 user = User.find(1)
42
43 assert_difference 'Token.count', 10 do
44 10.times { Token.create!(:user => user, :action => 'session') }
45 end
46
47 assert_no_difference 'Token.count' do
48 Token.create!(:user => user, :action => 'session')
49 end
50 end
51
39 def test_destroy_expired_should_not_destroy_feeds_and_api_tokens
52 def test_destroy_expired_should_not_destroy_feeds_and_api_tokens
40 Token.delete_all
53 Token.delete_all
41
54
General Comments 0
You need to be logged in to leave comments. Login now