Completed
Push — EZEE-2932 ( ce785a...e7ccd9 )
by
unknown
25:31
created

testCanUserWithTargetThrowsInvalidArgumentException()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 35

Duplication

Lines 35
Ratio 100 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 35
loc 35
rs 9.36
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * @copyright Copyright (C) eZ Systems AS. All rights reserved.
5
 * @license For full copyright and license information view LICENSE file distributed with this source code.
6
 */
7
namespace eZ\Publish\API\Repository\Tests;
8
9
use function array_filter;
10
use eZ\Publish\API\Repository\Repository;
11
use eZ\Publish\API\Repository\Values\Content\ContentCreateStruct;
12
use eZ\Publish\API\Repository\Values\User\Limitation;
13
use eZ\Publish\API\Repository\Values\User\LookupLimitationResult;
14
use eZ\Publish\API\Repository\Values\User\LookupPolicyLimitations;
15
use eZ\Publish\API\Repository\Values\ValueObject;
16
use eZ\Publish\Core\Repository\Values\User\UserReference;
17
18
/**
19
 *  Test case for operations in the PermissionResolver.
20
 *
21
 * @see \eZ\Publish\API\Repository\PermissionResolver
22
 * @group integration
23
 * @group permission
24
 */
25
class PermissionResolverTest extends BaseTest
26
{
27
    /**
28
     * Test for the getCurrentUser() method.
29
     *
30
     * @see \eZ\Publish\API\Repository\PermissionResolver::getCurrentUserReference()
31
     */
32
    public function testGetCurrentUserReferenceReturnsAnonymousUserReference()
33
    {
34
        $repository = $this->getRepository();
35
        $anonymousUserId = $this->generateId('user', 10);
36
        $repository->getPermissionResolver()->setCurrentUserReference(
37
            new UserReference($anonymousUserId)
38
        );
39
40
        /* BEGIN: Use Case */
41
        // $anonymousUserId is the ID of the "Anonymous" user in a eZ
42
        // Publish demo installation.
43
        // Only a UserReference has previously been set to the $repository
44
45
        $permissionResolver = $repository->getPermissionResolver();
46
        $anonymousUserReference = $permissionResolver->getCurrentUserReference();
47
        /* END: Use Case */
48
49
        $this->assertInstanceOf(
50
            'eZ\Publish\API\Repository\Values\User\UserReference',
51
            $anonymousUserReference
52
        );
53
        $this->assertEquals(
54
            $anonymousUserReference->getUserId(),
55
            $repository->getUserService()->loadUser($anonymousUserId)->id
56
        );
57
    }
58
59
    /**
60
     * Test for the setCurrentUser() method.
61
     *
62
     * @see \eZ\Publish\API\Repository\PermissionResolver::setCurrentUserReference()
63
     * @depends eZ\Publish\API\Repository\Tests\RepositoryTest::testGetUserService
64
     */
65 View Code Duplication
    public function testSetCurrentUserReference()
66
    {
67
        $repository = $this->getRepository();
68
        $repository->getPermissionResolver()->setCurrentUserReference(
69
            new UserReference(
70
                $this->generateId('user', 10)
71
            )
72
        );
73
74
        $administratorUserId = $this->generateId('user', 14);
75
76
        /* BEGIN: Use Case */
77
        // $administratorUserId contains the ID of the administrator user
78
79
        $permissionResolver = $repository->getPermissionResolver();
80
81
        $userService = $repository->getUserService();
82
83
        // Load administrator user
84
        $administratorUser = $userService->loadUser($administratorUserId);
85
86
        // Set administrator user as current user reference
87
        $permissionResolver->setCurrentUserReference($administratorUser);
88
        /* END: Use Case */
89
90
        $this->assertEquals(
91
            $administratorUserId,
92
            $permissionResolver->getCurrentUserReference()->getUserId()
93
        );
94
95
        $this->assertSame(
96
            $administratorUser,
97
            $permissionResolver->getCurrentUserReference()
98
        );
99
    }
100
101
    /**
102
     * Test for the hasAccess() method.
103
     *
104
     * @see \eZ\Publish\API\Repository\PermissionResolver::hasAccess()
105
     * @depends eZ\Publish\API\Repository\Tests\RepositoryTest::testGetUserService
106
     */
107
    public function testHasAccessWithAnonymousUserNo()
108
    {
109
        $repository = $this->getRepository();
110
111
        $anonymousUserId = $this->generateId('user', 10);
112
113
        /* BEGIN: Use Case */
114
        // $anonymousUserId is the ID of the "Anonymous" user in a eZ
115
        // Publish demo installation.
116
117
        $userService = $repository->getUserService();
118
        $permissionResolver = $repository->getPermissionResolver();
119
120
        // Load anonymous user
121
        $anonymousUser = $userService->loadUser($anonymousUserId);
122
123
        // This call will return false because anonymous user does not have access
124
        // to content removal
125
        $hasAccess = $permissionResolver->hasAccess('content', 'remove', $anonymousUser);
126
        /* END: Use Case */
127
128
        $this->assertFalse($hasAccess);
129
    }
130
131
    /**
132
     * Test for the hasAccess() method.
133
     *
134
     * @see \eZ\Publish\API\Repository\PermissionResolver::hasAccess()
135
     * @depends eZ\Publish\API\Repository\Tests\RepositoryTest::testGetUserService
136
     * @depends eZ\Publish\API\Repository\Tests\PermissionResolverTest::testHasAccessWithAnonymousUserNo
137
     */
138 View Code Duplication
    public function testHasAccessForCurrentUserNo()
139
    {
140
        $repository = $this->getRepository();
141
142
        $anonymousUserId = $this->generateId('user', 10);
143
144
        /* BEGIN: Use Case */
145
        // $anonymousUserId is the ID of the "Anonymous" user in a eZ
146
        // Publish demo installation.
147
148
        $userService = $repository->getUserService();
149
        $permissionResolver = $repository->getPermissionResolver();
150
151
        // Load anonymous user
152
        $anonymousUser = $userService->loadUser($anonymousUserId);
153
154
        // Set anonymous user as current user reference
155
        $permissionResolver->setCurrentUserReference($anonymousUser);
156
157
        // This call will return false because anonymous user does not have access
158
        // to content removal
159
        $hasAccess = $permissionResolver->hasAccess('content', 'remove');
160
        /* END: Use Case */
161
162
        $this->assertFalse($hasAccess);
163
    }
164
165
    /**
166
     * Test for the hasAccess() method.
167
     *
168
     * @see \eZ\Publish\API\Repository\PermissionResolver::hasAccess()
169
     * @depends eZ\Publish\API\Repository\Tests\RepositoryTest::testGetUserService
170
     */
171
    public function testHasAccessWithAdministratorUser()
172
    {
173
        $repository = $this->getRepository();
174
175
        $administratorUserId = $this->generateId('user', 14);
176
177
        /* BEGIN: Use Case */
178
        // $administratorUserId contains the ID of the administrator user
179
180
        $userService = $repository->getUserService();
181
        $permissionResolver = $repository->getPermissionResolver();
182
183
        // Load administrator user
184
        $administratorUser = $userService->loadUser($administratorUserId);
185
186
        // This call will return true
187
        $hasAccess = $permissionResolver->hasAccess('content', 'read', $administratorUser);
188
        /* END: Use Case */
189
190
        $this->assertTrue($hasAccess);
191
    }
192
193
    /**
194
     * Test for the hasAccess() method.
195
     *
196
     * @see \eZ\Publish\API\Repository\PermissionResolver::hasAccess()
197
     * @depends eZ\Publish\API\Repository\Tests\RepositoryTest::testGetUserService
198
     * @depends eZ\Publish\API\Repository\Tests\PermissionResolverTest::testSetCurrentUserReference
199
     * @depends eZ\Publish\API\Repository\Tests\PermissionResolverTest::testHasAccessWithAdministratorUser
200
     */
201 View Code Duplication
    public function testHasAccessForCurrentUserYes()
202
    {
203
        $repository = $this->getRepository();
204
205
        $administratorUserId = $this->generateId('user', 14);
206
207
        /* BEGIN: Use Case */
208
        // $administratorUserId contains the ID of the administrator user
209
210
        $userService = $repository->getUserService();
211
        $permissionResolver = $repository->getPermissionResolver();
212
213
        // Load administrator user
214
        $administratorUser = $userService->loadUser($administratorUserId);
215
216
        // Set administrator user as current user reference
217
        $permissionResolver->setCurrentUserReference($administratorUser);
218
219
        // This call will return true
220
        $hasAccess = $permissionResolver->hasAccess('content', 'read');
221
        /* END: Use Case */
222
223
        $this->assertTrue($hasAccess);
224
    }
225
226
    /**
227
     * Test for the hasAccess() method.
228
     *
229
     * @see \eZ\Publish\API\Repository\PermissionResolver::hasAccess()
230
     * @depends eZ\Publish\API\Repository\Tests\RepositoryTest::testGetUserService
231
     * @depends eZ\Publish\API\Repository\Tests\PermissionResolverTest::testSetCurrentUserReference
232
     */
233 View Code Duplication
    public function testHasAccessLimited()
234
    {
235
        $repository = $this->getRepository();
236
237
        /* BEGIN: Use Case */
238
        $user = $this->createUserVersion1();
239
240
        $permissionResolver = $repository->getPermissionResolver();
241
242
        // Set created user as current user reference
243
        $permissionResolver->setCurrentUserReference($user);
244
245
        // This call will return an array of permission sets describing user's access
246
        // to reading content
247
        $permissionSets = $permissionResolver->hasAccess('content', 'read');
248
        /* END: Use Case */
249
250
        $this->assertInternalType(
0 ignored issues
show
Deprecated Code introduced by
The method PHPUnit\Framework\Assert::assertInternalType() has been deprecated with message: https://github.com/sebastianbergmann/phpunit/issues/3369

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.

Loading history...
251
            'array',
252
            $permissionSets
253
        );
254
        $this->assertNotEmpty($permissionSets);
255
    }
256
257
    /**
258
     * Test for the canUser() method.
259
     *
260
     * @see \eZ\Publish\API\Repository\PermissionResolver::canUser()
261
     * @depends eZ\Publish\API\Repository\Tests\RepositoryTest::testGetUserService
262
     * @depends eZ\Publish\API\Repository\Tests\RepositoryTest::testGetContentService
263
     * @depends eZ\Publish\API\Repository\Tests\PermissionResolverTest::testHasAccessForCurrentUserNo
264
     * @expectedException \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
265
     */
266
    public function testCanUserForAnonymousUserNo()
267
    {
268
        $repository = $this->getRepository();
269
270
        $homeId = $this->generateId('object', 57);
271
272
        $anonymousUserId = $this->generateId('user', 10);
273
        /* BEGIN: Use Case */
274
        // $anonymousUserId is the ID of the "Anonymous" user in a eZ
275
        // Publish demo installation.
276
        // $homeId contains the ID of the "Home" frontpage
277
278
        $contentService = $repository->getContentService();
279
        $userService = $repository->getUserService();
280
        $permissionResolver = $repository->getPermissionResolver();
281
282
        // Load anonymous user
283
        $anonymousUser = $userService->loadUser($anonymousUserId);
284
285
        // Set anonymous user as current user reference
286
        $permissionResolver->setCurrentUserReference($anonymousUser);
287
288
        // Load the ContentInfo for "Home" frontpage
289
        $contentInfo = $contentService->loadContentInfo($homeId);
290
291
        // This call will return false because anonymous user does not have access
292
        // to content removal and hence no permission to remove given content
293
        $canUser = $permissionResolver->canUser('content', 'remove', $contentInfo);
294
295
        // Performing an action without necessary permissions will fail with "UnauthorizedException"
296
        if (!$canUser) {
297
            $contentService->deleteContent($contentInfo);
298
        }
299
        /* END: Use Case */
300
    }
301
302
    /**
303
     * Test for the canUser() method.
304
     *
305
     * @see \eZ\Publish\API\Repository\PermissionResolver::canUser()
306
     * @depends eZ\Publish\API\Repository\Tests\RepositoryTest::testGetUserService
307
     * @depends eZ\Publish\API\Repository\Tests\RepositoryTest::testGetContentService
308
     * @depends eZ\Publish\API\Repository\Tests\PermissionResolverTest::testHasAccessForCurrentUserYes
309
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
310
     */
311 View Code Duplication
    public function testCanUserForAdministratorUser()
312
    {
313
        $repository = $this->getRepository();
314
315
        $administratorUserId = $this->generateId('user', 14);
316
        $homeId = $this->generateId('object', 57);
317
318
        /* BEGIN: Use Case */
319
        // $administratorUserId contains the ID of the administrator user
320
        // $homeId contains the ID of the "Home" frontpage
321
322
        $contentService = $repository->getContentService();
323
        $userService = $repository->getUserService();
324
        $permissionResolver = $repository->getPermissionResolver();
325
326
        // Load administrator user
327
        $administratorUser = $userService->loadUser($administratorUserId);
328
329
        // Set administrator user as current user reference
330
        $permissionResolver->setCurrentUserReference($administratorUser);
331
332
        // Load the ContentInfo for "Home" frontpage
333
        $contentInfo = $contentService->loadContentInfo($homeId);
334
335
        // This call will return true
336
        $canUser = $permissionResolver->canUser('content', 'remove', $contentInfo);
337
338
        // Performing an action having necessary permissions will succeed
339
        $contentService->deleteContent($contentInfo);
340
        /* END: Use Case */
341
342
        $this->assertTrue($canUser);
343
        $contentService->loadContent($homeId);
344
    }
345
346
    /**
347
     * Test for the canUser() method.
348
     *
349
     * @see \eZ\Publish\API\Repository\PermissionResolver::canUser()
350
     * @depends eZ\Publish\API\Repository\Tests\RepositoryTest::testGetUserService
351
     * @depends eZ\Publish\API\Repository\Tests\RepositoryTest::testGetContentService
352
     * @depends eZ\Publish\API\Repository\Tests\PermissionResolverTest::testHasAccessLimited
353
     */
354 View Code Duplication
    public function testCanUserWithLimitationYes()
355
    {
356
        $repository = $this->getRepository();
357
358
        $imagesFolderId = $this->generateId('object', 49);
359
360
        /* BEGIN: Use Case */
361
        // $imagesFolderId contains the ID of the "Images" folder
362
363
        $user = $this->createUserVersion1();
364
365
        $permissionResolver = $repository->getPermissionResolver();
366
367
        // Set created user as current user reference
368
        $permissionResolver->setCurrentUserReference($user);
369
370
        $contentService = $repository->getContentService();
371
372
        // Performing an action having necessary permissions will succeed
373
        $imagesFolder = $contentService->loadContent($imagesFolderId);
374
375
        // This call will return true
376
        $canUser = $permissionResolver->canUser('content', 'read', $imagesFolder);
377
        /* END: Use Case */
378
379
        $this->assertTrue($canUser);
380
    }
381
382
    /**
383
     * Test for the canUser() method.
384
     *
385
     * @see \eZ\Publish\API\Repository\PermissionResolver::canUser()
386
     * @depends eZ\Publish\API\Repository\Tests\RepositoryTest::testGetUserService
387
     * @depends eZ\Publish\API\Repository\Tests\RepositoryTest::testGetContentService
388
     * @depends eZ\Publish\API\Repository\Tests\PermissionResolverTest::testHasAccessLimited
389
     * @expectedException \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
390
     */
391 View Code Duplication
    public function testCanUserWithLimitationNo()
392
    {
393
        $repository = $this->getRepository();
394
395
        $administratorUserId = $this->generateId('user', 14);
396
397
        /* BEGIN: Use Case */
398
        // $administratorUserId contains the ID of the administrator user
399
400
        $user = $this->createUserVersion1();
401
402
        $permissionResolver = $repository->getPermissionResolver();
403
404
        // Set created user as current user reference
405
        $permissionResolver->setCurrentUserReference($user);
406
407
        $userService = $repository->getUserService();
408
409
        // Load administrator user using UserService, this does not check for permissions
410
        $administratorUser = $userService->loadUser($administratorUserId);
411
412
        // This call will return false as user with Editor role does not have
413
        // permission to read "Users" subtree
414
        $canUser = $permissionResolver->canUser('content', 'read', $administratorUser);
415
416
        $contentService = $repository->getContentService();
417
418
        // Performing an action without necessary permissions will fail with "UnauthorizedException"
419
        if (!$canUser) {
420
            $content = $contentService->loadContent($administratorUserId);
0 ignored issues
show
Unused Code introduced by
$content is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
421
        }
422
        /* END: Use Case */
423
    }
424
425
    /**
426
     * Test for the canUser() method.
427
     *
428
     * @see \eZ\Publish\API\Repository\PermissionResolver::canUser()
429
     * @depends eZ\Publish\API\Repository\Tests\RepositoryTest::testGetUserService
430
     * @depends eZ\Publish\API\Repository\Tests\RepositoryTest::testGetContentTypeService
431
     * @depends eZ\Publish\API\Repository\Tests\PermissionResolverTest::testSetCurrentUserReference
432
     * @depends eZ\Publish\API\Repository\Tests\PermissionResolverTest::testHasAccessLimited
433
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
434
     */
435 View Code Duplication
    public function testCanUserThrowsInvalidArgumentException()
436
    {
437
        $repository = $this->getRepository();
438
439
        $userGroupContentTypeId = $this->generateId('type', 3);
440
441
        /* BEGIN: Use Case */
442
        // $userGroupContentTypeId contains the ID of the "UserGroup" ContentType
443
444
        $user = $this->createUserVersion1();
445
446
        $permissionResolver = $repository->getPermissionResolver();
447
448
        // Set created user as current user reference
449
        $permissionResolver->setCurrentUserReference($user);
450
451
        $contentTypeService = $repository->getContentTypeService();
452
453
        // Load the "UserGroup" ContentType
454
        $userGroupContentType = $contentTypeService->loadContentType($userGroupContentTypeId);
455
456
        // This call will throw "InvalidArgumentException" because $userGroupContentType
457
        // is an instance of \eZ\Publish\API\Repository\Values\ContentType\ContentType,
458
        // which can not be checked for user access
459
        $canUser = $permissionResolver->canUser('content', 'create', $userGroupContentType);
0 ignored issues
show
Unused Code introduced by
$canUser is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
460
        /* END: Use Case */
461
    }
462
463
    /**
464
     * Test for the canUser() method.
465
     *
466
     * @see \eZ\Publish\API\Repository\PermissionResolver::canUser()
467
     * @depends eZ\Publish\API\Repository\Tests\RepositoryTest::testGetUserService
468
     * @depends eZ\Publish\API\Repository\Tests\RepositoryTest::testGetContentService
469
     * @depends eZ\Publish\API\Repository\Tests\RepositoryTest::testGetContentTypeService
470
     * @depends eZ\Publish\API\Repository\Tests\PermissionResolverTest::testHasAccessLimited
471
     */
472 View Code Duplication
    public function testCanUserWithTargetYes()
473
    {
474
        $repository = $this->getRepository();
475
476
        $homeLocationId = $this->generateId('location', 2);
477
478
        /* BEGIN: Use Case */
479
        // $homeLocationId contains the ID of the "Home" location
480
481
        $user = $this->createUserVersion1();
482
483
        $permissionResolver = $repository->getPermissionResolver();
484
485
        // Set created user as current user reference
486
        $permissionResolver->setCurrentUserReference($user);
487
488
        $contentTypeService = $repository->getContentTypeService();
489
490
        $contentType = $contentTypeService->loadContentTypeByIdentifier('forums');
491
492
        $contentService = $repository->getContentService();
493
494
        $contentCreateStruct = $contentService->newContentCreateStruct($contentType, 'eng-US');
495
        $contentCreateStruct->setField('title', 'My awesome forums');
496
        $contentCreateStruct->remoteId = 'abcdef0123456789abcdef0123456789';
497
        $contentCreateStruct->alwaysAvailable = true;
498
499
        $locationService = $repository->getLocationService();
500
        $locationCreateStruct = $locationService->newLocationCreateStruct($homeLocationId);
501
502
        // This call will return true
503
        $canUser = $permissionResolver->canUser(
504
            'content',
505
            'create',
506
            $contentCreateStruct,
507
            [$locationCreateStruct]
508
        );
509
510
        // Performing an action having necessary permissions will succeed
511
        $contentDraft = $contentService->createContent(
512
            $contentCreateStruct,
513
            [$locationCreateStruct]
514
        );
515
        /* END: Use Case */
516
517
        $this->assertTrue($canUser);
518
        $this->assertEquals(
519
            'My awesome forums',
520
            $contentDraft->getFieldValue('title')->text
521
        );
522
    }
523
524
    /**
525
     * Test for the canUser() method.
526
     *
527
     * @see \eZ\Publish\API\Repository\PermissionResolver::canUser()
528
     * @depends eZ\Publish\API\Repository\Tests\RepositoryTest::testGetUserService
529
     * @depends eZ\Publish\API\Repository\Tests\RepositoryTest::testGetContentService
530
     * @depends eZ\Publish\API\Repository\Tests\RepositoryTest::testGetContentTypeService
531
     * @depends eZ\Publish\API\Repository\Tests\PermissionResolverTest::testHasAccessLimited
532
     * @expectedException \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
533
     */
534 View Code Duplication
    public function testCanUserWithTargetNo()
535
    {
536
        $repository = $this->getRepository();
537
538
        $homeLocationId = $this->generateId('location', 2);
539
540
        /* BEGIN: Use Case */
541
        // $homeLocationId contains the ID of the "Home" frontpage location
542
543
        $user = $this->createUserVersion1();
544
545
        $permissionResolver = $repository->getPermissionResolver();
546
547
        // Set created user as current user reference
548
        $permissionResolver->setCurrentUserReference($user);
549
550
        $contentTypeService = $repository->getContentTypeService();
551
552
        $contentType = $contentTypeService->loadContentTypeByIdentifier('forum');
553
554
        $contentService = $repository->getContentService();
555
556
        $contentCreateStruct = $contentService->newContentCreateStruct($contentType, 'eng-US');
557
        $contentCreateStruct->setField('name', 'My awesome forum');
558
        $contentCreateStruct->remoteId = 'abcdef0123456789abcdef0123456789';
559
        $contentCreateStruct->alwaysAvailable = true;
560
561
        $locationService = $repository->getLocationService();
562
        $locationCreateStruct = $locationService->newLocationCreateStruct($homeLocationId);
563
564
        // This call will return false because user with Editor role has permission to
565
        // create "forum" type content only under "folder" type content.
566
        $canUser = $permissionResolver->canUser(
567
            'content',
568
            'create',
569
            $contentCreateStruct,
570
            [$locationCreateStruct]
571
        );
572
573
        // Performing an action without necessary permissions will fail with "UnauthorizedException"
574
        if (!$canUser) {
575
            $contentDraft = $contentService->createContent(
0 ignored issues
show
Unused Code introduced by
$contentDraft is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
576
                $contentCreateStruct,
577
                [$locationCreateStruct]
578
            );
579
        }
580
        /* END: Use Case */
581
    }
582
583
    /**
584
     * Test for the canUser() method.
585
     *
586
     * @see \eZ\Publish\API\Repository\PermissionResolver::canUser()
587
     * @depends eZ\Publish\API\Repository\Tests\RepositoryTest::testGetUserService
588
     * @depends eZ\Publish\API\Repository\Tests\RepositoryTest::testGetContentService
589
     * @depends eZ\Publish\API\Repository\Tests\RepositoryTest::testGetContentTypeService
590
     * @depends eZ\Publish\API\Repository\Tests\PermissionResolverTest::testHasAccessLimited
591
     */
592 View Code Duplication
    public function testCanUserWithMultipleTargetsYes()
593
    {
594
        $repository = $this->getRepository();
595
596
        $imagesLocationId = $this->generateId('location', 51);
597
        $filesLocationId = $this->generateId('location', 52);
598
599
        /* BEGIN: Use Case */
600
        // $imagesLocationId contains the ID of the "Images" location
601
        // $filesLocationId contains the ID of the "Files" location
602
603
        $user = $this->createUserVersion1();
604
605
        $permissionResolver = $repository->getPermissionResolver();
606
607
        // Set created user as current user reference
608
        $permissionResolver->setCurrentUserReference($user);
609
610
        $contentTypeService = $repository->getContentTypeService();
611
612
        $contentType = $contentTypeService->loadContentTypeByIdentifier('folder');
613
614
        $contentService = $repository->getContentService();
615
616
        $contentCreateStruct = $contentService->newContentCreateStruct($contentType, 'eng-US');
617
        $contentCreateStruct->setField('name', 'My multipurpose folder');
618
        $contentCreateStruct->remoteId = 'abcdef0123456789abcdef0123456789';
619
        $contentCreateStruct->alwaysAvailable = true;
620
621
        $locationService = $repository->getLocationService();
622
        $locationCreateStruct1 = $locationService->newLocationCreateStruct($imagesLocationId);
623
        $locationCreateStruct2 = $locationService->newLocationCreateStruct($filesLocationId);
624
        $locationCreateStructs = [$locationCreateStruct1, $locationCreateStruct2];
625
626
        // This call will return true
627
        $canUser = $permissionResolver->canUser(
628
            'content',
629
            'create',
630
            $contentCreateStruct,
631
            $locationCreateStructs
632
        );
633
634
        // Performing an action having necessary permissions will succeed
635
        $contentDraft = $contentService->createContent($contentCreateStruct, $locationCreateStructs);
636
        /* END: Use Case */
637
638
        $this->assertTrue($canUser);
639
        $this->assertEquals(
640
            'My multipurpose folder',
641
            $contentDraft->getFieldValue('name')->text
642
        );
643
    }
644
645
    /**
646
     * Test for the canUser() method.
647
     *
648
     * @see \eZ\Publish\API\Repository\PermissionResolver::canUser()
649
     * @depends eZ\Publish\API\Repository\Tests\RepositoryTest::testGetUserService
650
     * @depends eZ\Publish\API\Repository\Tests\RepositoryTest::testGetContentService
651
     * @depends eZ\Publish\API\Repository\Tests\RepositoryTest::testGetContentTypeService
652
     * @depends eZ\Publish\API\Repository\Tests\PermissionResolverTest::testHasAccessLimited
653
     * @expectedException \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
654
     */
655 View Code Duplication
    public function testCanUserWithMultipleTargetsNo()
656
    {
657
        $repository = $this->getRepository();
658
659
        $homeLocationId = $this->generateId('location', 2);
660
        $administratorUsersLocationId = $this->generateId('location', 13);
661
662
        /* BEGIN: Use Case */
663
        // $homeLocationId contains the ID of the "Home" location
664
        // $administratorUsersLocationId contains the ID of the "Administrator users" location
665
666
        $user = $this->createUserVersion1();
667
668
        $permissionResolver = $repository->getPermissionResolver();
669
670
        // Set created user as current user reference
671
        $permissionResolver->setCurrentUserReference($user);
672
673
        $contentTypeService = $repository->getContentTypeService();
674
675
        $contentType = $contentTypeService->loadContentTypeByIdentifier('forums');
676
677
        $contentService = $repository->getContentService();
678
679
        $contentCreateStruct = $contentService->newContentCreateStruct($contentType, 'eng-US');
680
        $contentCreateStruct->setField('name', 'My awesome forums');
681
        $contentCreateStruct->remoteId = 'abcdef0123456789abcdef0123456789';
682
        $contentCreateStruct->alwaysAvailable = true;
683
684
        $locationService = $repository->getLocationService();
685
        $locationCreateStruct1 = $locationService->newLocationCreateStruct($homeLocationId);
686
        $locationCreateStruct2 = $locationService->newLocationCreateStruct($administratorUsersLocationId);
687
        $locationCreateStructs = [$locationCreateStruct1, $locationCreateStruct2];
688
689
        // This call will return false because user with Editor role does not have permission to
690
        // create content in the "Administrator users" location subtree
691
        $canUser = $permissionResolver->canUser(
692
            'content',
693
            'create',
694
            $contentCreateStruct,
695
            $locationCreateStructs
696
        );
697
698
        // Performing an action without necessary permissions will fail with "UnauthorizedException"
699
        if (!$canUser) {
700
            $contentDraft = $contentService->createContent($contentCreateStruct, $locationCreateStructs);
0 ignored issues
show
Unused Code introduced by
$contentDraft is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
701
        }
702
        /* END: Use Case */
703
    }
704
705
    /**
706
     * Test for the canUser() method.
707
     *
708
     * @see \eZ\Publish\API\Repository\PermissionResolver::canUser()
709
     * @depends eZ\Publish\API\Repository\Tests\RepositoryTest::testGetUserService
710
     * @depends eZ\Publish\API\Repository\Tests\RepositoryTest::testGetContentService
711
     * @depends eZ\Publish\API\Repository\Tests\RepositoryTest::testGetContentTypeService
712
     * @depends eZ\Publish\API\Repository\Tests\RepositoryTest::testGetURLAliasService
713
     * @depends eZ\Publish\API\Repository\Tests\PermissionResolverTest::testSetCurrentUserReference
714
     * @depends eZ\Publish\API\Repository\Tests\PermissionResolverTest::testHasAccessLimited
715
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
716
     */
717 View Code Duplication
    public function testCanUserWithTargetThrowsInvalidArgumentException()
718
    {
719
        $repository = $this->getRepository();
720
721
        /* BEGIN: Use Case */
722
        $user = $this->createUserVersion1();
723
724
        $permissionResolver = $repository->getPermissionResolver();
725
726
        // Set created user as current user reference
727
        $permissionResolver->setCurrentUserReference($user);
728
729
        $contentTypeService = $repository->getContentTypeService();
730
731
        $contentType = $contentTypeService->loadContentTypeByIdentifier('forum');
732
733
        $contentService = $repository->getContentService();
734
735
        $contentCreateStruct = $contentService->newContentCreateStruct($contentType, 'eng-US');
736
        $contentCreateStruct->setField('name', 'My awesome forum');
737
        $contentCreateStruct->remoteId = 'abcdef0123456789abcdef0123456789';
738
        $contentCreateStruct->alwaysAvailable = true;
739
740
        $urlAliasService = $repository->getURLAliasService();
741
        $rootUrlAlias = $urlAliasService->lookup('/');
742
743
        // This call will throw "InvalidArgumentException" because $rootAlias is not a valid target object
744
        $canUser = $permissionResolver->canUser(
0 ignored issues
show
Unused Code introduced by
$canUser is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
745
            'content',
746
            'create',
747
            $contentCreateStruct,
748
            [$rootUrlAlias]
749
        );
750
        /* END: Use Case */
751
    }
752
753
    /**
754
     * Test for the canUser() method.
755
     *
756
     * @see \eZ\Publish\API\Repository\PermissionResolver::canUser()
757
     * @expectedException \eZ\Publish\API\Repository\Exceptions\BadStateException
758
     */
759
    public function testCanUserThrowsBadStateException()
760
    {
761
        $this->markTestIncomplete(
762
            'Cannot be tested on current fixture since policy with unsupported limitation value is not available.'
763
        );
764
    }
765
766
    /**
767
     * Test PermissionResolver::canUser for Users with different Limitations.
768
     *
769
     * @covers       \eZ\Publish\API\Repository\PermissionResolver::canUser
770
     *
771
     * @dataProvider getDataForTestCanUserWithLimitations
772
     *
773
     * @param \eZ\Publish\API\Repository\Values\User\Limitation $limitation
774
     * @param string $module
775
     * @param string $function
776
     * @param \eZ\Publish\API\Repository\Values\ValueObject $object
777
     * @param array $targets
778
     * @param bool $expectedResult expected result of canUser check
779
     *
780
     * @throws \eZ\Publish\API\Repository\Exceptions\BadStateException
781
     * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
782
     */
783
    public function testCanUserWithLimitations(
784
        Limitation $limitation,
785
        $module,
786
        $function,
787
        ValueObject $object,
788
        array $targets,
789
        $expectedResult
790
    ) {
791
        $repository = $this->getRepository();
792
        $userService = $repository->getUserService();
793
        $roleService = $repository->getRoleService();
794
        $permissionResolver = $repository->getPermissionResolver();
795
796
        $role = $this->createRoleWithPolicies(
797
            'role_' . __FUNCTION__,
798
            [
799
                ['module' => $module, 'function' => $function, 'limitations' => [$limitation]],
800
            ]
801
        );
802
        // create user in root user group to avoid overlapping of existing policies and limitations
803
        $user = $this->createUser('user', 'John', 'Doe', $userService->loadUserGroup(4));
804
        $roleLimitation = $limitation instanceof Limitation\RoleLimitation ? $limitation : null;
805
        $roleService->assignRoleToUser($role, $user, $roleLimitation);
806
807
        $permissionResolver->setCurrentUserReference($user);
808
809
        self::assertEquals(
810
            $expectedResult,
811
            $permissionResolver->canUser($module, $function, $object, $targets)
812
        );
813
    }
814
815
    /**
816
     * Data provider for testCanUserWithLimitations.
817
     * @see testCanUserWithLimitations
818
     *
819
     * @return array
820
     *
821
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
822
     */
823
    public function getDataForTestCanUserWithLimitations()
824
    {
825
        $repository = $this->getRepository();
826
        $contentService = $repository->getContentService();
827
        $contentTypeService = $repository->getContentTypeService();
828
829
        $contentType = $contentTypeService->loadContentTypeByIdentifier('folder');
830
831
        $contentCreateStruct = $contentService->newContentCreateStruct($contentType, 'eng-US');
832
        $contentCreateStruct->sectionId = 2;
833
834
        // return data sets, numbered for readability and debugging
835
        return [
836
            0 => [
837
                new Limitation\SubtreeLimitation(['limitationValues' => ['/1/2/']]),
838
                'content',
839
                'create',
840
                $contentCreateStruct,
841
                [],
842
                false,
843
            ],
844
            1 => [
845
                new Limitation\SectionLimitation(['limitationValues' => [2]]),
846
                'content',
847
                'create',
848
                $contentCreateStruct,
849
                [],
850
                true,
851
            ],
852
            2 => [
853
                new Limitation\ParentContentTypeLimitation(['limitationValues' => [1]]),
854
                'content',
855
                'create',
856
                $contentCreateStruct,
857
                [],
858
                false,
859
            ],
860
            3 => [
861
                new Limitation\ParentContentTypeLimitation(['limitationValues' => [3]]), // parent type has to be the UserGroup
862
                'content',
863
                'create',
864
                $contentService->loadContentInfo(14), // content type user (Administrator)
865
                [],
866
                true,
867
            ],
868
        ];
869
    }
870
871
    /**
872
     * Test for the lookupLimitations() method.
873
     *
874
     * @see \eZ\Publish\API\Repository\PermissionResolver::lookupLimitations()
875
     * @depends \eZ\Publish\API\Repository\Tests\RepositoryTest::testGetUserService
876
     * @depends \eZ\Publish\API\Repository\Tests\RepositoryTest::testGetContentService
877
     * @depends \eZ\Publish\API\Repository\Tests\PermissionResolverTest::testHasAccessForCurrentUserNo
878
     */
879 View Code Duplication
    public function testLookupLimitationsForAnonymousUserHasNoAccess(): void
880
    {
881
        $repository = $this->getRepository();
882
883
        $homeId = $this->generateId('object', 57);
884
885
        $anonymousUserId = $this->generateId('user', 10);
886
        /* BEGIN: Use Case */
887
        // $anonymousUserId is the ID of the "Anonymous" user in a eZ
888
        // Publish demo installation.
889
        // $homeId contains the ID of the "Home" frontpage
890
891
        $contentService = $repository->getContentService();
892
        $userService = $repository->getUserService();
893
        $permissionResolver = $repository->getPermissionResolver();
894
895
        // Load anonymous user
896
        $anonymousUser = $userService->loadUser($anonymousUserId);
897
898
        // Set anonymous user as current user reference
899
        $permissionResolver->setCurrentUserReference($anonymousUser);
900
901
        // Load the ContentInfo for "Home" frontpage
902
        $contentInfo = $contentService->loadContentInfo($homeId);
903
904
        // `$lookupLimitations->hasAccess` will return false because anonymous user does not have access
905
        // to content removal and hence no permission to remove given content. `$lookupLimitations->lookupPolicyLimitations`
906
        // will be empty array
907
        $lookupLimitations = $permissionResolver->lookupLimitations('content', 'remove', $contentInfo);
908
        /* END: Use Case */
909
910
        $this->assertFalse($lookupLimitations->hasAccess);
911
        $this->assertEquals($lookupLimitations->roleLimitations, []);
912
        $this->assertEquals($lookupLimitations->lookupPolicyLimitations, []);
913
    }
914
915
    /**
916
     * Test for the lookupLimitations() method.
917
     *
918
     * @see \eZ\Publish\API\Repository\PermissionResolver::lookupLimitations()
919
     * @depends \eZ\Publish\API\Repository\Tests\RepositoryTest::testGetUserService
920
     * @depends \eZ\Publish\API\Repository\Tests\RepositoryTest::testGetContentService
921
     * @depends \eZ\Publish\API\Repository\Tests\PermissionResolverTest::testHasAccessForCurrentUserYes
922
     */
923 View Code Duplication
    public function testLookupLimitationsForAdministratorUser(): void
924
    {
925
        $repository = $this->getRepository();
926
927
        $administratorUserId = $this->generateId('user', 14);
928
        $homeId = $this->generateId('object', 57);
929
930
        /* BEGIN: Use Case */
931
        // $administratorUserId contains the ID of the administrator user
932
        // $homeId contains the ID of the "Home" frontpage
933
934
        $contentService = $repository->getContentService();
935
        $userService = $repository->getUserService();
936
        $permissionResolver = $repository->getPermissionResolver();
937
938
        // Load administrator user
939
        $administratorUser = $userService->loadUser($administratorUserId);
940
941
        // Set administrator user as current user reference
942
        $permissionResolver->setCurrentUserReference($administratorUser);
943
944
        // Load the ContentInfo for "Home" frontpage
945
        $contentInfo = $contentService->loadContentInfo($homeId);
946
947
        // This call will return true
948
        $lookupLimitations = $permissionResolver->lookupLimitations('content', 'remove', $contentInfo);
949
        /* END: Use Case */
950
951
        $this->assertTrue($lookupLimitations->hasAccess);
952
        $this->assertEquals($lookupLimitations->roleLimitations, []);
953
        $this->assertEquals($lookupLimitations->lookupPolicyLimitations, []);
954
    }
955
956
    /**
957
     * When one of policy pass then all limitation should be returned.
958
     *
959
     * @see \eZ\Publish\API\Repository\PermissionResolver::lookupLimitations()
960
     * @depends \eZ\Publish\API\Repository\Tests\RepositoryTest::testGetUserService
961
     * @depends \eZ\Publish\API\Repository\Tests\RepositoryTest::testGetContentService
962
     * @depends \eZ\Publish\API\Repository\Tests\PermissionResolverTest::testHasAccessForCurrentUserYes
963
     *
964
     * @throws \eZ\Publish\API\Repository\Exceptions\BadStateException
965
     * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
966
     * @throws \eZ\Publish\API\Repository\Exceptions\LimitationValidationException
967
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
968
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
969
     */
970
    public function testLookupLimitationsWithLimitations(): void
971
    {
972
        $repository = $this->getRepository();
973
        $userService = $repository->getUserService();
974
        $permissionResolver = $repository->getPermissionResolver();
975
        $roleService = $repository->getRoleService();
976
977
        $module = 'content';
978
        $function = 'create';
979
980
        $role = $this->createRoleWithPolicies(
981
            'role_' . __FUNCTION__,
982
            [
983
                ['module' => $module, 'function' => $function, 'limitations' => [new Limitation\SubtreeLimitation(['limitationValues' => ['/1/2/']])]],
984
                ['module' => $module, 'function' => $function, 'limitations' => [
985
                    new Limitation\SectionLimitation(['limitationValues' => [2]]),
986
                    new Limitation\LanguageLimitation(['limitationValues' => ['eng-US']]),
987
                ]],
988
                ['module' => 'content', 'function' => 'edit', 'limitations' => [new Limitation\SectionLimitation(['limitationValues' => [2]])]],
989
            ]
990
        );
991
        // create user in root user group to avoid overlapping of existing policies and limitations
992
        $user = $this->createUser('user', 'John', 'Doe', $userService->loadUserGroup(4));
993
        // Here we have no RoleLimitation
994
        $roleService->assignRoleToUser($role, $user);
995
        $permissionResolver->setCurrentUserReference($user);
996
997
        $expected = new LookupLimitationResult(
998
            true,
999
            [],
1000
            [
1001
                new LookupPolicyLimitations(
1002
                    $role->getPolicies()[1],
1003
                    [
1004
                        new Limitation\SectionLimitation(['limitationValues' => [2]]),
1005
                        new Limitation\LanguageLimitation(['limitationValues' => ['eng-US']]),
1006
                    ]
1007
                ),
1008
            ]
1009
        );
1010
1011
        self::assertEquals(
1012
            $expected,
1013
            $permissionResolver->lookupLimitations($module, $function, $this->getContentCreateStruct($repository), [])
1014
        );
1015
    }
1016
1017
    /**
1018
     * When one of policy pass then only filtered limitation should be returned.
1019
     *
1020
     * @see \eZ\Publish\API\Repository\PermissionResolver::lookupLimitations()
1021
     * @depends \eZ\Publish\API\Repository\Tests\RepositoryTest::testGetUserService
1022
     * @depends \eZ\Publish\API\Repository\Tests\RepositoryTest::testGetContentService
1023
     * @depends \eZ\Publish\API\Repository\Tests\PermissionResolverTest::testHasAccessForCurrentUserYes
1024
     *
1025
     * @throws \eZ\Publish\API\Repository\Exceptions\BadStateException
1026
     * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
1027
     * @throws \eZ\Publish\API\Repository\Exceptions\LimitationValidationException
1028
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
1029
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
1030
     */
1031
    public function testLookupLimitationsWithFilteredLimitations(): void
1032
    {
1033
        $repository = $this->getRepository();
1034
        $userService = $repository->getUserService();
1035
        $permissionResolver = $repository->getPermissionResolver();
1036
        $roleService = $repository->getRoleService();
1037
1038
        $module = 'content';
1039
        $function = 'create';
1040
1041
        $role = $this->createRoleWithPolicies(
1042
            'role_' . __FUNCTION__,
1043
            [
1044
                ['module' => $module, 'function' => $function, 'limitations' => [new Limitation\SubtreeLimitation(['limitationValues' => ['/1/2/']])]],
1045
                ['module' => $module, 'function' => $function, 'limitations' => [
1046
                    new Limitation\SectionLimitation(['limitationValues' => [2]]),
1047
                    new Limitation\LanguageLimitation(['limitationValues' => ['eng-US']]),
1048
                ]],
1049
                ['module' => 'content', 'function' => 'edit', 'limitations' => [new Limitation\SectionLimitation(['limitationValues' => [2]])]],
1050
            ]
1051
        );
1052
        // create user in root user group to avoid overlapping of existing policies and limitations
1053
        $user = $this->createUser('user', 'John', 'Doe', $userService->loadUserGroup(4));
1054
        // Here we have no RoleLimitation
1055
        $roleService->assignRoleToUser($role, $user);
1056
        $permissionResolver->setCurrentUserReference($user);
1057
1058
        $expected = new LookupLimitationResult(
1059
            true,
1060
            [],
1061
            [
1062
                new LookupPolicyLimitations(
1063
                    $role->getPolicies()[1],
1064
                    [
1065
                        new Limitation\SectionLimitation(['limitationValues' => [2]]),
1066
                    ]
1067
                ),
1068
            ]
1069
        );
1070
1071
        self::assertEquals(
1072
            $expected,
1073
            $permissionResolver->lookupLimitations($module, $function, $this->getContentCreateStruct($repository), [], [Limitation::SECTION])
1074
        );
1075
    }
1076
1077
    /**
1078
     * If the role limitation is set it should be taken into account. In this case, role limitation
1079
     * will pass and ContentTypeLimitation should be returned.
1080
     *
1081
     * @throws \eZ\Publish\API\Repository\Exceptions\BadStateException
1082
     * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
1083
     * @throws \eZ\Publish\API\Repository\Exceptions\LimitationValidationException
1084
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
1085
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
1086
     */
1087
    public function testLookupLimitationsWithRoleLimitationsHasAccess(): void
1088
    {
1089
        $repository = $this->getRepository();
1090
        $userService = $repository->getUserService();
1091
        $permissionResolver = $repository->getPermissionResolver();
1092
        $roleService = $repository->getRoleService();
1093
1094
        $module = 'content';
1095
        $function = 'create';
1096
1097
        /* BEGIN: Use Case */
1098
        $role = $this->createRoleWithPolicies(
1099
            'role_' . __FUNCTION__,
1100
            [
1101
                ['module' => $module, 'function' => $function, 'limitations' => [new Limitation\SubtreeLimitation(['limitationValues' => ['/1/2/']])]],
1102
                ['module' => $module, 'function' => $function, 'limitations' => [new Limitation\LanguageLimitation(['limitationValues' => ['eng-US']])]],
1103
                ['module' => 'content', 'function' => 'edit', 'limitations' => [new Limitation\SectionLimitation(['limitationValues' => [2]])]],
1104
            ]
1105
        );
1106
        // create user in root user group to avoid overlapping of existing policies and limitations
1107
        $user = $this->createUser('user', 'John', 'Doe', $userService->loadUserGroup(4));
1108
        // SectionLimitation as RoleLimitation will pass
1109
        $roleLimitation = new Limitation\SectionLimitation(['limitationValues' => [2]]);
1110
        $roleService->assignRoleToUser($role, $user, $roleLimitation);
1111
        $permissionResolver->setCurrentUserReference($user);
1112
        /* END: Use Case */
1113
1114
        $expected = new LookupLimitationResult(
1115
            true,
1116
            [$roleLimitation],
1117
            [
1118
                new LookupPolicyLimitations(
1119
                    $role->getPolicies()[1],
1120
                    [new Limitation\LanguageLimitation(['limitationValues' => ['eng-US']])]
1121
                ),
1122
            ]
1123
        );
1124
1125
        self::assertEquals(
1126
            $expected,
1127
            $permissionResolver->lookupLimitations($module, $function, $this->getContentCreateStruct($repository), [])
1128
        );
1129
    }
1130
1131
    /**
1132
     * If the role limitation is set and policy limitation is not set it should be taken into account.
1133
     * In this case, role limitation will pass and SectionLimitation should be returned as role limitation
1134
     * and limitations in LookupPolicyLimitations should be an empty array.
1135
     *
1136
     * @see https://jira.ez.no/browse/EZP-30728
1137
     *
1138
     * @throws \eZ\Publish\API\Repository\Exceptions\BadStateException
1139
     * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
1140
     * @throws \eZ\Publish\API\Repository\Exceptions\LimitationValidationException
1141
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
1142
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
1143
     */
1144
    public function testLookupLimitationsWithRoleLimitationsWithoutPolicyLimitationsHasAccess(): void
1145
    {
1146
        $repository = $this->getRepository();
1147
        $userService = $repository->getUserService();
1148
        $permissionResolver = $repository->getPermissionResolver();
1149
        $roleService = $repository->getRoleService();
1150
1151
        $module = 'content';
1152
        $function = 'create';
1153
1154
        /* BEGIN: Use Case */
1155
        $role = $this->createRoleWithPolicies(
1156
            'role_' . __FUNCTION__,
1157
            [
1158
                ['module' => $module, 'function' => $function, 'limitations' => []],
1159
                ['module' => 'content', 'function' => 'edit', 'limitations' => []],
1160
            ]
1161
        );
1162
        // create user in root user group to avoid overlapping of existing policies and limitations
1163
        $user = $this->createUser('user', 'John', 'Doe', $userService->loadUserGroup(4));
1164
        // SectionLimitation as RoleLimitation will pass
1165
        $roleLimitation = new Limitation\SectionLimitation(['limitationValues' => [2]]);
1166
        $roleService->assignRoleToUser($role, $user, $roleLimitation);
1167
        $permissionResolver->setCurrentUserReference($user);
1168
        /* END: Use Case */
1169
1170
        $expectedPolicy = current(array_filter($role->getPolicies(), function ($policy) use ($module, $function) {
1171
            return $policy->module === $module && $policy->function === $function;
1172
        }));
1173
1174
        $expected = new LookupLimitationResult(
1175
            true,
1176
            [$roleLimitation],
1177
            [
1178
                new LookupPolicyLimitations(
1179
                    $expectedPolicy,
1180
                    []
1181
                ),
1182
            ]
1183
        );
1184
1185
        self::assertEquals(
1186
            $expected,
1187
            $permissionResolver->lookupLimitations($module, $function, $this->getContentCreateStruct($repository), [])
1188
        );
1189
    }
1190
1191
    /**
1192
     * If the role limitation is set it should be taken into account. In this case, role limitation
1193
     * will not pass and ContentTypeLimitation should not be returned.
1194
     *
1195
     * @throws \eZ\Publish\API\Repository\Exceptions\BadStateException
1196
     * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
1197
     * @throws \eZ\Publish\API\Repository\Exceptions\LimitationValidationException
1198
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
1199
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
1200
     */
1201
    public function testLookupLimitationsWithRoleLimitationsHasNoAccess(): void
1202
    {
1203
        $repository = $this->getRepository();
1204
        $userService = $repository->getUserService();
1205
        $permissionResolver = $repository->getPermissionResolver();
1206
        $roleService = $repository->getRoleService();
1207
1208
        $module = 'content';
1209
        $function = 'create';
1210
1211
        /* BEGIN: Use Case */
1212
        $role = $this->createRoleWithPolicies(
1213
            'role_' . __FUNCTION__,
1214
            [
1215
                ['module' => $module, 'function' => $function, 'limitations' => [new Limitation\SubtreeLimitation(['limitationValues' => ['/1/2/']])]],
1216
                ['module' => $module, 'function' => $function, 'limitations' => [new Limitation\LanguageLimitation(['limitationValues' => ['eng-US']])]],
1217
                ['module' => 'content', 'function' => 'edit', 'limitations' => [new Limitation\SectionLimitation(['limitationValues' => [2]])]],
1218
            ]
1219
        );
1220
        // create user in root user group to avoid overlapping of existing policies and limitations
1221
        $user = $this->createUser('user', 'John', 'Doe', $userService->loadUserGroup(4));
1222
        // SectionLimitation as RoleLimitation will not pass
1223
        $roleLimitation = new Limitation\SectionLimitation(['limitationValues' => [3]]);
1224
        $roleService->assignRoleToUser($role, $user, $roleLimitation);
1225
        $permissionResolver->setCurrentUserReference($user);
1226
        /* END: Use Case */
1227
1228
        $expected = new LookupLimitationResult(
1229
            false,
1230
            [],
1231
            []
1232
        );
1233
1234
        self::assertEquals(
1235
            $expected,
1236
            $permissionResolver->lookupLimitations($module, $function, $this->getContentCreateStruct($repository), [])
1237
        );
1238
    }
1239
1240
    /**
1241
     * @param \eZ\Publish\API\Repository\Repository $repository
1242
     * @param string $contentTypeIdentifier
1243
     * @param string $mainLanguageCode
1244
     * @param int $sectionId
1245
     *
1246
     * @return \eZ\Publish\API\Repository\Values\Content\ContentCreateStruct
1247
     *
1248
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
1249
     */
1250
    private function getContentCreateStruct(
1251
        Repository $repository,
1252
        string $contentTypeIdentifier = 'folder',
1253
        string $mainLanguageCode = 'eng-US',
1254
        int $sectionId = 2
1255
    ): ContentCreateStruct {
1256
        $contentService = $repository->getContentService();
1257
        $contentTypeService = $repository->getContentTypeService();
1258
        $contentType = $contentTypeService->loadContentTypeByIdentifier($contentTypeIdentifier);
1259
        $contentCreateStruct = $contentService->newContentCreateStruct($contentType, $mainLanguageCode);
1260
        $contentCreateStruct->sectionId = $sectionId;
1261
1262
        return $contentCreateStruct;
1263
    }
1264
}