Page MenuHomePhabricator

D20026.diff
No OneTemporary

D20026.diff

diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -2983,6 +2983,7 @@
'PhabricatorDraftEngine' => 'applications/transactions/draft/PhabricatorDraftEngine.php',
'PhabricatorDraftInterface' => 'applications/transactions/draft/PhabricatorDraftInterface.php',
'PhabricatorDrydockApplication' => 'applications/drydock/application/PhabricatorDrydockApplication.php',
+ 'PhabricatorDuoFuture' => 'applications/auth/future/PhabricatorDuoFuture.php',
'PhabricatorEdgeChangeRecord' => 'infrastructure/edges/util/PhabricatorEdgeChangeRecord.php',
'PhabricatorEdgeChangeRecordTestCase' => 'infrastructure/edges/__tests__/PhabricatorEdgeChangeRecordTestCase.php',
'PhabricatorEdgeConfig' => 'infrastructure/edges/constants/PhabricatorEdgeConfig.php',
@@ -8829,6 +8830,7 @@
'PhabricatorDraftDAO' => 'PhabricatorLiskDAO',
'PhabricatorDraftEngine' => 'Phobject',
'PhabricatorDrydockApplication' => 'PhabricatorApplication',
+ 'PhabricatorDuoFuture' => 'FutureProxy',
'PhabricatorEdgeChangeRecord' => 'Phobject',
'PhabricatorEdgeChangeRecordTestCase' => 'PhabricatorTestCase',
'PhabricatorEdgeConfig' => 'PhabricatorEdgeConstants',
diff --git a/src/applications/auth/future/PhabricatorDuoFuture.php b/src/applications/auth/future/PhabricatorDuoFuture.php
new file mode 100644
--- /dev/null
+++ b/src/applications/auth/future/PhabricatorDuoFuture.php
@@ -0,0 +1,150 @@
+<?php
+
+final class PhabricatorDuoFuture
+ extends FutureProxy {
+
+ private $future;
+
+ private $integrationKey;
+ private $secretKey;
+ private $apiHostname;
+
+ private $httpMethod = 'POST';
+ private $method;
+ private $parameters;
+ private $timeout;
+
+ public function __construct() {
+ parent::__construct(null);
+ }
+
+ public function setIntegrationKey($integration_key) {
+ $this->integrationKey = $integration_key;
+ return $this;
+ }
+
+ public function setSecretKey(PhutilOpaqueEnvelope $key) {
+ $this->secretKey = $key;
+ return $this;
+ }
+
+ public function setAPIHostname($hostname) {
+ $this->apiHostname = $hostname;
+ return $this;
+ }
+
+ public function setMethod($method, array $parameters) {
+ $this->method = $method;
+ $this->parameters = $parameters;
+ return $this;
+ }
+
+ public function setTimeout($timeout) {
+ $this->timeout = $timeout;
+ return $this;
+ }
+
+ public function getTimeout() {
+ return $this->timeout;
+ }
+
+ public function setHTTPMethod($method) {
+ $this->httpMethod = $method;
+ return $this;
+ }
+
+ public function getHTTPMethod() {
+ return $this->httpMethod;
+ }
+
+ protected function getProxiedFuture() {
+ if (!$this->future) {
+ if ($this->integrationKey === null) {
+ throw new PhutilInvalidStateException('setIntegrationKey');
+ }
+
+ if ($this->secretKey === null) {
+ throw new PhutilInvalidStateException('setSecretKey');
+ }
+
+ if ($this->apiHostname === null) {
+ throw new PhutilInvalidStateException('setAPIHostname');
+ }
+
+ if ($this->method === null || $this->parameters === null) {
+ throw new PhutilInvalidStateException('setMethod');
+ }
+
+ $path = (string)urisprintf('/auth/v2/%s', $this->method);
+
+ $host = $this->apiHostname;
+ $host = phutil_utf8_strtolower($host);
+
+ $uri = id(new PhutilURI(''))
+ ->setProtocol('https')
+ ->setDomain($host)
+ ->setPath($path);
+
+ $data = $this->parameters;
+ $date = date('r');
+
+ $http_method = $this->getHTTPMethod();
+
+ ksort($data);
+ $data_parts = array();
+ foreach ($data as $key => $value) {
+ $data_parts[] = rawurlencode($key).'='.rawurlencode($value);
+ }
+ $data_parts = implode('&', $data_parts);
+
+ $corpus = array(
+ $date,
+ $http_method,
+ $host,
+ $path,
+ $data_parts,
+ );
+ $corpus = implode("\n", $corpus);
+
+ $signature = hash_hmac(
+ 'sha1',
+ $corpus,
+ $this->secretKey->openEnvelope());
+ $signature = new PhutilOpaqueEnvelope($signature);
+
+ $future = id(new HTTPSFuture($uri, $data))
+ ->setHTTPBasicAuthCredentials($this->integrationKey, $signature)
+ ->setMethod($http_method)
+ ->addHeader('Accept', 'application/json')
+ ->addHeader('Date', $date);
+
+ $timeout = $this->getTimeout();
+ if ($timeout) {
+ $future->setTimeout($timeout);
+ }
+
+ $this->future = $future;
+ }
+
+ return $this->future;
+ }
+
+ protected function didReceiveResult($result) {
+ list($status, $body, $headers) = $result;
+
+ if ($status->isError()) {
+ throw $status;
+ }
+
+ try {
+ $data = phutil_json_decode($body);
+ } catch (PhutilJSONParserException $ex) {
+ throw new PhutilProxyException(
+ pht('Expected JSON response from Duo.'),
+ $ex);
+ }
+
+ return $data;
+ }
+
+}
diff --git a/src/applications/metamta/future/PhabricatorTwilioFuture.php b/src/applications/metamta/future/PhabricatorTwilioFuture.php
--- a/src/applications/metamta/future/PhabricatorTwilioFuture.php
+++ b/src/applications/metamta/future/PhabricatorTwilioFuture.php
@@ -58,7 +58,7 @@
$this->accountSID,
$this->method);
- $uri = id(new PhutilURI('https://api.twilio.com/2010-04-01/accounts/'))
+ $uri = id(new PhutilURI('https://api.twilio.com/'))
->setPath($path);
$data = $this->parameters;

File Metadata

Mime Type
text/plain
Expires
Sun, Mar 16, 5:20 AM (5 d, 20 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7705997
Default Alt Text
D20026.diff (5 KB)

Event Timeline