Commit c1744c60 authored by Balasankar "Balu" C's avatar Balasankar "Balu" C

Add rake task to reset user password

Signed-off-by: default avatarBalasankar "Balu" C <balasankarc@autistici.org>
parent d036dafa
---
title: Add rake task to reset user password
merge_request: 52347
author:
type: added
...@@ -7,70 +7,91 @@ type: howto ...@@ -7,70 +7,91 @@ type: howto
# How to reset user password # How to reset user password
To reset the password of a user, first log into your server with root privileges. There are a few ways to reset the password of a user.
Start a Ruby on Rails console with this command: ## Rake Task
GitLab provides a Rake Task to reset passwords of users using their usernames,
which can be invoked by the following command:
```shell ```shell
gitlab-rails console -e production sudo gitlab-rake "gitlab:password:reset"
``` ```
Wait until the console has loaded. You will be asked for username, password, and password confirmation. Upon giving
proper values for them, the password of the specified user will be updated.
## Find the user
There are multiple ways to find your user. You can search by email or user ID number. The Rake task also takes the username as an argument, as shown in the example
below:
```shell ```shell
user = User.where(id: 7).first sudo gitlab-rake "gitlab:password:reset[johndoe]"
``` ```
or NOTE:
To reset the default admin password, run this Rake task with the username
`root`, which is the default username of that admin account.
```shell ## Rails console
user = User.find_by(email: 'user@example.com')
```
## Reset the password The Rake task is capable of finding users via their usernames. However, if only
user ID or email ID of the user is known, Rails console can be used to find user
using user ID and then change password of the user manually.
Now you can change your password: 1. Start a Rails console
```shell ```shell
user.password = 'secret_pass' sudo gitlab-rails console -e production
user.password_confirmation = 'secret_pass' ```
```
It's important that you change both password and password_confirmation to make it work. 1. Find the user either by user ID or email ID:
When using this method instead of the [Users API](../api/users.md#user-modification), GitLab sends an email to the user stating that the user changed their password. ```ruby
user = User.find(123)
If the password was changed by an administrator, execute the following command to notify the user by email: #or
```shell user = User.find_by(email: 'user@example.com')
user.send_only_admin_changed_your_password_notification! ```
```
Don't forget to save the changes. 1. Reset the password
```shell ```ruby
user.save! user.password = 'secret_pass'
``` user.password_confirmation = 'secret_pass'
```
1. When using this method instead of the [Users API](../api/users.md#user-modification),
GitLab sends an email to the user stating that the user changed their
password. If the password was changed by an administrator, execute the
following command to notify the user by email:
```ruby
user.send_only_admin_changed_your_password_notification!
```
Exit the console, and then try to sign in with your new password. 1. Save the changes:
```ruby
user.save!
```
1. Exit the console, and then try to sign in with your new password.
NOTE: NOTE:
You can also reset passwords by using the [Users API](../api/users.md#user-modification). You can also reset passwords by using the [Users API](../api/users.md#user-modification).
### Reset your root password ## Reset your root password
The previously described steps can also be used to reset the root password. First, The previously described steps can also be used to reset the root password.
identify the root user, with an `id` of `1`. To do so, run the following command:
```shell In normal installations where the username of root account hasn't been changed
user = User.where(id: 1).first manually, the Rake task can be used with username `root` to reset the root
``` password.
After finding the user, follow the steps mentioned in the [Reset the password](#reset-the-password) section to reset the password of the root user. If the username was changed to something else and has been forgotten, one
possible way is to reset the password using Rails console with user ID `1` (in
almost all the cases, the first user will be the default admin account).
<!-- ## Troubleshooting <!-- ## Troubleshooting
......
...@@ -66,6 +66,18 @@ module Gitlab ...@@ -66,6 +66,18 @@ module Gitlab
answer answer
end end
# Prompt the user to input a password
#
# message - custom message to display before input
def prompt_for_password(message = 'Enter password: ')
unless STDIN.tty?
print(message)
return STDIN.gets.chomp
end
STDIN.getpass(message)
end
# Runs the given command and matches the output against the given pattern # Runs the given command and matches the output against the given pattern
# #
# Returns nil if nothing matched # Returns nil if nothing matched
......
# frozen_string_literal: true
namespace :gitlab do
namespace :password do
desc "GitLab | Password | Reset a user's password"
task :reset, [:username] => :environment do |_, args|
username = args[:username] || Gitlab::TaskHelpers.prompt('Enter username: ')
abort('Username can not be empty.') if username.blank?
user = User.find_by(username: username)
abort("Unable to find user with username #{username}.") unless user
password = Gitlab::TaskHelpers.prompt_for_password
password_confirm = Gitlab::TaskHelpers.prompt_for_password('Confirm password: ')
user.password = password
user.password_confirmation = password_confirm
user.send_only_admin_changed_your_password_notification!
unless user.save
message = <<~EOF
Unable to change password of the user with username #{username}.
#{user.errors.full_messages.to_sentence}
EOF
abort(message)
end
puts "Password successfully updated for user with username #{username}."
end
end
end
# frozen_string_literal: true
require 'rake_helper'
RSpec.describe 'gitlab:password rake tasks' do
let_it_be(:user_1) { create(:user, username: 'foobar', password: 'initial_password') }
def stub_username(username)
allow(Gitlab::TaskHelpers).to receive(:prompt).with('Enter username: ').and_return(username)
end
def stub_password(password, confirmation = nil)
confirmation ||= password
allow(Gitlab::TaskHelpers).to receive(:prompt_for_password).and_return(password)
allow(Gitlab::TaskHelpers).to receive(:prompt_for_password).with('Confirm password: ').and_return(confirmation)
end
before do
Rake.application.rake_require 'tasks/gitlab/password'
stub_username('foobar')
stub_password('secretpassword')
end
describe ':reset' do
context 'when all inputs are correct' do
it 'updates the password properly' do
run_rake_task('gitlab:password:reset', user_1.username)
expect(user_1.reload.valid_password?('secretpassword')).to eq(true)
end
end
context 'when username is not provided' do
it 'asks for username' do
expect(Gitlab::TaskHelpers).to receive(:prompt).with('Enter username: ')
run_rake_task('gitlab:password:reset')
end
context 'when username is empty' do
it 'aborts with an error' do
stub_username('')
expect { run_rake_task('gitlab:password:reset') }.to raise_error(/Username can not be empty./)
end
end
end
context 'when username is passed as argument' do
it 'does not ask for username' do
expect(Gitlab::TaskHelpers).not_to receive(:prompt)
run_rake_task('gitlab:password:reset', 'foobar')
end
end
context 'when passwords do not match' do
before do
stub_password('randompassword', 'differentpassword')
end
it 'aborts with an error' do
expect { run_rake_task('gitlab:password:reset') }.to raise_error(%r{Unable to change password of the user with username foobar.\nPassword confirmation doesn't match Password})
end
end
context 'when user cannot be found' do
before do
stub_username('nonexistentuser')
end
it 'aborts with an error' do
expect { run_rake_task('gitlab:password:reset') }.to raise_error(/Unable to find user with username nonexistentuser./)
end
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment