From cf61f0e32dd16614745eeb7625a433f38e1c5126 Mon Sep 17 00:00:00 2001 From: Bob Trahan Date: Tue, 10 Jan 2012 16:48:59 -0800 Subject: [PATCH] Adding an "ssh" client for conduit Summary: ..."ssh" is in quotes 'cuz this is step 1 and there's no ssh in sight at the moment. Test Plan: ran api.php PHID-USER-xee4ju2teq7mflitwfcs differential.query a few times... - tried valid input, it worked! - tried bad input, it worked in that it failed and told me so! ran api.php crap_user differential.query a few times... - verified error message with respect to crap_user ran api.php PHID-USER-xee4ju2teq7mflitwfcs crap_method a few times... - verified error message with respect to crap_method visited http://phabricator.dev/conduit/method/differential.query a few times... - tried valid input, it worked! Reviewers: epriestley Reviewed By: epriestley CC: aran, btrahan, epriestley Maniphest Tasks: T550 Differential Revision: https://secure.phabricator.com/D1357 --- scripts/conduit/api.php | 97 +++++++++++++++++++ src/__phutil_library_map__.php | 1 + .../api/PhabricatorConduitAPIController.php | 15 ++- .../conduit/controller/api/__init__.php | 1 + .../protocol/request/ConduitAPIRequest.php | 4 +- .../protocol/response/ConduitAPIResponse.php | 63 ++++++++++++ .../conduit/protocol/response/__init__.php | 10 ++ 7 files changed, 181 insertions(+), 10 deletions(-) create mode 100644 scripts/conduit/api.php create mode 100644 src/applications/conduit/protocol/response/ConduitAPIResponse.php create mode 100644 src/applications/conduit/protocol/response/__init__.php diff --git a/scripts/conduit/api.php b/scripts/conduit/api.php new file mode 100644 index 0000000000..2844c2f393 --- /dev/null +++ b/scripts/conduit/api.php @@ -0,0 +1,97 @@ +#!/usr/bin/env php + \n"; + exit(1); +} + +$user = null; +$user_str = $argv[1]; +try { + $user = id(new PhabricatorUser()) + ->loadOneWhere('phid = %s', $user_str); +} catch (Exception $e) { + // no op; we'll error in a line or two +} +if (empty($user)) { + echo "usage: api.php \n" . + "user {$user_str} does not exist or failed to load\n"; + exit(1); +} + +$method = $argv[2]; +$method_class_str = ConduitAPIMethod::getClassNameFromAPIMethodName($method); +try { + $method_class = newv($method_class_str, array()); +} catch (Exception $e) { + echo "usage: api.php \n" . + "method {$method_class_str} does not exist\n"; + exit(1); +} +$log = new PhabricatorConduitMethodCallLog(); +$log->setMethod($method); + +$params = @file_get_contents('php://stdin'); +$params = json_decode($params, true); +if (!is_array($params)) { + echo "provide method parameters on stdin as a JSON blob"; + exit(1); +} + +// build a quick ConduitAPIRequest from stdin PLUS the authenticated user +$conduit_request = new ConduitAPIRequest($params); +$conduit_request->setUser($user); + +try { + $result = $method_class->executeMethod($conduit_request); + $error_code = null; + $error_info = null; +} catch (ConduitException $ex) { + $result = null; + $error_code = $ex->getMessage(); + if ($ex->getErrorDescription()) { + $error_info = $ex->getErrorDescription(); + } else { + $error_info = $method_handler->getErrorDescription($error_code); + } +} +$time_end = microtime(true); + +$response = id(new ConduitAPIResponse()) + ->setResult($result) + ->setErrorCode($error_code) + ->setErrorInfo($error_info); +echo $response->toJSON(), "\n"; + +// TODO -- how get $connection_id from SSH? +$connection_id = null; +$log->setConnectionID($connection_id); +$log->setError((string)$error_code); +$log->setDuration(1000000 * ($time_end - $time_start)); +$log->save(); + +exit(); diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 7f7fe2bb8f..aa0072fada 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -90,6 +90,7 @@ phutil_register_library_map(array( 'CelerityStaticResourceResponse' => 'infrastructure/celerity/response', 'ConduitAPIMethod' => 'applications/conduit/method/base', 'ConduitAPIRequest' => 'applications/conduit/protocol/request', + 'ConduitAPIResponse' => 'applications/conduit/protocol/response', 'ConduitAPI_arcanist_Method' => 'applications/conduit/method/arcanist/base', 'ConduitAPI_arcanist_projectinfo_Method' => 'applications/conduit/method/arcanist/projectinfo', 'ConduitAPI_conduit_connect_Method' => 'applications/conduit/method/conduit/connect', diff --git a/src/applications/conduit/controller/api/PhabricatorConduitAPIController.php b/src/applications/conduit/controller/api/PhabricatorConduitAPIController.php index 6ab7948f3d..a471485632 100644 --- a/src/applications/conduit/controller/api/PhabricatorConduitAPIController.php +++ b/src/applications/conduit/controller/api/PhabricatorConduitAPIController.php @@ -1,7 +1,7 @@ $result, - 'error_code' => $error_code, - 'error_info' => $error_info, - ); + $response = id(new ConduitAPIResponse()) + ->setResult($result) + ->setErrorCode($error_code) + ->setErrorInfo($error_info); switch ($request->getStr('output')) { case 'human': return $this->buildHumanReadableResponse( $method, $api_request, - $result); + $response->toDictionary()); case 'json': default: return id(new AphrontFileResponse()) ->setMimeType('application/json') - ->setContent('for(;;);'.json_encode($result)); + ->setContent('for(;;);'.$response->toJSON()); } } diff --git a/src/applications/conduit/controller/api/__init__.php b/src/applications/conduit/controller/api/__init__.php index e6c5f66402..c4bd197750 100644 --- a/src/applications/conduit/controller/api/__init__.php +++ b/src/applications/conduit/controller/api/__init__.php @@ -11,6 +11,7 @@ phutil_require_module('phabricator', 'aphront/writeguard'); phutil_require_module('phabricator', 'applications/conduit/controller/base'); phutil_require_module('phabricator', 'applications/conduit/method/base'); phutil_require_module('phabricator', 'applications/conduit/protocol/request'); +phutil_require_module('phabricator', 'applications/conduit/protocol/response'); phutil_require_module('phabricator', 'applications/conduit/storage/methodcalllog'); phutil_require_module('phabricator', 'applications/people/storage/user'); phutil_require_module('phabricator', 'storage/queryfx'); diff --git a/src/applications/conduit/protocol/request/ConduitAPIRequest.php b/src/applications/conduit/protocol/request/ConduitAPIRequest.php index d22099f3e0..cb3e9827a1 100644 --- a/src/applications/conduit/protocol/request/ConduitAPIRequest.php +++ b/src/applications/conduit/protocol/request/ConduitAPIRequest.php @@ -1,7 +1,7 @@ params; } - public function setUser($user) { + public function setUser(PhabricatorUser $user) { $this->user = $user; return $this; } diff --git a/src/applications/conduit/protocol/response/ConduitAPIResponse.php b/src/applications/conduit/protocol/response/ConduitAPIResponse.php new file mode 100644 index 0000000000..83b8f3bb24 --- /dev/null +++ b/src/applications/conduit/protocol/response/ConduitAPIResponse.php @@ -0,0 +1,63 @@ +result = $result; + return $this; + } + public function getResult() { + return $this->result; + } + + public function setErrorCode($error_code) { + $this->errorCode = $error_code; + return $this; + } + public function getErrorCode() { + return $this->errorCode; + } + + public function setErrorInfo($error_info) { + $this->errorInfo = $error_info; + return $this; + } + public function getErrorInfo() { + return $this->errorInfo; + } + + public function toDictionary() { + return array( + 'result' => $this->getResult(), + 'error_code' => $this->getErrorCode(), + 'error_info' => $this->getErrorInfo(), + ); + } + + public function toJSON() { + return json_encode($this->toDictionary()); + } +} diff --git a/src/applications/conduit/protocol/response/__init__.php b/src/applications/conduit/protocol/response/__init__.php new file mode 100644 index 0000000000..184c55a6d2 --- /dev/null +++ b/src/applications/conduit/protocol/response/__init__.php @@ -0,0 +1,10 @@ +