Path: blob/master/src/applications/almanac/storage/AlmanacDevice.php
12256 views
<?php12final class AlmanacDevice3extends AlmanacDAO4implements5PhabricatorPolicyInterface,6PhabricatorApplicationTransactionInterface,7PhabricatorProjectInterface,8PhabricatorSSHPublicKeyInterface,9AlmanacPropertyInterface,10PhabricatorDestructibleInterface,11PhabricatorNgramsInterface,12PhabricatorConduitResultInterface,13PhabricatorExtendedPolicyInterface {1415protected $name;16protected $nameIndex;17protected $viewPolicy;18protected $editPolicy;19protected $status;20protected $isBoundToClusterService;2122private $almanacProperties = self::ATTACHABLE;2324public static function initializeNewDevice() {25return id(new AlmanacDevice())26->setViewPolicy(PhabricatorPolicies::POLICY_USER)27->setEditPolicy(PhabricatorPolicies::POLICY_ADMIN)28->setStatus(AlmanacDeviceStatus::ACTIVE)29->attachAlmanacProperties(array())30->setIsBoundToClusterService(0);31}3233protected function getConfiguration() {34return array(35self::CONFIG_AUX_PHID => true,36self::CONFIG_COLUMN_SCHEMA => array(37'name' => 'text128',38'nameIndex' => 'bytes12',39'status' => 'text32',40'isBoundToClusterService' => 'bool',41),42self::CONFIG_KEY_SCHEMA => array(43'key_name' => array(44'columns' => array('nameIndex'),45'unique' => true,46),47'key_nametext' => array(48'columns' => array('name'),49),50),51) + parent::getConfiguration();52}5354public function getPHIDType() {55return AlmanacDevicePHIDType::TYPECONST;56}5758public function save() {59AlmanacNames::validateName($this->getName());6061$this->nameIndex = PhabricatorHash::digestForIndex($this->getName());6263return parent::save();64}6566public function getURI() {67return urisprintf(68'/almanac/device/view/%s/',69$this->getName());70}7172public function rebuildClusterBindingStatus() {73$services = id(new AlmanacServiceQuery())74->setViewer(PhabricatorUser::getOmnipotentUser())75->withDevicePHIDs(array($this->getPHID()))76->execute();7778$is_cluster = false;79foreach ($services as $service) {80if ($service->isClusterService()) {81$is_cluster = true;82break;83}84}8586if ($is_cluster != $this->getIsBoundToClusterService()) {87$this->setIsBoundToClusterService((int)$is_cluster);88$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();89queryfx(90$this->establishConnection('w'),91'UPDATE %R SET isBoundToClusterService = %d WHERE id = %d',92$this,93$this->getIsBoundToClusterService(),94$this->getID());95unset($unguarded);96}9798return $this;99}100101public function isClusterDevice() {102return $this->getIsBoundToClusterService();103}104105public function getStatusObject() {106return $this->newStatusObject();107}108109private function newStatusObject() {110return AlmanacDeviceStatus::newStatusFromValue($this->getStatus());111}112113public function isDisabled() {114return $this->getStatusObject()->isDisabled();115}116117118/* -( AlmanacPropertyInterface )------------------------------------------- */119120121public function attachAlmanacProperties(array $properties) {122assert_instances_of($properties, 'AlmanacProperty');123$this->almanacProperties = mpull($properties, null, 'getFieldName');124return $this;125}126127public function getAlmanacProperties() {128return $this->assertAttached($this->almanacProperties);129}130131public function hasAlmanacProperty($key) {132$this->assertAttached($this->almanacProperties);133return isset($this->almanacProperties[$key]);134}135136public function getAlmanacProperty($key) {137return $this->assertAttachedKey($this->almanacProperties, $key);138}139140public function getAlmanacPropertyValue($key, $default = null) {141if ($this->hasAlmanacProperty($key)) {142return $this->getAlmanacProperty($key)->getFieldValue();143} else {144return $default;145}146}147148public function getAlmanacPropertyFieldSpecifications() {149return array();150}151152public function newAlmanacPropertyEditEngine() {153return new AlmanacDevicePropertyEditEngine();154}155156public function getAlmanacPropertySetTransactionType() {157return AlmanacDeviceSetPropertyTransaction::TRANSACTIONTYPE;158}159160public function getAlmanacPropertyDeleteTransactionType() {161return AlmanacDeviceDeletePropertyTransaction::TRANSACTIONTYPE;162}163164165/* -( PhabricatorPolicyInterface )----------------------------------------- */166167168public function getCapabilities() {169return array(170PhabricatorPolicyCapability::CAN_VIEW,171PhabricatorPolicyCapability::CAN_EDIT,172);173}174175public function getPolicy($capability) {176switch ($capability) {177case PhabricatorPolicyCapability::CAN_VIEW:178return $this->getViewPolicy();179case PhabricatorPolicyCapability::CAN_EDIT:180return $this->getEditPolicy();181}182}183184public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {185return false;186}187188189/* -( PhabricatorExtendedPolicyInterface )--------------------------------- */190191192public function getExtendedPolicy($capability, PhabricatorUser $viewer) {193switch ($capability) {194case PhabricatorPolicyCapability::CAN_EDIT:195if ($this->isClusterDevice()) {196return array(197array(198new PhabricatorAlmanacApplication(),199AlmanacManageClusterServicesCapability::CAPABILITY,200),201);202}203break;204}205206return array();207}208209210/* -( PhabricatorApplicationTransactionInterface )------------------------- */211212213public function getApplicationTransactionEditor() {214return new AlmanacDeviceEditor();215}216217public function getApplicationTransactionTemplate() {218return new AlmanacDeviceTransaction();219}220221222/* -( PhabricatorSSHPublicKeyInterface )----------------------------------- */223224225public function getSSHPublicKeyManagementURI(PhabricatorUser $viewer) {226return $this->getURI();227}228229public function getSSHKeyDefaultName() {230return $this->getName();231}232233public function getSSHKeyNotifyPHIDs() {234// Devices don't currently have anyone useful to notify about SSH key235// edits, and they're usually a difficult vector to attack since you need236// access to a cluster host. However, it would be nice to make them237// subscribable at some point.238return array();239}240241242/* -( PhabricatorDestructibleInterface )----------------------------------- */243244245public function destroyObjectPermanently(246PhabricatorDestructionEngine $engine) {247248$interfaces = id(new AlmanacInterfaceQuery())249->setViewer($engine->getViewer())250->withDevicePHIDs(array($this->getPHID()))251->execute();252foreach ($interfaces as $interface) {253$engine->destroyObject($interface);254}255256$this->delete();257}258259260/* -( PhabricatorNgramsInterface )----------------------------------------- */261262263public function newNgrams() {264return array(265id(new AlmanacDeviceNameNgrams())266->setValue($this->getName()),267);268}269270271/* -( PhabricatorConduitResultInterface )---------------------------------- */272273274public function getFieldSpecificationsForConduit() {275return array(276id(new PhabricatorConduitSearchFieldSpecification())277->setKey('name')278->setType('string')279->setDescription(pht('The name of the device.')),280id(new PhabricatorConduitSearchFieldSpecification())281->setKey('status')282->setType('map<string, wild>')283->setDescription(pht('Device status information.')),284id(new PhabricatorConduitSearchFieldSpecification())285->setKey('disabled')286->setType('bool')287->setDescription(pht('True if device is disabled.')),288);289}290291public function getFieldValuesForConduit() {292$status = $this->getStatusObject();293294return array(295'name' => $this->getName(),296'status' => array(297'value' => $status->getValue(),298'name' => $status->getName(),299),300'disabled' => $this->isDisabled(),301);302}303304public function getConduitSearchAttachments() {305return array(306id(new AlmanacPropertiesSearchEngineAttachment())307->setAttachmentKey('properties'),308);309}310311}312313314