mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-21 22:32:41 +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->setSynopsis(<<<EOSYNOPSIS
|
||||
**people** __command__ [__options__]
|
||||
Manage user profiles and accounts.
|
||||
**user** __command__ [__options__]
|
||||
Modify user accounts to regain access to an install.
|
||||
|
||||
EOSYNOPSIS
|
||||
);
|
|
@ -4051,6 +4051,8 @@ phutil_register_library_map(array(
|
|||
'PhabricatorPeopleMailEngine' => 'applications/people/mail/PhabricatorPeopleMailEngine.php',
|
||||
'PhabricatorPeopleMailEngineException' => 'applications/people/mail/PhabricatorPeopleMailEngineException.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',
|
||||
'PhabricatorPeopleNewController' => 'applications/people/controller/PhabricatorPeopleNewController.php',
|
||||
'PhabricatorPeopleNoOwnerDatasource' => 'applications/people/typeahead/PhabricatorPeopleNoOwnerDatasource.php',
|
||||
|
@ -4060,7 +4062,6 @@ phutil_register_library_map(array(
|
|||
'PhabricatorPeopleProfileCommitsController' => 'applications/people/controller/PhabricatorPeopleProfileCommitsController.php',
|
||||
'PhabricatorPeopleProfileController' => 'applications/people/controller/PhabricatorPeopleProfileController.php',
|
||||
'PhabricatorPeopleProfileEditController' => 'applications/people/controller/PhabricatorPeopleProfileEditController.php',
|
||||
'PhabricatorPeopleProfileImageWorkflow' => 'applications/people/management/PhabricatorPeopleProfileImageWorkflow.php',
|
||||
'PhabricatorPeopleProfileManageController' => 'applications/people/controller/PhabricatorPeopleProfileManageController.php',
|
||||
'PhabricatorPeopleProfileMenuEngine' => 'applications/people/engine/PhabricatorPeopleProfileMenuEngine.php',
|
||||
'PhabricatorPeopleProfilePictureController' => 'applications/people/controller/PhabricatorPeopleProfilePictureController.php',
|
||||
|
@ -10332,6 +10333,8 @@ phutil_register_library_map(array(
|
|||
'PhabricatorPeopleMailEngine' => 'Phobject',
|
||||
'PhabricatorPeopleMailEngineException' => 'Exception',
|
||||
'PhabricatorPeopleManageProfileMenuItem' => 'PhabricatorProfileMenuItem',
|
||||
'PhabricatorPeopleManagementEmpowerWorkflow' => 'PhabricatorPeopleManagementWorkflow',
|
||||
'PhabricatorPeopleManagementEnableWorkflow' => 'PhabricatorPeopleManagementWorkflow',
|
||||
'PhabricatorPeopleManagementWorkflow' => 'PhabricatorManagementWorkflow',
|
||||
'PhabricatorPeopleNewController' => 'PhabricatorPeopleController',
|
||||
'PhabricatorPeopleNoOwnerDatasource' => 'PhabricatorTypeaheadDatasource',
|
||||
|
@ -10341,7 +10344,6 @@ phutil_register_library_map(array(
|
|||
'PhabricatorPeopleProfileCommitsController' => 'PhabricatorPeopleProfileController',
|
||||
'PhabricatorPeopleProfileController' => 'PhabricatorPeopleController',
|
||||
'PhabricatorPeopleProfileEditController' => 'PhabricatorPeopleProfileController',
|
||||
'PhabricatorPeopleProfileImageWorkflow' => 'PhabricatorPeopleManagementWorkflow',
|
||||
'PhabricatorPeopleProfileManageController' => 'PhabricatorPeopleProfileController',
|
||||
'PhabricatorPeopleProfileMenuEngine' => 'PhabricatorProfileMenuEngine',
|
||||
'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
|
||||
extends PhabricatorManagementWorkflow {
|
||||
|
||||
protected function buildIterator(PhutilArgumentParser $args) {
|
||||
$usernames = $args->getArg('users');
|
||||
final protected function getUserSelectionArguments() {
|
||||
return array(
|
||||
array(
|
||||
'name' => 'user',
|
||||
'param' => 'username',
|
||||
'help' => pht('User account to act on.'),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
if ($args->getArg('all')) {
|
||||
if ($usernames) {
|
||||
final protected function selectUser(PhutilArgumentParser $argv) {
|
||||
$username = $argv->getArg('user');
|
||||
|
||||
if (!strlen($username)) {
|
||||
throw new PhutilArgumentUsageException(
|
||||
pht(
|
||||
'Specify either a list of users or `%s`, but not both.',
|
||||
'--all'));
|
||||
}
|
||||
return new LiskMigrationIterator(new PhabricatorUser());
|
||||
'Select a user account to act on with "--user <username>".'));
|
||||
}
|
||||
|
||||
if ($usernames) {
|
||||
return $this->loadUsersWithUsernames($usernames);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected function loadUsersWithUsernames(array $usernames) {
|
||||
$users = array();
|
||||
foreach($usernames as $username) {
|
||||
$query = id(new PhabricatorPeopleQuery())
|
||||
$user = id(new PhabricatorPeopleQuery())
|
||||
->setViewer($this->getViewer())
|
||||
->withUsernames(array($username))
|
||||
->executeOne();
|
||||
|
||||
if (!$query) {
|
||||
if (!$user) {
|
||||
throw new PhutilArgumentUsageException(
|
||||
pht(
|
||||
'"%s" is not a valid username.',
|
||||
'No user with username "%s" exists.',
|
||||
$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