@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 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}