diff options
author | Sean McGivern <sean@gitlab.com> | 2016-05-03 14:42:55 +0300 |
---|---|---|
committer | Sean McGivern <sean@gitlab.com> | 2016-05-16 11:21:24 +0300 |
commit | bec350528cdc81e26476780f1ca3db8171b3ece8 (patch) | |
tree | 31e273cd2202ad4e2647d127d464dd1c31b52ded | |
parent | 78a67fc48dab434b43a080e5b15491963656661a (diff) |
Force password change after admin reset
When an admin changes a user's password for them, force the user to
reset the password after logging in by expiring the new password
immediately.
-rw-r--r-- | CHANGELOG | 1 | ||||
-rw-r--r-- | app/controllers/admin/users_controller.rb | 1 | ||||
-rw-r--r-- | spec/controllers/admin/users_controller_spec.rb | 76 | ||||
-rw-r--r-- | spec/features/admin/admin_users_spec.rb | 3 |
4 files changed, 81 insertions, 0 deletions
diff --git a/CHANGELOG b/CHANGELOG index ca59f488e0f..02b94e5a0b7 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -28,6 +28,7 @@ v 8.8.0 (unreleased) - Display informative message when new milestone is created - Sanitize milestones and labels titles - Support multi-line tag messages. !3833 (Calin Seciu) + - Force users to reset their password after an admin changes it - Allow "NEWS" and "CHANGES" as alternative names for CHANGELOG. !3768 (Connor Shea) - Added button to toggle whitespaces changes on diff view - Backport GitHub Enterprise import support from EE diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb index f2f654c7bcd..6908a3bf946 100644 --- a/app/controllers/admin/users_controller.rb +++ b/app/controllers/admin/users_controller.rb @@ -119,6 +119,7 @@ class Admin::UsersController < Admin::ApplicationController user_params_with_pass.merge!( password: params[:user][:password], password_confirmation: params[:user][:password_confirmation], + password_expires_at: Time.now ) end diff --git a/spec/controllers/admin/users_controller_spec.rb b/spec/controllers/admin/users_controller_spec.rb index ce2a62ae1fd..6caf37ddc2c 100644 --- a/spec/controllers/admin/users_controller_spec.rb +++ b/spec/controllers/admin/users_controller_spec.rb @@ -114,6 +114,82 @@ describe Admin::UsersController do end end + describe 'POST update' do + context 'when the password has changed' do + def update_password(user, password, password_confirmation = nil) + params = { + id: user.to_param, + user: { + password: password, + password_confirmation: password_confirmation || password + } + } + + post :update, params + end + + context 'when the new password is valid' do + it 'redirects to the user' do + update_password(user, 'AValidPassword1') + + expect(response).to redirect_to(admin_user_path(user)) + end + + it 'updates the password' do + update_password(user, 'AValidPassword1') + + expect { user.reload }.to change { user.encrypted_password } + end + + it 'sets the new password to expire immediately' do + update_password(user, 'AValidPassword1') + + expect { user.reload }.to change { user.password_expires_at }.to(a_value <= Time.now) + end + end + + context 'when the new password is invalid' do + it 'shows the edit page again' do + update_password(user, 'invalid') + + expect(response).to render_template(:edit) + end + + it 'returns the error message' do + update_password(user, 'invalid') + + expect(assigns[:user].errors).to contain_exactly(a_string_matching(/too short/)) + end + + it 'does not update the password' do + update_password(user, 'invalid') + + expect { user.reload }.not_to change { user.encrypted_password } + end + end + + context 'when the new password does not match the password confirmation' do + it 'shows the edit page again' do + update_password(user, 'AValidPassword1', 'AValidPassword2') + + expect(response).to render_template(:edit) + end + + it 'returns the error message' do + update_password(user, 'AValidPassword1', 'AValidPassword2') + + expect(assigns[:user].errors).to contain_exactly(a_string_matching(/doesn't match/)) + end + + it 'does not update the password' do + update_password(user, 'AValidPassword1', 'AValidPassword2') + + expect { user.reload }.not_to change { user.encrypted_password } + end + end + end + end + describe "POST impersonate" do context "when the user is blocked" do before do diff --git a/spec/features/admin/admin_users_spec.rb b/spec/features/admin/admin_users_spec.rb index 4570e409128..6dee0cd8d47 100644 --- a/spec/features/admin/admin_users_spec.rb +++ b/spec/features/admin/admin_users_spec.rb @@ -210,6 +210,8 @@ describe "Admin::Users", feature: true do before do fill_in "user_name", with: "Big Bang" fill_in "user_email", with: "bigbang@mail.com" + fill_in "user_password", with: "AValidPassword1" + fill_in "user_password_confirmation", with: "AValidPassword1" check "user_admin" click_button "Save changes" end @@ -223,6 +225,7 @@ describe "Admin::Users", feature: true do @simple_user.reload expect(@simple_user.name).to eq('Big Bang') expect(@simple_user.is_admin?).to be_truthy + expect(@simple_user.password_expires_at).to be <= Time.now end end end |