1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-09-20 17:28:51 +02:00
phorge-phorge/scripts/user/account_admin.php
epriestley aa3b582c7b Remove "set password" from bin/accountadmin and let bin/auth recover recover anyone
Summary:
Ref T13043. This cleans some things up to prepare for moving account passwords to shared infrastructure.

Currently, the (very old, fairly unusual) `bin/accountadmin` tool can set account passwords. This is a bit weird, generally not great, and makes upgrading to shared infrastructure more difficult. Just get rid of this to simplify things. Many installs don't have passwords and this is pointless and unhelpful in those cases.

Instead, let `bin/auth recover` recover any account, not just administrator accounts. This was a guardrail against administrative abuse, but it has always seemed especially flimsy (since anyone who can run the tool can easily comment out the checks) and I use this tool in cluster support with some frequency, occasionally just commenting out the checks. This is generally a better solution than actually setting a password on accounts anyway. Just get rid of the check and give users enough rope to shoot themselves in the foot with if they truly desire.

Test Plan:
  - Ran `bin/accountadmin`, didn't get prompted to swap passwords anymore.
  - Ran `bin/auth recover` to recover a non-admin account.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13043

Differential Revision: https://secure.phabricator.com/D18901
2018-01-23 10:58:11 -08:00

208 lines
5.6 KiB
PHP
Executable file

#!/usr/bin/env php
<?php
$root = dirname(dirname(dirname(__FILE__)));
require_once $root.'/scripts/__init_script__.php';
$table = new PhabricatorUser();
$any_user = queryfx_one(
$table->establishConnection('r'),
'SELECT * FROM %T LIMIT 1',
$table->getTableName());
$is_first_user = (!$any_user);
if ($is_first_user) {
echo pht(
"WARNING\n\n".
"You're about to create the first account on this install. Normally, ".
"you should use the web interface to create the first account, not ".
"this script.\n\n".
"If you use the web interface, it will drop you into a nice UI workflow ".
"which gives you more help setting up your install. If you create an ".
"account with this script instead, you will skip the setup help and you ".
"will not be able to access it later.");
if (!phutil_console_confirm(pht('Skip easy setup and create account?'))) {
echo pht('Cancelled.')."\n";
exit(1);
}
}
echo pht(
'Enter a username to create a new account or edit an existing account.');
$username = phutil_console_prompt(pht('Enter a username:'));
if (!strlen($username)) {
echo pht('Cancelled.')."\n";
exit(1);
}
if (!PhabricatorUser::validateUsername($username)) {
$valid = PhabricatorUser::describeValidUsername();
echo pht("The username '%s' is invalid. %s", $username, $valid)."\n";
exit(1);
}
$user = id(new PhabricatorUser())->loadOneWhere(
'username = %s',
$username);
if (!$user) {
$original = new PhabricatorUser();
echo pht("There is no existing user account '%s'.", $username)."\n";
$ok = phutil_console_confirm(
pht("Do you want to create a new '%s' account?", $username),
$default_no = false);
if (!$ok) {
echo pht('Cancelled.')."\n";
exit(1);
}
$user = new PhabricatorUser();
$user->setUsername($username);
$is_new = true;
} else {
$original = clone $user;
echo pht("There is an existing user account '%s'.", $username)."\n";
$ok = phutil_console_confirm(
pht("Do you want to edit the existing '%s' account?", $username),
$default_no = false);
if (!$ok) {
echo pht('Cancelled.')."\n";
exit(1);
}
$is_new = false;
}
$user_realname = $user->getRealName();
if (strlen($user_realname)) {
$realname_prompt = ' ['.$user_realname.']:';
} else {
$realname_prompt = ':';
}
$realname = nonempty(
phutil_console_prompt(pht('Enter user real name').$realname_prompt),
$user_realname);
$user->setRealName($realname);
// When creating a new user we prompt for an email address; when editing an
// existing user we just skip this because it would be quite involved to provide
// a reasonable CLI interface for editing multiple addresses and managing email
// verification and primary addresses.
$create_email = null;
if ($is_new) {
do {
$email = phutil_console_prompt(pht('Enter user email address:'));
$duplicate = id(new PhabricatorUserEmail())->loadOneWhere(
'address = %s',
$email);
if ($duplicate) {
echo pht(
"ERROR: There is already a user with that email address. ".
"Each user must have a unique email address.\n");
} else {
break;
}
} while (true);
$create_email = $email;
}
$is_system_agent = $user->getIsSystemAgent();
$set_system_agent = phutil_console_confirm(
pht('Is this user a bot?'),
$default_no = !$is_system_agent);
$verify_email = null;
$set_verified = false;
// Allow administrators to verify primary email addresses at this time in edit
// scenarios. (Create will work just fine from here as we auto-verify email
// on create.)
if (!$is_new) {
$verify_email = $user->loadPrimaryEmail();
if (!$verify_email->getIsVerified()) {
$set_verified = phutil_console_confirm(
pht('Should the primary email address be verified?'),
$default_no = true);
} else {
// Already verified so let's not make a fuss.
$verify_email = null;
}
}
$is_admin = $user->getIsAdmin();
$set_admin = phutil_console_confirm(
pht('Should this user be an administrator?'),
$default_no = !$is_admin);
echo "\n\n".pht('ACCOUNT SUMMARY')."\n\n";
$tpl = "%12s %-30s %-30s\n";
printf($tpl, null, pht('OLD VALUE'), pht('NEW VALUE'));
printf($tpl, pht('Username'), $original->getUsername(), $user->getUsername());
printf($tpl, pht('Real Name'), $original->getRealName(), $user->getRealName());
if ($is_new) {
printf($tpl, pht('Email'), '', $create_email);
}
printf(
$tpl,
pht('Bot'),
$original->getIsSystemAgent() ? 'Y' : 'N',
$set_system_agent ? 'Y' : 'N');
if ($verify_email) {
printf(
$tpl,
pht('Verify Email'),
$verify_email->getIsVerified() ? 'Y' : 'N',
$set_verified ? 'Y' : 'N');
}
printf(
$tpl,
pht('Admin'),
$original->getIsAdmin() ? 'Y' : 'N',
$set_admin ? 'Y' : 'N');
echo "\n";
if (!phutil_console_confirm(pht('Save these changes?'), $default_no = false)) {
echo pht('Cancelled.')."\n";
exit(1);
}
$user->openTransaction();
$editor = new PhabricatorUserEditor();
// TODO: This is wrong, but we have a chicken-and-egg problem when you use
// this script to create the first user.
$editor->setActor($user);
if ($is_new) {
$email = id(new PhabricatorUserEmail())
->setAddress($create_email)
->setIsVerified(1);
// Unconditionally approve new accounts created from the CLI.
$user->setIsApproved(1);
$editor->createNewUser($user, $email);
} else {
if ($verify_email) {
$user->setIsEmailVerified(1);
$verify_email->setIsVerified($set_verified ? 1 : 0);
}
$editor->updateUser($user, $verify_email);
}
$editor->makeAdminUser($user, $set_admin);
$editor->makeSystemAgentUser($user, $set_system_agent);
$user->saveTransaction();
echo pht('Saved changes.')."\n";