From 72d7191b9f80206516077ae8d7dcf81e73f46a66 Mon Sep 17 00:00:00 2001 From: Andrej Shadura <andrew.shadura@collabora.co.uk> Date: Tue, 15 Jun 2021 14:32:30 +0200 Subject: [PATCH] Mark passwords for SSO-only users as invalid to allow changing them later MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a new "hash type" for invalid passwords, which is never equal to normal passwords, but nevertheless can be changed without being known by the user. This "invalid" password can only be set by directly setting the password hash type. When updating the password using update_password method, it will always be upgrade it to the strongest hash type, sha256crypt. To allow changing this "invalid" password to a normal one, stop requiring a non-empty current password in the password change dialog when changing a password from an "invalid" one. Don’t show the current password box either, as it is not used anyway in this case, making it better not to show it to avoid confusion. Signed-off-by: Andrej Shadura <andrew.shadura@collabora.co.uk> Gbp-Pq: Topic collabora/sso Gbp-Pq: Name Mark-passwords-for-SSO-only-users-as-invalid-to-allow-cha.patch --- src/api/app/controllers/webui/user_controller.rb | 2 +- src/api/app/models/user.rb | 13 +++++++++++-- .../app/views/webui/user/_password_dialog.html.erb | 2 ++ 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/api/app/controllers/webui/user_controller.rb b/src/api/app/controllers/webui/user_controller.rb index 6fc44ebb59..cbb86da090 100644 --- a/src/api/app/controllers/webui/user_controller.rb +++ b/src/api/app/controllers/webui/user_controller.rb @@ -217,7 +217,7 @@ class Webui::UserController < Webui::WebuiController def change_password # check the valid of the params - unless User.current.password_equals?(params[:password]) + unless User.current.password_equals?(params[:password]) || User.current.password_invalid? errmsg = 'The value of current password does not match your current password. Please enter the password and try again.' end if not params[:new_password] == params[:repeat_password] diff --git a/src/api/app/models/user.rb b/src/api/app/models/user.rb index 4e0f71a7a7..c2851a38ea 100644 --- a/src/api/app/models/user.rb +++ b/src/api/app/models/user.rb @@ -23,7 +23,7 @@ class User < ActiveRecord::Base include ActiveModel::Dirty include CanRenderModel - PASSWORD_HASH_TYPES = ['md5', 'md5crypt', 'sha256crypt'] + PASSWORD_HASH_TYPES = ['md5', 'md5crypt', 'sha256crypt', 'invalid'] STATES = { 'unconfirmed' => 1, @@ -131,6 +131,9 @@ class User < ActiveRecord::Base # def update_password(pass) password_will_change! + if password_invalid? + self.password_hash_type = 'sha256crypt' + end self.password_crypted = hash_string(pass).crypt('os') self.password_confirmation = hash_string(pass) self.password = hash_string(pass) @@ -311,7 +314,11 @@ class User < ActiveRecord::Base # This method checks whether the given value equals the password when # hashed with this user's password hash type. Returns a boolean. def password_equals?(value) - hash_string(value) == self.password + hash_string(value) == self.password && !password_invalid? + end + + def password_invalid? + self.password_hash_type == 'invalid' end # Sets the last login time and saves the object. Note: Must currently be @@ -1048,6 +1055,8 @@ class User < ActiveRecord::Base Digest::MD5.hexdigest(value + password_salt) elsif crypt2index.keys.include?(password_hash_type) value.crypt("$#{crypt2index[password_hash_type]}$#{password_salt}$").split("$")[3] + else + 'invalid' end end diff --git a/src/api/app/views/webui/user/_password_dialog.html.erb b/src/api/app/views/webui/user/_password_dialog.html.erb index 45172f0219..c5113acc30 100644 --- a/src/api/app/views/webui/user/_password_dialog.html.erb +++ b/src/api/app/views/webui/user/_password_dialog.html.erb @@ -5,10 +5,12 @@ <h2 class="box-header">Change Your Password</h2> <div class="dialog-content"> <%= form_tag(:action => 'change_password') do %> + <% if !User.current.password_invalid? %> <p> <%= label_tag :password, 'Current Password:' %><br/> <%= text_field_tag :password, nil, :type => 'password', :required => 'true'%> </p> + <% end %> <p> <%= label_tag :new_password, 'New Password:' %><br/> <%= text_field_tag :new_password, nil, :type => 'password', :autocomplete => 'off', :required => 'true' %> -- GitLab