From a66310bd5682d08582c1d72ac429e6f5329bbefe Mon Sep 17 00:00:00 2001 From: Ben Thomson Date: Mon, 23 Dec 2019 08:19:15 +0800 Subject: [PATCH] Allow changing of Backend user passwords through CLI. (#4836) Adds an Artisan command "october:passwd" to change the password of a Backend User through CLI. This command may only be run through CLI - it will not work if called through a web handler. Refs: #3521, #4835. Docs: https://github.com/octobercms/docs/commit/1f3bfc719ed9ccbd588c625ff33be6d301d61a23 --- modules/system/ServiceProvider.php | 1 + modules/system/console/OctoberPasswd.php | 112 +++++++++++++++++++++++ 2 files changed, 113 insertions(+) create mode 100644 modules/system/console/OctoberPasswd.php diff --git a/modules/system/ServiceProvider.php b/modules/system/ServiceProvider.php index fa729eb5a..892547bc1 100644 --- a/modules/system/ServiceProvider.php +++ b/modules/system/ServiceProvider.php @@ -247,6 +247,7 @@ class ServiceProvider extends ModuleServiceProvider $this->registerConsoleCommand('october.fresh', 'System\Console\OctoberFresh'); $this->registerConsoleCommand('october.env', 'System\Console\OctoberEnv'); $this->registerConsoleCommand('october.install', 'System\Console\OctoberInstall'); + $this->registerConsoleCommand('october.passwd', 'System\Console\OctoberPasswd'); $this->registerConsoleCommand('plugin.install', 'System\Console\PluginInstall'); $this->registerConsoleCommand('plugin.remove', 'System\Console\PluginRemove'); diff --git a/modules/system/console/OctoberPasswd.php b/modules/system/console/OctoberPasswd.php new file mode 100644 index 000000000..bd2a4031d --- /dev/null +++ b/modules/system/console/OctoberPasswd.php @@ -0,0 +1,112 @@ +argument('username') + ?? $this->ask( + 'Which user would you like to change the password for?' + ); + + // Check that the user exists + try { + $user = User::where('login', $username) + ->orWhere('email', $username) + ->firstOrFail(); + } catch (ModelNotFoundException $e) { + $this->error('The specified user does not exist.'); + exit(1); + } + + $password = $this->argument('password') + ?? ( + $this->optionalSecret( + 'Enter in a new password, or press ENTER to use a generated password', + false, + false + ) ?: $this->generatePassword() + ); + + // Change password + $user->password = $password; + $user->forceSave(); + + $this->info('Password successfully changed.'); + if (!$this->generatedPassword) { + $this->output->writeLn('The new password is ' . $password . '.'); + } + exit(0); + } + + /** + * Get the console command options. + */ + protected function getArguments() + { + return [ + ['username', InputArgument::OPTIONAL, 'The username of the Backend user'], + ['password', InputArgument::OPTIONAL, 'The new password'] + ]; + } + + /** + * Prompt the user for input but hide the answer from the console. + * + * Also allows for a default to be specified. + * + * @param string $question + * @param bool $fallback + * @return string + */ + protected function optionalSecret($question, $fallback = true, $default = null) + { + $question = new Question($question, $default); + + $question->setHidden(true)->setHiddenFallback($fallback); + + return $this->output->askQuestion($question); + } + + /** + * Generate a password and flag it as an automatically-generated password. + * + * @return string + */ + protected function generatePassword() + { + $this->generatedPassword = true; + + return Str::random(22); + } +}