Correct a parameter order swap in "diffusion.historyquery" for Mercurial
[phabricator.git] / src / applications / herald / storage / HeraldWebhook.php
blob0101dbef527aad993ec39266d925218a4b3b4d1e
1 <?php
3 final class HeraldWebhook
4 extends HeraldDAO
5 implements
6 PhabricatorPolicyInterface,
7 PhabricatorApplicationTransactionInterface,
8 PhabricatorDestructibleInterface,
9 PhabricatorProjectInterface {
11 protected $name;
12 protected $webhookURI;
13 protected $viewPolicy;
14 protected $editPolicy;
15 protected $status;
16 protected $hmacKey;
18 const HOOKSTATUS_FIREHOSE = 'firehose';
19 const HOOKSTATUS_ENABLED = 'enabled';
20 const HOOKSTATUS_DISABLED = 'disabled';
22 protected function getConfiguration() {
23 return array(
24 self::CONFIG_AUX_PHID => true,
25 self::CONFIG_COLUMN_SCHEMA => array(
26 'name' => 'text128',
27 'webhookURI' => 'text255',
28 'status' => 'text32',
29 'hmacKey' => 'text32',
31 self::CONFIG_KEY_SCHEMA => array(
32 'key_status' => array(
33 'columns' => array('status'),
36 ) + parent::getConfiguration();
39 public function getPHIDType() {
40 return HeraldWebhookPHIDType::TYPECONST;
43 public static function initializeNewWebhook(PhabricatorUser $viewer) {
44 return id(new self())
45 ->setStatus(self::HOOKSTATUS_ENABLED)
46 ->setViewPolicy(PhabricatorPolicies::getMostOpenPolicy())
47 ->setEditPolicy($viewer->getPHID())
48 ->regenerateHMACKey();
51 public function getURI() {
52 return '/herald/webhook/view/'.$this->getID().'/';
55 public function isDisabled() {
56 return ($this->getStatus() === self::HOOKSTATUS_DISABLED);
59 public static function getStatusDisplayNameMap() {
60 $specs = self::getStatusSpecifications();
61 return ipull($specs, 'name', 'key');
64 private static function getStatusSpecifications() {
65 $specs = array(
66 array(
67 'key' => self::HOOKSTATUS_FIREHOSE,
68 'name' => pht('Firehose'),
69 'color' => 'orange',
70 'icon' => 'fa-star-o',
72 array(
73 'key' => self::HOOKSTATUS_ENABLED,
74 'name' => pht('Enabled'),
75 'color' => 'bluegrey',
76 'icon' => 'fa-check',
78 array(
79 'key' => self::HOOKSTATUS_DISABLED,
80 'name' => pht('Disabled'),
81 'color' => 'dark',
82 'icon' => 'fa-ban',
86 return ipull($specs, null, 'key');
90 private static function getSpecificationForStatus($status) {
91 $specs = self::getStatusSpecifications();
93 if (isset($specs[$status])) {
94 return $specs[$status];
97 return array(
98 'key' => $status,
99 'name' => pht('Unknown ("%s")', $status),
100 'icon' => 'fa-question',
101 'color' => 'indigo',
105 public static function getDisplayNameForStatus($status) {
106 $spec = self::getSpecificationForStatus($status);
107 return $spec['name'];
110 public static function getIconForStatus($status) {
111 $spec = self::getSpecificationForStatus($status);
112 return $spec['icon'];
115 public static function getColorForStatus($status) {
116 $spec = self::getSpecificationForStatus($status);
117 return $spec['color'];
120 public function getStatusDisplayName() {
121 $status = $this->getStatus();
122 return self::getDisplayNameForStatus($status);
125 public function getStatusIcon() {
126 $status = $this->getStatus();
127 return self::getIconForStatus($status);
130 public function getStatusColor() {
131 $status = $this->getStatus();
132 return self::getColorForStatus($status);
135 public function getErrorBackoffWindow() {
136 return phutil_units('5 minutes in seconds');
139 public function getErrorBackoffThreshold() {
140 return 10;
143 public function isInErrorBackoff(PhabricatorUser $viewer) {
144 $backoff_window = $this->getErrorBackoffWindow();
145 $backoff_threshold = $this->getErrorBackoffThreshold();
147 $now = PhabricatorTime::getNow();
149 $window_start = ($now - $backoff_window);
151 $requests = id(new HeraldWebhookRequestQuery())
152 ->setViewer($viewer)
153 ->withWebhookPHIDs(array($this->getPHID()))
154 ->withLastRequestEpochBetween($window_start, null)
155 ->withLastRequestResults(
156 array(
157 HeraldWebhookRequest::RESULT_FAIL,
159 ->execute();
161 if (count($requests) >= $backoff_threshold) {
162 return true;
165 return false;
168 public function regenerateHMACKey() {
169 return $this->setHMACKey(Filesystem::readRandomCharacters(32));
172 /* -( PhabricatorPolicyInterface )----------------------------------------- */
175 public function getCapabilities() {
176 return array(
177 PhabricatorPolicyCapability::CAN_VIEW,
178 PhabricatorPolicyCapability::CAN_EDIT,
182 public function getPolicy($capability) {
183 switch ($capability) {
184 case PhabricatorPolicyCapability::CAN_VIEW:
185 return $this->getViewPolicy();
186 case PhabricatorPolicyCapability::CAN_EDIT:
187 return $this->getEditPolicy();
191 public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
192 return false;
196 /* -( PhabricatorApplicationTransactionInterface )------------------------- */
199 public function getApplicationTransactionEditor() {
200 return new HeraldWebhookEditor();
203 public function getApplicationTransactionTemplate() {
204 return new HeraldWebhookTransaction();
208 /* -( PhabricatorDestructibleInterface )----------------------------------- */
211 public function destroyObjectPermanently(
212 PhabricatorDestructionEngine $engine) {
214 while (true) {
215 $requests = id(new HeraldWebhookRequestQuery())
216 ->setViewer($engine->getViewer())
217 ->withWebhookPHIDs(array($this->getPHID()))
218 ->setLimit(100)
219 ->execute();
221 if (!$requests) {
222 break;
225 foreach ($requests as $request) {
226 $request->delete();
230 $this->delete();