@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 231 lines 6.5 kB view raw
1<?php 2 3final class AlmanacDeviceViewController 4 extends AlmanacDeviceController { 5 6 public function shouldAllowPublic() { 7 return true; 8 } 9 10 public function handleRequest(AphrontRequest $request) { 11 $viewer = $request->getViewer(); 12 13 $name = $request->getURIData('name'); 14 15 $device = id(new AlmanacDeviceQuery()) 16 ->setViewer($viewer) 17 ->withNames(array($name)) 18 ->needProperties(true) 19 ->executeOne(); 20 if (!$device) { 21 return new Aphront404Response(); 22 } 23 24 $title = pht('Device %s', $device->getName()); 25 26 $curtain = $this->buildCurtain($device); 27 28 $header = id(new PHUIHeaderView()) 29 ->setUser($viewer) 30 ->setHeader($device->getName()) 31 ->setPolicyObject($device) 32 ->setHeaderIcon('fa-server'); 33 34 $status = $device->getStatusObject(); 35 if ($status->hasStatusTag()) { 36 $header->setStatus( 37 $status->getStatusTagIcon(), 38 $status->getStatusTagColor(), 39 $status->getName()); 40 } 41 42 $issue = null; 43 if ($device->isClusterDevice()) { 44 $issue = $this->addClusterMessage( 45 pht('This device is bound to a cluster service.'), 46 pht( 47 'This device is bound to a cluster service. You do not have '. 48 'permission to manage cluster services, so the device can not '. 49 'be edited.')); 50 } 51 52 $interfaces = $this->buildInterfaceList($device); 53 54 $crumbs = $this->buildApplicationCrumbs(); 55 $crumbs->addTextCrumb($device->getName()); 56 $crumbs->setBorder(true); 57 58 $timeline = $this->buildTransactionTimeline( 59 $device, 60 new AlmanacDeviceTransactionQuery()); 61 $timeline->setShouldTerminate(true); 62 63 $view = id(new PHUITwoColumnView()) 64 ->setHeader($header) 65 ->setCurtain($curtain) 66 ->setMainColumn(array( 67 $issue, 68 $interfaces, 69 $this->buildAlmanacPropertiesTable($device), 70 $this->buildSSHKeysTable($device), 71 $this->buildServicesTable($device), 72 $timeline, 73 )); 74 75 return $this->newPage() 76 ->setTitle($title) 77 ->setCrumbs($crumbs) 78 ->appendChild( 79 array( 80 $view, 81 )); 82 } 83 84 private function buildCurtain(AlmanacDevice $device) { 85 $viewer = $this->getViewer(); 86 87 $can_edit = PhabricatorPolicyFilter::hasCapability( 88 $viewer, 89 $device, 90 PhabricatorPolicyCapability::CAN_EDIT); 91 92 $id = $device->getID(); 93 $edit_uri = $this->getApplicationURI("device/edit/{$id}/"); 94 95 $curtain = $this->newCurtainView($device); 96 97 $curtain->addAction( 98 id(new PhabricatorActionView()) 99 ->setIcon('fa-pencil') 100 ->setName(pht('Edit Device')) 101 ->setHref($edit_uri) 102 ->setWorkflow(!$can_edit) 103 ->setDisabled(!$can_edit)); 104 105 return $curtain; 106 } 107 108 private function buildInterfaceList(AlmanacDevice $device) { 109 $viewer = $this->getViewer(); 110 $id = $device->getID(); 111 112 $can_edit = PhabricatorPolicyFilter::hasCapability( 113 $viewer, 114 $device, 115 PhabricatorPolicyCapability::CAN_EDIT); 116 117 $interfaces = id(new AlmanacInterfaceQuery()) 118 ->setViewer($viewer) 119 ->withDevicePHIDs(array($device->getPHID())) 120 ->execute(); 121 122 $table = id(new AlmanacInterfaceTableView()) 123 ->setUser($viewer) 124 ->setInterfaces($interfaces) 125 ->setCanEdit($can_edit); 126 127 $header = id(new PHUIHeaderView()) 128 ->setHeader(pht('Device Interfaces')) 129 ->addActionLink( 130 id(new PHUIButtonView()) 131 ->setTag('a') 132 ->setHref($this->getApplicationURI("interface/edit/?deviceID={$id}")) 133 ->setWorkflow(!$can_edit) 134 ->setDisabled(!$can_edit) 135 ->setText(pht('Add Interface')) 136 ->setIcon('fa-plus')); 137 138 return id(new PHUIObjectBoxView()) 139 ->setHeader($header) 140 ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) 141 ->setTable($table); 142 } 143 144 private function buildSSHKeysTable(AlmanacDevice $device) { 145 $viewer = $this->getViewer(); 146 $id = $device->getID(); 147 $device_phid = $device->getPHID(); 148 149 $can_edit = PhabricatorPolicyFilter::hasCapability( 150 $viewer, 151 $device, 152 PhabricatorPolicyCapability::CAN_EDIT); 153 154 $keys = id(new PhabricatorAuthSSHKeyQuery()) 155 ->setViewer($viewer) 156 ->withObjectPHIDs(array($device_phid)) 157 ->withIsActive(true) 158 ->execute(); 159 160 $table = id(new PhabricatorAuthSSHKeyTableView()) 161 ->setUser($viewer) 162 ->setKeys($keys) 163 ->setCanEdit($can_edit) 164 ->setShowID(true) 165 ->setShowTrusted(true) 166 ->setNoDataString(pht('This device has no associated SSH public keys.')); 167 168 $menu_button = PhabricatorAuthSSHKeyTableView::newKeyActionsMenu( 169 $viewer, 170 $device); 171 172 $header = id(new PHUIHeaderView()) 173 ->setHeader(pht('SSH Public Keys')) 174 ->addActionLink($menu_button); 175 176 return id(new PHUIObjectBoxView()) 177 ->setHeader($header) 178 ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) 179 ->setTable($table); 180 } 181 182 private function buildServicesTable(AlmanacDevice $device) { 183 $viewer = $this->getViewer(); 184 185 // NOTE: We're loading all services so we can show hidden, locked services. 186 // In general, we let you know about all the things the device is bound to, 187 // even if you don't have permission to see their details. This is similar 188 // to exposing the existence of edges in other applications, with the 189 // addition of always letting you see that locks exist. 190 191 $services = id(new AlmanacServiceQuery()) 192 ->setViewer(PhabricatorUser::getOmnipotentUser()) 193 ->withDevicePHIDs(array($device->getPHID())) 194 ->execute(); 195 196 $handles = $viewer->loadHandles(mpull($services, 'getPHID')); 197 198 $icon_cluster = id(new PHUIIconView()) 199 ->setIcon('fa-sitemap'); 200 201 $rows = array(); 202 foreach ($services as $service) { 203 $rows[] = array( 204 ($service->isClusterService() 205 ? $icon_cluster 206 : null), 207 $handles->renderHandle($service->getPHID()), 208 ); 209 } 210 211 $table = id(new AphrontTableView($rows)) 212 ->setNoDataString(pht('No services are bound to this device.')) 213 ->setHeaders( 214 array( 215 null, 216 pht('Service'), 217 )) 218 ->setColumnClasses( 219 array( 220 null, 221 'wide pri', 222 )); 223 224 return id(new PHUIObjectBoxView()) 225 ->setHeaderText(pht('Bound Services')) 226 ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) 227 ->setTable($table); 228 } 229 230 231}