1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2025-02-25 13:09:08 +01:00
phorge-phorge/src/applications/auth/management/PhabricatorAuthManagementRecoverWorkflow.php
epriestley ff49d1ef77 Allow "bin/auth recover" to generate a link which forces a full login session
Summary:
Depends on D19902. Ref T13222. This is mostly a "while I'm in here..." change since MFA is getting touched so much anyway.

Doing cluster support, I sometimes need to log into user accounts on instances that have MFA. I currently accomplish this by doing `bin/auth recover`, getting a parital session, and then forcing it into a full session in the database. This is inconvenient and somewhat dangerous.

Instead, allow `bin/auth recover` to generate a link that skips the "partial session" stage: adding required MFA, providing MFA, and signing legalpad documents.

Anyone who can run `bin/auth recover` can do this anyway, this just reduces the chance I accidentally bypass MFA on the wrong session when doing support stuff.

Test Plan:
  - Logged in with `bin/auth recover`, was prompted for MFA.
  - Logged in with `bin/auth recover --force-full-session`, was not prompted for MFA.
  - Did a password reset, followed reset link, was prompted for MFA.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13222

Differential Revision: https://secure.phabricator.com/D19903
2018-12-28 00:15:36 -08:00

91 lines
2.6 KiB
PHP

<?php
final class PhabricatorAuthManagementRecoverWorkflow
extends PhabricatorAuthManagementWorkflow {
protected function didConstruct() {
$this
->setName('recover')
->setExamples('**recover** __username__')
->setSynopsis(
pht(
'Recover access to an account if you have locked yourself out '.
'of Phabricator.'))
->setArguments(
array(
array(
'name' => 'force-full-session',
'help' => pht(
'Recover directly into a full session without requiring MFA '.
'or other login checks.'),
),
array(
'name' => 'username',
'wildcard' => true,
),
));
}
public function execute(PhutilArgumentParser $args) {
$usernames = $args->getArg('username');
if (!$usernames) {
throw new PhutilArgumentUsageException(
pht('You must specify the username of the account to recover.'));
} else if (count($usernames) > 1) {
throw new PhutilArgumentUsageException(
pht('You can only recover the username for one account.'));
}
$username = head($usernames);
$user = id(new PhabricatorPeopleQuery())
->setViewer($this->getViewer())
->withUsernames(array($username))
->executeOne();
if (!$user) {
throw new PhutilArgumentUsageException(
pht(
'No such user "%s" to recover.',
$username));
}
if (!$user->canEstablishWebSessions()) {
throw new PhutilArgumentUsageException(
pht(
'This account ("%s") can not establish web sessions, so it is '.
'not possible to generate a functional recovery link. Special '.
'accounts like daemons and mailing lists can not log in via the '.
'web UI.',
$username));
}
$force_full_session = $args->getArg('force-full-session');
$engine = new PhabricatorAuthSessionEngine();
$onetime_uri = $engine->getOneTimeLoginURI(
$user,
null,
PhabricatorAuthSessionEngine::ONETIME_RECOVER,
$force_full_session);
$console = PhutilConsole::getConsole();
$console->writeOut(
pht(
'Use this link to recover access to the "%s" account from the web '.
'interface:',
$username));
$console->writeOut("\n\n");
$console->writeOut(' %s', $onetime_uri);
$console->writeOut("\n\n");
$console->writeOut(
"%s\n",
pht(
'After logging in, you can use the "Auth" application to add or '.
'restore authentication providers and allow normal logins to '.
'succeed.'));
return 0;
}
}