Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/src/applications/auth/future/PhabricatorDuoFuture.php
12256 views
1
<?php
2
3
final class PhabricatorDuoFuture
4
extends FutureProxy {
5
6
private $future;
7
8
private $integrationKey;
9
private $secretKey;
10
private $apiHostname;
11
12
private $httpMethod = 'POST';
13
private $method;
14
private $parameters;
15
private $timeout;
16
17
public function __construct() {
18
parent::__construct(null);
19
}
20
21
public function setIntegrationKey($integration_key) {
22
$this->integrationKey = $integration_key;
23
return $this;
24
}
25
26
public function setSecretKey(PhutilOpaqueEnvelope $key) {
27
$this->secretKey = $key;
28
return $this;
29
}
30
31
public function setAPIHostname($hostname) {
32
$this->apiHostname = $hostname;
33
return $this;
34
}
35
36
public function setMethod($method, array $parameters) {
37
$this->method = $method;
38
$this->parameters = $parameters;
39
return $this;
40
}
41
42
public function setTimeout($timeout) {
43
$this->timeout = $timeout;
44
return $this;
45
}
46
47
public function getTimeout() {
48
return $this->timeout;
49
}
50
51
public function setHTTPMethod($method) {
52
$this->httpMethod = $method;
53
return $this;
54
}
55
56
public function getHTTPMethod() {
57
return $this->httpMethod;
58
}
59
60
protected function getProxiedFuture() {
61
if (!$this->future) {
62
if ($this->integrationKey === null) {
63
throw new PhutilInvalidStateException('setIntegrationKey');
64
}
65
66
if ($this->secretKey === null) {
67
throw new PhutilInvalidStateException('setSecretKey');
68
}
69
70
if ($this->apiHostname === null) {
71
throw new PhutilInvalidStateException('setAPIHostname');
72
}
73
74
if ($this->method === null || $this->parameters === null) {
75
throw new PhutilInvalidStateException('setMethod');
76
}
77
78
$path = (string)urisprintf('/auth/v2/%s', $this->method);
79
80
$host = $this->apiHostname;
81
$host = phutil_utf8_strtolower($host);
82
83
$data = $this->parameters;
84
$date = date('r');
85
86
$http_method = $this->getHTTPMethod();
87
88
ksort($data);
89
$data_parts = phutil_build_http_querystring($data);
90
91
$corpus = array(
92
$date,
93
$http_method,
94
$host,
95
$path,
96
$data_parts,
97
);
98
$corpus = implode("\n", $corpus);
99
100
$signature = hash_hmac(
101
'sha1',
102
$corpus,
103
$this->secretKey->openEnvelope());
104
$signature = new PhutilOpaqueEnvelope($signature);
105
106
if ($http_method === 'GET') {
107
$uri_data = $data;
108
$body_data = array();
109
} else {
110
$uri_data = array();
111
$body_data = $data;
112
}
113
114
$uri = id(new PhutilURI('', $uri_data))
115
->setProtocol('https')
116
->setDomain($host)
117
->setPath($path);
118
119
$future = id(new HTTPSFuture($uri, $body_data))
120
->setHTTPBasicAuthCredentials($this->integrationKey, $signature)
121
->setMethod($http_method)
122
->addHeader('Accept', 'application/json')
123
->addHeader('Date', $date);
124
125
$timeout = $this->getTimeout();
126
if ($timeout) {
127
$future->setTimeout($timeout);
128
}
129
130
$this->future = $future;
131
}
132
133
return $this->future;
134
}
135
136
protected function didReceiveResult($result) {
137
list($status, $body, $headers) = $result;
138
139
if ($status->isError()) {
140
throw $status;
141
}
142
143
try {
144
$data = phutil_json_decode($body);
145
} catch (PhutilJSONParserException $ex) {
146
throw new PhutilProxyException(
147
pht('Expected JSON response from Duo.'),
148
$ex);
149
}
150
151
return $data;
152
}
153
154
}
155
156