1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* File containing the eZ\Publish\Core\Repository\RoleService class. |
5
|
|
|
* |
6
|
|
|
* @copyright Copyright (C) eZ Systems AS. All rights reserved. |
7
|
|
|
* @license For full copyright and license information view LICENSE file distributed with this source code. |
8
|
|
|
*/ |
9
|
|
|
namespace eZ\Publish\Core\Repository; |
10
|
|
|
|
11
|
|
|
use eZ\Publish\API\Repository\Exceptions\NotFoundException as APINotFoundException; |
12
|
|
|
use eZ\Publish\API\Repository\Repository as RepositoryInterface; |
13
|
|
|
use eZ\Publish\API\Repository\RoleService as RoleServiceInterface; |
14
|
|
|
use eZ\Publish\API\Repository\Values\User\Limitation; |
15
|
|
|
use eZ\Publish\API\Repository\Values\User\Limitation\RoleLimitation; |
16
|
|
|
use eZ\Publish\API\Repository\Values\User\Policy as APIPolicy; |
17
|
|
|
use eZ\Publish\API\Repository\Values\User\PolicyCreateStruct as APIPolicyCreateStruct; |
18
|
|
|
use eZ\Publish\API\Repository\Values\User\PolicyDraft; |
19
|
|
|
use eZ\Publish\API\Repository\Values\User\PolicyUpdateStruct as APIPolicyUpdateStruct; |
20
|
|
|
use eZ\Publish\API\Repository\Values\User\Role as APIRole; |
21
|
|
|
use eZ\Publish\API\Repository\Values\User\RoleAssignment; |
22
|
|
|
use eZ\Publish\API\Repository\Values\User\RoleCreateStruct as APIRoleCreateStruct; |
23
|
|
|
use eZ\Publish\API\Repository\Values\User\RoleDraft as APIRoleDraft; |
24
|
|
|
use eZ\Publish\API\Repository\Values\User\RoleUpdateStruct; |
25
|
|
|
use eZ\Publish\API\Repository\Values\User\User; |
26
|
|
|
use eZ\Publish\API\Repository\Values\User\UserGroup; |
27
|
|
|
use eZ\Publish\Core\Base\Exceptions\BadStateException; |
28
|
|
|
use eZ\Publish\Core\Base\Exceptions\InvalidArgumentException; |
29
|
|
|
use eZ\Publish\Core\Base\Exceptions\InvalidArgumentValue; |
30
|
|
|
use eZ\Publish\Core\Base\Exceptions\LimitationValidationException; |
31
|
|
|
use eZ\Publish\Core\Base\Exceptions\NotFoundException; |
32
|
|
|
use eZ\Publish\Core\Base\Exceptions\NotFound\LimitationNotFoundException; |
33
|
|
|
use eZ\Publish\Core\Base\Exceptions\UnauthorizedException; |
34
|
|
|
use eZ\Publish\Core\Repository\Values\User\Policy; |
35
|
|
|
use eZ\Publish\Core\Repository\Values\User\PolicyCreateStruct; |
36
|
|
|
use eZ\Publish\Core\Repository\Values\User\PolicyUpdateStruct; |
37
|
|
|
use eZ\Publish\Core\Repository\Values\User\Role; |
38
|
|
|
use eZ\Publish\Core\Repository\Values\User\RoleCreateStruct; |
39
|
|
|
use eZ\Publish\Core\Repository\Values\User\RoleDraft; |
40
|
|
|
use eZ\Publish\SPI\Persistence\User\Handler; |
41
|
|
|
use eZ\Publish\SPI\Persistence\User\Role as SPIRole; |
42
|
|
|
use eZ\Publish\SPI\Persistence\User\RoleUpdateStruct as SPIRoleUpdateStruct; |
43
|
|
|
use Exception; |
44
|
|
|
|
45
|
|
|
/** |
46
|
|
|
* This service provides methods for managing Roles and Policies. |
47
|
|
|
*/ |
48
|
|
|
class RoleService implements RoleServiceInterface |
49
|
|
|
{ |
50
|
|
|
const DEFAULT_CORE_POLICYMAP = [ |
51
|
|
|
'content' => [ |
52
|
|
|
'read' => ['Class' => true, 'Section' => true, 'Owner' => true, 'Group' => true, 'Node' => true, 'Subtree' => true, 'State' => true], |
53
|
|
|
'diff' => ['Class' => true, 'Section' => true, 'Owner' => true, 'Node' => true, 'Subtree' => true], |
54
|
|
|
'view_embed' => ['Class' => true, 'Section' => true, 'Owner' => true, 'Node' => true, 'Subtree' => true], |
55
|
|
|
'create' => ['Class' => true, 'Section' => true, 'ParentOwner' => true, 'ParentGroup' => true, 'ParentClass' => true, 'ParentDepth' => true, 'Node' => true, 'Subtree' => true, 'Language' => true], |
56
|
|
|
'edit' => ['Class' => true, 'Section' => true, 'Owner' => true, 'Group' => true, 'Node' => true, 'Subtree' => true, 'Language' => true, 'State' => true], |
57
|
|
|
'manage_locations' => ['Class' => true, 'Section' => true, 'Owner' => true, 'Subtree' => true], |
58
|
|
|
'hide' => ['Class' => true, 'Section' => true, 'Owner' => true, 'Group' => true, 'Node' => true, 'Subtree' => true, 'Language' => true], |
59
|
|
|
'reverserelatedlist' => null, |
60
|
|
|
'translate' => ['Class' => true, 'Section' => true, 'Owner' => true, 'Node' => true, 'Subtree' => true, 'Language' => true], |
61
|
|
|
'remove' => ['Class' => true, 'Section' => true, 'Owner' => true, 'Node' => true, 'Subtree' => true, 'State' => true], |
62
|
|
|
'versionread' => ['Class' => true, 'Section' => true, 'Owner' => true, 'Status' => true, 'Node' => true, 'Subtree' => true], |
63
|
|
|
'versionremove' => ['Class' => true, 'Section' => true, 'Owner' => true, 'Status' => true, 'Node' => true, 'Subtree' => true], |
64
|
|
|
'translations' => null, |
65
|
|
|
'urltranslator' => null, |
66
|
|
|
'pendinglist' => null, |
67
|
|
|
'restore' => null, |
68
|
|
|
'cleantrash' => null, |
69
|
|
|
], |
70
|
|
|
'class' => [ |
71
|
|
|
'update' => null, |
72
|
|
|
'create' => null, |
73
|
|
|
'delete' => null, |
74
|
|
|
], |
75
|
|
|
'state' => [ |
76
|
|
|
'assign' => ['Class' => true, 'Section' => true, 'Owner' => true, 'Group' => true, 'Node' => true, 'Subtree' => true, 'State' => true, 'NewState' => true], |
77
|
|
|
'administrate' => null, |
78
|
|
|
], |
79
|
|
|
'role' => [ |
80
|
|
|
'assign' => null, |
81
|
|
|
'update' => null, |
82
|
|
|
'create' => null, |
83
|
|
|
'delete' => null, |
84
|
|
|
'read' => null, |
85
|
|
|
], |
86
|
|
|
'section' => [ |
87
|
|
|
'assign' => ['Class' => true, 'Section' => true, 'Owner' => true, 'NewSection' => true], |
88
|
|
|
'edit' => null, |
89
|
|
|
'view' => null, |
90
|
|
|
], |
91
|
|
|
'user' => [ |
92
|
|
|
'login' => ['SiteAccess' => true], |
93
|
|
|
'password' => null, |
94
|
|
|
'preferences' => null, |
95
|
|
|
'register' => null, |
96
|
|
|
'selfedit' => null, |
97
|
|
|
'activation' => null, |
98
|
|
|
], |
99
|
|
|
]; |
100
|
|
|
|
101
|
|
|
/** |
102
|
|
|
* @var \eZ\Publish\API\Repository\Repository |
103
|
|
|
*/ |
104
|
|
|
protected $repository; |
105
|
|
|
|
106
|
|
|
/** |
107
|
|
|
* @var \eZ\Publish\SPI\Persistence\User\Handler |
108
|
|
|
*/ |
109
|
|
|
protected $userHandler; |
110
|
|
|
|
111
|
|
|
/** |
112
|
|
|
* @var \eZ\Publish\Core\Repository\Helper\LimitationService |
113
|
|
|
*/ |
114
|
|
|
protected $limitationService; |
115
|
|
|
|
116
|
|
|
/** |
117
|
|
|
* @var \eZ\Publish\Core\Repository\Helper\RoleDomainMapper |
118
|
|
|
*/ |
119
|
|
|
protected $roleDomainMapper; |
120
|
|
|
|
121
|
|
|
/** |
122
|
|
|
* @var array |
123
|
|
|
*/ |
124
|
|
|
protected $settings; |
125
|
|
|
|
126
|
|
|
/** |
127
|
|
|
* Setups service with reference to repository object that created it & corresponding handler. |
128
|
|
|
* |
129
|
|
|
* @param \eZ\Publish\API\Repository\Repository $repository |
130
|
|
|
* @param \eZ\Publish\SPI\Persistence\User\Handler $userHandler |
131
|
|
|
* @param \eZ\Publish\Core\Repository\Helper\LimitationService $limitationService |
132
|
|
|
* @param \eZ\Publish\Core\Repository\Helper\RoleDomainMapper $roleDomainMapper |
133
|
|
|
* @param array $settings |
134
|
|
|
*/ |
135
|
|
|
public function __construct( |
136
|
|
|
RepositoryInterface $repository, |
137
|
|
|
Handler $userHandler, |
138
|
|
|
Helper\LimitationService $limitationService, |
139
|
|
|
Helper\RoleDomainMapper $roleDomainMapper, |
140
|
|
|
array $settings = array() |
141
|
|
|
) { |
142
|
|
|
$this->repository = $repository; |
143
|
|
|
$this->userHandler = $userHandler; |
144
|
|
|
$this->limitationService = $limitationService; |
145
|
|
|
$this->roleDomainMapper = $roleDomainMapper; |
146
|
|
|
$this->settings = $settings; |
147
|
|
|
// Union makes sure default settings are ignored if provided in argument |
148
|
|
|
$this->settings['policyMap'] = isset($settings['policyMap']) ? |
149
|
|
|
$settings['policyMap'] + self::DEFAULT_CORE_POLICYMAP : |
150
|
|
|
self::DEFAULT_CORE_POLICYMAP; |
151
|
|
|
} |
152
|
|
|
|
153
|
|
|
/** |
154
|
|
|
* Creates a new RoleDraft. |
155
|
|
|
* |
156
|
|
|
* @since 6.0 |
157
|
|
|
* |
158
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to create a RoleDraft |
159
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException |
160
|
|
|
* if the name of the role already exists or if limitation of the same type |
161
|
|
|
* is repeated in the policy create struct or if limitation is not allowed on module/function |
162
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\LimitationValidationException if a policy limitation in the $roleCreateStruct is not valid |
163
|
|
|
* |
164
|
|
|
* @param \eZ\Publish\API\Repository\Values\User\RoleCreateStruct $roleCreateStruct |
165
|
|
|
* |
166
|
|
|
* @return \eZ\Publish\API\Repository\Values\User\RoleDraft |
167
|
|
|
*/ |
168
|
|
|
public function createRole(APIRoleCreateStruct $roleCreateStruct) |
169
|
|
|
{ |
170
|
|
|
if (!is_string($roleCreateStruct->identifier) || empty($roleCreateStruct->identifier)) { |
171
|
|
|
throw new InvalidArgumentValue('identifier', $roleCreateStruct->identifier, 'RoleCreateStruct'); |
172
|
|
|
} |
173
|
|
|
|
174
|
|
|
if ($this->repository->hasAccess('role', 'create') !== true) { |
|
|
|
|
175
|
|
|
throw new UnauthorizedException('role', 'create'); |
176
|
|
|
} |
177
|
|
|
|
178
|
|
|
try { |
179
|
|
|
$existingRole = $this->loadRoleByIdentifier($roleCreateStruct->identifier); |
180
|
|
|
|
181
|
|
|
throw new InvalidArgumentException( |
182
|
|
|
'$roleCreateStruct', |
183
|
|
|
"Role '{$existingRole->id}' with the specified identifier '{$roleCreateStruct->identifier}' " . |
184
|
|
|
'already exists' |
185
|
|
|
); |
186
|
|
|
} catch (APINotFoundException $e) { |
187
|
|
|
// Do nothing |
188
|
|
|
} |
189
|
|
|
|
190
|
|
|
$limitationValidationErrors = $this->validateRoleCreateStruct($roleCreateStruct); |
191
|
|
|
if (!empty($limitationValidationErrors)) { |
192
|
|
|
throw new LimitationValidationException($limitationValidationErrors); |
193
|
|
|
} |
194
|
|
|
|
195
|
|
|
$spiRoleCreateStruct = $this->roleDomainMapper->buildPersistenceRoleCreateStruct($roleCreateStruct); |
196
|
|
|
|
197
|
|
|
$this->repository->beginTransaction(); |
198
|
|
|
try { |
199
|
|
|
$spiRole = $this->userHandler->createRole($spiRoleCreateStruct); |
200
|
|
|
$this->repository->commit(); |
201
|
|
|
} catch (Exception $e) { |
202
|
|
|
$this->repository->rollback(); |
203
|
|
|
throw $e; |
204
|
|
|
} |
205
|
|
|
|
206
|
|
|
return $this->roleDomainMapper->buildDomainRoleDraftObject($spiRole); |
207
|
|
|
} |
208
|
|
|
|
209
|
|
|
/** |
210
|
|
|
* Creates a new RoleDraft for an existing Role. |
211
|
|
|
* |
212
|
|
|
* @since 6.0 |
213
|
|
|
* |
214
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to create a RoleDraft |
215
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException if the Role already has a RoleDraft that will need to be removed first |
216
|
|
|
* |
217
|
|
|
* @param \eZ\Publish\API\Repository\Values\User\Role $role |
218
|
|
|
* |
219
|
|
|
* @return \eZ\Publish\API\Repository\Values\User\RoleDraft |
220
|
|
|
*/ |
221
|
|
View Code Duplication |
public function createRoleDraft(APIRole $role) |
222
|
|
|
{ |
223
|
|
|
if ($this->repository->hasAccess('role', 'create') !== true) { |
|
|
|
|
224
|
|
|
throw new UnauthorizedException('role', 'create'); |
225
|
|
|
} |
226
|
|
|
|
227
|
|
|
try { |
228
|
|
|
$this->userHandler->loadRole($role->id, Role::STATUS_DRAFT); |
229
|
|
|
|
230
|
|
|
// Throw exception, so platformui et al can do conflict management. Follow-up: EZP-24719 |
231
|
|
|
throw new InvalidArgumentException( |
232
|
|
|
'$role', |
233
|
|
|
"Cannot create a draft for role '{$role->identifier}' because another draft exists" |
234
|
|
|
); |
235
|
|
|
} catch (APINotFoundException $e) { |
236
|
|
|
$this->repository->beginTransaction(); |
237
|
|
|
try { |
238
|
|
|
$spiRole = $this->userHandler->createRoleDraft($role->id); |
239
|
|
|
$this->repository->commit(); |
240
|
|
|
} catch (Exception $e) { |
241
|
|
|
$this->repository->rollback(); |
242
|
|
|
throw $e; |
243
|
|
|
} |
244
|
|
|
} |
245
|
|
|
|
246
|
|
|
return $this->roleDomainMapper->buildDomainRoleDraftObject($spiRole); |
247
|
|
|
} |
248
|
|
|
|
249
|
|
|
/** |
250
|
|
|
* Loads a RoleDraft for the given id. |
251
|
|
|
* |
252
|
|
|
* @since 6.0 |
253
|
|
|
* |
254
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to read this RoleDraft |
255
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException if a RoleDraft with the given id was not found |
256
|
|
|
* |
257
|
|
|
* @param mixed $id |
258
|
|
|
* |
259
|
|
|
* @return \eZ\Publish\API\Repository\Values\User\RoleDraft |
260
|
|
|
*/ |
261
|
|
View Code Duplication |
public function loadRoleDraft($id) |
262
|
|
|
{ |
263
|
|
|
if ($this->repository->hasAccess('role', 'read') !== true) { |
|
|
|
|
264
|
|
|
throw new UnauthorizedException('role', 'read'); |
265
|
|
|
} |
266
|
|
|
|
267
|
|
|
$spiRole = $this->userHandler->loadRole($id, Role::STATUS_DRAFT); |
268
|
|
|
|
269
|
|
|
return $this->roleDomainMapper->buildDomainRoleDraftObject($spiRole); |
270
|
|
|
} |
271
|
|
|
|
272
|
|
|
/** |
273
|
|
|
* Loads a RoleDraft by the ID of the role it was created from. |
274
|
|
|
* |
275
|
|
|
* @param mixed $roleId ID of the role the draft was created from. |
276
|
|
|
* |
277
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to read this role |
278
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException if a RoleDraft with the given id was not found |
279
|
|
|
* |
280
|
|
|
* @return \eZ\Publish\API\Repository\Values\User\RoleDraft |
281
|
|
|
*/ |
282
|
|
View Code Duplication |
public function loadRoleDraftByRoleId($roleId) |
283
|
|
|
{ |
284
|
|
|
if ($this->repository->hasAccess('role', 'read') !== true) { |
|
|
|
|
285
|
|
|
throw new UnauthorizedException('role', 'read'); |
286
|
|
|
} |
287
|
|
|
|
288
|
|
|
$spiRole = $this->userHandler->loadRoleDraftByRoleId($roleId); |
289
|
|
|
|
290
|
|
|
return $this->roleDomainMapper->buildDomainRoleDraftObject($spiRole); |
291
|
|
|
} |
292
|
|
|
|
293
|
|
|
/** |
294
|
|
|
* Updates the properties of a RoleDraft. |
295
|
|
|
* |
296
|
|
|
* @since 6.0 |
297
|
|
|
* |
298
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to update a RoleDraft |
299
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException if the identifier of the RoleDraft already exists |
300
|
|
|
* |
301
|
|
|
* @param \eZ\Publish\API\Repository\Values\User\RoleDraft $roleDraft |
302
|
|
|
* @param \eZ\Publish\API\Repository\Values\User\RoleUpdateStruct $roleUpdateStruct |
303
|
|
|
* |
304
|
|
|
* @return \eZ\Publish\API\Repository\Values\User\RoleDraft |
305
|
|
|
*/ |
306
|
|
|
public function updateRoleDraft(APIRoleDraft $roleDraft, RoleUpdateStruct $roleUpdateStruct) |
307
|
|
|
{ |
308
|
|
View Code Duplication |
if ($roleUpdateStruct->identifier !== null && !is_string($roleUpdateStruct->identifier)) { |
|
|
|
|
309
|
|
|
throw new InvalidArgumentValue('identifier', $roleUpdateStruct->identifier, 'RoleUpdateStruct'); |
310
|
|
|
} |
311
|
|
|
|
312
|
|
|
$loadedRoleDraft = $this->loadRoleDraft($roleDraft->id); |
313
|
|
|
|
314
|
|
|
if ($this->repository->hasAccess('role', 'update') !== true) { |
|
|
|
|
315
|
|
|
throw new UnauthorizedException('role', 'update'); |
316
|
|
|
} |
317
|
|
|
|
318
|
|
|
if ($roleUpdateStruct->identifier !== null) { |
319
|
|
|
try { |
320
|
|
|
/* Throw exception if: |
321
|
|
|
* - A published role with the same identifier exists, AND |
322
|
|
|
* - The ID of the published role does not match the original ID of the draft |
323
|
|
|
*/ |
324
|
|
|
$existingSPIRole = $this->userHandler->loadRoleByIdentifier($roleUpdateStruct->identifier); |
325
|
|
|
$SPIRoleDraft = $this->userHandler->loadRole($loadedRoleDraft->id, Role::STATUS_DRAFT); |
326
|
|
|
if ($existingSPIRole->id != $SPIRoleDraft->originalId) { |
327
|
|
|
throw new InvalidArgumentException( |
328
|
|
|
'$roleUpdateStruct', |
329
|
|
|
"Role '{$existingSPIRole->id}' with the specified identifier '{$roleUpdateStruct->identifier}' " . |
330
|
|
|
'already exists' |
331
|
|
|
); |
332
|
|
|
} |
333
|
|
|
} catch (APINotFoundException $e) { |
334
|
|
|
// Do nothing |
335
|
|
|
} |
336
|
|
|
} |
337
|
|
|
|
338
|
|
|
$this->repository->beginTransaction(); |
339
|
|
|
try { |
340
|
|
|
$this->userHandler->updateRole( |
341
|
|
|
new SPIRoleUpdateStruct( |
342
|
|
|
array( |
343
|
|
|
'id' => $loadedRoleDraft->id, |
344
|
|
|
'identifier' => $roleUpdateStruct->identifier ?: $loadedRoleDraft->identifier, |
345
|
|
|
) |
346
|
|
|
) |
347
|
|
|
); |
348
|
|
|
$this->repository->commit(); |
349
|
|
|
} catch (Exception $e) { |
350
|
|
|
$this->repository->rollback(); |
351
|
|
|
throw $e; |
352
|
|
|
} |
353
|
|
|
|
354
|
|
|
return $this->loadRoleDraft($loadedRoleDraft->id); |
355
|
|
|
} |
356
|
|
|
|
357
|
|
|
/** |
358
|
|
|
* Adds a new policy to the RoleDraft. |
359
|
|
|
* |
360
|
|
|
* @since 6.0 |
361
|
|
|
* |
362
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to add a policy |
363
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException if limitation of the same type is repeated in policy create |
364
|
|
|
* struct or if limitation is not allowed on module/function |
365
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\LimitationValidationException if a limitation in the $policyCreateStruct is not valid |
366
|
|
|
* |
367
|
|
|
* @param \eZ\Publish\API\Repository\Values\User\RoleDraft $roleDraft |
368
|
|
|
* @param \eZ\Publish\API\Repository\Values\User\PolicyCreateStruct $policyCreateStruct |
369
|
|
|
* |
370
|
|
|
* @return \eZ\Publish\API\Repository\Values\User\RoleDraft |
371
|
|
|
*/ |
372
|
|
View Code Duplication |
public function addPolicyByRoleDraft(APIRoleDraft $roleDraft, APIPolicyCreateStruct $policyCreateStruct) |
373
|
|
|
{ |
374
|
|
|
if (!is_string($policyCreateStruct->module) || empty($policyCreateStruct->module)) { |
375
|
|
|
throw new InvalidArgumentValue('module', $policyCreateStruct->module, 'PolicyCreateStruct'); |
376
|
|
|
} |
377
|
|
|
|
378
|
|
|
if (!is_string($policyCreateStruct->function) || empty($policyCreateStruct->function)) { |
379
|
|
|
throw new InvalidArgumentValue('function', $policyCreateStruct->function, 'PolicyCreateStruct'); |
380
|
|
|
} |
381
|
|
|
|
382
|
|
|
if ($policyCreateStruct->module === '*' && $policyCreateStruct->function !== '*') { |
383
|
|
|
throw new InvalidArgumentValue('module', $policyCreateStruct->module, 'PolicyCreateStruct'); |
384
|
|
|
} |
385
|
|
|
|
386
|
|
|
if ($this->repository->hasAccess('role', 'update') !== true) { |
|
|
|
|
387
|
|
|
throw new UnauthorizedException('role', 'update'); |
388
|
|
|
} |
389
|
|
|
|
390
|
|
|
$loadedRoleDraft = $this->loadRoleDraft($roleDraft->id); |
391
|
|
|
|
392
|
|
|
$limitations = $policyCreateStruct->getLimitations(); |
393
|
|
|
$limitationValidationErrors = $this->validatePolicy( |
394
|
|
|
$policyCreateStruct->module, |
395
|
|
|
$policyCreateStruct->function, |
396
|
|
|
$limitations |
397
|
|
|
); |
398
|
|
|
if (!empty($limitationValidationErrors)) { |
399
|
|
|
throw new LimitationValidationException($limitationValidationErrors); |
400
|
|
|
} |
401
|
|
|
|
402
|
|
|
$spiPolicy = $this->roleDomainMapper->buildPersistencePolicyObject( |
403
|
|
|
$policyCreateStruct->module, |
404
|
|
|
$policyCreateStruct->function, |
405
|
|
|
$limitations |
406
|
|
|
); |
407
|
|
|
|
408
|
|
|
$this->repository->beginTransaction(); |
409
|
|
|
try { |
410
|
|
|
$this->userHandler->addPolicyByRoleDraft($loadedRoleDraft->id, $spiPolicy); |
411
|
|
|
$this->repository->commit(); |
412
|
|
|
} catch (Exception $e) { |
413
|
|
|
$this->repository->rollback(); |
414
|
|
|
throw $e; |
415
|
|
|
} |
416
|
|
|
|
417
|
|
|
return $this->loadRoleDraft($loadedRoleDraft->id); |
418
|
|
|
} |
419
|
|
|
|
420
|
|
|
/** |
421
|
|
|
* Removes a policy from a RoleDraft. |
422
|
|
|
* |
423
|
|
|
* @since 6.0 |
424
|
|
|
* |
425
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to remove a policy |
426
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException if policy does not belong to the given RoleDraft |
427
|
|
|
* |
428
|
|
|
* @param \eZ\Publish\API\Repository\Values\User\RoleDraft $roleDraft |
429
|
|
|
* @param PolicyDraft $policyDraft the policy to remove from the RoleDraft |
430
|
|
|
* |
431
|
|
|
* @return APIRoleDraft if the authenticated user is not allowed to remove a policy |
432
|
|
|
*/ |
433
|
|
View Code Duplication |
public function removePolicyByRoleDraft(APIRoleDraft $roleDraft, PolicyDraft $policyDraft) |
434
|
|
|
{ |
435
|
|
|
if ($this->repository->hasAccess('role', 'update') !== true) { |
|
|
|
|
436
|
|
|
throw new UnauthorizedException('role', 'update'); |
437
|
|
|
} |
438
|
|
|
|
439
|
|
|
if ($policyDraft->roleId != $roleDraft->id) { |
440
|
|
|
throw new InvalidArgumentException('$policy', 'Policy does not belong to the given role'); |
441
|
|
|
} |
442
|
|
|
|
443
|
|
|
$this->internalDeletePolicy($policyDraft); |
444
|
|
|
|
445
|
|
|
return $this->loadRoleDraft($roleDraft->id); |
446
|
|
|
} |
447
|
|
|
|
448
|
|
|
/** |
449
|
|
|
* Updates the limitations of a policy. The module and function cannot be changed and |
450
|
|
|
* the limitations are replaced by the ones in $roleUpdateStruct. |
451
|
|
|
* |
452
|
|
|
* @since 6.0 |
453
|
|
|
* |
454
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to update a policy |
455
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException if limitation of the same type is repeated in policy update |
456
|
|
|
* struct or if limitation is not allowed on module/function |
457
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\LimitationValidationException if a limitation in the $policyUpdateStruct is not valid |
458
|
|
|
* |
459
|
|
|
* @param \eZ\Publish\API\Repository\Values\User\RoleDraft $roleDraft |
460
|
|
|
* @param \eZ\Publish\API\Repository\Values\User\PolicyDraft $policy |
461
|
|
|
* @param \eZ\Publish\API\Repository\Values\User\PolicyUpdateStruct $policyUpdateStruct |
462
|
|
|
* |
463
|
|
|
* @return \eZ\Publish\API\Repository\Values\User\PolicyDraft |
464
|
|
|
*/ |
465
|
|
|
public function updatePolicyByRoleDraft(APIRoleDraft $roleDraft, PolicyDraft $policy, APIPolicyUpdateStruct $policyUpdateStruct) |
466
|
|
|
{ |
467
|
|
|
if (!is_string($policy->module)) { |
468
|
|
|
throw new InvalidArgumentValue('module', $policy->module, 'Policy'); |
469
|
|
|
} |
470
|
|
|
|
471
|
|
|
if (!is_string($policy->function)) { |
472
|
|
|
throw new InvalidArgumentValue('function', $policy->function, 'Policy'); |
473
|
|
|
} |
474
|
|
|
|
475
|
|
|
if ($this->repository->hasAccess('role', 'update') !== true) { |
|
|
|
|
476
|
|
|
throw new UnauthorizedException('role', 'update'); |
477
|
|
|
} |
478
|
|
|
|
479
|
|
|
if ($policy->roleId !== $roleDraft->id) { |
480
|
|
|
throw new InvalidArgumentException('$policy', "doesn't belong to provided role draft"); |
481
|
|
|
} |
482
|
|
|
|
483
|
|
|
$limitations = $policyUpdateStruct->getLimitations(); |
484
|
|
|
$limitationValidationErrors = $this->validatePolicy( |
485
|
|
|
$policy->module, |
486
|
|
|
$policy->function, |
487
|
|
|
$limitations |
488
|
|
|
); |
489
|
|
|
if (!empty($limitationValidationErrors)) { |
490
|
|
|
throw new LimitationValidationException($limitationValidationErrors); |
491
|
|
|
} |
492
|
|
|
|
493
|
|
|
$spiPolicy = $this->roleDomainMapper->buildPersistencePolicyObject( |
494
|
|
|
$policy->module, |
495
|
|
|
$policy->function, |
496
|
|
|
$limitations |
497
|
|
|
); |
498
|
|
|
$spiPolicy->id = $policy->id; |
499
|
|
|
$spiPolicy->roleId = $policy->roleId; |
500
|
|
|
$spiPolicy->originalId = $policy->originalId; |
501
|
|
|
|
502
|
|
|
$this->repository->beginTransaction(); |
503
|
|
|
try { |
504
|
|
|
$this->userHandler->updatePolicy($spiPolicy); |
505
|
|
|
$this->repository->commit(); |
506
|
|
|
} catch (Exception $e) { |
507
|
|
|
$this->repository->rollback(); |
508
|
|
|
throw $e; |
509
|
|
|
} |
510
|
|
|
|
511
|
|
|
return $this->roleDomainMapper->buildDomainPolicyObject($spiPolicy); |
|
|
|
|
512
|
|
|
} |
513
|
|
|
|
514
|
|
|
/** |
515
|
|
|
* Deletes the given RoleDraft. |
516
|
|
|
* |
517
|
|
|
* @since 6.0 |
518
|
|
|
* |
519
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to delete this RoleDraft |
520
|
|
|
* |
521
|
|
|
* @param \eZ\Publish\API\Repository\Values\User\RoleDraft $roleDraft |
522
|
|
|
*/ |
523
|
|
|
public function deleteRoleDraft(APIRoleDraft $roleDraft) |
524
|
|
|
{ |
525
|
|
|
$loadedRoleDraft = $this->loadRoleDraft($roleDraft->id); |
526
|
|
|
|
527
|
|
|
$this->repository->beginTransaction(); |
528
|
|
|
try { |
529
|
|
|
$this->userHandler->deleteRole($loadedRoleDraft->id, Role::STATUS_DRAFT); |
530
|
|
|
$this->repository->commit(); |
531
|
|
|
} catch (Exception $e) { |
532
|
|
|
$this->repository->rollback(); |
533
|
|
|
throw $e; |
534
|
|
|
} |
535
|
|
|
} |
536
|
|
|
|
537
|
|
|
/** |
538
|
|
|
* Publishes a given RoleDraft. |
539
|
|
|
* |
540
|
|
|
* @since 6.0 |
541
|
|
|
* |
542
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to publish this RoleDraft |
543
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\BadStateException if the role draft cannot be loaded |
544
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException if the role draft has no policies |
545
|
|
|
* |
546
|
|
|
* @param \eZ\Publish\API\Repository\Values\User\RoleDraft $roleDraft |
547
|
|
|
*/ |
548
|
|
View Code Duplication |
public function publishRoleDraft(APIRoleDraft $roleDraft) |
549
|
|
|
{ |
550
|
|
|
if ($this->repository->hasAccess('role', 'update') !== true) { |
|
|
|
|
551
|
|
|
throw new UnauthorizedException('role', 'update'); |
552
|
|
|
} |
553
|
|
|
|
554
|
|
|
try { |
555
|
|
|
$loadedRoleDraft = $this->loadRoleDraft($roleDraft->id); |
556
|
|
|
} catch (APINotFoundException $e) { |
557
|
|
|
throw new BadStateException( |
558
|
|
|
'$roleDraft', |
559
|
|
|
'The role does not have a draft.', |
560
|
|
|
$e |
561
|
|
|
); |
562
|
|
|
} |
563
|
|
|
|
564
|
|
|
// TODO: Uncomment when role policy editing is done, see EZP-24711 & EZP-24713 |
565
|
|
|
/*if (count($loadedRoleDraft->getPolicies()) === 0) { |
566
|
|
|
throw new InvalidArgumentException( |
567
|
|
|
"\$roleDraft", |
568
|
|
|
'The role draft should have at least one policy.' |
569
|
|
|
); |
570
|
|
|
}*/ |
571
|
|
|
|
572
|
|
|
$this->repository->beginTransaction(); |
573
|
|
|
try { |
574
|
|
|
$this->userHandler->publishRoleDraft($loadedRoleDraft->id); |
575
|
|
|
$this->repository->commit(); |
576
|
|
|
} catch (Exception $e) { |
577
|
|
|
$this->repository->rollback(); |
578
|
|
|
throw $e; |
579
|
|
|
} |
580
|
|
|
} |
581
|
|
|
|
582
|
|
|
/** |
583
|
|
|
* Updates the name of the role. |
584
|
|
|
* |
585
|
|
|
* @deprecated since 6.0, use {@see updateRoleDraft} |
586
|
|
|
* |
587
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to update a role |
588
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException if the name of the role already exists |
589
|
|
|
* |
590
|
|
|
* @param \eZ\Publish\API\Repository\Values\User\Role $role |
591
|
|
|
* @param \eZ\Publish\API\Repository\Values\User\RoleUpdateStruct $roleUpdateStruct |
592
|
|
|
* |
593
|
|
|
* @return \eZ\Publish\API\Repository\Values\User\Role |
594
|
|
|
*/ |
595
|
|
|
public function updateRole(APIRole $role, RoleUpdateStruct $roleUpdateStruct) |
596
|
|
|
{ |
597
|
|
View Code Duplication |
if ($roleUpdateStruct->identifier !== null && !is_string($roleUpdateStruct->identifier)) { |
|
|
|
|
598
|
|
|
throw new InvalidArgumentValue('identifier', $roleUpdateStruct->identifier, 'RoleUpdateStruct'); |
599
|
|
|
} |
600
|
|
|
|
601
|
|
|
$loadedRole = $this->loadRole($role->id); |
602
|
|
|
|
603
|
|
|
if ($this->repository->hasAccess('role', 'update') !== true) { |
|
|
|
|
604
|
|
|
throw new UnauthorizedException('role', 'update'); |
605
|
|
|
} |
606
|
|
|
|
607
|
|
|
if ($roleUpdateStruct->identifier !== null) { |
608
|
|
|
try { |
609
|
|
|
$existingRole = $this->loadRoleByIdentifier($roleUpdateStruct->identifier); |
610
|
|
|
|
611
|
|
|
if ($existingRole->id != $loadedRole->id) { |
612
|
|
|
throw new InvalidArgumentException( |
613
|
|
|
'$roleUpdateStruct', |
614
|
|
|
'Role with provided identifier already exists' |
615
|
|
|
); |
616
|
|
|
} |
617
|
|
|
} catch (APINotFoundException $e) { |
618
|
|
|
// Do nothing |
619
|
|
|
} |
620
|
|
|
} |
621
|
|
|
|
622
|
|
|
$this->repository->beginTransaction(); |
623
|
|
|
try { |
624
|
|
|
$this->userHandler->updateRole( |
625
|
|
|
new SPIRoleUpdateStruct( |
626
|
|
|
array( |
627
|
|
|
'id' => $loadedRole->id, |
628
|
|
|
'identifier' => $roleUpdateStruct->identifier ?: $loadedRole->identifier, |
629
|
|
|
) |
630
|
|
|
) |
631
|
|
|
); |
632
|
|
|
$this->repository->commit(); |
633
|
|
|
} catch (Exception $e) { |
634
|
|
|
$this->repository->rollback(); |
635
|
|
|
throw $e; |
636
|
|
|
} |
637
|
|
|
|
638
|
|
|
return $this->loadRole($loadedRole->id); |
639
|
|
|
} |
640
|
|
|
|
641
|
|
|
/** |
642
|
|
|
* Adds a new policy to the role. |
643
|
|
|
* |
644
|
|
|
* @deprecated since 6.0, use {@see addPolicyByRoleDraft} |
645
|
|
|
* |
646
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to add a policy |
647
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException if limitation of the same type is repeated in policy create |
648
|
|
|
* struct or if limitation is not allowed on module/function |
649
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\LimitationValidationException if a limitation in the $policyCreateStruct is not valid |
650
|
|
|
* |
651
|
|
|
* @param \eZ\Publish\API\Repository\Values\User\Role $role |
652
|
|
|
* @param \eZ\Publish\API\Repository\Values\User\PolicyCreateStruct $policyCreateStruct |
653
|
|
|
* |
654
|
|
|
* @return \eZ\Publish\API\Repository\Values\User\Role |
655
|
|
|
*/ |
656
|
|
View Code Duplication |
public function addPolicy(APIRole $role, APIPolicyCreateStruct $policyCreateStruct) |
657
|
|
|
{ |
658
|
|
|
if (!is_string($policyCreateStruct->module) || empty($policyCreateStruct->module)) { |
659
|
|
|
throw new InvalidArgumentValue('module', $policyCreateStruct->module, 'PolicyCreateStruct'); |
660
|
|
|
} |
661
|
|
|
|
662
|
|
|
if (!is_string($policyCreateStruct->function) || empty($policyCreateStruct->function)) { |
663
|
|
|
throw new InvalidArgumentValue('function', $policyCreateStruct->function, 'PolicyCreateStruct'); |
664
|
|
|
} |
665
|
|
|
|
666
|
|
|
if ($policyCreateStruct->module === '*' && $policyCreateStruct->function !== '*') { |
667
|
|
|
throw new InvalidArgumentValue('module', $policyCreateStruct->module, 'PolicyCreateStruct'); |
668
|
|
|
} |
669
|
|
|
|
670
|
|
|
if ($this->repository->hasAccess('role', 'update') !== true) { |
|
|
|
|
671
|
|
|
throw new UnauthorizedException('role', 'update'); |
672
|
|
|
} |
673
|
|
|
|
674
|
|
|
$loadedRole = $this->loadRole($role->id); |
675
|
|
|
|
676
|
|
|
$limitations = $policyCreateStruct->getLimitations(); |
677
|
|
|
$limitationValidationErrors = $this->validatePolicy( |
678
|
|
|
$policyCreateStruct->module, |
679
|
|
|
$policyCreateStruct->function, |
680
|
|
|
$limitations |
681
|
|
|
); |
682
|
|
|
if (!empty($limitationValidationErrors)) { |
683
|
|
|
throw new LimitationValidationException($limitationValidationErrors); |
684
|
|
|
} |
685
|
|
|
|
686
|
|
|
$spiPolicy = $this->roleDomainMapper->buildPersistencePolicyObject( |
687
|
|
|
$policyCreateStruct->module, |
688
|
|
|
$policyCreateStruct->function, |
689
|
|
|
$limitations |
690
|
|
|
); |
691
|
|
|
|
692
|
|
|
$this->repository->beginTransaction(); |
693
|
|
|
try { |
694
|
|
|
$this->userHandler->addPolicy($loadedRole->id, $spiPolicy); |
695
|
|
|
$this->repository->commit(); |
696
|
|
|
} catch (Exception $e) { |
697
|
|
|
$this->repository->rollback(); |
698
|
|
|
throw $e; |
699
|
|
|
} |
700
|
|
|
|
701
|
|
|
return $this->loadRole($loadedRole->id); |
702
|
|
|
} |
703
|
|
|
|
704
|
|
|
/** |
705
|
|
|
* Removes a policy from the role. |
706
|
|
|
* |
707
|
|
|
* @deprecated since 5.3, use {@link removePolicyByRoleDraft()} instead. |
708
|
|
|
* |
709
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to remove a policy |
710
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException if policy does not belong to the given role |
711
|
|
|
* |
712
|
|
|
* @param \eZ\Publish\API\Repository\Values\User\Role $role |
713
|
|
|
* @param \eZ\Publish\API\Repository\Values\User\Policy $policy the policy to remove from the role |
714
|
|
|
* |
715
|
|
|
* @return \eZ\Publish\API\Repository\Values\User\Role the updated role |
716
|
|
|
*/ |
717
|
|
View Code Duplication |
public function removePolicy(APIRole $role, APIPolicy $policy) |
718
|
|
|
{ |
719
|
|
|
if ($this->repository->hasAccess('role', 'update') !== true) { |
|
|
|
|
720
|
|
|
throw new UnauthorizedException('role', 'update'); |
721
|
|
|
} |
722
|
|
|
|
723
|
|
|
if ($policy->roleId != $role->id) { |
724
|
|
|
throw new InvalidArgumentException('$policy', 'Policy does not belong to the given role'); |
725
|
|
|
} |
726
|
|
|
|
727
|
|
|
$this->internalDeletePolicy($policy); |
728
|
|
|
|
729
|
|
|
return $this->loadRole($role->id); |
730
|
|
|
} |
731
|
|
|
|
732
|
|
|
/** |
733
|
|
|
* Deletes a policy. |
734
|
|
|
* |
735
|
|
|
* @deprecated since 6.0, use {@link removePolicyByRoleDraft()} instead. |
736
|
|
|
* |
737
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to remove a policy |
738
|
|
|
* |
739
|
|
|
* @param \eZ\Publish\API\Repository\Values\User\Policy $policy the policy to delete |
740
|
|
|
*/ |
741
|
|
|
public function deletePolicy(APIPolicy $policy) |
742
|
|
|
{ |
743
|
|
|
if ($this->repository->hasAccess('role', 'update') !== true) { |
|
|
|
|
744
|
|
|
throw new UnauthorizedException('role', 'update'); |
745
|
|
|
} |
746
|
|
|
|
747
|
|
|
$this->internalDeletePolicy($policy); |
748
|
|
|
} |
749
|
|
|
|
750
|
|
|
/** |
751
|
|
|
* Deletes a policy. |
752
|
|
|
* |
753
|
|
|
* Used by {@link removePolicy()} and {@link deletePolicy()} |
754
|
|
|
* |
755
|
|
|
* @param APIPolicy $policy |
756
|
|
|
* |
757
|
|
|
* @throws \Exception |
758
|
|
|
*/ |
759
|
|
|
protected function internalDeletePolicy(APIPolicy $policy) |
760
|
|
|
{ |
761
|
|
|
$this->repository->beginTransaction(); |
762
|
|
|
try { |
763
|
|
|
$this->userHandler->deletePolicy($policy->id); |
764
|
|
|
$this->repository->commit(); |
765
|
|
|
} catch (Exception $e) { |
766
|
|
|
$this->repository->rollback(); |
767
|
|
|
throw $e; |
768
|
|
|
} |
769
|
|
|
} |
770
|
|
|
|
771
|
|
|
/** |
772
|
|
|
* Updates the limitations of a policy. The module and function cannot be changed and |
773
|
|
|
* the limitations are replaced by the ones in $roleUpdateStruct. |
774
|
|
|
* |
775
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to update a policy |
776
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException if limitation of the same type is repeated in policy update |
777
|
|
|
* struct or if limitation is not allowed on module/function |
778
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\LimitationValidationException if a limitation in the $policyUpdateStruct is not valid |
779
|
|
|
* |
780
|
|
|
* @param \eZ\Publish\API\Repository\Values\User\PolicyUpdateStruct $policyUpdateStruct |
781
|
|
|
* @param \eZ\Publish\API\Repository\Values\User\Policy $policy |
782
|
|
|
* |
783
|
|
|
* @return \eZ\Publish\API\Repository\Values\User\Policy |
784
|
|
|
*/ |
785
|
|
|
public function updatePolicy(APIPolicy $policy, APIPolicyUpdateStruct $policyUpdateStruct) |
786
|
|
|
{ |
787
|
|
|
if (!is_string($policy->module)) { |
788
|
|
|
throw new InvalidArgumentValue('module', $policy->module, 'Policy'); |
789
|
|
|
} |
790
|
|
|
|
791
|
|
|
if (!is_string($policy->function)) { |
792
|
|
|
throw new InvalidArgumentValue('function', $policy->function, 'Policy'); |
793
|
|
|
} |
794
|
|
|
|
795
|
|
|
if ($this->repository->hasAccess('role', 'update') !== true) { |
|
|
|
|
796
|
|
|
throw new UnauthorizedException('role', 'update'); |
797
|
|
|
} |
798
|
|
|
|
799
|
|
|
$limitations = $policyUpdateStruct->getLimitations(); |
800
|
|
|
$limitationValidationErrors = $this->validatePolicy( |
801
|
|
|
$policy->module, |
802
|
|
|
$policy->function, |
803
|
|
|
$limitations |
804
|
|
|
); |
805
|
|
|
if (!empty($limitationValidationErrors)) { |
806
|
|
|
throw new LimitationValidationException($limitationValidationErrors); |
807
|
|
|
} |
808
|
|
|
|
809
|
|
|
$spiPolicy = $this->roleDomainMapper->buildPersistencePolicyObject( |
810
|
|
|
$policy->module, |
811
|
|
|
$policy->function, |
812
|
|
|
$limitations |
813
|
|
|
); |
814
|
|
|
$spiPolicy->id = $policy->id; |
815
|
|
|
$spiPolicy->roleId = $policy->roleId; |
816
|
|
|
|
817
|
|
|
$this->repository->beginTransaction(); |
818
|
|
|
try { |
819
|
|
|
$this->userHandler->updatePolicy($spiPolicy); |
820
|
|
|
$this->repository->commit(); |
821
|
|
|
} catch (Exception $e) { |
822
|
|
|
$this->repository->rollback(); |
823
|
|
|
throw $e; |
824
|
|
|
} |
825
|
|
|
|
826
|
|
|
return $this->roleDomainMapper->buildDomainPolicyObject($spiPolicy); |
827
|
|
|
} |
828
|
|
|
|
829
|
|
|
/** |
830
|
|
|
* Loads a role for the given id. |
831
|
|
|
* |
832
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to read this role |
833
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException if a role with the given id was not found |
834
|
|
|
* |
835
|
|
|
* @param mixed $id |
836
|
|
|
* |
837
|
|
|
* @return \eZ\Publish\API\Repository\Values\User\Role |
838
|
|
|
*/ |
839
|
|
View Code Duplication |
public function loadRole($id) |
840
|
|
|
{ |
841
|
|
|
if ($this->repository->hasAccess('role', 'read') !== true) { |
|
|
|
|
842
|
|
|
throw new UnauthorizedException('role', 'read'); |
843
|
|
|
} |
844
|
|
|
|
845
|
|
|
$spiRole = $this->userHandler->loadRole($id); |
846
|
|
|
|
847
|
|
|
return $this->roleDomainMapper->buildDomainRoleObject($spiRole); |
848
|
|
|
} |
849
|
|
|
|
850
|
|
|
/** |
851
|
|
|
* Loads a role for the given identifier. |
852
|
|
|
* |
853
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to read this role |
854
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException if a role with the given name was not found |
855
|
|
|
* |
856
|
|
|
* @param string $identifier |
857
|
|
|
* |
858
|
|
|
* @return \eZ\Publish\API\Repository\Values\User\Role |
859
|
|
|
*/ |
860
|
|
View Code Duplication |
public function loadRoleByIdentifier($identifier) |
861
|
|
|
{ |
862
|
|
|
if (!is_string($identifier)) { |
863
|
|
|
throw new InvalidArgumentValue('identifier', $identifier); |
864
|
|
|
} |
865
|
|
|
|
866
|
|
|
if ($this->repository->hasAccess('role', 'read') !== true) { |
|
|
|
|
867
|
|
|
throw new UnauthorizedException('role', 'read'); |
868
|
|
|
} |
869
|
|
|
|
870
|
|
|
$spiRole = $this->userHandler->loadRoleByIdentifier($identifier); |
871
|
|
|
|
872
|
|
|
return $this->roleDomainMapper->buildDomainRoleObject($spiRole); |
873
|
|
|
} |
874
|
|
|
|
875
|
|
|
/** |
876
|
|
|
* Loads all roles. |
877
|
|
|
* |
878
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to read the roles |
879
|
|
|
* |
880
|
|
|
* @return \eZ\Publish\API\Repository\Values\User\Role[] |
881
|
|
|
*/ |
882
|
|
View Code Duplication |
public function loadRoles() |
883
|
|
|
{ |
884
|
|
|
if ($this->repository->hasAccess('role', 'read') !== true) { |
|
|
|
|
885
|
|
|
throw new UnauthorizedException('role', 'read'); |
886
|
|
|
} |
887
|
|
|
|
888
|
|
|
$spiRoles = $this->userHandler->loadRoles(); |
889
|
|
|
|
890
|
|
|
$roles = array(); |
891
|
|
|
foreach ($spiRoles as $spiRole) { |
892
|
|
|
$roles[] = $this->roleDomainMapper->buildDomainRoleObject($spiRole); |
893
|
|
|
} |
894
|
|
|
|
895
|
|
|
return $roles; |
896
|
|
|
} |
897
|
|
|
|
898
|
|
|
/** |
899
|
|
|
* Deletes the given role. |
900
|
|
|
* |
901
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to delete this role |
902
|
|
|
* |
903
|
|
|
* @param \eZ\Publish\API\Repository\Values\User\Role $role |
904
|
|
|
*/ |
905
|
|
|
public function deleteRole(APIRole $role) |
906
|
|
|
{ |
907
|
|
|
if ($this->repository->hasAccess('role', 'delete') !== true) { |
|
|
|
|
908
|
|
|
throw new UnauthorizedException('role', 'delete'); |
909
|
|
|
} |
910
|
|
|
|
911
|
|
|
$loadedRole = $this->loadRole($role->id); |
912
|
|
|
|
913
|
|
|
$this->repository->beginTransaction(); |
914
|
|
|
try { |
915
|
|
|
$this->userHandler->deleteRole($loadedRole->id); |
916
|
|
|
$this->repository->commit(); |
917
|
|
|
} catch (Exception $e) { |
918
|
|
|
$this->repository->rollback(); |
919
|
|
|
throw $e; |
920
|
|
|
} |
921
|
|
|
} |
922
|
|
|
|
923
|
|
|
/** |
924
|
|
|
* Loads all policies from roles which are assigned to a user or to user groups to which the user belongs. |
925
|
|
|
* |
926
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException if a user with the given id was not found |
927
|
|
|
* |
928
|
|
|
* @param mixed $userId |
929
|
|
|
* |
930
|
|
|
* @return \eZ\Publish\API\Repository\Values\User\Policy[] |
931
|
|
|
*/ |
932
|
|
|
public function loadPoliciesByUserId($userId) |
933
|
|
|
{ |
934
|
|
|
$spiPolicies = $this->userHandler->loadPoliciesByUserId($userId); |
935
|
|
|
|
936
|
|
|
$policies = array(); |
937
|
|
|
foreach ($spiPolicies as $spiPolicy) { |
938
|
|
|
$policies[] = $this->roleDomainMapper->buildDomainPolicyObject($spiPolicy); |
939
|
|
|
} |
940
|
|
|
|
941
|
|
|
if (empty($policies)) { |
942
|
|
|
$this->userHandler->load($userId); |
943
|
|
|
}// For NotFoundException in case userId is invalid |
944
|
|
|
|
945
|
|
|
return $policies; |
946
|
|
|
} |
947
|
|
|
|
948
|
|
|
/** |
949
|
|
|
* Assigns a role to the given user group. |
950
|
|
|
* |
951
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to assign a role |
952
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\LimitationValidationException if $roleLimitation is not valid |
953
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException If assignment already exists |
954
|
|
|
* |
955
|
|
|
* @param \eZ\Publish\API\Repository\Values\User\Role $role |
956
|
|
|
* @param \eZ\Publish\API\Repository\Values\User\UserGroup $userGroup |
957
|
|
|
* @param \eZ\Publish\API\Repository\Values\User\Limitation\RoleLimitation $roleLimitation an optional role limitation (which is either a subtree limitation or section limitation) |
958
|
|
|
*/ |
959
|
|
View Code Duplication |
public function assignRoleToUserGroup(APIRole $role, UserGroup $userGroup, RoleLimitation $roleLimitation = null) |
960
|
|
|
{ |
961
|
|
|
if ($this->repository->canUser('role', 'assign', $userGroup, $role) !== true) { |
|
|
|
|
962
|
|
|
throw new UnauthorizedException('role', 'assign'); |
963
|
|
|
} |
964
|
|
|
|
965
|
|
|
if ($roleLimitation === null) { |
966
|
|
|
$limitation = null; |
967
|
|
|
} else { |
968
|
|
|
$limitationValidationErrors = $this->limitationService->validateLimitation($roleLimitation); |
969
|
|
|
if (!empty($limitationValidationErrors)) { |
970
|
|
|
throw new LimitationValidationException($limitationValidationErrors); |
971
|
|
|
} |
972
|
|
|
|
973
|
|
|
$limitation = array($roleLimitation->getIdentifier() => $roleLimitation->limitationValues); |
974
|
|
|
} |
975
|
|
|
|
976
|
|
|
// Check if objects exists |
977
|
|
|
$spiRole = $this->userHandler->loadRole($role->id); |
978
|
|
|
$loadedUserGroup = $this->repository->getUserService()->loadUserGroup($userGroup->id); |
979
|
|
|
|
980
|
|
|
$limitation = $this->checkAssignmentAndFilterLimitationValues($loadedUserGroup->id, $spiRole, $limitation); |
981
|
|
|
|
982
|
|
|
$this->repository->beginTransaction(); |
983
|
|
|
try { |
984
|
|
|
$this->userHandler->assignRole( |
985
|
|
|
$loadedUserGroup->id, |
986
|
|
|
$spiRole->id, |
987
|
|
|
$limitation |
988
|
|
|
); |
989
|
|
|
$this->repository->commit(); |
990
|
|
|
} catch (Exception $e) { |
991
|
|
|
$this->repository->rollback(); |
992
|
|
|
throw $e; |
993
|
|
|
} |
994
|
|
|
} |
995
|
|
|
|
996
|
|
|
/** |
997
|
|
|
* removes a role from the given user group. |
998
|
|
|
* |
999
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to remove a role |
1000
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException If the role is not assigned to the given user group |
1001
|
|
|
* |
1002
|
|
|
* @param \eZ\Publish\API\Repository\Values\User\Role $role |
1003
|
|
|
* @param \eZ\Publish\API\Repository\Values\User\UserGroup $userGroup |
1004
|
|
|
*/ |
1005
|
|
View Code Duplication |
public function unassignRoleFromUserGroup(APIRole $role, UserGroup $userGroup) |
1006
|
|
|
{ |
1007
|
|
|
if ($this->repository->canUser('role', 'assign', $userGroup, $role) !== true) { |
|
|
|
|
1008
|
|
|
throw new UnauthorizedException('role', 'assign'); |
1009
|
|
|
} |
1010
|
|
|
|
1011
|
|
|
$spiRoleAssignments = $this->userHandler->loadRoleAssignmentsByGroupId($userGroup->id); |
1012
|
|
|
$isAssigned = false; |
1013
|
|
|
foreach ($spiRoleAssignments as $spiRoleAssignment) { |
1014
|
|
|
if ($spiRoleAssignment->roleId === $role->id) { |
1015
|
|
|
$isAssigned = true; |
1016
|
|
|
break; |
1017
|
|
|
} |
1018
|
|
|
} |
1019
|
|
|
|
1020
|
|
|
if (!$isAssigned) { |
1021
|
|
|
throw new InvalidArgumentException( |
1022
|
|
|
'$userGroup', |
1023
|
|
|
'Role is not assigned to the given UserGroup' |
1024
|
|
|
); |
1025
|
|
|
} |
1026
|
|
|
|
1027
|
|
|
$this->repository->beginTransaction(); |
1028
|
|
|
try { |
1029
|
|
|
$this->userHandler->unassignRole($userGroup->id, $role->id); |
1030
|
|
|
$this->repository->commit(); |
1031
|
|
|
} catch (Exception $e) { |
1032
|
|
|
$this->repository->rollback(); |
1033
|
|
|
throw $e; |
1034
|
|
|
} |
1035
|
|
|
} |
1036
|
|
|
|
1037
|
|
|
/** |
1038
|
|
|
* Assigns a role to the given user. |
1039
|
|
|
* |
1040
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to assign a role |
1041
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\LimitationValidationException if $roleLimitation is not valid |
1042
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException If assignment already exists |
1043
|
|
|
* |
1044
|
|
|
* @param \eZ\Publish\API\Repository\Values\User\Role $role |
1045
|
|
|
* @param \eZ\Publish\API\Repository\Values\User\User $user |
1046
|
|
|
* @param \eZ\Publish\API\Repository\Values\User\Limitation\RoleLimitation $roleLimitation an optional role limitation (which is either a subtree limitation or section limitation) |
1047
|
|
|
*/ |
1048
|
|
View Code Duplication |
public function assignRoleToUser(APIRole $role, User $user, RoleLimitation $roleLimitation = null) |
1049
|
|
|
{ |
1050
|
|
|
if ($this->repository->canUser('role', 'assign', $user, $role) !== true) { |
|
|
|
|
1051
|
|
|
throw new UnauthorizedException('role', 'assign'); |
1052
|
|
|
} |
1053
|
|
|
|
1054
|
|
|
if ($roleLimitation === null) { |
1055
|
|
|
$limitation = null; |
1056
|
|
|
} else { |
1057
|
|
|
$limitationValidationErrors = $this->limitationService->validateLimitation($roleLimitation); |
1058
|
|
|
if (!empty($limitationValidationErrors)) { |
1059
|
|
|
throw new LimitationValidationException($limitationValidationErrors); |
1060
|
|
|
} |
1061
|
|
|
|
1062
|
|
|
$limitation = array($roleLimitation->getIdentifier() => $roleLimitation->limitationValues); |
1063
|
|
|
} |
1064
|
|
|
|
1065
|
|
|
// Check if objects exists |
1066
|
|
|
$spiRole = $this->userHandler->loadRole($role->id); |
1067
|
|
|
$spiUser = $this->userHandler->load($user->id); |
1068
|
|
|
|
1069
|
|
|
$limitation = $this->checkAssignmentAndFilterLimitationValues($spiUser->id, $spiRole, $limitation); |
1070
|
|
|
|
1071
|
|
|
$this->repository->beginTransaction(); |
1072
|
|
|
try { |
1073
|
|
|
$this->userHandler->assignRole( |
1074
|
|
|
$spiUser->id, |
1075
|
|
|
$spiRole->id, |
1076
|
|
|
$limitation |
1077
|
|
|
); |
1078
|
|
|
$this->repository->commit(); |
1079
|
|
|
} catch (Exception $e) { |
1080
|
|
|
$this->repository->rollback(); |
1081
|
|
|
throw $e; |
1082
|
|
|
} |
1083
|
|
|
} |
1084
|
|
|
|
1085
|
|
|
/** |
1086
|
|
|
* removes a role from the given user. |
1087
|
|
|
* |
1088
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to remove a role |
1089
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException If the role is not assigned to the user |
1090
|
|
|
* |
1091
|
|
|
* @param \eZ\Publish\API\Repository\Values\User\Role $role |
1092
|
|
|
* @param \eZ\Publish\API\Repository\Values\User\User $user |
1093
|
|
|
*/ |
1094
|
|
View Code Duplication |
public function unassignRoleFromUser(APIRole $role, User $user) |
1095
|
|
|
{ |
1096
|
|
|
if ($this->repository->canUser('role', 'assign', $user, $role) !== true) { |
|
|
|
|
1097
|
|
|
throw new UnauthorizedException('role', 'assign'); |
1098
|
|
|
} |
1099
|
|
|
|
1100
|
|
|
$spiRoleAssignments = $this->userHandler->loadRoleAssignmentsByGroupId($user->id); |
1101
|
|
|
$isAssigned = false; |
1102
|
|
|
foreach ($spiRoleAssignments as $spiRoleAssignment) { |
1103
|
|
|
if ($spiRoleAssignment->roleId === $role->id) { |
1104
|
|
|
$isAssigned = true; |
1105
|
|
|
break; |
1106
|
|
|
} |
1107
|
|
|
} |
1108
|
|
|
|
1109
|
|
|
if (!$isAssigned) { |
1110
|
|
|
throw new InvalidArgumentException( |
1111
|
|
|
'$user', |
1112
|
|
|
'Role is not assigned to the given User' |
1113
|
|
|
); |
1114
|
|
|
} |
1115
|
|
|
|
1116
|
|
|
$this->repository->beginTransaction(); |
1117
|
|
|
try { |
1118
|
|
|
$this->userHandler->unassignRole($user->id, $role->id); |
1119
|
|
|
$this->repository->commit(); |
1120
|
|
|
} catch (Exception $e) { |
1121
|
|
|
$this->repository->rollback(); |
1122
|
|
|
throw $e; |
1123
|
|
|
} |
1124
|
|
|
} |
1125
|
|
|
|
1126
|
|
|
/** |
1127
|
|
|
* Removes the given role assignment. |
1128
|
|
|
* |
1129
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to remove a role assignment |
1130
|
|
|
* |
1131
|
|
|
* @param \eZ\Publish\API\Repository\Values\User\RoleAssignment $roleAssignment |
1132
|
|
|
*/ |
1133
|
|
|
public function removeRoleAssignment(RoleAssignment $roleAssignment) |
1134
|
|
|
{ |
1135
|
|
|
if ($this->repository->canUser('role', 'assign', $roleAssignment) !== true) { |
|
|
|
|
1136
|
|
|
throw new UnauthorizedException('role', 'assign'); |
1137
|
|
|
} |
1138
|
|
|
|
1139
|
|
|
$spiRoleAssignment = $this->userHandler->loadRoleAssignment($roleAssignment->id); |
1140
|
|
|
|
1141
|
|
|
$this->repository->beginTransaction(); |
1142
|
|
|
try { |
1143
|
|
|
$this->userHandler->removeRoleAssignment($spiRoleAssignment->id); |
1144
|
|
|
$this->repository->commit(); |
1145
|
|
|
} catch (Exception $e) { |
1146
|
|
|
$this->repository->rollback(); |
1147
|
|
|
throw $e; |
1148
|
|
|
} |
1149
|
|
|
} |
1150
|
|
|
|
1151
|
|
|
/** |
1152
|
|
|
* Loads a role assignment for the given id. |
1153
|
|
|
* |
1154
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to read this role |
1155
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException If the role assignment was not found |
1156
|
|
|
* |
1157
|
|
|
* @param mixed $roleAssignmentId |
1158
|
|
|
* |
1159
|
|
|
* @return \eZ\Publish\API\Repository\Values\User\RoleAssignment |
1160
|
|
|
*/ |
1161
|
|
|
public function loadRoleAssignment($roleAssignmentId) |
1162
|
|
|
{ |
1163
|
|
|
if ($this->repository->hasAccess('role', 'read') !== true) { |
|
|
|
|
1164
|
|
|
throw new UnauthorizedException('role', 'read'); |
1165
|
|
|
} |
1166
|
|
|
|
1167
|
|
|
$spiRoleAssignment = $this->userHandler->loadRoleAssignment($roleAssignmentId); |
1168
|
|
|
$userService = $this->repository->getUserService(); |
1169
|
|
|
$role = $this->loadRole($spiRoleAssignment->roleId); |
1170
|
|
|
$roleAssignment = null; |
1171
|
|
|
|
1172
|
|
|
// First check if the Role is assigned to a User |
1173
|
|
|
// If no User is found, see if it belongs to a UserGroup |
1174
|
|
|
try { |
1175
|
|
|
$user = $userService->loadUser($spiRoleAssignment->contentId); |
1176
|
|
|
$roleAssignment = $this->roleDomainMapper->buildDomainUserRoleAssignmentObject( |
1177
|
|
|
$spiRoleAssignment, |
1178
|
|
|
$user, |
1179
|
|
|
$role |
1180
|
|
|
); |
1181
|
|
|
} catch (APINotFoundException $e) { |
1182
|
|
|
try { |
1183
|
|
|
$userGroup = $userService->loadUserGroup($spiRoleAssignment->contentId); |
1184
|
|
|
$roleAssignment = $this->roleDomainMapper->buildDomainUserGroupRoleAssignmentObject( |
1185
|
|
|
$spiRoleAssignment, |
1186
|
|
|
$userGroup, |
1187
|
|
|
$role |
1188
|
|
|
); |
1189
|
|
|
} catch (APINotFoundException $e) { |
1190
|
|
|
// Do nothing |
1191
|
|
|
} |
1192
|
|
|
} |
1193
|
|
|
|
1194
|
|
|
return $roleAssignment; |
1195
|
|
|
} |
1196
|
|
|
|
1197
|
|
|
/** |
1198
|
|
|
* Returns the assigned user and user groups to this role. |
1199
|
|
|
* |
1200
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to read a role |
1201
|
|
|
* |
1202
|
|
|
* @param \eZ\Publish\API\Repository\Values\User\Role $role |
1203
|
|
|
* |
1204
|
|
|
* @return \eZ\Publish\API\Repository\Values\User\RoleAssignment[] |
1205
|
|
|
*/ |
1206
|
|
|
public function getRoleAssignments(APIRole $role) |
1207
|
|
|
{ |
1208
|
|
|
if ($this->repository->hasAccess('role', 'read') !== true) { |
|
|
|
|
1209
|
|
|
throw new UnauthorizedException('role', 'read'); |
1210
|
|
|
} |
1211
|
|
|
|
1212
|
|
|
$userService = $this->repository->getUserService(); |
1213
|
|
|
$spiRoleAssignments = $this->userHandler->loadRoleAssignmentsByRoleId($role->id); |
1214
|
|
|
$roleAssignments = array(); |
1215
|
|
|
|
1216
|
|
|
foreach ($spiRoleAssignments as $spiRoleAssignment) { |
1217
|
|
|
// First check if the Role is assigned to a User |
1218
|
|
|
// If no User is found, see if it belongs to a UserGroup |
1219
|
|
|
try { |
1220
|
|
|
$user = $userService->loadUser($spiRoleAssignment->contentId); |
1221
|
|
|
$roleAssignments[] = $this->roleDomainMapper->buildDomainUserRoleAssignmentObject( |
1222
|
|
|
$spiRoleAssignment, |
1223
|
|
|
$user, |
1224
|
|
|
$role |
1225
|
|
|
); |
1226
|
|
|
} catch (APINotFoundException $e) { |
1227
|
|
|
try { |
1228
|
|
|
$userGroup = $userService->loadUserGroup($spiRoleAssignment->contentId); |
1229
|
|
|
$roleAssignments[] = $this->roleDomainMapper->buildDomainUserGroupRoleAssignmentObject( |
1230
|
|
|
$spiRoleAssignment, |
1231
|
|
|
$userGroup, |
1232
|
|
|
$role |
1233
|
|
|
); |
1234
|
|
|
} catch (APINotFoundException $e) { |
1235
|
|
|
// Do nothing |
1236
|
|
|
} |
1237
|
|
|
} |
1238
|
|
|
} |
1239
|
|
|
|
1240
|
|
|
return $roleAssignments; |
1241
|
|
|
} |
1242
|
|
|
|
1243
|
|
|
/** |
1244
|
|
|
* @see \eZ\Publish\API\Repository\RoleService::getRoleAssignmentsForUser() |
1245
|
|
|
*/ |
1246
|
|
|
public function getRoleAssignmentsForUser(User $user, $inherited = false) |
1247
|
|
|
{ |
1248
|
|
|
if ($this->repository->hasAccess('role', 'read') !== true) { |
|
|
|
|
1249
|
|
|
throw new UnauthorizedException('role', 'read'); |
1250
|
|
|
} |
1251
|
|
|
|
1252
|
|
|
$roleAssignments = array(); |
1253
|
|
|
$spiRoleAssignments = $this->userHandler->loadRoleAssignmentsByGroupId($user->id, $inherited); |
1254
|
|
|
foreach ($spiRoleAssignments as $spiRoleAssignment) { |
1255
|
|
|
$role = $this->loadRole($spiRoleAssignment->roleId); |
1256
|
|
|
if (!$inherited || $spiRoleAssignment->contentId == $user->id) { |
1257
|
|
|
$roleAssignments[] = $this->roleDomainMapper->buildDomainUserRoleAssignmentObject( |
1258
|
|
|
$spiRoleAssignment, |
1259
|
|
|
$user, |
1260
|
|
|
$role |
1261
|
|
|
); |
1262
|
|
|
} else { |
1263
|
|
|
$userGroup = $this->repository->getUserService()->loadUserGroup($spiRoleAssignment->contentId); |
1264
|
|
|
$roleAssignments[] = $this->roleDomainMapper->buildDomainUserGroupRoleAssignmentObject( |
1265
|
|
|
$spiRoleAssignment, |
1266
|
|
|
$userGroup, |
1267
|
|
|
$role |
1268
|
|
|
); |
1269
|
|
|
} |
1270
|
|
|
} |
1271
|
|
|
|
1272
|
|
|
return $roleAssignments; |
1273
|
|
|
} |
1274
|
|
|
|
1275
|
|
|
/** |
1276
|
|
|
* Returns the roles assigned to the given user group. |
1277
|
|
|
* |
1278
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to read a role |
1279
|
|
|
* |
1280
|
|
|
* @param \eZ\Publish\API\Repository\Values\User\UserGroup $userGroup |
1281
|
|
|
* |
1282
|
|
|
* @return \eZ\Publish\API\Repository\Values\User\UserGroupRoleAssignment[] |
1283
|
|
|
*/ |
1284
|
|
|
public function getRoleAssignmentsForUserGroup(UserGroup $userGroup) |
1285
|
|
|
{ |
1286
|
|
|
if ($this->repository->hasAccess('role', 'read') !== true) { |
|
|
|
|
1287
|
|
|
throw new UnauthorizedException('role', 'read'); |
1288
|
|
|
} |
1289
|
|
|
|
1290
|
|
|
$roleAssignments = array(); |
1291
|
|
|
$spiRoleAssignments = $this->userHandler->loadRoleAssignmentsByGroupId($userGroup->id); |
1292
|
|
|
foreach ($spiRoleAssignments as $spiRoleAssignment) { |
1293
|
|
|
$role = $this->loadRole($spiRoleAssignment->roleId); |
1294
|
|
|
$roleAssignments[] = $this->roleDomainMapper->buildDomainUserGroupRoleAssignmentObject( |
1295
|
|
|
$spiRoleAssignment, |
1296
|
|
|
$userGroup, |
1297
|
|
|
$role |
1298
|
|
|
); |
1299
|
|
|
} |
1300
|
|
|
|
1301
|
|
|
return $roleAssignments; |
1302
|
|
|
} |
1303
|
|
|
|
1304
|
|
|
/** |
1305
|
|
|
* Instantiates a role create class. |
1306
|
|
|
* |
1307
|
|
|
* @param string $name |
1308
|
|
|
* |
1309
|
|
|
* @return \eZ\Publish\API\Repository\Values\User\RoleCreateStruct |
1310
|
|
|
*/ |
1311
|
|
|
public function newRoleCreateStruct($name) |
1312
|
|
|
{ |
1313
|
|
|
return new RoleCreateStruct( |
1314
|
|
|
array( |
1315
|
|
|
'identifier' => $name, |
1316
|
|
|
'policies' => array(), |
1317
|
|
|
) |
1318
|
|
|
); |
1319
|
|
|
} |
1320
|
|
|
|
1321
|
|
|
/** |
1322
|
|
|
* Instantiates a policy create class. |
1323
|
|
|
* |
1324
|
|
|
* @param string $module |
1325
|
|
|
* @param string $function |
1326
|
|
|
* |
1327
|
|
|
* @return \eZ\Publish\API\Repository\Values\User\PolicyCreateStruct |
1328
|
|
|
*/ |
1329
|
|
|
public function newPolicyCreateStruct($module, $function) |
1330
|
|
|
{ |
1331
|
|
|
return new PolicyCreateStruct( |
1332
|
|
|
array( |
1333
|
|
|
'module' => $module, |
1334
|
|
|
'function' => $function, |
1335
|
|
|
'limitations' => array(), |
1336
|
|
|
) |
1337
|
|
|
); |
1338
|
|
|
} |
1339
|
|
|
|
1340
|
|
|
/** |
1341
|
|
|
* Instantiates a policy update class. |
1342
|
|
|
* |
1343
|
|
|
* @return \eZ\Publish\API\Repository\Values\User\PolicyUpdateStruct |
1344
|
|
|
*/ |
1345
|
|
|
public function newPolicyUpdateStruct() |
1346
|
|
|
{ |
1347
|
|
|
return new PolicyUpdateStruct( |
1348
|
|
|
array( |
1349
|
|
|
'limitations' => array(), |
1350
|
|
|
) |
1351
|
|
|
); |
1352
|
|
|
} |
1353
|
|
|
|
1354
|
|
|
/** |
1355
|
|
|
* Instantiates a policy update class. |
1356
|
|
|
* |
1357
|
|
|
* @return \eZ\Publish\API\Repository\Values\User\RoleUpdateStruct |
1358
|
|
|
*/ |
1359
|
|
|
public function newRoleUpdateStruct() |
1360
|
|
|
{ |
1361
|
|
|
return new RoleUpdateStruct(); |
1362
|
|
|
} |
1363
|
|
|
|
1364
|
|
|
/** |
1365
|
|
|
* Returns the LimitationType registered with the given identifier. |
1366
|
|
|
* |
1367
|
|
|
* Returns the correct implementation of API Limitation value object |
1368
|
|
|
* based on provided identifier |
1369
|
|
|
* |
1370
|
|
|
* @param string $identifier |
1371
|
|
|
* |
1372
|
|
|
* @return \eZ\Publish\SPI\Limitation\Type |
1373
|
|
|
* |
1374
|
|
|
* @throws \RuntimeException if there is no LimitationType with $identifier |
1375
|
|
|
*/ |
1376
|
|
|
public function getLimitationType($identifier) |
1377
|
|
|
{ |
1378
|
|
|
return $this->limitationService->getLimitationType($identifier); |
1379
|
|
|
} |
1380
|
|
|
|
1381
|
|
|
/** |
1382
|
|
|
* Returns the LimitationType's assigned to a given module/function. |
1383
|
|
|
* |
1384
|
|
|
* Typically used for: |
1385
|
|
|
* - Internal validation limitation value use on Policies |
1386
|
|
|
* - Role admin gui for editing policy limitations incl list limitation options via valueSchema() |
1387
|
|
|
* |
1388
|
|
|
* @param string $module Legacy name of "controller", it's a unique identifier like "content" |
1389
|
|
|
* @param string $function Legacy name of a controller "action", it's a unique within the controller like "read" |
1390
|
|
|
* |
1391
|
|
|
* @return \eZ\Publish\SPI\Limitation\Type[] |
1392
|
|
|
* |
1393
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\BadStateException If module/function to limitation type mapping |
1394
|
|
|
* refers to a non existing identifier. |
1395
|
|
|
*/ |
1396
|
|
|
public function getLimitationTypesByModuleFunction($module, $function) |
1397
|
|
|
{ |
1398
|
|
|
if (empty($this->settings['policyMap'][$module][$function])) { |
1399
|
|
|
return array(); |
1400
|
|
|
} |
1401
|
|
|
|
1402
|
|
|
$types = array(); |
1403
|
|
|
try { |
1404
|
|
|
foreach (array_keys($this->settings['policyMap'][$module][$function]) as $identifier) { |
1405
|
|
|
$types[$identifier] = $this->limitationService->getLimitationType($identifier); |
1406
|
|
|
} |
1407
|
|
|
} catch (LimitationNotFoundException $e) { |
1408
|
|
|
throw new BadStateException( |
1409
|
|
|
"{$module}/{$function}", |
1410
|
|
|
"policyMap configuration is referring to non existing identifier: {$identifier}", |
1411
|
|
|
$e |
1412
|
|
|
); |
1413
|
|
|
} |
1414
|
|
|
|
1415
|
|
|
return $types; |
1416
|
|
|
} |
1417
|
|
|
|
1418
|
|
|
/** |
1419
|
|
|
* Validates Policies and Limitations in Role create struct. |
1420
|
|
|
* |
1421
|
|
|
* @uses ::validatePolicy() |
1422
|
|
|
* |
1423
|
|
|
* @param \eZ\Publish\API\Repository\Values\User\RoleCreateStruct $roleCreateStruct |
1424
|
|
|
* |
1425
|
|
|
* @return \eZ\Publish\Core\FieldType\ValidationError[][][] |
1426
|
|
|
*/ |
1427
|
|
|
protected function validateRoleCreateStruct(APIRoleCreateStruct $roleCreateStruct) |
1428
|
|
|
{ |
1429
|
|
|
$allErrors = array(); |
1430
|
|
|
foreach ($roleCreateStruct->getPolicies() as $key => $policyCreateStruct) { |
1431
|
|
|
$errors = $this->validatePolicy( |
1432
|
|
|
$policyCreateStruct->module, |
1433
|
|
|
$policyCreateStruct->function, |
1434
|
|
|
$policyCreateStruct->getLimitations() |
1435
|
|
|
); |
1436
|
|
|
|
1437
|
|
|
if (!empty($errors)) { |
1438
|
|
|
$allErrors[$key] = $errors; |
1439
|
|
|
} |
1440
|
|
|
} |
1441
|
|
|
|
1442
|
|
|
return $allErrors; |
1443
|
|
|
} |
1444
|
|
|
|
1445
|
|
|
/** |
1446
|
|
|
* Validates Policy context: Limitations on a module and function. |
1447
|
|
|
* |
1448
|
|
|
* @throws \eZ\Publish\Core\Base\Exceptions\InvalidArgumentException If the same limitation is repeated or if |
1449
|
|
|
* limitation is not allowed on module/function |
1450
|
|
|
* |
1451
|
|
|
* @param string $module |
1452
|
|
|
* @param string $function |
1453
|
|
|
* @param \eZ\Publish\API\Repository\Values\User\Limitation[] $limitations |
1454
|
|
|
* |
1455
|
|
|
* @return \eZ\Publish\Core\FieldType\ValidationError[][] |
1456
|
|
|
*/ |
1457
|
|
|
protected function validatePolicy($module, $function, array $limitations) |
1458
|
|
|
{ |
1459
|
|
|
if ($module !== '*' && $function !== '*' && !empty($limitations)) { |
1460
|
|
|
$limitationSet = array(); |
1461
|
|
|
foreach ($limitations as $limitation) { |
1462
|
|
|
if (isset($limitationSet[$limitation->getIdentifier()])) { |
1463
|
|
|
throw new InvalidArgumentException( |
1464
|
|
|
'limitations', |
1465
|
|
|
"'{$limitation->getIdentifier()}' was found several times among the limitations" |
1466
|
|
|
); |
1467
|
|
|
} |
1468
|
|
|
|
1469
|
|
|
if (!isset($this->settings['policyMap'][$module][$function][$limitation->getIdentifier()])) { |
1470
|
|
|
throw new InvalidArgumentException( |
1471
|
|
|
'policy', |
1472
|
|
|
"The limitation '{$limitation->getIdentifier()}' is not applicable on '{$module}/{$function}'" |
1473
|
|
|
); |
1474
|
|
|
} |
1475
|
|
|
|
1476
|
|
|
$limitationSet[$limitation->getIdentifier()] = true; |
1477
|
|
|
} |
1478
|
|
|
} |
1479
|
|
|
|
1480
|
|
|
return $this->limitationService->validateLimitations($limitations); |
1481
|
|
|
} |
1482
|
|
|
|
1483
|
|
|
/** |
1484
|
|
|
* Validate that assignments not already exists and filter validations against existing. |
1485
|
|
|
* |
1486
|
|
|
* @param mixed $contentId |
1487
|
|
|
* @param SPIRole $spiRole |
1488
|
|
|
* @param array|null $limitation |
1489
|
|
|
* |
1490
|
|
|
* @return array[]|null Filtered version of $limitation |
1491
|
|
|
* |
1492
|
|
|
* @throws \eZ\Publish\Core\Base\Exceptions\InvalidArgumentException If assignment already exists |
1493
|
|
|
*/ |
1494
|
|
|
protected function checkAssignmentAndFilterLimitationValues($contentId, SPIRole $spiRole, array $limitation = null) |
1495
|
|
|
{ |
1496
|
|
|
$spiRoleAssignments = $this->userHandler->loadRoleAssignmentsByGroupId($contentId); |
1497
|
|
|
foreach ($spiRoleAssignments as $spiAssignment) { |
1498
|
|
|
// Ignore assignments to other roles |
1499
|
|
|
if ($spiAssignment->roleId !== $spiRole->id) { |
1500
|
|
|
continue; |
1501
|
|
|
} |
1502
|
|
|
|
1503
|
|
|
// Throw if Role is already assigned without limitations |
1504
|
|
|
if ($spiAssignment->limitationIdentifier === null) { |
1505
|
|
|
throw new InvalidArgumentException( |
1506
|
|
|
'$role', |
1507
|
|
|
"Role '{$spiRole->id}' already assigned without limitations" |
1508
|
|
|
); |
1509
|
|
|
} |
1510
|
|
|
|
1511
|
|
|
// Ignore if we are going to assign without limitations |
1512
|
|
|
if ($limitation === null) { |
1513
|
|
|
continue; |
1514
|
|
|
} |
1515
|
|
|
|
1516
|
|
|
// Ignore if not assigned with same limitation identifier |
1517
|
|
|
if (!isset($limitation[$spiAssignment->limitationIdentifier])) { |
1518
|
|
|
continue; |
1519
|
|
|
} |
1520
|
|
|
|
1521
|
|
|
// Throw if Role is already assigned with all the same limitations |
1522
|
|
|
$newValues = array_diff($limitation[$spiAssignment->limitationIdentifier], $spiAssignment->values); |
1523
|
|
|
if (empty($newValues)) { |
1524
|
|
|
throw new InvalidArgumentException( |
1525
|
|
|
'$role', |
1526
|
|
|
"Role '{$spiRole->id}' already assigned with same '{$spiAssignment->limitationIdentifier}' value" |
1527
|
|
|
); |
1528
|
|
|
} |
1529
|
|
|
|
1530
|
|
|
// Continue using the filtered list of limitations |
1531
|
|
|
$limitation[$spiAssignment->limitationIdentifier] = $newValues; |
1532
|
|
|
} |
1533
|
|
|
|
1534
|
|
|
return $limitation; |
1535
|
|
|
} |
1536
|
|
|
} |
1537
|
|
|
|
This method has been deprecated. The supplier of the class has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.