2011-06-14 12:18:40 -07:00
|
|
|
<?php
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Installs arcanist certificates.
|
|
|
|
*/
|
2014-07-22 07:49:15 +10:00
|
|
|
final class ArcanistInstallCertificateWorkflow extends ArcanistWorkflow {
|
2011-06-14 12:18:40 -07:00
|
|
|
|
Make Arcanist workflow names explicit
Summary:
Currently, adding a new workflow requires you to override ArcanistConfiguration, which is messy. Instead, just load everything that extends ArcanistBaseWorkflow.
Remove all the rules tying workflow names to class names through arcane incantations.
This has a very small performance cost in that we need to load every Workflow class every time now, but we don't hit __init__ and such anymore and it was pretty negligible on my machine (98ms vs 104ms or something).
Test Plan: Ran "arc help", "arc which", "arc diff", etc.
Reviewers: edward, vrana, btrahan
Reviewed By: edward
CC: aran, zeeg
Differential Revision: https://secure.phabricator.com/D3691
2012-10-17 08:35:03 -07:00
|
|
|
public function getWorkflowName() {
|
|
|
|
return 'install-certificate';
|
|
|
|
}
|
|
|
|
|
2012-03-05 10:02:37 -08:00
|
|
|
public function getCommandSynopses() {
|
2011-06-14 12:18:40 -07:00
|
|
|
return phutil_console_format(<<<EOTEXT
|
|
|
|
**install-certificate** [uri]
|
2012-03-05 10:02:37 -08:00
|
|
|
EOTEXT
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getCommandHelp() {
|
|
|
|
return phutil_console_format(<<<EOTEXT
|
2011-06-14 12:18:40 -07:00
|
|
|
Supports: http, https
|
|
|
|
Installs Conduit credentials into your ~/.arcrc for the given install
|
|
|
|
of Phabricator. You need to do this before you can use 'arc', as it
|
|
|
|
enables 'arc' to link your command-line activity with your account on
|
|
|
|
the web. Run this command from within a project directory to install
|
|
|
|
that project's certificate, or specify an explicit URI (like
|
|
|
|
"https://phabricator.example.com/").
|
|
|
|
EOTEXT
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getArguments() {
|
|
|
|
return array(
|
|
|
|
'*' => 'uri',
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2015-01-07 07:36:00 +11:00
|
|
|
protected function shouldShellComplete() {
|
2011-06-14 12:18:40 -07:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function requiresConduit() {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function requiresWorkingCopy() {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function run() {
|
2014-12-15 11:12:38 -08:00
|
|
|
$console = PhutilConsole::getConsole();
|
|
|
|
|
2011-06-14 12:18:40 -07:00
|
|
|
$uri = $this->determineConduitURI();
|
2013-01-03 09:23:20 -08:00
|
|
|
$this->setConduitURI($uri);
|
2013-10-18 16:10:06 -07:00
|
|
|
$configuration_manager = $this->getConfigurationManager();
|
2011-06-14 12:18:40 -07:00
|
|
|
|
2013-10-18 16:10:06 -07:00
|
|
|
$config = $configuration_manager->readUserConfigurationFile();
|
2011-06-14 12:18:40 -07:00
|
|
|
|
2014-12-15 11:12:38 -08:00
|
|
|
$console->writeOut(
|
|
|
|
"%s\n",
|
|
|
|
pht('Trying to connect to server...'));
|
|
|
|
|
2012-12-17 17:58:53 -08:00
|
|
|
$conduit = $this->establishConduit()->getConduit();
|
2011-06-14 12:18:40 -07:00
|
|
|
try {
|
|
|
|
$conduit->callMethodSynchronous('conduit.ping', array());
|
|
|
|
} catch (Exception $ex) {
|
|
|
|
throw new ArcanistUsageException(
|
2014-12-15 11:12:38 -08:00
|
|
|
pht(
|
|
|
|
'Failed to connect to server (%s): %s',
|
|
|
|
$uri,
|
|
|
|
$ex->getMessage()));
|
2011-06-14 12:18:40 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
$token_uri = new PhutilURI($uri);
|
|
|
|
$token_uri->setPath('/conduit/token/');
|
|
|
|
|
2014-12-15 11:12:38 -08:00
|
|
|
// Check if this server supports the more modern token-based login.
|
|
|
|
$is_token_auth = false;
|
|
|
|
try {
|
|
|
|
$capabilities = $conduit->callMethodSynchronous(
|
|
|
|
'conduit.getcapabilities',
|
|
|
|
array());
|
|
|
|
$auth = idx($capabilities, 'authentication', array());
|
|
|
|
if (in_array('token', $auth)) {
|
|
|
|
$token_uri->setPath('/conduit/login/');
|
|
|
|
$is_token_auth = true;
|
|
|
|
}
|
|
|
|
} catch (Exception $ex) {
|
|
|
|
// Ignore.
|
|
|
|
}
|
|
|
|
|
2011-06-14 12:18:40 -07:00
|
|
|
echo phutil_console_format("**LOGIN TO PHABRICATOR**\n");
|
|
|
|
echo "Open this page in your browser and login to Phabricator if ".
|
|
|
|
"necessary:\n";
|
|
|
|
echo "\n";
|
|
|
|
echo " {$token_uri}\n";
|
|
|
|
echo "\n";
|
2014-12-15 11:12:38 -08:00
|
|
|
echo 'Then paste the API Token on that page below.';
|
2011-06-14 12:18:40 -07:00
|
|
|
|
|
|
|
|
|
|
|
do {
|
2014-12-15 11:12:38 -08:00
|
|
|
$token = phutil_console_prompt('Paste API Token from that page:');
|
2011-06-14 12:18:40 -07:00
|
|
|
$token = trim($token);
|
|
|
|
if (strlen($token)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} while (true);
|
|
|
|
|
2014-12-15 11:12:38 -08:00
|
|
|
if ($is_token_auth) {
|
|
|
|
if (strlen($token) != 32) {
|
|
|
|
throw new ArcanistUsageException(
|
|
|
|
pht(
|
|
|
|
'The token "%s" is not formatted correctly. API tokens should '.
|
|
|
|
'be 32 characters long. Make sure you visited the correct URI '.
|
|
|
|
'and copy/pasted the token correctly.',
|
|
|
|
$token));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (strncmp($token, 'cli-', 4) !== 0) {
|
|
|
|
throw new ArcanistUsageException(
|
|
|
|
pht(
|
|
|
|
'The token "%s" is not formatted correctly. Valid API tokens '.
|
|
|
|
'should begin "cli-" and be 32 characters long. Make sure you '.
|
|
|
|
'visited the correct URI and copy/pasted the token correctly.',
|
|
|
|
$token));
|
|
|
|
}
|
|
|
|
|
|
|
|
$conduit->setConduitToken($token);
|
|
|
|
try {
|
|
|
|
$conduit->callMethodSynchronous('user.whoami', array());
|
|
|
|
} catch (Exception $ex) {
|
|
|
|
throw new ArcanistUsageException(
|
|
|
|
pht(
|
|
|
|
'The token "%s" is not a valid API Token. The server returned '.
|
|
|
|
'this response when trying to use it as a token: %s',
|
|
|
|
$token,
|
|
|
|
$ex->getMessage()));
|
|
|
|
}
|
|
|
|
|
|
|
|
$config['hosts'][$uri] = array(
|
2011-06-14 12:18:40 -07:00
|
|
|
'token' => $token,
|
2014-12-15 11:12:38 -08:00
|
|
|
);
|
|
|
|
} else {
|
|
|
|
echo "\n";
|
|
|
|
echo "Downloading authentication certificate...\n";
|
|
|
|
$info = $conduit->callMethodSynchronous(
|
|
|
|
'conduit.getcertificate',
|
|
|
|
array(
|
|
|
|
'token' => $token,
|
|
|
|
'host' => $uri,
|
|
|
|
));
|
|
|
|
|
|
|
|
$user = $info['username'];
|
|
|
|
echo "Installing certificate for '{$user}'...\n";
|
|
|
|
$config['hosts'][$uri] = array(
|
|
|
|
'user' => $user,
|
|
|
|
'cert' => $info['certificate'],
|
|
|
|
);
|
|
|
|
}
|
2011-06-14 12:18:40 -07:00
|
|
|
|
2011-06-21 16:03:02 -07:00
|
|
|
echo "Writing ~/.arcrc...\n";
|
2013-10-18 16:10:06 -07:00
|
|
|
$configuration_manager->writeUserConfigurationFile($config);
|
2011-06-14 12:18:40 -07:00
|
|
|
|
2014-12-15 11:12:38 -08:00
|
|
|
if ($is_token_auth) {
|
|
|
|
echo phutil_console_format(
|
|
|
|
"<bg:green>** SUCCESS! **</bg> API Token installed.\n");
|
|
|
|
} else {
|
|
|
|
echo phutil_console_format(
|
|
|
|
"<bg:green>** SUCCESS! **</bg> Certificate installed.\n");
|
|
|
|
}
|
2011-06-14 12:18:40 -07:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
private function determineConduitURI() {
|
|
|
|
$uri = $this->getArgument('uri');
|
|
|
|
if (count($uri) > 1) {
|
2014-05-23 13:53:05 -07:00
|
|
|
throw new ArcanistUsageException('Specify at most one URI.');
|
2011-06-14 12:18:40 -07:00
|
|
|
} else if (count($uri) == 1) {
|
|
|
|
$uri = reset($uri);
|
|
|
|
} else {
|
2012-01-23 15:31:56 -08:00
|
|
|
$conduit_uri = $this->getConduitURI();
|
|
|
|
if (!$conduit_uri) {
|
2011-06-14 12:18:40 -07:00
|
|
|
throw new ArcanistUsageException(
|
2014-05-23 13:53:05 -07:00
|
|
|
'Specify an explicit URI or run this command from within a project '.
|
|
|
|
'which is configured with a .arcconfig.');
|
2011-06-14 12:18:40 -07:00
|
|
|
}
|
|
|
|
$uri = $conduit_uri;
|
|
|
|
}
|
|
|
|
|
|
|
|
$uri = new PhutilURI($uri);
|
|
|
|
$uri->setPath('/api/');
|
|
|
|
|
|
|
|
return (string)$uri;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|