Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/src/applications/almanac/storage/AlmanacDevice.php
12256 views
1
<?php
2
3
final 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
public function attachAlmanacProperties(array $properties) {
123
assert_instances_of($properties, 'AlmanacProperty');
124
$this->almanacProperties = mpull($properties, null, 'getFieldName');
125
return $this;
126
}
127
128
public function getAlmanacProperties() {
129
return $this->assertAttached($this->almanacProperties);
130
}
131
132
public function hasAlmanacProperty($key) {
133
$this->assertAttached($this->almanacProperties);
134
return isset($this->almanacProperties[$key]);
135
}
136
137
public function getAlmanacProperty($key) {
138
return $this->assertAttachedKey($this->almanacProperties, $key);
139
}
140
141
public function getAlmanacPropertyValue($key, $default = null) {
142
if ($this->hasAlmanacProperty($key)) {
143
return $this->getAlmanacProperty($key)->getFieldValue();
144
} else {
145
return $default;
146
}
147
}
148
149
public function getAlmanacPropertyFieldSpecifications() {
150
return array();
151
}
152
153
public function newAlmanacPropertyEditEngine() {
154
return new AlmanacDevicePropertyEditEngine();
155
}
156
157
public function getAlmanacPropertySetTransactionType() {
158
return AlmanacDeviceSetPropertyTransaction::TRANSACTIONTYPE;
159
}
160
161
public function getAlmanacPropertyDeleteTransactionType() {
162
return AlmanacDeviceDeletePropertyTransaction::TRANSACTIONTYPE;
163
}
164
165
166
/* -( PhabricatorPolicyInterface )----------------------------------------- */
167
168
169
public function getCapabilities() {
170
return array(
171
PhabricatorPolicyCapability::CAN_VIEW,
172
PhabricatorPolicyCapability::CAN_EDIT,
173
);
174
}
175
176
public function getPolicy($capability) {
177
switch ($capability) {
178
case PhabricatorPolicyCapability::CAN_VIEW:
179
return $this->getViewPolicy();
180
case PhabricatorPolicyCapability::CAN_EDIT:
181
return $this->getEditPolicy();
182
}
183
}
184
185
public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
186
return false;
187
}
188
189
190
/* -( PhabricatorExtendedPolicyInterface )--------------------------------- */
191
192
193
public function getExtendedPolicy($capability, PhabricatorUser $viewer) {
194
switch ($capability) {
195
case PhabricatorPolicyCapability::CAN_EDIT:
196
if ($this->isClusterDevice()) {
197
return array(
198
array(
199
new PhabricatorAlmanacApplication(),
200
AlmanacManageClusterServicesCapability::CAPABILITY,
201
),
202
);
203
}
204
break;
205
}
206
207
return array();
208
}
209
210
211
/* -( PhabricatorApplicationTransactionInterface )------------------------- */
212
213
214
public function getApplicationTransactionEditor() {
215
return new AlmanacDeviceEditor();
216
}
217
218
public function getApplicationTransactionTemplate() {
219
return new AlmanacDeviceTransaction();
220
}
221
222
223
/* -( PhabricatorSSHPublicKeyInterface )----------------------------------- */
224
225
226
public function getSSHPublicKeyManagementURI(PhabricatorUser $viewer) {
227
return $this->getURI();
228
}
229
230
public function getSSHKeyDefaultName() {
231
return $this->getName();
232
}
233
234
public function getSSHKeyNotifyPHIDs() {
235
// Devices don't currently have anyone useful to notify about SSH key
236
// edits, and they're usually a difficult vector to attack since you need
237
// access to a cluster host. However, it would be nice to make them
238
// subscribable at some point.
239
return array();
240
}
241
242
243
/* -( PhabricatorDestructibleInterface )----------------------------------- */
244
245
246
public function destroyObjectPermanently(
247
PhabricatorDestructionEngine $engine) {
248
249
$interfaces = id(new AlmanacInterfaceQuery())
250
->setViewer($engine->getViewer())
251
->withDevicePHIDs(array($this->getPHID()))
252
->execute();
253
foreach ($interfaces as $interface) {
254
$engine->destroyObject($interface);
255
}
256
257
$this->delete();
258
}
259
260
261
/* -( PhabricatorNgramsInterface )----------------------------------------- */
262
263
264
public function newNgrams() {
265
return array(
266
id(new AlmanacDeviceNameNgrams())
267
->setValue($this->getName()),
268
);
269
}
270
271
272
/* -( PhabricatorConduitResultInterface )---------------------------------- */
273
274
275
public function getFieldSpecificationsForConduit() {
276
return array(
277
id(new PhabricatorConduitSearchFieldSpecification())
278
->setKey('name')
279
->setType('string')
280
->setDescription(pht('The name of the device.')),
281
id(new PhabricatorConduitSearchFieldSpecification())
282
->setKey('status')
283
->setType('map<string, wild>')
284
->setDescription(pht('Device status information.')),
285
id(new PhabricatorConduitSearchFieldSpecification())
286
->setKey('disabled')
287
->setType('bool')
288
->setDescription(pht('True if device is disabled.')),
289
);
290
}
291
292
public function getFieldValuesForConduit() {
293
$status = $this->getStatusObject();
294
295
return array(
296
'name' => $this->getName(),
297
'status' => array(
298
'value' => $status->getValue(),
299
'name' => $status->getName(),
300
),
301
'disabled' => $this->isDisabled(),
302
);
303
}
304
305
public function getConduitSearchAttachments() {
306
return array(
307
id(new AlmanacPropertiesSearchEngineAttachment())
308
->setAttachmentKey('properties'),
309
);
310
}
311
312
}
313
314