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

Configure Feed

Select the types of activity you want to include in your feed.

at upstream/main 315 lines 8.4 kB view raw
1<?php 2 3final class AlmanacDevice 4 extends AlmanacDAO 5 implements 6 PhabricatorPolicyInterface, 7 PhabricatorApplicationTransactionInterface, 8 PhabricatorProjectInterface, 9 PhabricatorSSHPublicKeyInterface, 10 AlmanacPropertyInterface, 11 PhabricatorDestructibleInterface, 12 PhabricatorNgramsInterface, 13 PhabricatorConduitResultInterface, 14 PhabricatorExtendedPolicyInterface { 15 16 protected $name; 17 protected $nameIndex; 18 protected $viewPolicy; 19 protected $editPolicy; 20 protected $status; 21 protected $isBoundToClusterService; 22 23 private $almanacProperties = self::ATTACHABLE; 24 25 public static function initializeNewDevice() { 26 return id(new AlmanacDevice()) 27 ->setViewPolicy(PhabricatorPolicies::POLICY_USER) 28 ->setEditPolicy(PhabricatorPolicies::POLICY_ADMIN) 29 ->setStatus(AlmanacDeviceStatus::ACTIVE) 30 ->attachAlmanacProperties(array()) 31 ->setIsBoundToClusterService(0); 32 } 33 34 protected function getConfiguration() { 35 return array( 36 self::CONFIG_AUX_PHID => true, 37 self::CONFIG_COLUMN_SCHEMA => array( 38 'name' => 'text128', 39 'nameIndex' => 'bytes12', 40 'status' => 'text32', 41 'isBoundToClusterService' => 'bool', 42 ), 43 self::CONFIG_KEY_SCHEMA => array( 44 'key_name' => array( 45 'columns' => array('nameIndex'), 46 'unique' => true, 47 ), 48 'key_nametext' => array( 49 'columns' => array('name'), 50 ), 51 ), 52 ) + parent::getConfiguration(); 53 } 54 55 public function getPHIDType() { 56 return AlmanacDevicePHIDType::TYPECONST; 57 } 58 59 public function save() { 60 AlmanacNames::validateName($this->getName()); 61 62 $this->nameIndex = PhabricatorHash::digestForIndex($this->getName()); 63 64 return parent::save(); 65 } 66 67 public function getURI() { 68 return urisprintf( 69 '/almanac/device/view/%s/', 70 $this->getName()); 71 } 72 73 public function rebuildClusterBindingStatus() { 74 $services = id(new AlmanacServiceQuery()) 75 ->setViewer(PhabricatorUser::getOmnipotentUser()) 76 ->withDevicePHIDs(array($this->getPHID())) 77 ->execute(); 78 79 $is_cluster = false; 80 foreach ($services as $service) { 81 if ($service->isClusterService()) { 82 $is_cluster = true; 83 break; 84 } 85 } 86 87 if ($is_cluster != $this->getIsBoundToClusterService()) { 88 $this->setIsBoundToClusterService((int)$is_cluster); 89 $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); 90 queryfx( 91 $this->establishConnection('w'), 92 'UPDATE %R SET isBoundToClusterService = %d WHERE id = %d', 93 $this, 94 $this->getIsBoundToClusterService(), 95 $this->getID()); 96 unset($unguarded); 97 } 98 99 return $this; 100 } 101 102 public function isClusterDevice() { 103 return $this->getIsBoundToClusterService(); 104 } 105 106 public function getStatusObject() { 107 return $this->newStatusObject(); 108 } 109 110 private function newStatusObject() { 111 return AlmanacDeviceStatus::newStatusFromValue($this->getStatus()); 112 } 113 114 public function isDisabled() { 115 return $this->getStatusObject()->isDisabled(); 116 } 117 118 119/* -( AlmanacPropertyInterface )------------------------------------------- */ 120 121 122 /** 123 * @param array<AlmanacProperty> $properties 124 */ 125 public function attachAlmanacProperties(array $properties) { 126 assert_instances_of($properties, AlmanacProperty::class); 127 $this->almanacProperties = mpull($properties, null, 'getFieldName'); 128 return $this; 129 } 130 131 public function getAlmanacProperties() { 132 return $this->assertAttached($this->almanacProperties); 133 } 134 135 public function hasAlmanacProperty($key) { 136 $this->assertAttached($this->almanacProperties); 137 return isset($this->almanacProperties[$key]); 138 } 139 140 public function getAlmanacProperty($key) { 141 return $this->assertAttachedKey($this->almanacProperties, $key); 142 } 143 144 public function getAlmanacPropertyValue($key, $default = null) { 145 if ($this->hasAlmanacProperty($key)) { 146 return $this->getAlmanacProperty($key)->getFieldValue(); 147 } else { 148 return $default; 149 } 150 } 151 152 public function getAlmanacPropertyFieldSpecifications() { 153 return array(); 154 } 155 156 public function newAlmanacPropertyEditEngine() { 157 return new AlmanacDevicePropertyEditEngine(); 158 } 159 160 public function getAlmanacPropertySetTransactionType() { 161 return AlmanacDeviceSetPropertyTransaction::TRANSACTIONTYPE; 162 } 163 164 public function getAlmanacPropertyDeleteTransactionType() { 165 return AlmanacDeviceDeletePropertyTransaction::TRANSACTIONTYPE; 166 } 167 168 169/* -( PhabricatorPolicyInterface )----------------------------------------- */ 170 171 172 public function getCapabilities() { 173 return array( 174 PhabricatorPolicyCapability::CAN_VIEW, 175 PhabricatorPolicyCapability::CAN_EDIT, 176 ); 177 } 178 179 public function getPolicy($capability) { 180 switch ($capability) { 181 case PhabricatorPolicyCapability::CAN_VIEW: 182 return $this->getViewPolicy(); 183 case PhabricatorPolicyCapability::CAN_EDIT: 184 return $this->getEditPolicy(); 185 } 186 } 187 188 public function hasAutomaticCapability($capability, PhabricatorUser $viewer) { 189 return false; 190 } 191 192 193/* -( PhabricatorExtendedPolicyInterface )--------------------------------- */ 194 195 196 public function getExtendedPolicy($capability, PhabricatorUser $viewer) { 197 switch ($capability) { 198 case PhabricatorPolicyCapability::CAN_EDIT: 199 if ($this->isClusterDevice()) { 200 return array( 201 array( 202 new PhabricatorAlmanacApplication(), 203 AlmanacManageClusterServicesCapability::CAPABILITY, 204 ), 205 ); 206 } 207 break; 208 } 209 210 return array(); 211 } 212 213 214/* -( PhabricatorApplicationTransactionInterface )------------------------- */ 215 216 217 public function getApplicationTransactionEditor() { 218 return new AlmanacDeviceEditor(); 219 } 220 221 public function getApplicationTransactionTemplate() { 222 return new AlmanacDeviceTransaction(); 223 } 224 225 226/* -( PhabricatorSSHPublicKeyInterface )----------------------------------- */ 227 228 229 public function getSSHPublicKeyManagementURI(PhabricatorUser $viewer) { 230 return $this->getURI(); 231 } 232 233 public function getSSHKeyDefaultName() { 234 return $this->getName(); 235 } 236 237 public function getSSHKeyNotifyPHIDs() { 238 // Devices don't currently have anyone useful to notify about SSH key 239 // edits, and they're usually a difficult vector to attack since you need 240 // access to a cluster host. However, it would be nice to make them 241 // subscribable at some point. 242 return array(); 243 } 244 245 246/* -( PhabricatorDestructibleInterface )----------------------------------- */ 247 248 249 public function destroyObjectPermanently( 250 PhabricatorDestructionEngine $engine) { 251 252 $interfaces = id(new AlmanacInterfaceQuery()) 253 ->setViewer($engine->getViewer()) 254 ->withDevicePHIDs(array($this->getPHID())) 255 ->execute(); 256 foreach ($interfaces as $interface) { 257 $engine->destroyObject($interface); 258 } 259 260 $this->delete(); 261 } 262 263 264/* -( PhabricatorNgramsInterface )----------------------------------------- */ 265 266 267 public function newNgrams() { 268 return array( 269 id(new AlmanacDeviceNameNgrams()) 270 ->setValue($this->getName()), 271 ); 272 } 273 274 275/* -( PhabricatorConduitResultInterface )---------------------------------- */ 276 277 278 public function getFieldSpecificationsForConduit() { 279 return array( 280 id(new PhabricatorConduitSearchFieldSpecification()) 281 ->setKey('name') 282 ->setType('string') 283 ->setDescription(pht('The name of the device.')), 284 id(new PhabricatorConduitSearchFieldSpecification()) 285 ->setKey('status') 286 ->setType('map<string, wild>') 287 ->setDescription(pht('Device status information.')), 288 id(new PhabricatorConduitSearchFieldSpecification()) 289 ->setKey('disabled') 290 ->setType('bool') 291 ->setDescription(pht('True if device is disabled.')), 292 ); 293 } 294 295 public function getFieldValuesForConduit() { 296 $status = $this->getStatusObject(); 297 298 return array( 299 'name' => $this->getName(), 300 'status' => array( 301 'value' => $status->getValue(), 302 'name' => $status->getName(), 303 ), 304 'disabled' => $this->isDisabled(), 305 ); 306 } 307 308 public function getConduitSearchAttachments() { 309 return array( 310 id(new AlmanacPropertiesSearchEngineAttachment()) 311 ->setAttachmentKey('properties'), 312 ); 313 } 314 315}