@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.)
hq.recaptime.dev/wiki/Phorge
phorge
phabricator
1<?php
2
3final class HeraldWebhookRequest
4 extends HeraldDAO
5 implements
6 PhabricatorPolicyInterface,
7 PhabricatorExtendedPolicyInterface {
8
9 protected $webhookPHID;
10 protected $objectPHID;
11 protected $status;
12 protected $properties = array();
13 protected $lastRequestResult;
14 protected $lastRequestEpoch;
15
16 private $webhook = self::ATTACHABLE;
17
18 const RETRY_NEVER = 'never';
19 const RETRY_FOREVER = 'forever';
20
21 const STATUS_QUEUED = 'queued';
22 const STATUS_FAILED = 'failed';
23 const STATUS_SENT = 'sent';
24
25 const RESULT_NONE = 'none';
26 const RESULT_OKAY = 'okay';
27 const RESULT_FAIL = 'fail';
28
29 const ERRORTYPE_HOOK = 'hook';
30 const ERRORTYPE_HTTP = 'http';
31 const ERRORTYPE_TIMEOUT = 'timeout';
32
33 const ERROR_SILENT = 'silent';
34 const ERROR_DISABLED = 'disabled';
35 const ERROR_URI = 'uri';
36 const ERROR_OBJECT = 'object';
37
38 protected function getConfiguration() {
39 return array(
40 self::CONFIG_AUX_PHID => true,
41 self::CONFIG_SERIALIZATION => array(
42 'properties' => self::SERIALIZATION_JSON,
43 ),
44 self::CONFIG_COLUMN_SCHEMA => array(
45 'status' => 'text32',
46 'lastRequestResult' => 'text32',
47 'lastRequestEpoch' => 'epoch',
48 ),
49 self::CONFIG_KEY_SCHEMA => array(
50 'key_ratelimit' => array(
51 'columns' => array(
52 'webhookPHID',
53 'lastRequestResult',
54 'lastRequestEpoch',
55 ),
56 ),
57 'key_collect' => array(
58 'columns' => array('dateCreated'),
59 ),
60 ),
61 ) + parent::getConfiguration();
62 }
63
64 public function getPHIDType() {
65 return HeraldWebhookRequestPHIDType::TYPECONST;
66 }
67
68 public static function initializeNewWebhookRequest(HeraldWebhook $hook) {
69 return id(new self())
70 ->setWebhookPHID($hook->getPHID())
71 ->attachWebhook($hook)
72 ->setStatus(self::STATUS_QUEUED)
73 ->setRetryMode(self::RETRY_NEVER)
74 ->setLastRequestResult(self::RESULT_NONE)
75 ->setLastRequestEpoch(0);
76 }
77
78 public function getWebhook() {
79 return $this->assertAttached($this->webhook);
80 }
81
82 public function attachWebhook(HeraldWebhook $hook) {
83 $this->webhook = $hook;
84 return $this;
85 }
86
87 protected function setProperty($key, $value) {
88 $this->properties[$key] = $value;
89 return $this;
90 }
91
92 protected function getProperty($key, $default = null) {
93 return idx($this->properties, $key, $default);
94 }
95
96 public function setRetryMode($mode) {
97 return $this->setProperty('retry', $mode);
98 }
99
100 public function getRetryMode() {
101 return $this->getProperty('retry');
102 }
103
104 public function setErrorType($error_type) {
105 return $this->setProperty('errorType', $error_type);
106 }
107
108 public function getErrorType() {
109 return $this->getProperty('errorType');
110 }
111
112 public function setErrorCode($error_code) {
113 return $this->setProperty('errorCode', $error_code);
114 }
115
116 public function getErrorCode() {
117 return $this->getProperty('errorCode');
118 }
119
120 public function getErrorTypeForDisplay() {
121 $map = array(
122 self::ERRORTYPE_HOOK => pht('Hook Error'),
123 self::ERRORTYPE_HTTP => pht('HTTP Status Code'),
124 self::ERRORTYPE_TIMEOUT => pht('Request Timeout'),
125 );
126
127 $type = $this->getErrorType();
128 return idx($map, $type, $type);
129 }
130
131 public function getErrorCodeForDisplay() {
132 $code = $this->getErrorCode();
133
134 if ($this->getErrorType() !== self::ERRORTYPE_HOOK) {
135 return $code;
136 }
137
138 $spec = $this->getHookErrorSpec($code);
139 return idx($spec, 'display', $code);
140 }
141
142 public function setTransactionPHIDs(array $phids) {
143 return $this->setProperty('transactionPHIDs', $phids);
144 }
145
146 public function getTransactionPHIDs() {
147 return $this->getProperty('transactionPHIDs', array());
148 }
149
150 public function setTriggerPHIDs(array $phids) {
151 return $this->setProperty('triggerPHIDs', $phids);
152 }
153
154 public function getTriggerPHIDs() {
155 return $this->getProperty('triggerPHIDs', array());
156 }
157
158 public function setIsSilentAction($bool) {
159 return $this->setProperty('silent', $bool);
160 }
161
162 public function getIsSilentAction() {
163 return $this->getProperty('silent', false);
164 }
165
166 public function setIsTestAction($bool) {
167 return $this->setProperty('test', $bool);
168 }
169
170 public function getIsTestAction() {
171 return $this->getProperty('test', false);
172 }
173
174 public function setIsSecureAction($bool) {
175 return $this->setProperty('secure', $bool);
176 }
177
178 public function getIsSecureAction() {
179 return $this->getProperty('secure', false);
180 }
181
182 public function queueCall() {
183 PhabricatorWorker::scheduleTask(
184 'HeraldWebhookWorker',
185 array(
186 'webhookRequestPHID' => $this->getPHID(),
187 ),
188 array(
189 'objectPHID' => $this->getPHID(),
190 ));
191
192 return $this;
193 }
194
195 public function newStatusIcon() {
196 switch ($this->getStatus()) {
197 case self::STATUS_QUEUED:
198 $icon = 'fa-refresh';
199 $color = 'blue';
200 $tooltip = pht('Queued');
201 break;
202 case self::STATUS_SENT:
203 $icon = 'fa-check';
204 $color = 'green';
205 $tooltip = pht('Sent');
206 break;
207 case self::STATUS_FAILED:
208 default:
209 $icon = 'fa-times';
210 $color = 'red';
211 $tooltip = pht('Failed');
212 break;
213
214 }
215
216 return id(new PHUIIconView())
217 ->setIcon($icon, $color)
218 ->setTooltip($tooltip);
219 }
220
221 private function getHookErrorSpec($code) {
222 $map = $this->getHookErrorMap();
223 return idx($map, $code, array());
224 }
225
226 private function getHookErrorMap() {
227 return array(
228 self::ERROR_SILENT => array(
229 'display' => pht('In Silent Mode'),
230 ),
231 self::ERROR_DISABLED => array(
232 'display' => pht('Hook Disabled'),
233 ),
234 self::ERROR_URI => array(
235 'display' => pht('Invalid URI'),
236 ),
237 self::ERROR_OBJECT => array(
238 'display' => pht('Invalid Object'),
239 ),
240 );
241 }
242
243
244/* -( PhabricatorPolicyInterface )----------------------------------------- */
245
246
247 public function getCapabilities() {
248 return array(
249 PhabricatorPolicyCapability::CAN_VIEW,
250 );
251 }
252
253 public function getPolicy($capability) {
254 switch ($capability) {
255 case PhabricatorPolicyCapability::CAN_VIEW:
256 return PhabricatorPolicies::getMostOpenPolicy();
257 }
258 }
259
260 public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
261 return false;
262 }
263
264
265/* -( PhabricatorExtendedPolicyInterface )--------------------------------- */
266
267
268 public function getExtendedPolicy($capability, PhabricatorUser $viewer) {
269 return array(
270 array($this->getWebhook(), PhabricatorPolicyCapability::CAN_VIEW),
271 );
272 }
273
274
275
276}