Path: blob/master/src/applications/auth/future/PhabricatorDuoFuture.php
12256 views
<?php12final class PhabricatorDuoFuture3extends FutureProxy {45private $future;67private $integrationKey;8private $secretKey;9private $apiHostname;1011private $httpMethod = 'POST';12private $method;13private $parameters;14private $timeout;1516public function __construct() {17parent::__construct(null);18}1920public function setIntegrationKey($integration_key) {21$this->integrationKey = $integration_key;22return $this;23}2425public function setSecretKey(PhutilOpaqueEnvelope $key) {26$this->secretKey = $key;27return $this;28}2930public function setAPIHostname($hostname) {31$this->apiHostname = $hostname;32return $this;33}3435public function setMethod($method, array $parameters) {36$this->method = $method;37$this->parameters = $parameters;38return $this;39}4041public function setTimeout($timeout) {42$this->timeout = $timeout;43return $this;44}4546public function getTimeout() {47return $this->timeout;48}4950public function setHTTPMethod($method) {51$this->httpMethod = $method;52return $this;53}5455public function getHTTPMethod() {56return $this->httpMethod;57}5859protected function getProxiedFuture() {60if (!$this->future) {61if ($this->integrationKey === null) {62throw new PhutilInvalidStateException('setIntegrationKey');63}6465if ($this->secretKey === null) {66throw new PhutilInvalidStateException('setSecretKey');67}6869if ($this->apiHostname === null) {70throw new PhutilInvalidStateException('setAPIHostname');71}7273if ($this->method === null || $this->parameters === null) {74throw new PhutilInvalidStateException('setMethod');75}7677$path = (string)urisprintf('/auth/v2/%s', $this->method);7879$host = $this->apiHostname;80$host = phutil_utf8_strtolower($host);8182$data = $this->parameters;83$date = date('r');8485$http_method = $this->getHTTPMethod();8687ksort($data);88$data_parts = phutil_build_http_querystring($data);8990$corpus = array(91$date,92$http_method,93$host,94$path,95$data_parts,96);97$corpus = implode("\n", $corpus);9899$signature = hash_hmac(100'sha1',101$corpus,102$this->secretKey->openEnvelope());103$signature = new PhutilOpaqueEnvelope($signature);104105if ($http_method === 'GET') {106$uri_data = $data;107$body_data = array();108} else {109$uri_data = array();110$body_data = $data;111}112113$uri = id(new PhutilURI('', $uri_data))114->setProtocol('https')115->setDomain($host)116->setPath($path);117118$future = id(new HTTPSFuture($uri, $body_data))119->setHTTPBasicAuthCredentials($this->integrationKey, $signature)120->setMethod($http_method)121->addHeader('Accept', 'application/json')122->addHeader('Date', $date);123124$timeout = $this->getTimeout();125if ($timeout) {126$future->setTimeout($timeout);127}128129$this->future = $future;130}131132return $this->future;133}134135protected function didReceiveResult($result) {136list($status, $body, $headers) = $result;137138if ($status->isError()) {139throw $status;140}141142try {143$data = phutil_json_decode($body);144} catch (PhutilJSONParserException $ex) {145throw new PhutilProxyException(146pht('Expected JSON response from Duo.'),147$ex);148}149150return $data;151}152153}154155156