mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-25 08:12:40 +01:00
Replace "bin/people profileimage" with "bin/user enable|empower"
Summary: Ref T13382. - Remove "bin/people profileimage" which previously generated profile image caches but now feels obsolete. - Replace it with "bin/user", with "enable" and "empower" flows. This command is now focused on regaining access to an install after you lock your keys inside. - Document the various ways to unlock objects and accounts from the CLI. Test Plan: - Ran `bin/user enable` and `bin/user empower` with various flags. - Grepped for `people profileimage` and found no references. - Grepped for `bin/people` and found no references. - Read documentation. Maniphest Tasks: T13382 Differential Revision: https://secure.phabricator.com/D20724
This commit is contained in:
parent
721a86401f
commit
fc34554892
9 changed files with 254 additions and 123 deletions
|
@ -1 +0,0 @@
|
||||||
../scripts/people/manage_people.php
|
|
1
bin/user
Symbolic link
1
bin/user
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../scripts/setup/manage_user.php
|
|
@ -6,8 +6,8 @@ require_once $root.'/scripts/__init_script__.php';
|
||||||
|
|
||||||
$args = new PhutilArgumentParser($argv);
|
$args = new PhutilArgumentParser($argv);
|
||||||
$args->setSynopsis(<<<EOSYNOPSIS
|
$args->setSynopsis(<<<EOSYNOPSIS
|
||||||
**people** __command__ [__options__]
|
**user** __command__ [__options__]
|
||||||
Manage user profiles and accounts.
|
Modify user accounts to regain access to an install.
|
||||||
|
|
||||||
EOSYNOPSIS
|
EOSYNOPSIS
|
||||||
);
|
);
|
|
@ -4051,6 +4051,8 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorPeopleMailEngine' => 'applications/people/mail/PhabricatorPeopleMailEngine.php',
|
'PhabricatorPeopleMailEngine' => 'applications/people/mail/PhabricatorPeopleMailEngine.php',
|
||||||
'PhabricatorPeopleMailEngineException' => 'applications/people/mail/PhabricatorPeopleMailEngineException.php',
|
'PhabricatorPeopleMailEngineException' => 'applications/people/mail/PhabricatorPeopleMailEngineException.php',
|
||||||
'PhabricatorPeopleManageProfileMenuItem' => 'applications/people/menuitem/PhabricatorPeopleManageProfileMenuItem.php',
|
'PhabricatorPeopleManageProfileMenuItem' => 'applications/people/menuitem/PhabricatorPeopleManageProfileMenuItem.php',
|
||||||
|
'PhabricatorPeopleManagementEmpowerWorkflow' => 'applications/people/management/PhabricatorPeopleManagementEmpowerWorkflow.php',
|
||||||
|
'PhabricatorPeopleManagementEnableWorkflow' => 'applications/people/management/PhabricatorPeopleManagementEnableWorkflow.php',
|
||||||
'PhabricatorPeopleManagementWorkflow' => 'applications/people/management/PhabricatorPeopleManagementWorkflow.php',
|
'PhabricatorPeopleManagementWorkflow' => 'applications/people/management/PhabricatorPeopleManagementWorkflow.php',
|
||||||
'PhabricatorPeopleNewController' => 'applications/people/controller/PhabricatorPeopleNewController.php',
|
'PhabricatorPeopleNewController' => 'applications/people/controller/PhabricatorPeopleNewController.php',
|
||||||
'PhabricatorPeopleNoOwnerDatasource' => 'applications/people/typeahead/PhabricatorPeopleNoOwnerDatasource.php',
|
'PhabricatorPeopleNoOwnerDatasource' => 'applications/people/typeahead/PhabricatorPeopleNoOwnerDatasource.php',
|
||||||
|
@ -4060,7 +4062,6 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorPeopleProfileCommitsController' => 'applications/people/controller/PhabricatorPeopleProfileCommitsController.php',
|
'PhabricatorPeopleProfileCommitsController' => 'applications/people/controller/PhabricatorPeopleProfileCommitsController.php',
|
||||||
'PhabricatorPeopleProfileController' => 'applications/people/controller/PhabricatorPeopleProfileController.php',
|
'PhabricatorPeopleProfileController' => 'applications/people/controller/PhabricatorPeopleProfileController.php',
|
||||||
'PhabricatorPeopleProfileEditController' => 'applications/people/controller/PhabricatorPeopleProfileEditController.php',
|
'PhabricatorPeopleProfileEditController' => 'applications/people/controller/PhabricatorPeopleProfileEditController.php',
|
||||||
'PhabricatorPeopleProfileImageWorkflow' => 'applications/people/management/PhabricatorPeopleProfileImageWorkflow.php',
|
|
||||||
'PhabricatorPeopleProfileManageController' => 'applications/people/controller/PhabricatorPeopleProfileManageController.php',
|
'PhabricatorPeopleProfileManageController' => 'applications/people/controller/PhabricatorPeopleProfileManageController.php',
|
||||||
'PhabricatorPeopleProfileMenuEngine' => 'applications/people/engine/PhabricatorPeopleProfileMenuEngine.php',
|
'PhabricatorPeopleProfileMenuEngine' => 'applications/people/engine/PhabricatorPeopleProfileMenuEngine.php',
|
||||||
'PhabricatorPeopleProfilePictureController' => 'applications/people/controller/PhabricatorPeopleProfilePictureController.php',
|
'PhabricatorPeopleProfilePictureController' => 'applications/people/controller/PhabricatorPeopleProfilePictureController.php',
|
||||||
|
@ -10332,6 +10333,8 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorPeopleMailEngine' => 'Phobject',
|
'PhabricatorPeopleMailEngine' => 'Phobject',
|
||||||
'PhabricatorPeopleMailEngineException' => 'Exception',
|
'PhabricatorPeopleMailEngineException' => 'Exception',
|
||||||
'PhabricatorPeopleManageProfileMenuItem' => 'PhabricatorProfileMenuItem',
|
'PhabricatorPeopleManageProfileMenuItem' => 'PhabricatorProfileMenuItem',
|
||||||
|
'PhabricatorPeopleManagementEmpowerWorkflow' => 'PhabricatorPeopleManagementWorkflow',
|
||||||
|
'PhabricatorPeopleManagementEnableWorkflow' => 'PhabricatorPeopleManagementWorkflow',
|
||||||
'PhabricatorPeopleManagementWorkflow' => 'PhabricatorManagementWorkflow',
|
'PhabricatorPeopleManagementWorkflow' => 'PhabricatorManagementWorkflow',
|
||||||
'PhabricatorPeopleNewController' => 'PhabricatorPeopleController',
|
'PhabricatorPeopleNewController' => 'PhabricatorPeopleController',
|
||||||
'PhabricatorPeopleNoOwnerDatasource' => 'PhabricatorTypeaheadDatasource',
|
'PhabricatorPeopleNoOwnerDatasource' => 'PhabricatorTypeaheadDatasource',
|
||||||
|
@ -10341,7 +10344,6 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorPeopleProfileCommitsController' => 'PhabricatorPeopleProfileController',
|
'PhabricatorPeopleProfileCommitsController' => 'PhabricatorPeopleProfileController',
|
||||||
'PhabricatorPeopleProfileController' => 'PhabricatorPeopleController',
|
'PhabricatorPeopleProfileController' => 'PhabricatorPeopleController',
|
||||||
'PhabricatorPeopleProfileEditController' => 'PhabricatorPeopleProfileController',
|
'PhabricatorPeopleProfileEditController' => 'PhabricatorPeopleProfileController',
|
||||||
'PhabricatorPeopleProfileImageWorkflow' => 'PhabricatorPeopleManagementWorkflow',
|
|
||||||
'PhabricatorPeopleProfileManageController' => 'PhabricatorPeopleProfileController',
|
'PhabricatorPeopleProfileManageController' => 'PhabricatorPeopleProfileController',
|
||||||
'PhabricatorPeopleProfileMenuEngine' => 'PhabricatorProfileMenuEngine',
|
'PhabricatorPeopleProfileMenuEngine' => 'PhabricatorProfileMenuEngine',
|
||||||
'PhabricatorPeopleProfilePictureController' => 'PhabricatorPeopleProfileController',
|
'PhabricatorPeopleProfilePictureController' => 'PhabricatorPeopleProfileController',
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorPeopleManagementEmpowerWorkflow
|
||||||
|
extends PhabricatorPeopleManagementWorkflow {
|
||||||
|
|
||||||
|
protected function didConstruct() {
|
||||||
|
$arguments = array_merge(
|
||||||
|
$this->getUserSelectionArguments(),
|
||||||
|
array());
|
||||||
|
|
||||||
|
$this
|
||||||
|
->setName('empower')
|
||||||
|
->setExamples('**empower** --user __username__')
|
||||||
|
->setSynopsis(pht('Turn a user account into an administrator account.'))
|
||||||
|
->setArguments($arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function execute(PhutilArgumentParser $args) {
|
||||||
|
$user = $this->selectUser($args);
|
||||||
|
$display_name = $user->getUsername();
|
||||||
|
|
||||||
|
if ($user->getIsAdmin()) {
|
||||||
|
throw new PhutilArgumentUsageException(
|
||||||
|
pht(
|
||||||
|
'User account "%s" is already an administrator. You can only '.
|
||||||
|
'empower accounts that are not yet administrators.',
|
||||||
|
$display_name));
|
||||||
|
}
|
||||||
|
|
||||||
|
$xactions = array();
|
||||||
|
$xactions[] = $user->getApplicationTransactionTemplate()
|
||||||
|
->setTransactionType(PhabricatorUserEmpowerTransaction::TRANSACTIONTYPE)
|
||||||
|
->setNewValue(true);
|
||||||
|
|
||||||
|
$this->applyTransactions($user, $xactions);
|
||||||
|
|
||||||
|
$this->logOkay(
|
||||||
|
pht('DONE'),
|
||||||
|
pht('Empowered user account "%s".', $display_name));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorPeopleManagementEnableWorkflow
|
||||||
|
extends PhabricatorPeopleManagementWorkflow {
|
||||||
|
|
||||||
|
protected function didConstruct() {
|
||||||
|
$arguments = array_merge(
|
||||||
|
$this->getUserSelectionArguments(),
|
||||||
|
array());
|
||||||
|
|
||||||
|
$this
|
||||||
|
->setName('enable')
|
||||||
|
->setExamples('**enable** --user __username__')
|
||||||
|
->setSynopsis(pht('Enable a disabled user account.'))
|
||||||
|
->setArguments($arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function execute(PhutilArgumentParser $args) {
|
||||||
|
$user = $this->selectUser($args);
|
||||||
|
$display_name = $user->getUsername();
|
||||||
|
|
||||||
|
if (!$user->getIsDisabled()) {
|
||||||
|
throw new PhutilArgumentUsageException(
|
||||||
|
pht(
|
||||||
|
'User account "%s" is not disabled. You can only enable accounts '.
|
||||||
|
'that are disabled.',
|
||||||
|
$display_name));
|
||||||
|
}
|
||||||
|
|
||||||
|
$xactions = array();
|
||||||
|
$xactions[] = $user->getApplicationTransactionTemplate()
|
||||||
|
->setTransactionType(PhabricatorUserDisableTransaction::TRANSACTIONTYPE)
|
||||||
|
->setNewValue(false);
|
||||||
|
|
||||||
|
$this->applyTransactions($user, $xactions);
|
||||||
|
|
||||||
|
$this->logOkay(
|
||||||
|
pht('DONE'),
|
||||||
|
pht('Enabled user account "%s".', $display_name));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -3,45 +3,55 @@
|
||||||
abstract class PhabricatorPeopleManagementWorkflow
|
abstract class PhabricatorPeopleManagementWorkflow
|
||||||
extends PhabricatorManagementWorkflow {
|
extends PhabricatorManagementWorkflow {
|
||||||
|
|
||||||
protected function buildIterator(PhutilArgumentParser $args) {
|
final protected function getUserSelectionArguments() {
|
||||||
$usernames = $args->getArg('users');
|
return array(
|
||||||
|
array(
|
||||||
|
'name' => 'user',
|
||||||
|
'param' => 'username',
|
||||||
|
'help' => pht('User account to act on.'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if ($args->getArg('all')) {
|
final protected function selectUser(PhutilArgumentParser $argv) {
|
||||||
if ($usernames) {
|
$username = $argv->getArg('user');
|
||||||
|
|
||||||
|
if (!strlen($username)) {
|
||||||
throw new PhutilArgumentUsageException(
|
throw new PhutilArgumentUsageException(
|
||||||
pht(
|
pht(
|
||||||
'Specify either a list of users or `%s`, but not both.',
|
'Select a user account to act on with "--user <username>".'));
|
||||||
'--all'));
|
|
||||||
}
|
|
||||||
return new LiskMigrationIterator(new PhabricatorUser());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($usernames) {
|
$user = id(new PhabricatorPeopleQuery())
|
||||||
return $this->loadUsersWithUsernames($usernames);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function loadUsersWithUsernames(array $usernames) {
|
|
||||||
$users = array();
|
|
||||||
foreach($usernames as $username) {
|
|
||||||
$query = id(new PhabricatorPeopleQuery())
|
|
||||||
->setViewer($this->getViewer())
|
->setViewer($this->getViewer())
|
||||||
->withUsernames(array($username))
|
->withUsernames(array($username))
|
||||||
->executeOne();
|
->executeOne();
|
||||||
|
if (!$user) {
|
||||||
if (!$query) {
|
|
||||||
throw new PhutilArgumentUsageException(
|
throw new PhutilArgumentUsageException(
|
||||||
pht(
|
pht(
|
||||||
'"%s" is not a valid username.',
|
'No user with username "%s" exists.',
|
||||||
$username));
|
$username));
|
||||||
}
|
}
|
||||||
$users[] = $query;
|
|
||||||
|
return $user;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $users;
|
final protected function applyTransactions(
|
||||||
}
|
PhabricatorUser $user,
|
||||||
|
array $xactions) {
|
||||||
|
assert_instances_of($xactions, 'PhabricatorUserTransaction');
|
||||||
|
|
||||||
|
$viewer = $this->getViewer();
|
||||||
|
$application = id(new PhabricatorPeopleApplication())->getPHID();
|
||||||
|
$content_source = $this->newContentSource();
|
||||||
|
|
||||||
|
$editor = $user->getApplicationTransactionEditor()
|
||||||
|
->setActor($viewer)
|
||||||
|
->setActingAsPHID($application)
|
||||||
|
->setContentSource($content_source)
|
||||||
|
->setContinueOnMissingFields(true);
|
||||||
|
|
||||||
|
return $editor->applyTransactions($user, $xactions);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,85 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
final class PhabricatorPeopleProfileImageWorkflow
|
|
||||||
extends PhabricatorPeopleManagementWorkflow {
|
|
||||||
|
|
||||||
protected function didConstruct() {
|
|
||||||
$this
|
|
||||||
->setName('profileimage')
|
|
||||||
->setExamples('**profileimage** --users __username__')
|
|
||||||
->setSynopsis(pht('Generate default profile images.'))
|
|
||||||
->setArguments(
|
|
||||||
array(
|
|
||||||
array(
|
|
||||||
'name' => 'all',
|
|
||||||
'help' => pht(
|
|
||||||
'Generate default profile images for all users.'),
|
|
||||||
),
|
|
||||||
array(
|
|
||||||
'name' => 'force',
|
|
||||||
'short' => 'f',
|
|
||||||
'help' => pht(
|
|
||||||
'Force a default profile image to be replaced.'),
|
|
||||||
),
|
|
||||||
array(
|
|
||||||
'name' => 'users',
|
|
||||||
'wildcard' => true,
|
|
||||||
),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function execute(PhutilArgumentParser $args) {
|
|
||||||
$console = PhutilConsole::getConsole();
|
|
||||||
|
|
||||||
$is_force = $args->getArg('force');
|
|
||||||
$is_all = $args->getArg('all');
|
|
||||||
|
|
||||||
$gd = function_exists('imagecreatefromstring');
|
|
||||||
if (!$gd) {
|
|
||||||
throw new PhutilArgumentUsageException(
|
|
||||||
pht(
|
|
||||||
'GD is not installed for php-cli. Aborting.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$iterator = $this->buildIterator($args);
|
|
||||||
if (!$iterator) {
|
|
||||||
throw new PhutilArgumentUsageException(
|
|
||||||
pht(
|
|
||||||
'Either specify a list of users to update, or use `%s` '.
|
|
||||||
'to update all users.',
|
|
||||||
'--all'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$version = PhabricatorFilesComposeAvatarBuiltinFile::VERSION;
|
|
||||||
$generator = new PhabricatorFilesComposeAvatarBuiltinFile();
|
|
||||||
|
|
||||||
foreach ($iterator as $user) {
|
|
||||||
$username = $user->getUsername();
|
|
||||||
$default_phid = $user->getDefaultProfileImagePHID();
|
|
||||||
$gen_version = $user->getDefaultProfileImageVersion();
|
|
||||||
|
|
||||||
$generate = false;
|
|
||||||
if ($gen_version != $version) {
|
|
||||||
$generate = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($default_phid == null || $is_force || $generate) {
|
|
||||||
$console->writeOut(
|
|
||||||
"%s\n",
|
|
||||||
pht(
|
|
||||||
'Generating profile image for "%s".',
|
|
||||||
$username));
|
|
||||||
|
|
||||||
$generator->updateUser($user);
|
|
||||||
} else {
|
|
||||||
$console->writeOut(
|
|
||||||
"%s\n",
|
|
||||||
pht(
|
|
||||||
'Default profile image "%s" already set for "%s".',
|
|
||||||
$version,
|
|
||||||
$username));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
116
src/docs/user/userguide/unlocking.diviner
Normal file
116
src/docs/user/userguide/unlocking.diviner
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
@title User Guide: Unlocking Objects
|
||||||
|
@group userguide
|
||||||
|
|
||||||
|
Explains how to access locked or invisible objects and accounts.
|
||||||
|
|
||||||
|
Overview
|
||||||
|
========
|
||||||
|
|
||||||
|
Phabricator tries to make it difficult for users to lock themselves out of
|
||||||
|
things, but you can occasionally end up in situations where no one has access
|
||||||
|
to an object that you need access to.
|
||||||
|
|
||||||
|
For example, sometimes the only user who had edit permission for something has
|
||||||
|
left the organization, or you configured a "Phase of the Moon" policy rule and
|
||||||
|
the stars aren't currently aligned.
|
||||||
|
|
||||||
|
You can use various CLI tools to unlock objects and accounts if you need to
|
||||||
|
regain access.
|
||||||
|
|
||||||
|
|
||||||
|
Unlocking Accounts
|
||||||
|
==================
|
||||||
|
|
||||||
|
If you need to regain access to an object, the easiest approach is usually to
|
||||||
|
recover access to the account which owns it, then change the object policies
|
||||||
|
to be more open using the web UI.
|
||||||
|
|
||||||
|
For example, if an important task was accidentally locked so that only a user
|
||||||
|
who is currently on vacation can edit it, you can log in as that user and
|
||||||
|
change the edit policy to something more permissive.
|
||||||
|
|
||||||
|
To regain access to an account:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ./bin/auth recover <username>
|
||||||
|
```
|
||||||
|
|
||||||
|
If the account you're recovering access to has MFA or other session prompts,
|
||||||
|
use the `--force-full-session` to bypass them:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ./bin/auth recover <username> --force-full-session
|
||||||
|
```
|
||||||
|
|
||||||
|
In either case, the command will give you a link you a one-time link you can
|
||||||
|
use to access the account from the web UI. From there, you can open up objects
|
||||||
|
or change settings.
|
||||||
|
|
||||||
|
|
||||||
|
Unlocking MFA
|
||||||
|
=============
|
||||||
|
|
||||||
|
You can completely strip MFA from a user account with:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ./bin/auth strip --user <username> ...
|
||||||
|
```
|
||||||
|
|
||||||
|
For detailed help on managing and stripping MFA, see the instructions in
|
||||||
|
@{article:User Guide: Multi-Factor Authentication}
|
||||||
|
|
||||||
|
|
||||||
|
Unlocking Objects
|
||||||
|
=================
|
||||||
|
|
||||||
|
If you aren't sure who owns an object, or no user account has access to an
|
||||||
|
object, you can directly change object policies from the CLI:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ./bin/policy unlock <object> [--view ...] [--edit ...] [--owner ...]
|
||||||
|
```
|
||||||
|
|
||||||
|
To identify the object you want to unlock, you can specify an object name (like
|
||||||
|
`T123`) or a PHID as the `<object>` parameter.
|
||||||
|
|
||||||
|
Use the `--view` and `--edit` flags (and, for some objects, the `--owner`
|
||||||
|
flag) to specify new policies for the object.
|
||||||
|
|
||||||
|
For example, to make task `T123` editable by user `@alice`, run:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ./bin/policy unlock T123 --edit alice
|
||||||
|
```
|
||||||
|
|
||||||
|
Not every object has mutable view and edit policies, and not every object has
|
||||||
|
an owner, so each flag only works on some types of objects.
|
||||||
|
|
||||||
|
From here, you can log in to the web UI and change the relevant policies to
|
||||||
|
whatever you want to set them to.
|
||||||
|
|
||||||
|
|
||||||
|
No Enabled Users
|
||||||
|
================
|
||||||
|
|
||||||
|
If you accidentally disabled all administrator accounts, you can enable a
|
||||||
|
disabled account from the CLI like this:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ./bin/user enable --user <username>
|
||||||
|
```
|
||||||
|
|
||||||
|
From here, recover the account or log in normally.
|
||||||
|
|
||||||
|
|
||||||
|
No Administrators
|
||||||
|
=================
|
||||||
|
|
||||||
|
If you accidentally deleted all the administrator accounts, you can empower
|
||||||
|
a user as an administrator from the CLI like this:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ./bin/user empower --user <username>
|
||||||
|
```
|
||||||
|
|
||||||
|
This will upgrade the user account from a regular account to an administrator
|
||||||
|
account.
|
Loading…
Reference in a new issue