mirror of
https://we.phorge.it/source/arcanist.git
synced 2024-12-25 23:10:56 +01:00
"arc install-certificate", client side changes
Summary: Provide an "install-certificate" workflow to simplify ~/.arcrc edits. See also D460. Test Plan: Installed certificates via "arc install-certificate". Reviewed By: aran Reviewers: aran, jungejason, tuomaspelkonen CC: aran, epriestley Differential Revision: 465
This commit is contained in:
parent
36de84eeee
commit
d73179ea99
6 changed files with 212 additions and 11 deletions
|
@ -61,6 +61,7 @@ if (function_exists('posix_isatty') && !posix_isatty(STDOUT)) {
|
|||
}
|
||||
|
||||
$args = array_values($args);
|
||||
$working_directory = $_SERVER['PWD'];
|
||||
|
||||
try {
|
||||
|
||||
|
@ -72,7 +73,7 @@ try {
|
|||
throw new ArcanistUsageException("No command provided. Try 'arc help'.");
|
||||
}
|
||||
|
||||
$working_copy = ArcanistWorkingCopyIdentity::newFromPath($_SERVER['PWD']);
|
||||
$working_copy = ArcanistWorkingCopyIdentity::newFromPath($working_directory);
|
||||
if ($load) {
|
||||
$libs = $load;
|
||||
} else {
|
||||
|
@ -118,16 +119,7 @@ try {
|
|||
}
|
||||
}
|
||||
|
||||
$user_config = array();
|
||||
$user_config_path = getenv('HOME').'/.arcrc';
|
||||
if (Filesystem::pathExists($user_config_path)) {
|
||||
$user_config_data = Filesystem::readFile($user_config_path);
|
||||
$user_config = json_decode($user_config_data, true);
|
||||
if (!is_array($user_config)) {
|
||||
throw new ArcanistUsageException(
|
||||
"Your '~/.arcrc' file is not a valid JSON file.");
|
||||
}
|
||||
}
|
||||
$user_config = ArcanistBaseWorkflow::readUserConfigurationFile();
|
||||
|
||||
$config = $working_copy->getConfig('arcanist_configuration');
|
||||
if ($config) {
|
||||
|
@ -145,6 +137,7 @@ try {
|
|||
}
|
||||
$workflow->setArcanistConfiguration($config);
|
||||
$workflow->setCommand($command);
|
||||
$workflow->setWorkingDirectory($working_directory);
|
||||
$workflow->parseArguments(array_slice($args, 1));
|
||||
|
||||
$need_working_copy = $workflow->requiresWorkingCopy();
|
||||
|
|
|
@ -36,6 +36,7 @@ phutil_register_library_map(array(
|
|||
'ArcanistGitAPI' => 'repository/api/git',
|
||||
'ArcanistGitHookPreReceiveWorkflow' => 'workflow/git-hook-pre-receive',
|
||||
'ArcanistHelpWorkflow' => 'workflow/help',
|
||||
'ArcanistInstallCertificateWorkflow' => 'workflow/install-certificate',
|
||||
'ArcanistLiberateLintEngine' => 'lint/engine/liberate',
|
||||
'ArcanistLiberateWorkflow' => 'workflow/liberate',
|
||||
'ArcanistLicenseLinter' => 'lint/linter/license',
|
||||
|
@ -101,6 +102,7 @@ phutil_register_library_map(array(
|
|||
'ArcanistGitAPI' => 'ArcanistRepositoryAPI',
|
||||
'ArcanistGitHookPreReceiveWorkflow' => 'ArcanistBaseWorkflow',
|
||||
'ArcanistHelpWorkflow' => 'ArcanistBaseWorkflow',
|
||||
'ArcanistInstallCertificateWorkflow' => 'ArcanistBaseWorkflow',
|
||||
'ArcanistLiberateLintEngine' => 'ArcanistLintEngine',
|
||||
'ArcanistLiberateWorkflow' => 'ArcanistBaseWorkflow',
|
||||
'ArcanistLicenseLinter' => 'ArcanistLinter',
|
||||
|
|
|
@ -33,6 +33,7 @@ class ArcanistBaseWorkflow {
|
|||
|
||||
private $arcanistConfiguration;
|
||||
private $parentWorkflow;
|
||||
private $workingDirectory;
|
||||
|
||||
private $changeCache = array();
|
||||
|
||||
|
@ -91,6 +92,15 @@ class ArcanistBaseWorkflow {
|
|||
return array();
|
||||
}
|
||||
|
||||
public function setWorkingDirectory($working_directory) {
|
||||
$this->workingDirectory = $working_directory;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getWorkingDirectory() {
|
||||
return $this->workingDirectory;
|
||||
}
|
||||
|
||||
private function setParentWorkflow($parent_workflow) {
|
||||
$this->parentWorkflow = $parent_workflow;
|
||||
return $this;
|
||||
|
@ -627,4 +637,22 @@ class ArcanistBaseWorkflow {
|
|||
return $argv;
|
||||
}
|
||||
|
||||
public static function getUserConfigurationFileLocation() {
|
||||
return getenv('HOME').'/.arcrc';
|
||||
}
|
||||
|
||||
public static function readUserConfigurationFile() {
|
||||
$user_config = array();
|
||||
$user_config_path = self::getUserConfigurationFileLocation();
|
||||
if (Filesystem::pathExists($user_config_path)) {
|
||||
$user_config_data = Filesystem::readFile($user_config_path);
|
||||
$user_config = json_decode($user_config_data, true);
|
||||
if (!is_array($user_config)) {
|
||||
throw new ArcanistUsageException(
|
||||
"Your '~/.arcrc' file is not a valid JSON file.");
|
||||
}
|
||||
}
|
||||
return $user_config;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ phutil_require_module('arcanist', 'parser/diff/change');
|
|||
phutil_require_module('arcanist', 'repository/api/git');
|
||||
|
||||
phutil_require_module('phutil', 'console');
|
||||
phutil_require_module('phutil', 'filesystem');
|
||||
phutil_require_module('phutil', 'future/exec');
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,156 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Installs arcanist certificates.
|
||||
*
|
||||
* @group workflow
|
||||
*/
|
||||
class ArcanistInstallCertificateWorkflow extends ArcanistBaseWorkflow {
|
||||
|
||||
public function getCommandHelp() {
|
||||
return phutil_console_format(<<<EOTEXT
|
||||
**install-certificate** [uri]
|
||||
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',
|
||||
);
|
||||
}
|
||||
|
||||
public function shouldShellComplete() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function requiresConduit() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function requiresWorkingCopy() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function run() {
|
||||
|
||||
$uri = $this->determineConduitURI();
|
||||
|
||||
echo "Installing certificate for '{$uri}'...\n";
|
||||
|
||||
$config = self::readUserConfigurationFile();
|
||||
|
||||
echo "Trying to connect to server...\n";
|
||||
$conduit = new ConduitClient($uri);
|
||||
$conduit->setTimeout(5);
|
||||
try {
|
||||
$conduit->callMethodSynchronous('conduit.ping', array());
|
||||
} catch (Exception $ex) {
|
||||
throw new ArcanistUsageException(
|
||||
"Failed to connect to server: ".$ex->getMessage());
|
||||
}
|
||||
echo "Connection OK!\n";
|
||||
|
||||
$token_uri = new PhutilURI($uri);
|
||||
$token_uri->setPath('/conduit/token/');
|
||||
|
||||
echo "\n";
|
||||
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";
|
||||
echo "Then paste the token on that page below.";
|
||||
|
||||
|
||||
do {
|
||||
$token = phutil_console_prompt('Paste token from that page:');
|
||||
$token = trim($token);
|
||||
if (strlen($token)) {
|
||||
break;
|
||||
}
|
||||
} while (true);
|
||||
|
||||
echo "\n";
|
||||
echo "Downloading authentication certificate...\n";
|
||||
$info = $conduit->callMethodSynchronous(
|
||||
'conduit.getcertificate',
|
||||
array(
|
||||
'token' => $token,
|
||||
));
|
||||
|
||||
$user = $info['username'];
|
||||
echo "Installing certificate for '{$user}'...\n";
|
||||
$config['hosts'][$uri] = array(
|
||||
'user' => $user,
|
||||
'cert' => $info['certificate'],
|
||||
);
|
||||
|
||||
$json_encoder = new PhutilJSON();
|
||||
$json = $json_encoder->encodeFormatted($config);
|
||||
|
||||
echo "Writing ~/.arcconfig...\n";
|
||||
|
||||
$path = self::getUserConfigurationFileLocation();
|
||||
Filesystem::writeFile($path, $json);
|
||||
execx('chmod 600 %s', $path);
|
||||
|
||||
echo phutil_console_format(
|
||||
"<bg:green>** SUCCESS! **</bg> Certificate installed.\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private function determineConduitURI() {
|
||||
$uri = $this->getArgument('uri');
|
||||
if (count($uri) > 1) {
|
||||
throw new ArcanistUsageException("Specify at most one URI.");
|
||||
} else if (count($uri) == 1) {
|
||||
$uri = reset($uri);
|
||||
} else {
|
||||
$working_copy = ArcanistWorkingCopyIdentity::newFromPath(
|
||||
$this->getWorkingDirectory());
|
||||
if (!$working_copy->getProjectRoot()) {
|
||||
throw new ArcanistUsageException(
|
||||
"Specify an explicit URI or run this command from within a project ".
|
||||
"which is configured with a .arcconfig.");
|
||||
}
|
||||
$conduit_uri = $working_copy->getConduitURI();
|
||||
if (!$conduit_uri) {
|
||||
throw new ArcanistUsageException(
|
||||
"This project's .arcconfig does not specify a Conduit URI.");
|
||||
}
|
||||
$uri = $conduit_uri;
|
||||
}
|
||||
|
||||
$uri = new PhutilURI($uri);
|
||||
$uri->setPath('/api/');
|
||||
|
||||
return (string)$uri;
|
||||
}
|
||||
|
||||
}
|
21
src/workflow/install-certificate/__init__.php
Normal file
21
src/workflow/install-certificate/__init__.php
Normal file
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('arcanist', 'exception/usage');
|
||||
phutil_require_module('arcanist', 'workflow/base');
|
||||
phutil_require_module('arcanist', 'workingcopyidentity');
|
||||
|
||||
phutil_require_module('phutil', 'conduit/client');
|
||||
phutil_require_module('phutil', 'console');
|
||||
phutil_require_module('phutil', 'filesystem');
|
||||
phutil_require_module('phutil', 'future/exec');
|
||||
phutil_require_module('phutil', 'parser/json');
|
||||
phutil_require_module('phutil', 'parser/uri');
|
||||
|
||||
|
||||
phutil_require_source('ArcanistInstallCertificateWorkflow.php');
|
Loading…
Reference in a new issue