@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
at recaptime-dev/main 238 lines 6.6 kB view raw
1<?php 2 3final class HeraldWebhookViewController 4 extends HeraldWebhookController { 5 6 public function shouldAllowPublic() { 7 return true; 8 } 9 10 public function handleRequest(AphrontRequest $request) { 11 $viewer = $this->getViewer(); 12 13 $hook = id(new HeraldWebhookQuery()) 14 ->setViewer($viewer) 15 ->withIDs(array($request->getURIData('id'))) 16 ->executeOne(); 17 if (!$hook) { 18 return new Aphront404Response(); 19 } 20 21 $header = $this->buildHeaderView($hook); 22 23 $warnings = null; 24 if ($hook->isInErrorBackoff($viewer)) { 25 $message = pht( 26 'Many requests to this webhook have failed recently (at least %s '. 27 'errors in the last %s seconds). New requests are temporarily paused.', 28 $hook->getErrorBackoffThreshold(), 29 $hook->getErrorBackoffWindow()); 30 31 $warnings = id(new PHUIInfoView()) 32 ->setSeverity(PHUIInfoView::SEVERITY_WARNING) 33 ->setErrors( 34 array( 35 $message, 36 )); 37 } 38 39 $curtain = $this->buildCurtain($hook); 40 $properties_view = $this->buildPropertiesView($hook); 41 42 $timeline = $this->buildTransactionTimeline( 43 $hook, 44 new HeraldWebhookTransactionQuery()); 45 $timeline->setShouldTerminate(true); 46 47 $requests = id(new HeraldWebhookRequestQuery()) 48 ->setViewer($viewer) 49 ->withWebhookPHIDs(array($hook->getPHID())) 50 ->setLimit(20) 51 ->execute(); 52 53 $warnings = array(); 54 if (PhabricatorEnv::getEnvConfig('phabricator.silent')) { 55 $message = pht( 56 'This server is running in silent mode, so it will not '. 57 'publish webhooks. To adjust this setting, see '. 58 '@{config:phabricator.silent} in Config.'); 59 60 $warnings[] = id(new PHUIInfoView()) 61 ->setTitle(pht('Silent Mode')) 62 ->setSeverity(PHUIInfoView::SEVERITY_WARNING) 63 ->appendChild(new PHUIRemarkupView($viewer, $message)); 64 } 65 66 $requests_table = id(new HeraldWebhookRequestListView()) 67 ->setViewer($viewer) 68 ->setRequests($requests) 69 ->setHighlightID($request->getURIData('requestID')); 70 71 $requests_view = id(new PHUIObjectBoxView()) 72 ->setHeaderText(pht('Recent Requests')) 73 ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) 74 ->setTable($requests_table); 75 76 $rules_view = $this->newRulesView($hook); 77 78 $hook_view = id(new PHUITwoColumnView()) 79 ->setHeader($header) 80 ->setMainColumn( 81 array( 82 $warnings, 83 $properties_view, 84 $rules_view, 85 $requests_view, 86 $timeline, 87 )) 88 ->setCurtain($curtain); 89 90 $crumbs = $this->buildApplicationCrumbs() 91 ->addTextCrumb(pht('Webhook %d', $hook->getID())) 92 ->setBorder(true); 93 94 return $this->newPage() 95 ->setTitle( 96 array( 97 pht('Webhook %d', $hook->getID()), 98 $hook->getName(), 99 )) 100 ->setCrumbs($crumbs) 101 ->setPageObjectPHIDs( 102 array( 103 $hook->getPHID(), 104 )) 105 ->appendChild($hook_view); 106 } 107 108 private function buildHeaderView(HeraldWebhook $hook) { 109 $viewer = $this->getViewer(); 110 111 $title = $hook->getName(); 112 113 $status_icon = $hook->getStatusIcon(); 114 $status_color = $hook->getStatusColor(); 115 $status_name = $hook->getStatusDisplayName(); 116 117 $header = id(new PHUIHeaderView()) 118 ->setHeader($title) 119 ->setViewer($viewer) 120 ->setPolicyObject($hook) 121 ->setStatus($status_icon, $status_color, $status_name) 122 ->setHeaderIcon('fa-cloud-upload'); 123 124 return $header; 125 } 126 127 128 private function buildCurtain(HeraldWebhook $hook) { 129 $viewer = $this->getViewer(); 130 $curtain = $this->newCurtainView($hook); 131 132 $can_edit = PhabricatorPolicyFilter::hasCapability( 133 $viewer, 134 $hook, 135 PhabricatorPolicyCapability::CAN_EDIT); 136 137 $id = $hook->getID(); 138 $edit_uri = $this->getApplicationURI("webhook/edit/{$id}/"); 139 $test_uri = $this->getApplicationURI("webhook/test/{$id}/"); 140 141 $key_view_uri = $this->getApplicationURI("webhook/key/view/{$id}/"); 142 $key_cycle_uri = $this->getApplicationURI("webhook/key/cycle/{$id}/"); 143 144 $curtain->addAction( 145 id(new PhabricatorActionView()) 146 ->setName(pht('Edit Webhook')) 147 ->setIcon('fa-pencil') 148 ->setDisabled(!$can_edit) 149 ->setWorkflow(!$can_edit) 150 ->setHref($edit_uri)); 151 152 $curtain->addAction( 153 id(new PhabricatorActionView()) 154 ->setName(pht('New Test Request')) 155 ->setIcon('fa-cloud-upload') 156 ->setDisabled(!$can_edit) 157 ->setWorkflow(true) 158 ->setHref($test_uri)); 159 160 $curtain->addAction( 161 id(new PhabricatorActionView()) 162 ->setName(pht('View HMAC Key')) 163 ->setIcon('fa-key') 164 ->setDisabled(!$can_edit) 165 ->setWorkflow(true) 166 ->setHref($key_view_uri)); 167 168 $curtain->addAction( 169 id(new PhabricatorActionView()) 170 ->setName(pht('Regenerate HMAC Key')) 171 ->setIcon('fa-refresh') 172 ->setDisabled(!$can_edit) 173 ->setWorkflow(true) 174 ->setHref($key_cycle_uri)); 175 176 return $curtain; 177 } 178 179 180 private function buildPropertiesView(HeraldWebhook $hook) { 181 $viewer = $this->getViewer(); 182 183 $properties = id(new PHUIPropertyListView()) 184 ->setViewer($viewer); 185 186 $properties->addProperty( 187 pht('URI'), 188 $hook->getWebhookURI()); 189 190 $properties->addProperty( 191 pht('Status'), 192 $hook->getStatusDisplayName()); 193 194 return id(new PHUIObjectBoxView()) 195 ->setHeaderText(pht('Details')) 196 ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) 197 ->appendChild($properties); 198 } 199 200 private function newRulesView(HeraldWebhook $hook) { 201 $viewer = $this->getViewer(); 202 203 $rules = id(new HeraldRuleQuery()) 204 ->setViewer($viewer) 205 ->withDisabled(false) 206 ->withAffectedObjectPHIDs(array($hook->getPHID())) 207 ->needValidateAuthors(true) 208 ->setLimit(10) 209 ->execute(); 210 211 $list = id(new HeraldRuleListView()) 212 ->setViewer($viewer) 213 ->setRules($rules) 214 ->newObjectList(); 215 216 $list->setNoDataString(pht('No active Herald rules call this webhook.')); 217 218 $more_href = new PhutilURI( 219 '/herald/', 220 array('affectedPHID' => $hook->getPHID())); 221 222 $more_link = id(new PHUIButtonView()) 223 ->setTag('a') 224 ->setIcon('fa-list-ul') 225 ->setText(pht('View All Rules')) 226 ->setHref($more_href); 227 228 $header = id(new PHUIHeaderView()) 229 ->setHeader(pht('Called By Herald Rules')) 230 ->addActionLink($more_link); 231 232 return id(new PHUIObjectBoxView()) 233 ->setHeader($header) 234 ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) 235 ->appendChild($list); 236 } 237 238}