Completed
Push — EZP-30427 ( 34539c )
by
unknown
22:09
created

testLoadContentDraftsThrowsUnauthorizedExceptionWithAllAgrumants()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10

Duplication

Lines 10
Ratio 100 %

Importance

Changes 0
Metric Value
dl 10
loc 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
rs 9.9332
1
<?php
2
3
/**
4
 * File containing the ContentServiceAuthorizationTest 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\API\Repository\Tests;
10
11
use eZ\Publish\API\Repository\Exceptions\UnauthorizedException;
12
use eZ\Publish\API\Repository\Repository;
13
use eZ\Publish\API\Repository\Values\Content\ContentInfo;
14
use eZ\Publish\API\Repository\Values\Content\Location;
15
use eZ\Publish\API\Repository\Values\User\Limitation\LocationLimitation;
16
use eZ\Publish\API\Repository\Values\User\Limitation\SubtreeLimitation;
17
18
/**
19
 * Test case for operations in the ContentServiceAuthorization using in memory storage.
20
 *
21
 * @see eZ\Publish\API\Repository\ContentService
22
 * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testLoadAnonymousUser
23
 * @group integration
24
 * @group authorization
25
 */
26
class ContentServiceAuthorizationTest extends BaseContentServiceTest
27
{
28
    /** @var \eZ\Publish\API\Repository\Values\User\User */
29
    private $administratorUser;
30
31
    /** @var \eZ\Publish\API\Repository\Values\User\User */
32
    private $anonymousUser;
33
34
    /** @var \eZ\Publish\API\Repository\Repository */
35
    private $repository;
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
36
37
    /** @var \eZ\Publish\API\Repository\PermissionResolver */
38
    private $permissionResolver;
39
40
    /** @var \eZ\Publish\API\Repository\UserService */
41
    private $userService;
42
43
    /** @var \eZ\Publish\API\Repository\ContentService */
44
    private $contentService;
45
46
    public function setUp(): void
47
    {
48
        parent::setUp();
49
50
        $anonymousUserId = $this->generateId('user', 10);
51
        $administratorUserId = $this->generateId('user', 14);
52
53
        $this->repository = $this->getRepository();
54
        $this->permissionResolver = $this->repository->getPermissionResolver();
55
        $this->userService = $this->repository->getUserService();
56
        $this->contentService = $this->repository->getContentService();
57
58
        $this->administratorUser = $this->userService->loadUser($administratorUserId);
59
        $this->anonymousUser = $this->userService->loadUser($anonymousUserId);
60
    }
61
62
    /**
63
     * Test for the createContent() method.
64
     *
65
     * @see \eZ\Publish\API\Repository\ContentService::createContent()
66
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
67
     */
68
    public function testCreateContentThrowsUnauthorizedException()
69
    {
70
        if ($this->isVersion4()) {
71
            $this->markTestSkipped('This test requires eZ Publish 5');
72
        }
73
74
        /* BEGIN: Use Case */
75
        $this->permissionResolver->setCurrentUserReference($this->anonymousUser);
76
77
        $contentTypeService = $this->getRepository()->getContentTypeService();
78
79
        $contentType = $contentTypeService->loadContentTypeByIdentifier('forum');
80
81
        $contentCreate = $this->contentService->newContentCreateStruct($contentType, 'eng-US');
82
        $contentCreate->setField('name', 'Awesome Sindelfingen forum');
83
84
        $contentCreate->remoteId = 'abcdef0123456789abcdef0123456789';
85
        $contentCreate->alwaysAvailable = true;
86
87
        $this->expectException(UnauthorizedException::class);
88
        $this->expectExceptionMessageRegExp('/\'create\' \'content\'/');
89
90
        $this->contentService->createContent($contentCreate);
91
        /* END: Use Case */
92
    }
93
94
    /**
95
     * Test for the createContent() method.
96
     *
97
     * @see \eZ\Publish\API\Repository\ContentService::createContent($contentCreateStruct, $locationCreateStructs)
98
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
99
     */
100
    public function testCreateContentThrowsUnauthorizedExceptionWithSecondParameter()
101
    {
102
        /* BEGIN: Use Case */
103
        $this->permissionResolver->setCurrentUserReference($this->anonymousUser);
104
105
        $this->expectException(UnauthorizedException::class);
106
        $this->expectExceptionMessageRegExp('/\'create\' \'content\'/');
107
108
        $this->createContentDraftVersion1();
109
        /* END: Use Case */
110
    }
111
112
    /**
113
     * Test for the loadContentInfo() method.
114
     *
115
     * @see \eZ\Publish\API\Repository\ContentService::loadContentInfo()
116
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfo
117
     */
118 View Code Duplication
    public function testLoadContentInfoThrowsUnauthorizedException()
119
    {
120
        $contentId = $this->generateId('object', 10);
121
        /* BEGIN: Use Case */
122
        $this->setRestrictedEditorUser();
123
124
        $this->expectException(UnauthorizedException::class);
125
        $this->expectExceptionMessageRegExp('/\'read\' \'content\'/');
126
127
        // $contentId contains a content object ID not accessible for anonymous
128
        $this->contentService->loadContentInfo($contentId);
129
        /* END: Use Case */
130
    }
131
132
    /**
133
     * Test for the sudo() method.
134
     *
135
     * @see \eZ\Publish\API\Repository\Repository::sudo()
136
     * @depends testLoadContentInfoThrowsUnauthorizedException
137
     */
138
    public function testSudo()
139
    {
140
        $repository = $this->getRepository();
141
        $contentId = $this->generateId('object', 10);
142
        $this->setRestrictedEditorUser();
143
144
        $contentInfo = $repository->sudo(function (Repository $repository) use ($contentId) {
145
            return $repository->getContentService()->loadContentInfo($contentId);
146
        });
147
148
        $this->assertInstanceOf(
149
            ContentInfo::class,
150
            $contentInfo
151
        );
152
    }
153
154
    /**
155
     * Test for the loadContentInfoList() method.
156
     *
157
     * @see \eZ\Publish\API\Repository\ContentService::loadContentInfoList()
158
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfoList
159
     */
160
    public function testLoadContentInfoListSkipsUnauthorizedItems()
161
    {
162
        $contentId = $this->generateId('object', 10);
163
        $this->setRestrictedEditorUser();
164
165
        $this->assertCount(0, $this->contentService->loadContentInfoList([$contentId]));
166
    }
167
168
    /**
169
     * Test for the loadContentInfoByRemoteId() method.
170
     *
171
     * @see \eZ\Publish\API\Repository\ContentService::loadContentInfoByRemoteId()
172
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfoByRemoteId
173
     */
174 View Code Duplication
    public function testLoadContentInfoByRemoteIdThrowsUnauthorizedException()
175
    {
176
        /* BEGIN: Use Case */
177
        $anonymousRemoteId = 'faaeb9be3bd98ed09f606fc16d144eca';
178
179
        $this->setRestrictedEditorUser();
180
181
        $this->expectException(UnauthorizedException::class);
182
        $this->expectExceptionMessageRegExp('/\'read\' \'content\'/');
183
184
        $this->contentService->loadContentInfoByRemoteId($anonymousRemoteId);
185
        /* END: Use Case */
186
    }
187
188
    /**
189
     * Test for the loadVersionInfo() method.
190
     *
191
     * @see \eZ\Publish\API\Repository\ContentService::loadVersionInfo()
192
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadVersionInfo
193
     */
194
    public function testLoadVersionInfoThrowsUnauthorizedException()
195
    {
196
        /* BEGIN: Use Case */
197
        $contentInfo = $this->getContentInfoForAnonymousUser();
198
199
        $this->setRestrictedEditorUser();
200
201
        $this->expectException(UnauthorizedException::class);
202
        $this->expectExceptionMessageRegExp('/\'read\' \'content\'/');
203
204
        $this->contentService->loadVersionInfo($contentInfo);
205
        /* END: Use Case */
206
    }
207
208
    /**
209
     * Test for the loadVersionInfo() method.
210
     *
211
     * @see \eZ\Publish\API\Repository\ContentService::loadVersionInfo($contentInfo, $versionNo)
212
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadVersionInfoWithSecondParameter
213
     */
214
    public function testLoadVersionInfoThrowsUnauthorizedExceptionWithSecondParameter()
215
    {
216
        /* BEGIN: Use Case */
217
        $contentInfo = $this->getContentInfoForAnonymousUser();
218
219
        $this->setRestrictedEditorUser();
220
221
        $this->expectException(UnauthorizedException::class);
222
        $this->expectExceptionMessageRegExp('/\'read\' \'content\'/');
223
224
        $this->contentService->loadVersionInfo($contentInfo, 2);
225
        /* END: Use Case */
226
    }
227
228
    /**
229
     * Test for the loadVersionInfoById() method.
230
     *
231
     * @see \eZ\Publish\API\Repository\ContentService::loadVersionInfoById()
232
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadVersionInfoById
233
     */
234 View Code Duplication
    public function testLoadVersionInfoByIdThrowsUnauthorizedException()
235
    {
236
        $anonymousUserId = $this->generateId('user', 10);
237
        /* BEGIN: Use Case */
238
        $this->setRestrictedEditorUser();
239
240
        $this->expectException(UnauthorizedException::class);
241
        $this->expectExceptionMessageRegExp('/\'read\' \'content\'/');
242
243
        $this->contentService->loadVersionInfoById($anonymousUserId);
244
        /* END: Use Case */
245
    }
246
247
    /**
248
     * Test for the loadVersionInfoById() method.
249
     *
250
     * @see \eZ\Publish\API\Repository\ContentService::loadVersionInfoById($contentId, $versionNo)
251
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadVersionInfoByIdWithSecondParameter
252
     */
253 View Code Duplication
    public function testLoadVersionInfoByIdThrowsUnauthorizedExceptionWithSecondParameter()
254
    {
255
        $anonymousUserId = $this->generateId('user', 10);
256
        /* BEGIN: Use Case */
257
        $this->setRestrictedEditorUser();
258
259
        $this->expectException(UnauthorizedException::class);
260
        $this->expectExceptionMessageRegExp('/\'read\' \'content\'/');
261
262
        $this->contentService->loadVersionInfoById($anonymousUserId, 2);
263
        /* END: Use Case */
264
    }
265
266
    /**
267
     * Test for the loadVersionInfoById() method.
268
     *
269
     * @see \eZ\Publish\API\Repository\ContentService::loadVersionInfoById($contentId, $versionNo)
270
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadVersionInfoById
271
     */
272
    public function testLoadVersionInfoByIdThrowsUnauthorizedExceptionForFirstDraft()
273
    {
274
        /* BEGIN: Use Case */
275
        $contentDraft = $this->createContentDraftVersion1();
276
277
        $this->permissionResolver->setCurrentUserReference($this->anonymousUser);
278
279
        $this->expectException(UnauthorizedException::class);
280
        // content versionread policy is needed because it is a draft
281
        $this->expectExceptionMessageRegExp('/\'versionread\' \'content\'/');
282
283
        $this->contentService->loadVersionInfoById(
284
            $contentDraft->id,
285
            $contentDraft->contentInfo->currentVersionNo
286
        );
287
        /* END: Use Case */
288
    }
289
290
    /**
291
     * Test for the loadContentByContentInfo() method.
292
     *
293
     * @see \eZ\Publish\API\Repository\ContentService::loadContentByContentInfo()
294
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentByContentInfo
295
     */
296
    public function testLoadContentByContentInfoThrowsUnauthorizedException()
297
    {
298
        /* BEGIN: Use Case */
299
        $contentInfo = $this->getContentInfoForAnonymousUser();
300
301
        $this->setRestrictedEditorUser();
302
303
        $this->expectException(UnauthorizedException::class);
304
        $this->expectExceptionMessageRegExp('/\'read\' \'content\'/');
305
306
        $this->contentService->loadContentByContentInfo($contentInfo);
307
        /* END: Use Case */
308
    }
309
310
    /**
311
     * Test for the loadContentByContentInfo() method.
312
     *
313
     * @see \eZ\Publish\API\Repository\ContentService::loadContentByContentInfo($contentInfo, $languages)
314
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentByContentInfoWithLanguageParameters
315
     */
316 View Code Duplication
    public function testLoadContentByContentInfoThrowsUnauthorizedExceptionWithSecondParameter()
317
    {
318
        /* BEGIN: Use Case */
319
        $contentInfo = $this->getContentInfoForAnonymousUser();
320
321
        $this->setRestrictedEditorUser();
322
323
        $this->expectException(UnauthorizedException::class);
324
        $this->expectExceptionMessageRegExp('/\'read\' \'content\'/');
325
326
        $this->contentService->loadContentByContentInfo($contentInfo, ['eng-US']);
327
        /* END: Use Case */
328
    }
329
330
    /**
331
     * Test for the loadContentByContentInfo() method.
332
     *
333
     * @see \eZ\Publish\API\Repository\ContentService::loadContentByContentInfo($contentInfo, $languages, $versionNo)
334
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentByContentInfoWithVersionNumberParameter
335
     */
336 View Code Duplication
    public function testLoadContentByContentInfoThrowsUnauthorizedExceptionWithThirdParameter()
337
    {
338
        /* BEGIN: Use Case */
339
        $contentInfo = $this->getContentInfoForAnonymousUser();
340
341
        $this->setRestrictedEditorUser();
342
343
        $this->expectException(UnauthorizedException::class);
344
        $this->expectExceptionMessageRegExp('/\'read\' \'content\'/');
345
346
        $this->contentService->loadContentByContentInfo($contentInfo, ['eng-US'], 2);
347
        /* END: Use Case */
348
    }
349
350
    /**
351
     * Test for the loadContentByVersionInfo() method.
352
     *
353
     * @see \eZ\Publish\API\Repository\ContentService::loadContentByVersionInfo()
354
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentByVersionInfo
355
     */
356 View Code Duplication
    public function testLoadContentByVersionInfoThrowsUnauthorizedException()
357
    {
358
        /* BEGIN: Use Case */
359
        $contentInfo = $this->getContentInfoForAnonymousUser();
360
361
        $versionInfo = $this->contentService->loadVersionInfo($contentInfo);
362
363
        $this->setRestrictedEditorUser();
364
365
        $this->expectException(UnauthorizedException::class);
366
        $this->expectExceptionMessageRegExp('/\'read\' \'content\'/');
367
368
        $this->contentService->loadContentByVersionInfo($versionInfo);
369
        /* END: Use Case */
370
    }
371
372
    /**
373
     * Test for the loadContentByVersionInfo() method.
374
     *
375
     * @see \eZ\Publish\API\Repository\ContentService::loadContentByVersionInfo($versionInfo, $languages)
376
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentByVersionInfoWithSecondParameter
377
     */
378 View Code Duplication
    public function testLoadContentByVersionInfoThrowsUnauthorizedExceptionWithSecondParameter()
379
    {
380
        /* BEGIN: Use Case */
381
        $contentInfo = $this->getContentInfoForAnonymousUser();
382
383
        $versionInfo = $this->contentService->loadVersionInfo($contentInfo);
384
385
        $this->setRestrictedEditorUser();
386
387
        $this->expectException(UnauthorizedException::class);
388
        $this->expectExceptionMessageRegExp('/\'read\' \'content\'/');
389
390
        $this->contentService->loadContentByVersionInfo($versionInfo, ['eng-US']);
391
        /* END: Use Case */
392
    }
393
394
    /**
395
     * Test for the loadContent() method.
396
     *
397
     * @see \eZ\Publish\API\Repository\ContentService::loadContent()
398
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContent
399
     */
400 View Code Duplication
    public function testLoadContentThrowsUnauthorizedException()
401
    {
402
        $anonymousUserId = $this->generateId('user', 10);
403
        /* BEGIN: Use Case */
404
        $this->setRestrictedEditorUser();
405
406
        $this->expectException(UnauthorizedException::class);
407
        $this->expectExceptionMessageRegExp('/\'read\' \'content\'/');
408
409
        $this->contentService->loadContent($anonymousUserId);
410
        /* END: Use Case */
411
    }
412
413
    /**
414
     * Test for the loadContent() method.
415
     *
416
     * @see \eZ\Publish\API\Repository\ContentService::loadContent($contentId, $languages)
417
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentWithSecondParameter
418
     */
419 View Code Duplication
    public function testLoadContentThrowsUnauthorizedExceptionWithSecondParameter()
420
    {
421
        $anonymousUserId = $this->generateId('user', 10);
422
        /* BEGIN: Use Case */
423
        $this->setRestrictedEditorUser();
424
425
        $this->expectException(UnauthorizedException::class);
426
        $this->expectExceptionMessageRegExp('/\'read\' \'content\'/');
427
428
        $this->contentService->loadContent($anonymousUserId, ['eng-US']);
429
        /* END: Use Case */
430
    }
431
432
    /**
433
     * Test for the loadContent() method.
434
     *
435
     * @see \eZ\Publish\API\Repository\ContentService::loadContent($contentId, $languages, $versionNo)
436
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentWithThirdParameter
437
     */
438 View Code Duplication
    public function testLoadContentThrowsUnauthorizedExceptionWithThirdParameter()
439
    {
440
        $anonymousUserId = $this->generateId('user', 10);
441
        /* BEGIN: Use Case */
442
        $this->setRestrictedEditorUser();
443
444
        $this->expectException(UnauthorizedException::class);
445
        $this->expectExceptionMessageRegExp('/\'read\' \'content\'/');
446
447
        $this->contentService->loadContent($anonymousUserId, ['eng-US'], 2);
448
        /* END: Use Case */
449
    }
450
451
    /**
452
     * Test for the loadContent() method on a draft.
453
     *
454
     * @see \eZ\Publish\API\Repository\ContentService::loadContent()
455
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContent
456
     */
457
    public function testLoadContentThrowsUnauthorizedExceptionOnDrafts()
458
    {
459
        /* BEGIN: Use Case */
460
        $editorUser = $this->createUserVersion1();
461
462
        $this->permissionResolver->setCurrentUserReference($editorUser);
463
464
        // Create draft with this user
465
        $draft = $this->createContentDraftVersion1(2, 'folder');
466
467
        $this->permissionResolver->setCurrentUserReference($this->anonymousUser);
468
469
        // Try to load the draft with anonymous user to make sure access won't be allowed by throwing an exception
470
        $this->expectException(UnauthorizedException::class);
471
        // content versionread policy is needed because it is a draft
472
        $this->expectExceptionMessageRegExp('/\'versionread\' \'content\'/');
473
474
        $this->contentService->loadContent($draft->id);
475
        /* END: Use Case */
476
    }
477
478
    /**
479
     * Test for the ContentService::loadContent() method on an archive.
480
     *
481
     * This test the version permission on loading archived versions
482
     *
483
     * @see \eZ\Publish\API\Repository\ContentService::loadContent()
484
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContent
485
     */
486
    public function testLoadContentThrowsUnauthorizedExceptionsOnArchives()
487
    {
488
        /* BEGIN: Use Case */
489
        $contentTypeService = $this->getRepository()->getContentTypeService();
490
491
        // set admin as current user
492
        $this->permissionResolver->setCurrentUserReference($this->administratorUser);
493
494
        // create folder
495
        $newStruct = $this->contentService->newContentCreateStruct(
496
            $contentTypeService->loadContentTypeByIdentifier('folder'),
497
            'eng-US'
498
        );
499
        $newStruct->setField('name', 'Test Folder');
500
        $draft = $this->contentService->createContent(
501
            $newStruct,
502
            [$this->repository->getLocationService()->newLocationCreateStruct(2)]
503
        );
504
        $object = $this->contentService->publishVersion($draft->versionInfo);
505
506
        // update folder to make an archived version
507
        $updateStruct = $this->contentService->newContentUpdateStruct();
508
        $updateStruct->setField('name', 'Test Folder Updated');
509
        $draftUpdated = $this->contentService->updateContent(
510
            $this->contentService->createContentDraft($object->contentInfo)->versionInfo,
511
            $updateStruct
512
        );
513
        $objectUpdated = $this->contentService->publishVersion($draftUpdated->versionInfo);
514
515
        // set an anonymous as current user
516
        $this->permissionResolver->setCurrentUserReference($this->anonymousUser);
517
518
        $this->expectException(UnauthorizedException::class);
519
        // content versionread policy is needed because it is a draft
520
        $this->expectExceptionMessageRegExp('/\'versionread\' \'content\'/');
521
522
        $this->contentService->loadContent($objectUpdated->id, null, 1);
523
        /* END: Use Case */
524
    }
525
526
    /**
527
     * Test for the loadContentByRemoteId() method.
528
     *
529
     * @see \eZ\Publish\API\Repository\ContentService::loadContentByRemoteId()
530
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentByRemoteId
531
     */
532 View Code Duplication
    public function testLoadContentByRemoteIdThrowsUnauthorizedException()
533
    {
534
        /* BEGIN: Use Case */
535
        $anonymousRemoteId = 'faaeb9be3bd98ed09f606fc16d144eca';
536
537
        $this->setRestrictedEditorUser();
538
539
        $this->expectException(UnauthorizedException::class);
540
        $this->expectExceptionMessageRegExp('/\'read\' \'content\'/');
541
542
        $this->contentService->loadContentByRemoteId($anonymousRemoteId);
543
        /* END: Use Case */
544
    }
545
546
    /**
547
     * Test for the loadContentByRemoteId() method.
548
     *
549
     * @see \eZ\Publish\API\Repository\ContentService::loadContentByRemoteId($remoteId, $languages)
550
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentByRemoteIdWithSecondParameter
551
     */
552 View Code Duplication
    public function testLoadContentByRemoteIdThrowsUnauthorizedExceptionWithSecondParameter()
553
    {
554
        /* BEGIN: Use Case */
555
        $anonymousRemoteId = 'faaeb9be3bd98ed09f606fc16d144eca';
556
557
        $this->setRestrictedEditorUser();
558
559
        $this->expectException(UnauthorizedException::class);
560
        $this->expectExceptionMessageRegExp('/\'read\' \'content\'/');
561
562
        $this->contentService->loadContentByRemoteId($anonymousRemoteId, ['eng-US']);
563
        /* END: Use Case */
564
    }
565
566
    /**
567
     * Test for the loadContentByRemoteId() method.
568
     *
569
     * @see \eZ\Publish\API\Repository\ContentService::loadContentByRemoteId($remoteId, $languages, $versionNo)
570
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentByRemoteIdWithThirdParameter
571
     */
572 View Code Duplication
    public function testLoadContentByRemoteIdThrowsUnauthorizedExceptionWithThirdParameter()
573
    {
574
        /* BEGIN: Use Case */
575
        $anonymousRemoteId = 'faaeb9be3bd98ed09f606fc16d144eca';
576
577
        $this->setRestrictedEditorUser();
578
579
        $this->expectException(UnauthorizedException::class);
580
        $this->expectExceptionMessageRegExp('/\'read\' \'content\'/');
581
582
        $this->contentService->loadContentByRemoteId($anonymousRemoteId, ['eng-US'], 2);
583
        /* END: Use Case */
584
    }
585
586
    /**
587
     * Test for the updateContentMetadata() method.
588
     *
589
     * @see \eZ\Publish\API\Repository\ContentService::updateContentMetadata()
590
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContentMetadata
591
     */
592
    public function testUpdateContentMetadataThrowsUnauthorizedException()
593
    {
594
        /* BEGIN: Use Case */
595
        $content = $this->createContentVersion1();
596
597
        $contentInfo = $content->contentInfo;
598
599
        $this->permissionResolver->setCurrentUserReference($this->anonymousUser);
600
601
        $metadataUpdate = $this->contentService->newContentMetadataUpdateStruct();
602
603
        $metadataUpdate->remoteId = 'aaaabbbbccccddddeeeeffff11112222';
604
        $metadataUpdate->mainLanguageCode = 'eng-US';
605
        $metadataUpdate->alwaysAvailable = false;
606
        $metadataUpdate->publishedDate = $this->createDateTime();
607
        $metadataUpdate->modificationDate = $this->createDateTime();
608
609
        $this->expectException(UnauthorizedException::class);
610
        $this->expectExceptionMessageRegExp('/\'edit\' \'content\'/');
611
612
        $this->contentService->updateContentMetadata(
613
            $contentInfo,
614
            $metadataUpdate
615
        );
616
        /* END: Use Case */
617
    }
618
619
    /**
620
     * Test for the deleteContent() method.
621
     *
622
     * @see \eZ\Publish\API\Repository\ContentService::deleteContent()
623
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testDeleteContent
624
     */
625 View Code Duplication
    public function testDeleteContentThrowsUnauthorizedException()
626
    {
627
        /* BEGIN: Use Case */
628
        $contentVersion2 = $this->createContentVersion2();
629
630
        $contentInfo = $contentVersion2->contentInfo;
631
632
        $this->permissionResolver->setCurrentUserReference($this->anonymousUser);
633
634
        $this->expectException(UnauthorizedException::class);
635
        $this->expectExceptionMessageRegExp('/\'remove\' \'content\'/');
636
637
        $this->contentService->deleteContent($contentInfo);
638
        /* END: Use Case */
639
    }
640
641
    /**
642
     * Test for the createContentDraft() method.
643
     *
644
     * @see \eZ\Publish\API\Repository\ContentService::createContentDraft()
645
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraft
646
     */
647 View Code Duplication
    public function testCreateContentDraftThrowsUnauthorizedException()
648
    {
649
        /* BEGIN: Use Case */
650
        $content = $this->createContentVersion1();
651
652
        $contentInfo = $content->contentInfo;
653
654
        $this->permissionResolver->setCurrentUserReference($this->anonymousUser);
655
656
        $this->expectException(UnauthorizedException::class);
657
        $this->expectExceptionMessageRegExp('/\'edit\' \'content\'/');
658
659
        $this->contentService->createContentDraft($contentInfo);
660
        /* END: Use Case */
661
    }
662
663
    /**
664
     * Test for the createContentDraft() method.
665
     *
666
     * @see \eZ\Publish\API\Repository\ContentService::createContentDraft($contentInfo, $versionInfo)
667
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraftWithSecondParameter
668
     */
669
    public function testCreateContentDraftThrowsUnauthorizedExceptionWithSecondParameter()
670
    {
671
        /* BEGIN: Use Case */
672
        $content = $this->createContentVersion1();
673
674
        $contentInfo = $content->contentInfo;
675
        $versionInfo = $content->getVersionInfo();
676
677
        $this->permissionResolver->setCurrentUserReference($this->anonymousUser);
678
679
        $this->expectException(UnauthorizedException::class);
680
        $this->expectExceptionMessageRegExp('/\'edit\' \'content\'/');
681
682
        $this->contentService->createContentDraft($contentInfo, $versionInfo);
683
        /* END: Use Case */
684
    }
685
686
    /**
687
     * Test for the loadContentDrafts() method.
688
     *
689
     * @see \eZ\Publish\API\Repository\ContentService::loadContentDrafts()
690
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentDrafts
691
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentDrafts
692
     */
693
    public function testLoadContentDraftsThrowsUnauthorizedException()
694
    {
695
        /* BEGIN: Use Case */
696
        $this->permissionResolver->setCurrentUserReference($this->anonymousUser);
697
698
        $this->expectException(UnauthorizedException::class);
699
        $this->expectExceptionMessageRegExp('/\'versionread\' \'content\'/');
700
701
        $this->contentService->loadContentDrafts();
702
        /* END: Use Case */
703
    }
704
705
    /**
706
     * Test for the loadContentDrafts() method.
707
     *
708
     * @see \eZ\Publish\API\Repository\ContentService::loadContentDrafts($user)
709
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentDrafts
710
     */
711 View Code Duplication
    public function testLoadContentDraftsThrowsUnauthorizedExceptionWithUser()
712
    {
713
        $this->permissionResolver->setCurrentUserReference($this->anonymousUser);
714
715
        $this->expectException(UnauthorizedException::class);
716
        $this->expectExceptionMessageRegExp('/\'versionread\' \'content\'/');
717
718
        $this->contentService->loadContentDrafts($this->administratorUser);
719
        /* END: Use Case */
720
    }
721
722
    /**
723
     * Test for the loadContentDrafts() method.
724
     *
725
     * @see \eZ\Publish\API\Repository\ContentService::loadContentDrafts($user)
726
     */
727 View Code Duplication
    public function testLoadContentDraftsThrowsUnauthorizedExceptionWithUserAndOffset()
728
    {
729
        $this->permissionResolver->setCurrentUserReference($this->anonymousUser);
730
731
        $this->expectException(UnauthorizedException::class);
732
        $this->expectExceptionMessageRegExp('/\'versionread\' \'content\'/');
733
734
        $this->contentService->loadContentDrafts($this->administratorUser, 1);
735
        /* END: Use Case */
736
    }
737
738
    /**
739
     * Test for the loadContentDrafts() method.
740
     *
741
     * @see \eZ\Publish\API\Repository\ContentService::loadContentDrafts($user)
742
     */
743 View Code Duplication
    public function testLoadContentDraftsThrowsUnauthorizedExceptionWithAllAgrumants()
744
    {
745
        $this->permissionResolver->setCurrentUserReference($this->anonymousUser);
746
747
        $this->expectException(UnauthorizedException::class);
748
        $this->expectExceptionMessageRegExp('/\'versionread\' \'content\'/');
749
750
        $this->contentService->loadContentDrafts($this->administratorUser, 1, 10);
751
        /* END: Use Case */
752
    }
753
754
    /**
755
     * Test for the updateContent() method.
756
     *
757
     * @see \eZ\Publish\API\Repository\ContentService::updateContent()
758
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContent
759
     */
760
    public function testUpdateContentThrowsUnauthorizedException()
761
    {
762
        /* BEGIN: Use Case */
763
        $draftVersion2 = $this->createContentDraftVersion2();
764
765
        $versionInfo = $draftVersion2->getVersionInfo();
766
767
        $this->permissionResolver->setCurrentUserReference($this->anonymousUser);
768
769
        // Create an update struct and modify some fields
770
        $contentUpdate = $this->contentService->newContentUpdateStruct();
771
        $contentUpdate->setField('name', 'An awesome² story about ezp.');
772
        $contentUpdate->setField('name', 'An awesome²³ story about ezp.', 'eng-GB');
773
774
        $contentUpdate->initialLanguageCode = 'eng-US';
775
776
        $this->expectException(UnauthorizedException::class);
777
        /* TODO - the `content/edit` policy should be probably needed */
778
        $this->expectExceptionMessageRegExp('/\'versionread\' \'content\'/');
779
780
        $this->contentService->updateContent($versionInfo, $contentUpdate);
781
        /* END: Use Case */
782
    }
783
784
    /**
785
     * Test for the publishVersion() method.
786
     *
787
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
788
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
789
     */
790 View Code Duplication
    public function testPublishVersionThrowsUnauthorizedException()
791
    {
792
        /* BEGIN: Use Case */
793
        $draft = $this->createContentDraftVersion1();
794
795
        $this->permissionResolver->setCurrentUserReference($this->anonymousUser);
796
797
        $this->expectException(UnauthorizedException::class);
798
        $this->expectExceptionMessageRegExp('/\'publish\' \'content\'/');
799
800
        $this->contentService->publishVersion($draft->getVersionInfo());
801
        /* END: Use Case */
802
    }
803
804
    /**
805
     * Test for the deleteVersion() method.
806
     *
807
     * @see \eZ\Publish\API\Repository\ContentService::deleteVersion()
808
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testDeleteVersion
809
     */
810 View Code Duplication
    public function testDeleteVersionThrowsUnauthorizedException()
811
    {
812
        /* BEGIN: Use Case */
813
        $draft = $this->createContentDraftVersion1();
814
815
        $this->permissionResolver->setCurrentUserReference($this->anonymousUser);
816
817
        $this->expectException(UnauthorizedException::class);
818
        $this->expectExceptionMessageRegExp('/\'versionremove\' \'content\'/');
819
820
        $this->contentService->deleteVersion($draft->getVersionInfo());
821
        /* END: Use Case */
822
    }
823
824
    /**
825
     * Test for the loadVersions() method.
826
     *
827
     * @see \eZ\Publish\API\Repository\ContentService::loadVersions()
828
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadVersions
829
     */
830 View Code Duplication
    public function testLoadVersionsThrowsUnauthorizedException()
831
    {
832
        /* BEGIN: Use Case */
833
        $contentVersion2 = $this->createContentVersion2();
834
835
        $contentInfo = $contentVersion2->contentInfo;
836
837
        $this->permissionResolver->setCurrentUserReference($this->anonymousUser);
838
839
        $this->expectException(UnauthorizedException::class);
840
        $this->expectExceptionMessageRegExp('/\'versionread\' \'content\'/');
841
842
        $this->contentService->loadVersions($contentInfo);
843
        /* END: Use Case */
844
    }
845
846
    /**
847
     * Test for the copyContent() method.
848
     *
849
     * @see \eZ\Publish\API\Repository\ContentService::copyContent()
850
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCopyContent
851
     */
852
    public function testCopyContentThrowsUnauthorizedException()
853
    {
854
        $parentLocationId = $this->generateId('location', 52);
855
856
        $locationService = $this->repository->getLocationService();
857
858
        /* BEGIN: Use Case */
859
        $contentVersion2 = $this->createMultipleLanguageContentVersion2();
860
861
        $contentInfo = $contentVersion2->contentInfo;
862
863
        $this->permissionResolver->setCurrentUserReference($this->anonymousUser);
864
865
        // Configure new target location
866
        $targetLocationCreate = $locationService->newLocationCreateStruct($parentLocationId);
867
868
        $targetLocationCreate->priority = 42;
869
        $targetLocationCreate->hidden = true;
870
        $targetLocationCreate->remoteId = '01234abcdef5678901234abcdef56789';
871
        $targetLocationCreate->sortField = Location::SORT_FIELD_NODE_ID;
872
        $targetLocationCreate->sortOrder = Location::SORT_ORDER_DESC;
873
874
        $this->expectException(UnauthorizedException::class);
875
        $this->expectExceptionMessageRegExp('/\'read\' \'content\'/');
876
877
        $this->contentService->copyContent(
878
            $contentInfo,
879
            $targetLocationCreate
880
        );
881
        /* END: Use Case */
882
    }
883
884
    /**
885
     * Test for the copyContent() method.
886
     *
887
     * @see \eZ\Publish\API\Repository\ContentService::copyContent($contentInfo, $destinationLocationCreateStruct, $versionInfo)
888
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCopyContentWithGivenVersion
889
     */
890
    public function testCopyContentThrowsUnauthorizedExceptionWithGivenVersion()
891
    {
892
        $parentLocationId = $this->generateId('location', 52);
893
894
        /* BEGIN: Use Case */
895
        $contentVersion2 = $this->createContentVersion2();
896
897
        $this->permissionResolver->setCurrentUserReference($this->anonymousUser);
898
899
        // Configure new target location
900
        $targetLocationCreate = $this->repository->getLocationService()->newLocationCreateStruct($parentLocationId);
901
902
        $targetLocationCreate->priority = 42;
903
        $targetLocationCreate->hidden = true;
904
        $targetLocationCreate->remoteId = '01234abcdef5678901234abcdef56789';
905
        $targetLocationCreate->sortField = Location::SORT_FIELD_NODE_ID;
906
        $targetLocationCreate->sortOrder = Location::SORT_ORDER_DESC;
907
908
        $this->expectException(UnauthorizedException::class);
909
        $this->expectExceptionMessageRegExp('/\'versionread\' \'content\'/');
910
911
        $this->contentService->copyContent(
912
            $contentVersion2->contentInfo,
913
            $targetLocationCreate,
914
            $this->contentService->loadVersionInfo($contentVersion2->contentInfo, 1)
915
        );
916
        /* END: Use Case */
917
    }
918
919
    /**
920
     * Test for the loadRelations() method.
921
     *
922
     * @see \eZ\Publish\API\Repository\ContentService::loadRelations()
923
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadRelations
924
     */
925 View Code Duplication
    public function testLoadRelationsThrowsUnauthorizedException()
926
    {
927
        /* BEGIN: Use Case */
928
        $mediaEditor = $this->createMediaUserVersion1();
929
930
        $setupRemoteId = '241d538ce310074e602f29f49e44e938';
931
932
        $versionInfo = $this->contentService->loadVersionInfo(
933
            $this->contentService->loadContentInfoByRemoteId(
934
                $setupRemoteId
935
            )
936
        );
937
938
        $this->permissionResolver->setCurrentUserReference($mediaEditor);
939
940
        $this->expectException(UnauthorizedException::class);
941
        $this->expectExceptionMessageRegExp('/\'read\' \'content\'/');
942
943
        $this->contentService->loadRelations($versionInfo);
944
        /* END: Use Case */
945
    }
946
947
    /**
948
     * Test for the loadRelations() method.
949
     *
950
     * @see \eZ\Publish\API\Repository\ContentService::loadRelations()
951
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadRelations
952
     */
953 View Code Duplication
    public function testLoadRelationsForDraftVersionThrowsUnauthorizedException()
954
    {
955
        /* BEGIN: Use Case */
956
        $draft = $this->createContentDraftVersion1();
957
958
        $this->permissionResolver->setCurrentUserReference($this->anonymousUser);
959
960
        $this->expectException(UnauthorizedException::class);
961
        $this->expectExceptionMessageRegExp('/\'versionread\' \'content\'/');
962
963
        $this->contentService->loadRelations($draft->versionInfo);
964
        /* END: Use Case */
965
    }
966
967
    /**
968
     * Test for the loadReverseRelations() method.
969
     *
970
     * @see \eZ\Publish\API\Repository\ContentService::loadReverseRelations()
971
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadReverseRelations
972
     */
973
    public function testLoadReverseRelationsThrowsUnauthorizedException()
974
    {
975
        /* BEGIN: Use Case */
976
        $mediaEditor = $this->createMediaUserVersion1();
977
978
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
979
980
        $contentInfo = $this->contentService->loadContentInfoByRemoteId($mediaRemoteId);
981
982
        $this->permissionResolver->setCurrentUserReference($mediaEditor);
983
984
        $this->expectException(UnauthorizedException::class);
985
        $this->expectExceptionMessageRegExp('/\'reverserelatedlist\' \'content\'/');
986
987
        $this->contentService->loadReverseRelations($contentInfo);
988
        /* END: Use Case */
989
    }
990
991
    /**
992
     * Test for the addRelation() method.
993
     *
994
     * @see \eZ\Publish\API\Repository\ContentService::addRelation()
995
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testAddRelation
996
     */
997 View Code Duplication
    public function testAddRelationThrowsUnauthorizedException()
998
    {
999
        /* BEGIN: Use Case */
1000
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
1001
1002
        $draft = $this->createContentDraftVersion1();
1003
1004
        $versionInfo = $draft->getVersionInfo();
1005
1006
        $media = $this->contentService->loadContentInfoByRemoteId($mediaRemoteId);
1007
1008
        $this->permissionResolver->setCurrentUserReference($this->anonymousUser);
1009
1010
        $this->expectException(UnauthorizedException::class);
1011
        $this->expectExceptionMessageRegExp('/\'versionread\' \'content\'/');
1012
1013
        $this->contentService->addRelation(
1014
            $versionInfo,
1015
            $media
1016
        );
1017
        /* END: Use Case */
1018
    }
1019
1020
    /**
1021
     * Test for the deleteRelation() method.
1022
     *
1023
     * @see \eZ\Publish\API\Repository\ContentService::deleteRelation()
1024
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testDeleteRelation
1025
     */
1026 View Code Duplication
    public function testDeleteRelationThrowsUnauthorizedException()
1027
    {
1028
        /* BEGIN: Use Case */
1029
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
1030
        $demoDesignRemoteId = '8b8b22fe3c6061ed500fbd2b377b885f';
1031
1032
        $draft = $this->createContentDraftVersion1();
1033
1034
        $versionInfo = $draft->getVersionInfo();
1035
1036
        $media = $this->contentService->loadContentInfoByRemoteId($mediaRemoteId);
1037
        $demoDesign = $this->contentService->loadContentInfoByRemoteId($demoDesignRemoteId);
1038
1039
        // Establish some relations
1040
        $this->contentService->addRelation($draft->getVersionInfo(), $media);
1041
        $this->contentService->addRelation($draft->getVersionInfo(), $demoDesign);
1042
1043
        $this->permissionResolver->setCurrentUserReference($this->anonymousUser);
1044
1045
        $this->expectException(UnauthorizedException::class);
1046
        $this->expectExceptionMessageRegExp('/\'versionread\' \'content\'/');
1047
1048
        $this->contentService->deleteRelation($versionInfo, $media);
1049
        /* END: Use Case */
1050
    }
1051
1052
    /**
1053
     * Creates a pseudo editor with a limitation to objects in the "Media/Images"
1054
     * subtree.
1055
     *
1056
     * @return \eZ\Publish\API\Repository\Values\User\User
1057
     */
1058
    private function createAnonymousWithEditorRole()
1059
    {
1060
        /* BEGIN: Use Case */
1061
        $roleService = $this->repository->getRoleService();
1062
1063
        $user = $this->anonymousUser;
1064
        $role = $roleService->loadRoleByIdentifier('Editor');
1065
1066
        // Assign "Editor" role with limitation to "Media/Images"
1067
        $roleService->assignRoleToUser(
1068
            $role,
1069
            $user,
1070
            new \eZ\Publish\API\Repository\Values\User\Limitation\SubtreeLimitation(
1071
                [
1072
                    'limitationValues' => ['/1/43/51/'],
1073
                ]
1074
            )
1075
        );
1076
        /* END: Use Case */
1077
1078
        return $this->userService->loadUser($user->id);
1079
    }
1080
1081
    /**
1082
     * Test that for an user that doesn't have access (read permissions) to an
1083
     * related object, executing loadRelations() would not throw any exception,
1084
     * only that the non-readable related object(s) won't be loaded.
1085
     *
1086
     * @see \eZ\Publish\API\Repository\ContentService::loadRelations()
1087
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testAddRelation
1088
     */
1089
    public function testLoadRelationsWithUnauthorizedRelations()
1090
    {
1091
        /* BEGIN: Use Case */
1092
        $mainLanguage = 'eng-GB';
1093
1094
        $contentTypeService = $this->repository->getContentTypeService();
1095
        $locationService = $this->repository->getLocationService();
1096
        $sectionService = $this->repository->getSectionService();
1097
1098
        // set the current user as admin to create the environment to test
1099
        $this->permissionResolver->setCurrentUserReference($this->administratorUser);
1100
1101
        // create section
1102
        // since anonymous users have their read permissions to specific sections
1103
        // the created section will be non-readable to them
1104
        $sectionCreate = $sectionService->newSectionCreateStruct();
1105
        $sectionCreate->identifier = 'private';
1106
        $sectionCreate->name = 'Private Section';
1107
        $section = $sectionService->createSection($sectionCreate);
1108
1109
        // create objects for testing
1110
        // here we will create 4 objects which 2 will be readable by an anonymous
1111
        // user, and the other 2 wont these last 2 will go to a private section
1112
        // where anonymous can't read, just like:
1113
        // readable object 1 -> /Main Folder
1114
        // readable object 2 -> /Main Folder/Available Folder
1115
        // non-readable object 1 -> /Restricted Folder
1116
        // non-readable object 2 -> /Restricted Folder/Unavailable Folder
1117
        //
1118
        // here is created - readable object 1 -> /Main Folder
1119
        $mainFolderCreate = $this->contentService->newContentCreateStruct(
1120
            $contentTypeService->loadContentTypeByIdentifier('folder'),
1121
            $mainLanguage
1122
        );
1123
        $mainFolderCreate->setField('name', 'Main Folder');
1124
        $mainFolder = $this->contentService->publishVersion(
1125
            $this->contentService->createContent(
1126
                $mainFolderCreate,
1127
                [$locationService->newLocationCreateStruct(2)]
1128
            )->versionInfo
1129
        );
1130
1131
        // here is created readable object 2 -> /Main Folder/Available Folder
1132
        $availableFolderCreate = $this->contentService->newContentCreateStruct(
1133
            $contentTypeService->loadContentTypeByIdentifier('folder'),
1134
            $mainLanguage
1135
        );
1136
        $availableFolderCreate->setField('name', 'Avaliable Folder');
1137
        $availableFolder = $this->contentService->publishVersion(
1138
            $this->contentService->createContent(
1139
                $availableFolderCreate,
1140
                [$locationService->newLocationCreateStruct($mainFolder->contentInfo->mainLocationId)]
1141
            )->versionInfo
1142
        );
1143
1144
        // here is created the non-readable object 1 -> /Restricted Folder
1145
        $restrictedFolderCreate = $this->contentService->newContentCreateStruct(
1146
            $contentTypeService->loadContentTypeByIdentifier('folder'),
1147
            $mainLanguage
1148
        );
1149
        $restrictedFolderCreate->setField('name', 'Restricted Folder');
1150
        $restrictedFolderCreate->sectionId = $section->id;
1151
        $restrictedFolder = $this->contentService->publishVersion(
1152
            $this->contentService->createContent(
1153
                $restrictedFolderCreate,
1154
                [$locationService->newLocationCreateStruct(2)]
1155
            )->versionInfo
1156
        );
1157
1158
        // here is created non-readable object 2 -> /Restricted Folder/Unavailable Folder
1159
        $unavailableFolderCreate = $this->contentService->newContentCreateStruct(
1160
            $contentTypeService->loadContentTypeByIdentifier('folder'),
1161
            $mainLanguage
1162
        );
1163
        $unavailableFolderCreate->setField('name', 'Unavailable Folder');
1164
        $unavailableFolder = $this->contentService->publishVersion(
1165
            $this->contentService->createContent(
1166
                $unavailableFolderCreate,
1167
                [$locationService->newLocationCreateStruct($restrictedFolder->contentInfo->mainLocationId)]
1168
            )->versionInfo
1169
        );
1170
1171
        // this will be our test object, which will have all the relations (as source)
1172
        // and it is readable by the anonymous user
1173
        $testFolderCreate = $this->contentService->newContentCreateStruct(
1174
            $contentTypeService->loadContentTypeByIdentifier('folder'),
1175
            $mainLanguage
1176
        );
1177
        $testFolderCreate->setField('name', 'Test Folder');
1178
        $testFolderDraft = $this->contentService->createContent(
1179
            $testFolderCreate,
1180
            [$locationService->newLocationCreateStruct(2)]
1181
        )->versionInfo;
1182
1183
        // add relations to test folder (as source)
1184
        // the first 2 will be read by the user
1185
        // and the other 2 wont
1186
        //
1187
        // create relation from Test Folder to Main Folder
1188
        $mainRelation = $this->contentService->addRelation(
1189
            $testFolderDraft,
1190
            $mainFolder->getVersionInfo()->getContentInfo()
1191
        );
1192
        // create relation from Test Folder to Available Folder
1193
        $availableRelation = $this->contentService->addRelation(
1194
            $testFolderDraft,
1195
            $availableFolder->getVersionInfo()->getContentInfo()
1196
        );
1197
        // create relation from Test Folder to Restricted Folder
1198
        $this->contentService->addRelation(
1199
            $testFolderDraft,
1200
            $restrictedFolder->getVersionInfo()->getContentInfo()
1201
        );
1202
        //create relation from Test Folder to Unavailable Folder
1203
        $this->contentService->addRelation(
1204
            $testFolderDraft,
1205
            $unavailableFolder->getVersionInfo()->getContentInfo()
1206
        );
1207
1208
        // publish Test Folder
1209
        $testFolder = $this->contentService->publishVersion($testFolderDraft);
1210
1211
        // set the current user to be an anonymous user since we want to test that
1212
        // if the user doesn't have access to an related object that object wont
1213
        // be loaded and no exception will be thrown
1214
        $this->permissionResolver->setCurrentUserReference($this->anonymousUser);
1215
1216
        // finaly load relations ( verify no exception is thrown )
1217
        $actualRelations = $this->contentService->loadRelations($testFolder->getVersionInfo());
1218
1219
        /* END: Use case */
1220
1221
        // assert results
1222
        // verify that the only expected relations are from the 2 readable objects
1223
        // Main Folder and Available Folder
1224
        $expectedRelations = [
1225
            $mainRelation->destinationContentInfo->id => $mainRelation,
1226
            $availableRelation->destinationContentInfo->id => $availableRelation,
1227
        ];
1228
1229
        // assert there are as many expected relations as actual ones
1230
        $this->assertEquals(
1231
            count($expectedRelations),
1232
            count($actualRelations),
1233
            "Expected '" . count($expectedRelations)
1234
            . "' relations found '" . count($actualRelations) . "'"
1235
        );
1236
1237
        // assert each relation
1238
        foreach ($actualRelations as $relation) {
1239
            $destination = $relation->destinationContentInfo;
1240
            $expected = $expectedRelations[$destination->id]->destinationContentInfo;
1241
            $this->assertNotEmpty($expected, "Non expected relation with '{$destination->id}' id found");
1242
            $this->assertEquals(
1243
                $expected->id,
1244
                $destination->id,
1245
                "Expected relation with '{$expected->id}' id found '{$destination->id}' id"
1246
            );
1247
            $this->assertEquals(
1248
                $expected->name,
1249
                $destination->name,
1250
                "Expected relation with '{$expected->name}' name found '{$destination->name}' name"
1251
            );
1252
1253
            // remove from list
1254
            unset($expectedRelations[$destination->id]);
1255
        }
1256
1257
        // verify all expected relations were found
1258
        $this->assertEquals(
1259
            0,
1260
            count($expectedRelations),
1261
            "Expected to find '" . (count($expectedRelations) + count($actualRelations))
1262
            . "' relations found '" . count($actualRelations) . "'"
1263
        );
1264
    }
1265
1266
    /**
1267
     * Test copying Content to the authorized Location (limited by policies).
1268
     */
1269
    public function testCopyContentToAuthorizedLocation()
1270
    {
1271
        $locationService = $this->repository->getLocationService();
1272
        $roleService = $this->repository->getRoleService();
1273
1274
        // Create and publish folders for the test case
1275
        $folderDraft = $this->createContentDraft('folder', 2, ['name' => 'Folder1']);
1276
        $this->contentService->publishVersion($folderDraft->versionInfo);
1277
        $authorizedFolderDraft = $this->createContentDraft('folder', 2, ['name' => 'AuthorizedFolder']);
1278
        $authorizedFolder = $this->contentService->publishVersion($authorizedFolderDraft->versionInfo);
1279
1280
        // Prepare Role for the test case
1281
        $roleIdentifier = 'authorized_folder';
1282
        $roleCreateStruct = $roleService->newRoleCreateStruct($roleIdentifier);
1283
        $locationLimitation = new LocationLimitation(
1284
            ['limitationValues' => [$authorizedFolder->contentInfo->mainLocationId]]
1285
        );
1286
        $roleCreateStruct->addPolicy($roleService->newPolicyCreateStruct('content', 'read'));
1287
        $roleCreateStruct->addPolicy($roleService->newPolicyCreateStruct('content', 'versionread'));
1288
        $roleCreateStruct->addPolicy($roleService->newPolicyCreateStruct('content', 'manage_locations'));
1289
1290
        $policyCreateStruct = $roleService->newPolicyCreateStruct('content', 'create');
1291
        $policyCreateStruct->addLimitation($locationLimitation);
1292
        $roleCreateStruct->addPolicy($policyCreateStruct);
1293
1294
        $roleDraft = $roleService->createRole($roleCreateStruct);
1295
        $roleService->publishRoleDraft($roleDraft);
1296
1297
        // Create a user with that Role
1298
        $user = $this->createCustomUserVersion1('Users', $roleIdentifier);
1299
        $this->permissionResolver->setCurrentUserReference($user);
1300
1301
        // Test copying Content to the authorized Location
1302
        $this->contentService->copyContent(
1303
            $authorizedFolder->contentInfo,
1304
            $locationService->newLocationCreateStruct(
1305
                $authorizedFolder->contentInfo->mainLocationId
1306
            )
1307
        );
1308
    }
1309
1310
    /**
1311
     * Test copying Content to the authorized Location (limited by policies).
1312
     */
1313
    public function testCopyContentToAuthorizedLocationWithSubtreeLimitation()
1314
    {
1315
        $locationService = $this->repository->getLocationService();
1316
1317
        // Create and publish folders for the test case
1318
        $folderDraft = $this->createContentDraft('folder', 2, ['name' => 'Folder1']);
1319
        $this->contentService->publishVersion($folderDraft->versionInfo);
1320
        $authorizedFolderDraft = $this->createContentDraft('folder', 2, ['name' => 'AuthorizedFolder']);
1321
        $authorizedFolder = $this->contentService->publishVersion($authorizedFolderDraft->versionInfo);
1322
1323
        // Prepare Role for the test case
1324
        $roleIdentifier = 'authorized_subree';
1325
        $subtreeLimitation = new SubtreeLimitation(
1326
            ['limitationValues' => ['/1/2']]
1327
        );
1328
        $policiesData = [
1329
            [
1330
                'module' => 'content',
1331
                'function' => 'read',
1332
                'limitations' => [$subtreeLimitation],
1333
            ],
1334
            [
1335
                'module' => 'content',
1336
                'function' => 'versionread',
1337
                'limitations' => [$subtreeLimitation],
1338
            ],
1339
            [
1340
                'module' => 'content',
1341
                'function' => 'create',
1342
                'limitations' => [$subtreeLimitation],
1343
            ],
1344
            [
1345
                'module' => 'content',
1346
                'function' => 'manage_locations',
1347
            ],
1348
        ];
1349
1350
        $this->createRoleWithPolicies($roleIdentifier, $policiesData);
1351
1352
        // Create a user with that Role
1353
        $user = $this->createCustomUserVersion1('Users', $roleIdentifier);
1354
        $this->permissionResolver->setCurrentUserReference($user);
1355
1356
        // Test copying Content to the authorized Location
1357
        $this->contentService->copyContent(
1358
            $authorizedFolder->contentInfo,
1359
            $locationService->newLocationCreateStruct(
1360
                $authorizedFolder->contentInfo->mainLocationId
1361
            )
1362
        );
1363
    }
1364
1365
    /**
1366
     * @return \eZ\Publish\API\Repository\Values\Content\ContentInfo
1367
     *
1368
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
1369
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
1370
     */
1371
    private function getContentInfoForAnonymousUser(): ContentInfo
1372
    {
1373
        $anonymousUserId = $this->generateId('user', 10);
1374
1375
        return $this->contentService->loadContentInfo($anonymousUserId);
1376
    }
1377
1378
    /**
1379
     * @return mixed
1380
     */
1381
    private function setRestrictedEditorUser()
1382
    {
1383
        return $this->permissionResolver->setCurrentUserReference($this->createAnonymousWithEditorRole());
1384
    }
1385
}
1386