Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/src/applications/drydock/storage/DrydockAuthorization.php
12256 views
1
<?php
2
3
final class DrydockAuthorization extends DrydockDAO
4
implements
5
PhabricatorPolicyInterface,
6
PhabricatorConduitResultInterface {
7
8
const OBJECTAUTH_ACTIVE = 'active';
9
const OBJECTAUTH_INACTIVE = 'inactive';
10
11
const BLUEPRINTAUTH_REQUESTED = 'requested';
12
const BLUEPRINTAUTH_AUTHORIZED = 'authorized';
13
const BLUEPRINTAUTH_DECLINED = 'declined';
14
15
protected $blueprintPHID;
16
protected $blueprintAuthorizationState;
17
protected $objectPHID;
18
protected $objectAuthorizationState;
19
20
private $blueprint = self::ATTACHABLE;
21
private $object = self::ATTACHABLE;
22
23
protected function getConfiguration() {
24
return array(
25
self::CONFIG_AUX_PHID => true,
26
self::CONFIG_COLUMN_SCHEMA => array(
27
'blueprintAuthorizationState' => 'text32',
28
'objectAuthorizationState' => 'text32',
29
),
30
self::CONFIG_KEY_SCHEMA => array(
31
'key_unique' => array(
32
'columns' => array('objectPHID', 'blueprintPHID'),
33
'unique' => true,
34
),
35
'key_blueprint' => array(
36
'columns' => array('blueprintPHID', 'blueprintAuthorizationState'),
37
),
38
'key_object' => array(
39
'columns' => array('objectPHID', 'objectAuthorizationState'),
40
),
41
),
42
) + parent::getConfiguration();
43
}
44
45
public function generatePHID() {
46
return PhabricatorPHID::generateNewPHID(
47
DrydockAuthorizationPHIDType::TYPECONST);
48
}
49
50
public function attachBlueprint(DrydockBlueprint $blueprint) {
51
$this->blueprint = $blueprint;
52
return $this;
53
}
54
55
public function getBlueprint() {
56
return $this->assertAttached($this->blueprint);
57
}
58
59
public function attachObject($object) {
60
$this->object = $object;
61
return $this;
62
}
63
64
public function getObject() {
65
return $this->assertAttached($this->object);
66
}
67
68
public static function getBlueprintStateIcon($state) {
69
$map = array(
70
self::BLUEPRINTAUTH_REQUESTED => 'fa-exclamation-circle pink',
71
self::BLUEPRINTAUTH_AUTHORIZED => 'fa-check-circle green',
72
self::BLUEPRINTAUTH_DECLINED => 'fa-times red',
73
);
74
75
return idx($map, $state, null);
76
}
77
78
public static function getBlueprintStateName($state) {
79
$map = array(
80
self::BLUEPRINTAUTH_REQUESTED => pht('Requested'),
81
self::BLUEPRINTAUTH_AUTHORIZED => pht('Authorized'),
82
self::BLUEPRINTAUTH_DECLINED => pht('Declined'),
83
);
84
85
return idx($map, $state, pht('<Unknown: %s>', $state));
86
}
87
88
public static function getObjectStateName($state) {
89
$map = array(
90
self::OBJECTAUTH_ACTIVE => pht('Active'),
91
self::OBJECTAUTH_INACTIVE => pht('Inactive'),
92
);
93
94
return idx($map, $state, pht('<Unknown: %s>', $state));
95
}
96
97
public function isAuthorized() {
98
$state = $this->getBlueprintAuthorizationState();
99
return ($state == self::BLUEPRINTAUTH_AUTHORIZED);
100
}
101
102
/**
103
* Apply external authorization effects after a user changes the value of a
104
* blueprint selector control an object.
105
*
106
* @param PhabricatorUser User applying the change.
107
* @param phid Object PHID change is being applied to.
108
* @param list<phid> Old blueprint PHIDs.
109
* @param list<phid> New blueprint PHIDs.
110
* @return void
111
*/
112
public static function applyAuthorizationChanges(
113
PhabricatorUser $viewer,
114
$object_phid,
115
array $old,
116
array $new) {
117
118
$old_phids = array_fuse($old);
119
$new_phids = array_fuse($new);
120
121
$rem_phids = array_diff_key($old_phids, $new_phids);
122
$add_phids = array_diff_key($new_phids, $old_phids);
123
124
$altered_phids = $rem_phids + $add_phids;
125
126
if (!$altered_phids) {
127
return;
128
}
129
130
$authorizations = id(new DrydockAuthorizationQuery())
131
->setViewer(PhabricatorUser::getOmnipotentUser())
132
->withObjectPHIDs(array($object_phid))
133
->withBlueprintPHIDs($altered_phids)
134
->execute();
135
$authorizations = mpull($authorizations, null, 'getBlueprintPHID');
136
137
$state_active = self::OBJECTAUTH_ACTIVE;
138
$state_inactive = self::OBJECTAUTH_INACTIVE;
139
140
$state_requested = self::BLUEPRINTAUTH_REQUESTED;
141
142
// Disable the object side of the authorization for any existing
143
// authorizations.
144
foreach ($rem_phids as $rem_phid) {
145
$authorization = idx($authorizations, $rem_phid);
146
if (!$authorization) {
147
continue;
148
}
149
150
$authorization
151
->setObjectAuthorizationState($state_inactive)
152
->save();
153
}
154
155
// For new authorizations, either add them or reactivate them depending
156
// on the current state.
157
foreach ($add_phids as $add_phid) {
158
$needs_update = false;
159
160
$authorization = idx($authorizations, $add_phid);
161
if (!$authorization) {
162
$authorization = id(new DrydockAuthorization())
163
->setObjectPHID($object_phid)
164
->setObjectAuthorizationState($state_active)
165
->setBlueprintPHID($add_phid)
166
->setBlueprintAuthorizationState($state_requested);
167
168
$needs_update = true;
169
} else {
170
$current_state = $authorization->getObjectAuthorizationState();
171
if ($current_state != $state_active) {
172
$authorization->setObjectAuthorizationState($state_active);
173
$needs_update = true;
174
}
175
}
176
177
if ($needs_update) {
178
$authorization->save();
179
}
180
}
181
}
182
183
/* -( PhabricatorPolicyInterface )----------------------------------------- */
184
185
186
public function getCapabilities() {
187
return array(
188
PhabricatorPolicyCapability::CAN_VIEW,
189
PhabricatorPolicyCapability::CAN_EDIT,
190
);
191
}
192
193
public function getPolicy($capability) {
194
return $this->getBlueprint()->getPolicy($capability);
195
}
196
197
public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
198
return $this->getBlueprint()->hasAutomaticCapability($capability, $viewer);
199
}
200
201
public function describeAutomaticCapability($capability) {
202
return pht(
203
'An authorization inherits the policies of the blueprint it '.
204
'authorizes access to.');
205
}
206
207
208
/* -( PhabricatorConduitResultInterface )---------------------------------- */
209
210
211
public function getFieldSpecificationsForConduit() {
212
return array(
213
id(new PhabricatorConduitSearchFieldSpecification())
214
->setKey('blueprintPHID')
215
->setType('phid')
216
->setDescription(pht(
217
'PHID of the blueprint this request was made for.')),
218
id(new PhabricatorConduitSearchFieldSpecification())
219
->setKey('blueprintAuthorizationState')
220
->setType('map<string, wild>')
221
->setDescription(pht('Authorization state of this request.')),
222
id(new PhabricatorConduitSearchFieldSpecification())
223
->setKey('objectPHID')
224
->setType('phid')
225
->setDescription(pht(
226
'PHID of the object which requested authorization.')),
227
id(new PhabricatorConduitSearchFieldSpecification())
228
->setKey('objectAuthorizationState')
229
->setType('map<string, wild>')
230
->setDescription(pht('Authorization state of the requesting object.')),
231
);
232
}
233
234
public function getFieldValuesForConduit() {
235
$blueprint_state = $this->getBlueprintAuthorizationState();
236
$object_state = $this->getObjectAuthorizationState();
237
return array(
238
'blueprintPHID' => $this->getBlueprintPHID(),
239
'blueprintAuthorizationState' => array(
240
'value' => $blueprint_state,
241
'name' => self::getBlueprintStateName($blueprint_state),
242
),
243
'objectPHID' => $this->getObjectPHID(),
244
'objectAuthorizationState' => array(
245
'value' => $object_state,
246
'name' => self::getObjectStateName($object_state),
247
),
248
);
249
}
250
251
public function getConduitSearchAttachments() {
252
return array(
253
);
254
}
255
256
}
257
258