Completed
Push — impl-EZP-26000-permission-look... ( ee4870 )
by
unknown
15:38
created

PermissionTest::testCanUserSimple()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 18
Code Lines 11

Duplication

Lines 18
Ratio 100 %

Importance

Changes 0
Metric Value
dl 18
loc 18
c 0
b 0
f 0
cc 1
eloc 11
nc 1
nop 2
rs 9.4285
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\Core\Repository\Tests\Service\Mock;
8
9
use eZ\Publish\API\Repository\Repository;
10
use eZ\Publish\API\Repository\Values\User\PermissionInfo;
11
use eZ\Publish\Core\Repository\Values\User\Policy;
12
use eZ\Publish\Core\Repository\Permission\PermissionResolver;
13
use eZ\Publish\Core\Repository\Values\User\UserReference;
14
use eZ\Publish\Core\Base\Exceptions\NotFound\LimitationNotFoundException;
15
use eZ\Publish\Core\Repository\Tests\Service\Mock\Base as BaseServiceMockTest;
16
use eZ\Publish\SPI\Persistence\User\RoleAssignment;
17
use eZ\Publish\SPI\Persistence\User\Role;
18
use eZ\Publish\SPI\Persistence\User\Policy as SPIPolicy;
19
use eZ\Publish\API\Repository\Values\User\Limitation;
20
21
/**
22
 * Mock test case for PermissionResolver.
23
 */
24
class PermissionTest extends BaseServiceMockTest
25
{
26
    public function providerForTestHasAccessReturnsTrue()
27
    {
28
        return array(
29
            array(
30
                array(
31
                    25 => $this->createRole(
32
                        array(
33
                            array('dummy-module', 'dummy-function', 'dummy-limitation'),
34
                            array('dummy-module2', 'dummy-function2', 'dummy-limitation2'),
35
                        ),
36
                        25
37
                    ),
38
                    26 => $this->createRole(
39
                        array(
40
                            array('*', 'dummy-function', 'dummy-limitation'),
41
                        ),
42
                        26
43
                    ),
44
                ),
45
                array(
46
                    new RoleAssignment(
47
                        array(
48
                            'roleId' => 25,
49
                        )
50
                    ),
51
                    new RoleAssignment(
52
                        array(
53
                            'roleId' => 26,
54
                        )
55
                    ),
56
                ),
57
            ),
58
            array(
59
                array(
60
                    27 => $this->createRole(
61
                        array(
62
                            array('test-module', '*', 'dummy-limitation'),
63
                        ),
64
                        27
65
                    ),
66
                ),
67
                array(
68
                    new RoleAssignment(
69
                        array(
70
                            'roleId' => 27,
71
                        )
72
                    ),
73
                ),
74
            ),
75
            array(
76
                array(
77
                    28 => $this->createRole(
78
                        array(
79
                            array('test-module', 'test-function', '*'),
80
                        ),
81
                        28
82
                    ),
83
                ),
84
                array(
85
                    new RoleAssignment(
86
                        array(
87
                            'roleId' => 28,
88
                        )
89
                    ),
90
                ),
91
            ),
92
        );
93
    }
94
95
    /**
96
     * Test for the hasAccess() method.
97
     *
98
     * @dataProvider providerForTestHasAccessReturnsTrue
99
     */
100 View Code Duplication
    public function testHasAccessReturnsTrue(array $roles, array $roleAssignments)
101
    {
102
        /** @var $userHandlerMock \PHPUnit_Framework_MockObject_MockObject */
103
        $userHandlerMock = $this->getPersistenceMock()->userHandler();
104
        $userReferenceMock = $this->getUserReferenceMock();
105
        $mockedService = $this->getPermissionResolverMock(null);
0 ignored issues
show
Documentation introduced by
null is of type null, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
106
107
        $userReferenceMock
108
            ->expects($this->once())
109
            ->method('getUserId')
110
            ->will($this->returnValue(10));
111
112
        $userHandlerMock
113
            ->expects($this->once())
114
            ->method('loadRoleAssignmentsByGroupId')
115
            ->with($this->equalTo(10), $this->equalTo(true))
116
            ->will($this->returnValue($roleAssignments));
117
118
        foreach ($roleAssignments as $at => $roleAssignment) {
119
            $userHandlerMock
120
                ->expects($this->at($at + 1))
121
                ->method('loadRole')
122
                ->with($roleAssignment->roleId)
123
                ->will($this->returnValue($roles[$roleAssignment->roleId]));
124
        }
125
126
        $result = $mockedService->hasAccess('test-module', 'test-function');
127
128
        self::assertEquals(true, $result);
129
    }
130
131
    public function providerForTestHasAccessReturnsFalse()
132
    {
133
        return array(
134
            array(array(), array()),
135
            array(
136
                array(
137
                    29 => $this->createRole(
138
                        array(
139
                            array('dummy-module', 'dummy-function', 'dummy-limitation'),
140
                        ),
141
                        29
142
                    ),
143
                ),
144
                array(
145
                    new RoleAssignment(
146
                        array(
147
                            'roleId' => 29,
148
                        )
149
                    ),
150
                ),
151
            ),
152
            array(
153
                array(
154
                    30 => $this->createRole(
155
                        array(
156
                            array('test-module', 'dummy-function', 'dummy-limitation'),
157
                        ),
158
                        30
159
                    ),
160
                ),
161
                array(
162
                    new RoleAssignment(
163
                        array(
164
                            'roleId' => 30,
165
                        )
166
                    ),
167
                ),
168
            ),
169
        );
170
    }
171
172
    /**
173
     * Test for the hasAccess() method.
174
     *
175
     * @dataProvider providerForTestHasAccessReturnsFalse
176
     */
177 View Code Duplication
    public function testHasAccessReturnsFalse(array $roles, array $roleAssignments)
178
    {
179
        /** @var $userHandlerMock \PHPUnit_Framework_MockObject_MockObject */
180
        $userHandlerMock = $this->getPersistenceMock()->userHandler();
181
        $userReferenceMock = $this->getUserReferenceMock();
182
        $service = $this->getPermissionResolverMock(null);
0 ignored issues
show
Documentation introduced by
null is of type null, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
183
184
        $userReferenceMock
185
            ->expects($this->once())
186
            ->method('getUserId')
187
            ->will($this->returnValue(10));
188
189
        $userHandlerMock
190
            ->expects($this->once())
191
            ->method('loadRoleAssignmentsByGroupId')
192
            ->with($this->equalTo(10), $this->equalTo(true))
193
            ->will($this->returnValue($roleAssignments));
194
195
        foreach ($roleAssignments as $at => $roleAssignment) {
196
            $userHandlerMock
197
                ->expects($this->at($at + 1))
198
                ->method('loadRole')
199
                ->with($roleAssignment->roleId)
200
                ->will($this->returnValue($roles[$roleAssignment->roleId]));
201
        }
202
203
        $result = $service->hasAccess('test-module', 'test-function');
204
205
        self::assertEquals(false, $result);
206
    }
207
208
    /**
209
     * Test for the sudo() & hasAccess() method.
210
     */
211
    public function testHasAccessReturnsFalseButSudoSoTrue()
212
    {
213
        /** @var $userHandlerMock \PHPUnit_Framework_MockObject_MockObject */
214
        $userHandlerMock = $this->getPersistenceMock()->userHandler();
215
        $service = $this->getPermissionResolverMock(null);
0 ignored issues
show
Documentation introduced by
null is of type null, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
216
        $repositoryMock = $this->getRepositoryMock();
217
        $repositoryMock
218
            ->expects($this->any())
219
            ->method('getPermissionResolver')
220
            ->will($this->returnValue($service));
221
222
        $userHandlerMock
223
            ->expects($this->never())
224
            ->method($this->anything());
225
226
        $result = $service->sudo(
227
            function (Repository $repo) {
228
                return $repo->hasAccess('test-module', 'test-function');
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repository\Repository::hasAccess() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::hasAccess() instead.

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...
229
            },
230
            $repositoryMock
231
        );
232
233
        self::assertEquals(true, $result);
234
    }
235
236
    /**
237
     * @return array
238
     */
239 View Code Duplication
    public function providerForTestHasAccessReturnsPermissionSets()
240
    {
241
        return array(
242
            array(
243
                array(
244
                    31 => $this->createRole(
245
                        array(
246
                            array('test-module', 'test-function', 'test-limitation'),
247
                        ),
248
                        31
249
                    ),
250
                ),
251
                array(
252
                    new RoleAssignment(
253
                        array(
254
                            'roleId' => 31,
255
                        )
256
                    ),
257
                ),
258
            ),
259
            array(
260
                array(
261
                    31 => $this->createRole(
262
                        array(
263
                            array('test-module', 'test-function', 'test-limitation'),
264
                        ),
265
                        31
266
                    ),
267
                    32 => $this->createRole(
268
                        array(
269
                            array('test-module', 'test-function', 'test-limitation2'),
270
                        ),
271
                        32
272
                    ),
273
                ),
274
                array(
275
                    new RoleAssignment(
276
                        array(
277
                            'roleId' => 31,
278
                        )
279
                    ),
280
                    new RoleAssignment(
281
                        array(
282
                            'roleId' => 32,
283
                        )
284
                    ),
285
                ),
286
            ),
287
        );
288
    }
289
290
    /**
291
     * Test for the hasAccess() method.
292
     *
293
     * @dataProvider providerForTestHasAccessReturnsPermissionSets
294
     */
295
    public function testHasAccessReturnsPermissionSets(array $roles, array $roleAssignments)
296
    {
297
        /** @var $userHandlerMock \PHPUnit_Framework_MockObject_MockObject */
298
        $userHandlerMock = $this->getPersistenceMock()->userHandler();
299
        $roleDomainMapper = $this->getRoleDomainMapperMock(['buildDomainPolicyObject']);
300
        $permissionResolverMock = $this->getPermissionResolverMock(['getCurrentUserReference']);
301
302
        $permissionResolverMock
303
            ->expects($this->once())
304
            ->method('getCurrentUserReference')
305
            ->will($this->returnValue(new UserReference(14)));
306
307
        $userHandlerMock
308
            ->expects($this->once())
309
            ->method('loadRoleAssignmentsByGroupId')
310
            ->with($this->isType('integer'), $this->equalTo(true))
311
            ->will($this->returnValue($roleAssignments));
312
313
        foreach ($roleAssignments as $at => $roleAssignment) {
314
            $userHandlerMock
315
                ->expects($this->at($at + 1))
316
                ->method('loadRole')
317
                ->with($roleAssignment->roleId)
318
                ->will($this->returnValue($roles[$roleAssignment->roleId]));
319
        }
320
321
        $permissionSets = array();
322
        $count = 0;
323
        /* @var $roleAssignments \eZ\Publish\SPI\Persistence\User\RoleAssignment[] */
324
        foreach ($roleAssignments as $i => $roleAssignment) {
325
            $permissionSet = array('limitation' => null);
326
            foreach ($roles[$roleAssignment->roleId]->policies as $k => $policy) {
327
                $policyName = 'policy-' . $i . '-' . $k;
328
                $return = $this->returnValue($policyName);
329
                $permissionSet['policies'][] = $policyName;
330
331
                $roleDomainMapper
332
                    ->expects($this->at($count++))
333
                    ->method('buildDomainPolicyObject')
334
                    ->with($policy)
335
                    ->will($return);
336
            }
337
338
            if (!empty($permissionSet['policies'])) {
339
                $permissionSets[] = $permissionSet;
340
            }
341
        }
342
343
        /* @var $repositoryMock \eZ\Publish\Core\Repository\Repository */
344
        self::assertEquals(
345
            $permissionSets,
346
            $permissionResolverMock->hasAccess('test-module', 'test-function')
347
        );
348
    }
349
350
    /**
351
     * @return array
352
     */
353 View Code Duplication
    public function providerForTestHasAccessReturnsException()
354
    {
355
        return array(
356
            array(
357
                array(
358
                    31 => $this->createRole(
359
                        array(
360
                            array('test-module', 'test-function', 'notfound'),
361
                        ),
362
                        31
363
                    ),
364
                ),
365
                array(
366
                    new RoleAssignment(
367
                        array(
368
                            'roleId' => 31,
369
                        )
370
                    ),
371
                ),
372
            ),
373
            array(
374
                array(
375
                    31 => $this->createRole(
376
                        array(
377
                            array('test-module', 'test-function', 'test-limitation'),
378
                        ),
379
                        31
380
                    ),
381
                    32 => $this->createRole(
382
                        array(
383
                            array('test-module', 'test-function', 'notfound'),
384
                        ),
385
                        32
386
                    ),
387
                ),
388
                array(
389
                    new RoleAssignment(
390
                        array(
391
                            'roleId' => 31,
392
                        )
393
                    ),
394
                    new RoleAssignment(
395
                        array(
396
                            'roleId' => 32,
397
                        )
398
                    ),
399
                ),
400
            ),
401
        );
402
    }
403
404
    /**
405
     * Test for the hasAccess() method.
406
     *
407
     * @dataProvider providerForTestHasAccessReturnsException
408
     * @expectedException \eZ\Publish\Core\Base\Exceptions\NotFound\LimitationNotFoundException
409
     */
410
    public function testHasAccessReturnsException(array $roles, array $roleAssignments)
411
    {
412
        /** @var $userHandlerMock \PHPUnit_Framework_MockObject_MockObject */
413
        $userHandlerMock = $this->getPersistenceMock()->userHandler();
414
        $roleDomainMapper = $this->getRoleDomainMapperMock();
415
        $permissionResolverMock = $this->getPermissionResolverMock(['getCurrentUserReference']);
416
417
        $permissionResolverMock
418
            ->expects($this->once())
419
            ->method('getCurrentUserReference')
420
            ->will($this->returnValue(new UserReference(14)));
421
422
        $userHandlerMock
423
            ->expects($this->once())
424
            ->method('loadRoleAssignmentsByGroupId')
425
            ->with($this->isType('integer'), $this->equalTo(true))
426
            ->will($this->returnValue($roleAssignments));
427
428
        foreach ($roleAssignments as $at => $roleAssignment) {
429
            $userHandlerMock
430
                ->expects($this->at($at + 1))
431
                ->method('loadRole')
432
                ->with($roleAssignment->roleId)
433
                ->will($this->returnValue($roles[$roleAssignment->roleId]));
434
        }
435
436
        $count = 0;
437
        /* @var $roleAssignments \eZ\Publish\SPI\Persistence\User\RoleAssignment[] */
438
        foreach ($roleAssignments as $i => $roleAssignment) {
439
            $permissionSet = array('limitation' => null);
440
            foreach ($roles[$roleAssignment->roleId]->policies as $k => $policy) {
441
                $policyName = 'policy-' . $i . '-' . $k;
442
                if ($policy->limitations === 'notfound') {
443
                    $return = $this->throwException(new LimitationNotFoundException('notfound'));
444
                } else {
445
                    $return = $this->returnValue($policyName);
446
                    $permissionSet['policies'][] = $policyName;
447
                }
448
449
                $roleDomainMapper
450
                    ->expects($this->at($count++))
451
                    ->method('buildDomainPolicyObject')
452
                    ->with($policy)
453
                    ->will($return);
454
455
                if ($policy->limitations === 'notfound') {
456
                    break 2;// no more execution after exception
457
                }
458
            }
459
        }
460
461
        $permissionResolverMock->hasAccess('test-module', 'test-function');
462
    }
463
464 View Code Duplication
    public function providerForTestHasAccessReturnsPermissionSetsWithRoleLimitation()
465
    {
466
        return array(
467
            array(
468
                array(
469
                    32 => $this->createRole(
470
                        array(
471
                            array('test-module', 'test-function', 'test-limitation'),
472
                        ),
473
                        32
474
                    ),
475
                ),
476
                array(
477
                    new RoleAssignment(
478
                        array(
479
                            'roleId' => 32,
480
                            'limitationIdentifier' => 'test-role-limitation',
481
                            'values' => array('test-role-limitation-value'),
482
                        )
483
                    ),
484
                ),
485
            ),
486
            array(
487
                array(
488
                    33 => $this->createRole(array(array('*', '*', '*')), 33),
489
                ),
490
                array(
491
                    new RoleAssignment(
492
                        array(
493
                            'roleId' => 33,
494
                            'limitationIdentifier' => 'test-role-limitation',
495
                            'values' => array('test-role-limitation-value'),
496
                        )
497
                    ),
498
                ),
499
            ),
500
        );
501
    }
502
503
    /**
504
     * Test for the hasAccess() method.
505
     *
506
     * @dataProvider providerForTestHasAccessReturnsPermissionSetsWithRoleLimitation
507
     */
508
    public function testHasAccessReturnsPermissionSetsWithRoleLimitation(array $roles, array $roleAssignments)
509
    {
510
        /** @var $userHandlerMock \PHPUnit_Framework_MockObject_MockObject */
511
        $userHandlerMock = $this->getPersistenceMock()->userHandler();
512
        $limitationTypeMock = $this->getMock('eZ\\Publish\\SPI\\Limitation\\Type');
513
        $limitationService = $this->getLimitationServiceMock();
514
        $roleDomainMapper = $this->getRoleDomainMapperMock();
515
        $permissionResolverMock = $this->getPermissionResolverMock(['getCurrentUserReference']);
516
517
        $permissionResolverMock
518
            ->expects($this->once())
519
            ->method('getCurrentUserReference')
520
            ->will($this->returnValue(new UserReference(14)));
521
522
        $userHandlerMock
523
            ->expects($this->once())
524
            ->method('loadRoleAssignmentsByGroupId')
525
            ->with($this->isType('integer'), $this->equalTo(true))
526
            ->will($this->returnValue($roleAssignments));
527
528
        foreach ($roleAssignments as $at => $roleAssignment) {
529
            $userHandlerMock
530
                ->expects($this->at($at + 1))
531
                ->method('loadRole')
532
                ->with($roleAssignment->roleId)
533
                ->will($this->returnValue($roles[$roleAssignment->roleId]));
534
        }
535
536
        $permissionSets = array();
537
        /** @var $roleAssignments \eZ\Publish\SPI\Persistence\User\RoleAssignment[] */
538
        foreach ($roleAssignments as $i => $roleAssignment) {
539
            $permissionSet = array();
540
            foreach ($roles[$roleAssignment->roleId]->policies as $k => $policy) {
541
                $policyName = "policy-{$i}-{$k}";
542
                $permissionSet['policies'][] = $policyName;
543
                $roleDomainMapper
544
                    ->expects($this->at($k))
545
                    ->method('buildDomainPolicyObject')
546
                    ->with($policy)
547
                    ->will($this->returnValue($policyName));
548
            }
549
550
            $permissionSet['limitation'] = "limitation-{$i}";
551
            $limitationTypeMock
552
                ->expects($this->at($i))
553
                ->method('buildValue')
554
                ->with($roleAssignment->values)
555
                ->will($this->returnValue($permissionSet['limitation']));
556
            $limitationService
557
                ->expects($this->any())
558
                ->method('getLimitationType')
559
                ->with($roleAssignment->limitationIdentifier)
560
                ->will($this->returnValue($limitationTypeMock));
561
562
            $permissionSets[] = $permissionSet;
563
        }
564
565
        self::assertEquals(
566
            $permissionSets,
567
            $permissionResolverMock->hasAccess('test-module', 'test-function')
568
        );
569
    }
570
571
    /**
572
     * Returns Role stub.
573
     *
574
     * @param array $policiesData
575
     * @param mixed $roleId
576
     *
577
     * @return \eZ\Publish\SPI\Persistence\User\Role
578
     */
579
    private function createRole(array $policiesData, $roleId = null)
580
    {
581
        $policies = array();
582
        foreach ($policiesData as $policyData) {
583
            $policies[] = new SPIPolicy(
584
                array(
585
                    'module' => $policyData[0],
586
                    'function' => $policyData[1],
587
                    'limitations' => $policyData[2],
588
                )
589
            );
590
        }
591
592
        return new Role(
593
            array(
594
                'id' => $roleId,
595
                'policies' => $policies,
596
            )
597
        );
598
    }
599
600
    public function providerForTestCanUserSimple()
601
    {
602
        return array(
603
            array(true, true),
604
            array(false, false),
605
            array(array(), false),
606
        );
607
    }
608
609
    /**
610
     * Test for the canUser() method.
611
     *
612
     * Tests execution paths with permission sets equaling to boolean value or empty array.
613
     *
614
     * @dataProvider providerForTestCanUserSimple
615
     */
616 View Code Duplication
    public function testCanUserSimple($permissionSets, $result)
617
    {
618
        $permissionResolverMock = $this->getPermissionResolverMock(['hasAccess']);
619
620
        $permissionResolverMock
621
            ->expects($this->once())
622
            ->method('hasAccess')
623
            ->with($this->equalTo('test-module'), $this->equalTo('test-function'))
624
            ->will($this->returnValue($permissionSets));
625
626
        /** @var $valueObject \eZ\Publish\API\Repository\Values\ValueObject */
627
        $valueObject = $this->getMockForAbstractClass('eZ\\Publish\\API\\Repository\\Values\\ValueObject');
628
629
        self::assertEquals(
630
            $result,
631
            $permissionResolverMock->canUser('test-module', 'test-function', $valueObject, [$valueObject])
632
        );
633
    }
634
635
    /**
636
     * Test for the canUser() method.
637
     *
638
     * Tests execution path with permission set defining no limitations.
639
     */
640
    public function testCanUserWithoutLimitations()
641
    {
642
        $permissionResolverMock = $this->getPermissionResolverMock(
643
            [
644
                'hasAccess',
645
                'getCurrentUserReference',
646
            ]
647
        );
648
649
        $policyMock = $this->getMock(
650
            'eZ\\Publish\\SPI\\Persistence\\User\\Policy',
651
            array('getLimitations'),
652
            array(),
653
            '',
654
            false
655
        );
656
        $policyMock
657
            ->expects($this->once())
658
            ->method('getLimitations')
659
            ->will($this->returnValue('*'));
660
        $permissionSets = array(
661
            array(
662
                'limitation' => null,
663
                'policies' => array($policyMock),
664
            ),
665
        );
666
        $permissionResolverMock
667
            ->expects($this->once())
668
            ->method('hasAccess')
669
            ->with($this->equalTo('test-module'), $this->equalTo('test-function'))
670
            ->will($this->returnValue($permissionSets));
671
672
        $permissionResolverMock
673
            ->expects($this->once())
674
            ->method('getCurrentUserReference')
675
            ->will($this->returnValue(new UserReference(14)));
676
677
        /** @var $valueObject \eZ\Publish\API\Repository\Values\ValueObject */
678
        $valueObject = $this->getMockForAbstractClass(
679
            'eZ\\Publish\\API\\Repository\\Values\\ValueObject'
680
        );
681
682
        self::assertTrue(
683
            $permissionResolverMock->canUser(
684
                'test-module',
685
                'test-function',
686
                $valueObject,
687
                [$valueObject]
688
            )
689
        );
690
    }
691
692
    /**
693
     * @return array
694
     */
695
    private function getPermissionSetsMock()
696
    {
697
        $roleLimitationMock = $this->getMock('eZ\\Publish\\API\\Repository\\Values\\User\\Limitation');
698
        $roleLimitationMock
699
            ->expects($this->any())
700
            ->method('getIdentifier')
701
            ->will($this->returnValue('test-role-limitation-identifier'));
702
703
        $policyLimitationMock = $this->getMock('eZ\\Publish\\API\\Repository\\Values\\User\\Limitation');
704
        $policyLimitationMock
705
            ->expects($this->any())
706
            ->method('getIdentifier')
707
            ->will($this->returnValue('test-policy-limitation-identifier'));
708
709
        $policyMock = $this->getMock(
710
            'eZ\\Publish\\SPI\\Persistence\\User\\Policy',
711
            array('getLimitations'),
712
            array(),
713
            '',
714
            false
715
        );
716
        $policyMock
717
            ->expects($this->any())
718
            ->method('getLimitations')
719
            ->will($this->returnValue(array($policyLimitationMock, $policyLimitationMock)));
720
721
        $permissionSet = array(
722
            'limitation' => clone $roleLimitationMock,
723
            'policies' => array($policyMock, $policyMock),
724
        );
725
        $permissionSets = array($permissionSet, $permissionSet);
726
727
        return $permissionSets;
728
    }
729
730
    /**
731
     * Provides evaluation results for two permission sets, each with a role limitation and two policies,
732
     * with two limitations per policy.
733
     *
734
     * @return array
735
     */
736
    public function providerForTestCanUserComplex()
737
    {
738
        return array(
739
            array(
740
                array(true, true),
741
                array(
742
                    array(
743
                        array(true, true),
744
                        array(true, true),
745
                    ),
746
                    array(
747
                        array(true, true),
748
                        array(true, true),
749
                    ),
750
                ),
751
                true,
752
            ),
753
            array(
754
                array(false, false),
755
                array(
756
                    array(
757
                        array(true, true),
758
                        array(true, true),
759
                    ),
760
                    array(
761
                        array(true, true),
762
                        array(true, true),
763
                    ),
764
                ),
765
                false,
766
            ),
767
            array(
768
                array(false, true),
769
                array(
770
                    array(
771
                        array(true, true),
772
                        array(true, true),
773
                    ),
774
                    array(
775
                        array(true, true),
776
                        array(true, true),
777
                    ),
778
                ),
779
                true,
780
            ),
781
            array(
782
                array(false, true),
783
                array(
784
                    array(
785
                        array(true, true),
786
                        array(true, true),
787
                    ),
788
                    array(
789
                        array(true, false),
790
                        array(true, true),
791
                    ),
792
                ),
793
                true,
794
            ),
795
            array(
796
                array(true, false),
797
                array(
798
                    array(
799
                        array(true, false),
800
                        array(false, true),
801
                    ),
802
                    array(
803
                        array(true, true),
804
                        array(true, true),
805
                    ),
806
                ),
807
                false,
808
            ),
809
        );
810
    }
811
812
    /**
813
     * Test for the canUser() method.
814
     *
815
     * Tests execution paths with permission sets containing limitations.
816
     *
817
     * @dataProvider providerForTestCanUserComplex
818
     */
819
    public function testCanUserComplex(array $roleLimitationEvaluations, array $policyLimitationEvaluations, $userCan)
820
    {
821
        /** @var $valueObject \eZ\Publish\API\Repository\Values\ValueObject */
822
        $valueObject = $this->getMock('eZ\\Publish\\API\\Repository\\Values\\ValueObject');
823
        $limitationServiceMock = $this->getLimitationServiceMock();
824
        $permissionResolverMock = $this->getPermissionResolverMock(
825
            [
826
                'hasAccess',
827
                'getCurrentUserReference',
828
            ]
829
        );
830
831
        $permissionSets = $this->getPermissionSetsMock();
832
        $permissionResolverMock
833
            ->expects($this->once())
834
            ->method('hasAccess')
835
            ->with($this->equalTo('test-module'), $this->equalTo('test-function'))
836
            ->will($this->returnValue($permissionSets));
837
838
        $userRef = new UserReference(14);
839
        $permissionResolverMock
840
            ->expects($this->once())
841
            ->method('getCurrentUserReference')
842
            ->will($this->returnValue(new UserReference(14)));
843
844
        $invocation = 0;
845
        for ($i = 0; $i < count($permissionSets); ++$i) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
846
            $limitation = $this->getMock('eZ\\Publish\\SPI\\Limitation\\Type');
847
            $limitation
848
                ->expects($this->once())
849
                ->method('evaluate')
850
                ->with($permissionSets[$i]['limitation'], $userRef, $valueObject, array($valueObject))
851
                ->will($this->returnValue($roleLimitationEvaluations[$i]));
852
            $limitationServiceMock
853
                ->expects($this->at($invocation++))
854
                ->method('getLimitationType')
855
                ->with('test-role-limitation-identifier')
856
                ->will($this->returnValue($limitation));
857
858
            if (!$roleLimitationEvaluations[$i]) {
859
                continue;
860
            }
861
862
            for ($j = 0; $j < count($permissionSets[$i]['policies']); ++$j) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
863
                /** @var $policy \eZ\Publish\API\Repository\Values\User\Policy */
864
                $policy = $permissionSets[$i]['policies'][$j];
865
                $limitations = $policy->getLimitations();
866
                for ($k = 0; $k < count($limitations); ++$k) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
867
                    $limitationsPass = true;
868
                    $limitation = $this->getMock('eZ\\Publish\\SPI\\Limitation\\Type');
869
                    $limitation
870
                        ->expects($this->once())
871
                        ->method('evaluate')
872
                        ->with($limitations[$k], $userRef, $valueObject, array($valueObject))
873
                        ->will($this->returnValue($policyLimitationEvaluations[$i][$j][$k]));
874
                    $limitationServiceMock
875
                        ->expects($this->at($invocation++))
876
                        ->method('getLimitationType')
877
                        ->with('test-policy-limitation-identifier')
878
                        ->will($this->returnValue($limitation));
879
880
                    if (!$policyLimitationEvaluations[$i][$j][$k]) {
881
                        $limitationsPass = false;
882
                        break;
883
                    }
884
                }
885
886
                /** @var $limitationsPass */
887
                if ($limitationsPass) {
0 ignored issues
show
Bug introduced by
The variable $limitationsPass does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
888
                    break 2;
889
                }
890
            }
891
        }
892
893
        self::assertEquals(
894
            $userCan,
895
            $permissionResolverMock->canUser(
896
                'test-module',
897
                'test-function',
898
                $valueObject,
899
                [$valueObject]
900
            )
901
        );
902
    }
903
904
    /**
905
     * Test for the setCurrentUserReference() and getCurrentUserReference() methods.
906
     */
907
    public function testSetAndGetCurrentUserReference()
908
    {
909
        $permissionResolverMock = $this->getPermissionResolverMock(null);
0 ignored issues
show
Documentation introduced by
null is of type null, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
910
        $userReferenceMock = $this->getUserReferenceMock();
911
912
        $userReferenceMock
913
            ->expects($this->once())
914
            ->method('getUserId')
915
            ->will($this->returnValue(42));
916
917
        $permissionResolverMock->setCurrentUserReference($userReferenceMock);
918
919
        self::assertSame(
920
            $userReferenceMock,
921
            $permissionResolverMock->getCurrentUserReference()
922
        );
923
    }
924
925
    /**
926
     * Test for the getCurrentUserReference() method.
927
     */
928
    public function testGetCurrentUserReferenceReturnsAnonymousUser()
929
    {
930
        $permissionResolverMock = $this->getPermissionResolverMock(null);
0 ignored issues
show
Documentation introduced by
null is of type null, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
931
        $userReferenceMock = $this->getUserReferenceMock();
932
933
        self::assertSame(
934
            $userReferenceMock,
935
            $permissionResolverMock->getCurrentUserReference()
936
        );
937
    }
938
939
    /**
940
     * Test for the lookup() method.
941
     *
942
     * @group permission-lookup
943
     */
944 View Code Duplication
    public function testLookupGrantedSimple()
945
    {
946
        $module = 'module';
947
        $function = 'function';
948
        $limitations = [];
949
        $permissionResolver = $this->getPermissionResolverMock(['hasAccess']);
950
951
        $permissionResolver
952
            ->expects($this->once())
953
            ->method('hasAccess')
954
            ->with($module, $function)
955
            ->willReturn(true);
956
957
        $permissionInfo = $permissionResolver->lookup($module, $function, $limitations);
958
959
        $this->assertInstanceOf(
960
            'eZ\Publish\API\Repository\Values\User\PermissionInfo',
961
            $permissionInfo
962
        );
963
        $this->assertSame(PermissionInfo::ACCESS_GRANTED, $permissionInfo->access);
964
        $this->assertEmpty($permissionInfo->limitationSets);
965
    }
966
967
    /**
968
     * Test for the lookup() method.
969
     *
970
     * @group permission-lookup
971
     */
972 View Code Duplication
    public function testLookupDeniedSimple()
973
    {
974
        $module = 'module';
975
        $function = 'function';
976
        $limitations = [];
977
        $permissionResolver = $this->getPermissionResolverMock(['hasAccess']);
978
979
        $permissionResolver
980
            ->expects($this->once())
981
            ->method('hasAccess')
982
            ->with($module, $function)
983
            ->willReturn(false);
984
985
        $permissionInfo = $permissionResolver->lookup($module, $function, $limitations);
986
987
        $this->assertInstanceOf(
988
            'eZ\Publish\API\Repository\Values\User\PermissionInfo',
989
            $permissionInfo
990
        );
991
        $this->assertSame(PermissionInfo::ACCESS_DENIED, $permissionInfo->access);
992
        $this->assertEmpty($permissionInfo->limitationSets);
993
    }
994
995
    protected function assertLimitationTypeForLookup()
996
    {
997
        $limitationTypeMock = $this->getMock('eZ\\Publish\\SPI\\Limitation\\Type');
998
        $limitationTypeMock
999
            ->expects($this->any())
1000
            ->method('evaluateSingle')
1001
            ->with(
1002
                $this->isInstanceOf('eZ\Publish\API\Repository\Values\User\Limitation'),
1003
                $this->anything()
1004
            )
1005
            ->will(
1006
                $this->returnCallback(
1007
                    function (Limitation $limitation, $value) {
1008
                        return in_array($value, $limitation->limitationValues);
1009
                    }
1010
                )
1011
            );
1012
1013
        $limitationService = $this->getLimitationServiceMock(['getLimitationType']);
1014
        $limitationService
1015
            ->expects($this->any())
1016
            ->method('getLimitationType')
1017
            ->with($this->anything())
1018
            ->will($this->returnValue($limitationTypeMock));
1019
    }
1020
1021
    public function providerForTestLookupGranted()
1022
    {
1023
        return [
1024
            0 => [
1025
                [
1026
                    [
1027
                        'limitation' => null,
1028
                        'policies' => [
1029
                            new Policy(
1030
                                [
1031
                                    'limitations' => [
1032
                                        new Limitation\LocationLimitation(['limitationValues' => [1, 2, 3]]),
1033
                                    ],
1034
                                ]
1035
                            ),
1036
                        ],
1037
                    ],
1038
                ],
1039
                [
1040
                    new Limitation\LocationLimitation(['limitationValues' => [1]]),
1041
                ],
1042
            ],
1043
            1 => [
1044
                [
1045
                    [
1046
                        'limitation' => null,
1047
                        'policies' => [
1048
                            new Policy(
1049
                                [
1050
                                    'limitations' => [
1051
                                        new Limitation\LocationLimitation(['limitationValues' => [1, 2, 3]]),
1052
                                        new Limitation\SectionLimitation(['limitationValues' => [4, 5, 6]]),
1053
                                    ],
1054
                                ]
1055
                            ),
1056
                        ],
1057
                    ],
1058
                ],
1059
                [
1060
                    new Limitation\LocationLimitation(['limitationValues' => [1]]),
1061
                    new Limitation\SectionLimitation(['limitationValues' => [5]]),
1062
                ],
1063
            ],
1064
            2 => [
1065
                [
1066
                    [
1067
                        'limitation' => null,
1068
                        'policies' => [
1069
                            new Policy(
1070
                                [
1071
                                    'limitations' => [
1072
                                        new Limitation\LocationLimitation(['limitationValues' => [1, 2, 3]]),
1073
                                        new Limitation\SectionLimitation(['limitationValues' => [7, 8, 9]]),
1074
                                    ],
1075
                                ]
1076
                            ),
1077
                        ],
1078
                    ],
1079
                    [
1080
                        'limitation' => null,
1081
                        'policies' => [
1082
                            new Policy(
1083
                                [
1084
                                    'limitations' => [
1085
                                        new Limitation\LocationLimitation(['limitationValues' => [4, 5, 6]]),
1086
                                        new Limitation\SectionLimitation(['limitationValues' => [10, 11, 12]]),
1087
                                    ],
1088
                                ]
1089
                            ),
1090
                        ],
1091
                    ],
1092
                ],
1093
                [
1094
                    new Limitation\LocationLimitation(['limitationValues' => [4]]),
1095
                    new Limitation\SectionLimitation(['limitationValues' => [10]]),
1096
                ],
1097
            ],
1098
            3 => [
1099
                [
1100
                    [
1101
                        'limitation' => null,
1102
                        'policies' => [
1103
                            new Policy(),
1104
                        ],
1105
                    ],
1106
                ],
1107
                [
1108
                    new Limitation\LocationLimitation(['limitationValues' => [4]]),
1109
                ],
1110
            ],
1111
            4 => [
1112
                [
1113
                    [
1114
                        'limitation' => null,
1115
                        'policies' => [
1116
                            new Policy(
1117
                                [
1118
                                    'limitations' => [
1119
                                        new Limitation\LocationLimitation(['limitationValues' => [1, 2, 3]]),
1120
                                        new Limitation\SectionLimitation(['limitationValues' => [7, 8, 9]]),
1121
                                    ],
1122
                                ]
1123
                            ),
1124
                        ],
1125
                    ],
1126
                    [
1127
                        'limitation' => null,
1128
                        'policies' => [
1129
                            new Policy(),
1130
                        ],
1131
                    ],
1132
                ],
1133
                [
1134
                    new Limitation\LocationLimitation(['limitationValues' => [4]]),
1135
                ],
1136
            ],
1137
            5 => [
1138
                [
1139
                    [
1140
                        'limitation' => null,
1141
                        'policies' => [
1142
                            new Policy(
1143
                                [
1144
                                    'limitations' => [
1145
                                        new Limitation\LocationLimitation(['limitationValues' => [1, 2, 3]]),
1146
                                        new Limitation\SectionLimitation(['limitationValues' => [7, 8, 9]]),
1147
                                    ],
1148
                                ]
1149
                            ),
1150
                        ],
1151
                    ],
1152
                    [
1153
                        'limitation' => null,
1154
                        'policies' => [
1155
                            new Policy(),
1156
                        ],
1157
                    ],
1158
                ],
1159
                [],
1160
            ],
1161
            6 => [
1162
                [
1163
                    [
1164
                        'limitation' => new Limitation\LocationLimitation(['limitationValues' => [2, 3, 4]]),
1165
                        'policies' => [
1166
                            new Policy(
1167
                                [
1168
                                    'limitations' => [
1169
                                        new Limitation\LocationLimitation(['limitationValues' => [1, 2, 3]]),
1170
                                    ],
1171
                                ]
1172
                            ),
1173
                        ],
1174
                    ],
1175
                ],
1176
                [
1177
                    new Limitation\LocationLimitation(['limitationValues' => [2]]),
1178
                ],
1179
            ],
1180
            7 => [
1181
                [
1182
                    [
1183
                        'limitation' => new Limitation\LocationLimitation(['limitationValues' => [2, 3, 4]]),
1184
                        'policies' => [
1185
                            new Policy(
1186
                                [
1187
                                    'limitations' => [
1188
                                        new Limitation\LocationLimitation(['limitationValues' => [1, 2, 3]]),
1189
                                    ],
1190
                                ]
1191
                            ),
1192
                        ],
1193
                    ],
1194
                    [
1195
                        'limitation' => new Limitation\LocationLimitation(['limitationValues' => [5, 6, 7]]),
1196
                        'policies' => [
1197
                            new Policy(
1198
                                [
1199
                                    'limitations' => [
1200
                                        new Limitation\LocationLimitation(['limitationValues' => [4, 5, 6]]),
1201
                                    ],
1202
                                ]
1203
                            ),
1204
                        ],
1205
                    ],
1206
                ],
1207
                [
1208
                    new Limitation\LocationLimitation(['limitationValues' => [6]]),
1209
                ],
1210
            ],
1211
        ];
1212
    }
1213
1214
    /**
1215
     * Test for the lookup() method.
1216
     *
1217
     * Permission sets without Role Limitations, resolving to granted permission.
1218
     *
1219
     * @group permission-lookup
1220
     * @dataProvider providerForTestLookupGranted
1221
     *
1222
     * @param array $permissionSets
1223
     * @param array $limitations
1224
     */
1225 View Code Duplication
    public function testLookupGranted($permissionSets, $limitations)
1226
    {
1227
        $module = 'module';
1228
        $function = 'function';
1229
        $permissionResolver = $this->getPermissionResolverMock(['hasAccess']);
1230
        $this->assertLimitationTypeForLookup();
1231
1232
        $permissionResolver
1233
            ->expects($this->once())
1234
            ->method('hasAccess')
1235
            ->with($module, $function)
1236
            ->willReturn($permissionSets);
1237
1238
        $permissionInfo = $permissionResolver->lookup($module, $function, $limitations);
1239
1240
        $this->assertInstanceOf(
1241
            'eZ\Publish\API\Repository\Values\User\PermissionInfo',
1242
            $permissionInfo
1243
        );
1244
        $this->assertSame(PermissionInfo::ACCESS_GRANTED, $permissionInfo->access);
1245
        $this->assertEmpty($permissionInfo->limitationSets);
1246
    }
1247
1248
    public function providerForTestLookupDenied()
1249
    {
1250
        return [
1251
            0 => [
1252
                [
1253
                    [
1254
                        'limitation' => null,
1255
                        'policies' => [
1256
                            new Policy(
1257
                                [
1258
                                    'limitations' => [
1259
                                        new Limitation\LocationLimitation(['limitationValues' => [1, 2, 3]]),
1260
                                    ],
1261
                                ]
1262
                            ),
1263
                        ],
1264
                    ],
1265
                ],
1266
                [
1267
                    new Limitation\LocationLimitation(['limitationValues' => [4]]),
1268
                ],
1269
            ],
1270
            1 => [
1271
                [
1272
                    [
1273
                        'limitation' => null,
1274
                        'policies' => [
1275
                            new Policy(
1276
                                [
1277
                                    'limitations' => [
1278
                                        new Limitation\LocationLimitation(['limitationValues' => [1, 2, 3]]),
1279
                                        new Limitation\SectionLimitation(['limitationValues' => [4, 5, 6]]),
1280
                                    ],
1281
                                ]
1282
                            ),
1283
                        ],
1284
                    ],
1285
                ],
1286
                [
1287
                    new Limitation\LocationLimitation(['limitationValues' => [1]]),
1288
                    new Limitation\SectionLimitation(['limitationValues' => [7]]),
1289
                ],
1290
            ],
1291
            2 => [
1292
                [
1293
                    [
1294
                        'limitation' => new Limitation\LocationLimitation(['limitationValues' => [2, 3, 4]]),
1295
                        'policies' => [
1296
                            new Policy(
1297
                                [
1298
                                    'limitations' => [
1299
                                        new Limitation\LocationLimitation(['limitationValues' => [1, 2, 3]]),
1300
                                        new Limitation\SectionLimitation(['limitationValues' => [4, 5, 6]]),
1301
                                    ],
1302
                                ]
1303
                            ),
1304
                        ],
1305
                    ],
1306
                ],
1307
                [
1308
                    new Limitation\LocationLimitation(['limitationValues' => [1]]),
1309
                    new Limitation\SectionLimitation(['limitationValues' => [5]]),
1310
                ],
1311
            ],
1312
            3 => [
1313
                [
1314
                    [
1315
                        'limitation' => new Limitation\LocationLimitation(['limitationValues' => [2, 3, 4]]),
1316
                        'policies' => [
1317
                            new Policy(
1318
                                [
1319
                                    'limitations' => [
1320
                                        new Limitation\LocationLimitation(['limitationValues' => [1, 2, 3]]),
1321
                                        new Limitation\SectionLimitation(['limitationValues' => [4, 5, 6]]),
1322
                                    ],
1323
                                ]
1324
                            ),
1325
                        ],
1326
                    ],
1327
                ],
1328
                [
1329
                    new Limitation\LocationLimitation(['limitationValues' => [4]]),
1330
                    new Limitation\SectionLimitation(['limitationValues' => [5]]),
1331
                ],
1332
            ],
1333
        ];
1334
    }
1335
1336
    /**
1337
     * Test for the lookup() method.
1338
     *
1339
     * Permission sets without Role Limitations, resolving to denied permission.
1340
     *
1341
     * @group permission-lookup
1342
     * @dataProvider providerForTestLookupDenied
1343
     *
1344
     * @param array $permissionSets
1345
     * @param array $limitations
1346
     */
1347 View Code Duplication
    public function testLookupDenied($permissionSets, $limitations)
1348
    {
1349
        $module = 'module';
1350
        $function = 'function';
1351
        $permissionResolver = $this->getPermissionResolverMock(['hasAccess']);
1352
        $this->assertLimitationTypeForLookup();
1353
1354
        $permissionResolver
1355
            ->expects($this->once())
1356
            ->method('hasAccess')
1357
            ->with($module, $function)
1358
            ->willReturn($permissionSets);
1359
1360
        $permissionInfo = $permissionResolver->lookup($module, $function, $limitations);
1361
1362
        $this->assertInstanceOf(
1363
            'eZ\Publish\API\Repository\Values\User\PermissionInfo',
1364
            $permissionInfo
1365
        );
1366
        $this->assertSame(PermissionInfo::ACCESS_DENIED, $permissionInfo->access);
1367
        $this->assertEmpty($permissionInfo->limitationSets);
1368
    }
1369
1370
    public function providerForTestLookupLimited()
1371
    {
1372
        return [
1373
            0 => [
1374
                [
1375
                    [
1376
                        'limitation' => null,
1377
                        'policies' => [
1378
                            new Policy(
1379
                                [
1380
                                    'limitations' => [
1381
                                        new Limitation\LocationLimitation(['limitationValues' => [1, 2, 3]]),
1382
                                        new Limitation\SectionLimitation(['limitationValues' => [4, 5, 6]]),
1383
                                    ],
1384
                                ]
1385
                            ),
1386
                        ],
1387
                    ],
1388
                ],
1389
                [
1390
                    new Limitation\LocationLimitation(['limitationValues' => [1]]),
1391
                ],
1392
                [
1393
                    [
1394
                        new Limitation\SectionLimitation(['limitationValues' => [4, 5, 6]]),
1395
                    ],
1396
                ],
1397
            ],
1398
            1 => [
1399
                [
1400
                    [
1401
                        'limitation' => null,
1402
                        'policies' => [
1403
                            new Policy(
1404
                                [
1405
                                    'limitations' => [
1406
                                        new Limitation\LocationLimitation(['limitationValues' => [1, 2, 3]]),
1407
                                        new Limitation\SectionLimitation(['limitationValues' => [4, 5, 6]]),
1408
                                        new Limitation\ContentTypeLimitation(['limitationValues' => [7, 8, 9]]),
1409
                                    ],
1410
                                ]
1411
                            ),
1412
                        ],
1413
                    ],
1414
                ],
1415
                [
1416
                    new Limitation\LocationLimitation(['limitationValues' => [1]]),
1417
                ],
1418
                [
1419
                    [
1420
                        new Limitation\SectionLimitation(['limitationValues' => [4, 5, 6]]),
1421
                        new Limitation\ContentTypeLimitation(['limitationValues' => [7, 8, 9]]),
1422
                    ],
1423
                ],
1424
            ],
1425
            2 => [
1426
                [
1427
                    [
1428
                        'limitation' => null,
1429
                        'policies' => [
1430
                            new Policy(
1431
                                [
1432
                                    'limitations' => [
1433
                                        new Limitation\LocationLimitation(['limitationValues' => [1, 2, 3]]),
1434
                                        new Limitation\SectionLimitation(['limitationValues' => [4, 5, 6]]),
1435
                                        new Limitation\ContentTypeLimitation(['limitationValues' => [7, 8, 9]]),
1436
                                    ],
1437
                                ]
1438
                            ),
1439
                        ],
1440
                    ],
1441
                    [
1442
                        'limitation' => null,
1443
                        'policies' => [
1444
                            new Policy(
1445
                                [
1446
                                    'limitations' => [
1447
                                        new Limitation\LocationLimitation(['limitationValues' => [1, 2, 3]]),
1448
                                        new Limitation\ContentTypeLimitation(['limitationValues' => [10, 11, 12]]),
1449
                                    ],
1450
                                ]
1451
                            ),
1452
                        ],
1453
                    ],
1454
                ],
1455
                [
1456
                    new Limitation\LocationLimitation(['limitationValues' => [1]]),
1457
                ],
1458
                [
1459
                    [
1460
                        new Limitation\SectionLimitation(['limitationValues' => [4, 5, 6]]),
1461
                        new Limitation\ContentTypeLimitation(['limitationValues' => [7, 8, 9]]),
1462
                    ],
1463
                    [
1464
                        new Limitation\ContentTypeLimitation(['limitationValues' => [10, 11, 12]]),
1465
                    ],
1466
                ],
1467
            ],
1468
            3 => [
1469
                [
1470
                    [
1471
                        'limitation' => null,
1472
                        'policies' => [
1473
                            new Policy(
1474
                                [
1475
                                    'limitations' => [
1476
                                        new Limitation\LocationLimitation(['limitationValues' => [1, 2, 3]]),
1477
                                        new Limitation\SectionLimitation(['limitationValues' => [4, 5, 6]]),
1478
                                        new Limitation\ContentTypeLimitation(['limitationValues' => [7, 8, 9]]),
1479
                                    ],
1480
                                ]
1481
                            ),
1482
                        ],
1483
                    ],
1484
                    [
1485
                        'limitation' => null,
1486
                        'policies' => [
1487
                            new Policy(
1488
                                [
1489
                                    'limitations' => [
1490
                                        new Limitation\SectionLimitation(['limitationValues' => [4, 5, 6]]),
1491
                                        new Limitation\ContentTypeLimitation(['limitationValues' => [10, 11, 12]]),
1492
                                    ],
1493
                                ]
1494
                            ),
1495
                        ],
1496
                    ],
1497
                ],
1498
                [
1499
                    new Limitation\LocationLimitation(['limitationValues' => [1]]),
1500
                ],
1501
                [
1502
                    [
1503
                        new Limitation\SectionLimitation(['limitationValues' => [4, 5, 6]]),
1504
                        new Limitation\ContentTypeLimitation(['limitationValues' => [7, 8, 9]]),
1505
                    ],
1506
                    [
1507
                        new Limitation\SectionLimitation(['limitationValues' => [4, 5, 6]]),
1508
                        new Limitation\ContentTypeLimitation(['limitationValues' => [10, 11, 12]]),
1509
                    ],
1510
                ],
1511
            ],
1512
            4 => [
1513
                [
1514
                    [
1515
                        'limitation' => new Limitation\LocationLimitation(['limitationValues' => [1, 3, 5, 7]]),
1516
                        'policies' => [
1517
                            new Policy(
1518
                                [
1519
                                    'limitations' => [
1520
                                        new Limitation\LocationLimitation(['limitationValues' => [1, 2, 3]]),
1521
                                        new Limitation\SectionLimitation(['limitationValues' => [4, 5, 6]]),
1522
                                        new Limitation\ContentTypeLimitation(['limitationValues' => [7, 8, 9]]),
1523
                                    ],
1524
                                ]
1525
                            ),
1526
                        ],
1527
                    ],
1528
                    [
1529
                        'limitation' => null,
1530
                        'policies' => [
1531
                            new Policy(
1532
                                [
1533
                                    'limitations' => [
1534
                                        new Limitation\SectionLimitation(['limitationValues' => [4, 5, 6]]),
1535
                                        new Limitation\ContentTypeLimitation(['limitationValues' => [10, 11, 12]]),
1536
                                    ],
1537
                                ]
1538
                            ),
1539
                        ],
1540
                    ],
1541
                ],
1542
                [
1543
                    new Limitation\LocationLimitation(['limitationValues' => [1]]),
1544
                ],
1545
                [
1546
                    [
1547
                        new Limitation\SectionLimitation(['limitationValues' => [4, 5, 6]]),
1548
                        new Limitation\ContentTypeLimitation(['limitationValues' => [7, 8, 9]]),
1549
                    ],
1550
                    [
1551
                        new Limitation\SectionLimitation(['limitationValues' => [4, 5, 6]]),
1552
                        new Limitation\ContentTypeLimitation(['limitationValues' => [10, 11, 12]]),
1553
                    ],
1554
                ],
1555
            ],
1556
            5 => [
1557
                [
1558
                    [
1559
                        'limitation' => new Limitation\SectionLimitation(['limitationValues' => [1, 3, 4, 7]]),
1560
                        'policies' => [
1561
                            new Policy(
1562
                                [
1563
                                    'limitations' => [
1564
                                        new Limitation\LocationLimitation(['limitationValues' => [1, 2, 3]]),
1565
                                        new Limitation\SectionLimitation(['limitationValues' => [4, 5, 6]]),
1566
                                        new Limitation\ContentTypeLimitation(['limitationValues' => [7, 8, 9]]),
1567
                                    ],
1568
                                ]
1569
                            ),
1570
                        ],
1571
                    ],
1572
                    [
1573
                        'limitation' => new Limitation\ContentTypeLimitation(['limitationValues' => [10, 14, 15]]),
1574
                        'policies' => [
1575
                            new Policy(
1576
                                [
1577
                                    'limitations' => [
1578
                                        new Limitation\SectionLimitation(['limitationValues' => [4, 5, 6]]),
1579
                                        new Limitation\ContentTypeLimitation(['limitationValues' => [10, 11, 12]]),
1580
                                    ],
1581
                                ]
1582
                            ),
1583
                        ],
1584
                    ],
1585
                ],
1586
                [
1587
                    new Limitation\LocationLimitation(['limitationValues' => [1]]),
1588
                ],
1589
                [
1590
                    [
1591
                        new Limitation\SectionLimitation(['limitationValues' => [4, 5, 6]]),
1592
                        new Limitation\ContentTypeLimitation(['limitationValues' => [7, 8, 9]]),
1593
                        new Limitation\SectionLimitation(['limitationValues' => [1, 3, 4, 7]]),
1594
                    ],
1595
                    [
1596
                        new Limitation\SectionLimitation(['limitationValues' => [4, 5, 6]]),
1597
                        new Limitation\ContentTypeLimitation(['limitationValues' => [10, 11, 12]]),
1598
                        new Limitation\ContentTypeLimitation(['limitationValues' => [10, 14, 15]]),
1599
                    ],
1600
                ],
1601
            ],
1602
            6 => [
1603
                [
1604
                    [
1605
                        'limitation' => new Limitation\SectionLimitation(['limitationValues' => [1, 3, 4, 7]]),
1606
                        'policies' => [
1607
                            new Policy(
1608
                                [
1609
                                    'limitations' => [
1610
                                        new Limitation\LocationLimitation(['limitationValues' => [1, 2, 3]]),
1611
                                        new Limitation\SectionLimitation(['limitationValues' => [4, 5, 6]]),
1612
                                        new Limitation\ContentTypeLimitation(['limitationValues' => [7, 8, 9]]),
1613
                                    ],
1614
                                ]
1615
                            ),
1616
                        ],
1617
                    ],
1618
                    [
1619
                        'limitation' => new Limitation\ContentTypeLimitation(['limitationValues' => [10, 14, 15]]),
1620
                        'policies' => [
1621
                            new Policy(
1622
                                [
1623
                                    'limitations' => [
1624
                                        new Limitation\SectionLimitation(['limitationValues' => [4, 5, 6]]),
1625
                                        new Limitation\ContentTypeLimitation(['limitationValues' => [10, 11, 12]]),
1626
                                    ],
1627
                                ]
1628
                            ),
1629
                        ],
1630
                    ],
1631
                ],
1632
                [
1633
                    new Limitation\LocationLimitation(['limitationValues' => [1]]),
1634
                    new Limitation\SectionLimitation(['limitationValues' => [4]]),
1635
                ],
1636
                [
1637
                    [
1638
                        new Limitation\ContentTypeLimitation(['limitationValues' => [7, 8, 9]]),
1639
                    ],
1640
                    [
1641
                        new Limitation\ContentTypeLimitation(['limitationValues' => [10, 11, 12]]),
1642
                        new Limitation\ContentTypeLimitation(['limitationValues' => [10, 14, 15]]),
1643
                    ],
1644
                ],
1645
            ],
1646
        ];
1647
    }
1648
1649
    /**
1650
     * Test for the lookup() method.
1651
     *
1652
     * Permission sets without Role Limitations, resolving to granted permission.
1653
     *
1654
     * @group permission-lookup
1655
     * @dataProvider providerForTestLookupLimited
1656
     *
1657
     * @param array $permissionSets
1658
     * @param array $limitations
1659
     * @param \eZ\Publish\API\Repository\Values\User\Limitation[][] $expectedLimitationSets
1660
     */
1661
    public function testLookupLimited($permissionSets, $limitations, $expectedLimitationSets)
1662
    {
1663
        $module = 'module';
1664
        $function = 'function';
1665
        $permissionResolver = $this->getPermissionResolverMock(['hasAccess']);
1666
        $this->assertLimitationTypeForLookup();
1667
1668
        $permissionResolver
1669
            ->expects($this->once())
1670
            ->method('hasAccess')
1671
            ->with($module, $function)
1672
            ->willReturn($permissionSets);
1673
1674
        $permissionInfo = $permissionResolver->lookup($module, $function, $limitations);
1675
1676
        $this->assertInstanceOf(
1677
            'eZ\Publish\API\Repository\Values\User\PermissionInfo',
1678
            $permissionInfo
1679
        );
1680
        $this->assertSame(PermissionInfo::ACCESS_LIMITED, $permissionInfo->access);
1681
1682
        $this->assertNotEmpty($permissionInfo->limitationSets);
1683
        $this->assertEquals(count($expectedLimitationSets), count($permissionInfo->limitationSets));
1684
1685
        /**
1686
         * @var \eZ\Publish\API\Repository\Values\User\Limitation[][] $limitationSets
1687
         */
1688
        $limitationSets = $permissionInfo->limitationSets;
1689
1690
        foreach ($limitationSets as $i => $limitationSet) {
1691
            $this->assertEquals(count($expectedLimitationSets[$i]), count($limitationSet));
1692
1693
            foreach ($limitationSet as $k => $limitation) {
1694
                $expectedLimitation = $expectedLimitationSets[$i][$k];
1695
                $this->assertEquals($expectedLimitation->getIdentifier(), $limitation->getIdentifier());
1696
                $this->assertEquals($expectedLimitation->limitationValues, $limitation->limitationValues);
1697
            }
1698
        }
1699
    }
1700
1701
    protected $permissionResolverMock;
1702
1703
    /**
1704
     * @return \eZ\Publish\API\Repository\PermissionResolver|\PHPUnit_Framework_MockObject_MockObject
1705
     */
1706
    protected function getPermissionResolverMock($methods = [])
1707
    {
1708
        if ($this->permissionResolverMock === null) {
1709
            $this->permissionResolverMock = $this
1710
                ->getMockBuilder('eZ\\Publish\\Core\\Repository\\Permission\\PermissionResolver')
1711
                ->setMethods($methods)
1712
                ->setConstructorArgs(
1713
                    [
1714
                        $this->getRoleDomainMapperMock(),
1715
                        $this->getLimitationServiceMock(),
1716
                        $this->getPersistenceMock()->userHandler(),
1717
                        $this->getUserReferenceMock(),
1718
                    ]
1719
                )
1720
                ->getMock();
1721
        }
1722
1723
        return $this->permissionResolverMock;
1724
    }
1725
1726
    protected $userReferenceMock;
1727
1728
    protected function getUserReferenceMock()
1729
    {
1730
        if ($this->userReferenceMock === null) {
1731
            $this->userReferenceMock = $this
1732
                ->getMockBuilder('eZ\Publish\API\Repository\Values\User\UserReference')
1733
                ->getMock();
1734
        }
1735
1736
        return $this->userReferenceMock;
1737
    }
1738
1739
    protected $repositoryMock;
1740
1741
    /**
1742
     * @return \eZ\Publish\API\Repository\Repository|\PHPUnit_Framework_MockObject_MockObject
1743
     */
1744
    protected function getRepositoryMock($methods = [])
0 ignored issues
show
Unused Code introduced by
The parameter $methods is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1745
    {
1746
        if ($this->repositoryMock === null) {
1747
            $this->repositoryMock = $this
1748
                ->getMockBuilder('eZ\\Publish\\Core\\Repository\\Repository')
1749
                ->setMethods(['getPermissionResolver'])
1750
                ->disableOriginalConstructor()
1751
                ->getMock();
1752
        }
1753
1754
        return $this->repositoryMock;
1755
    }
1756
1757
    protected $roleDomainMapperMock;
1758
1759
    /**
1760
     * @return \eZ\Publish\Core\Repository\Helper\RoleDomainMapper|\PHPUnit_Framework_MockObject_MockObject
1761
     */
1762
    protected function getRoleDomainMapperMock($methods = [])
1763
    {
1764
        if ($this->roleDomainMapperMock === null) {
1765
            $this->roleDomainMapperMock = $this
1766
                ->getMockBuilder('eZ\\Publish\\Core\\Repository\\Helper\\RoleDomainMapper')
1767
                ->setMethods($methods)
1768
                ->disableOriginalConstructor()
1769
                ->getMock();
1770
        }
1771
1772
        return $this->roleDomainMapperMock;
1773
    }
1774
1775
    protected $limitationServiceMock;
1776
1777
    /**
1778
     * @return \eZ\Publish\Core\Repository\Helper\LimitationService|\PHPUnit_Framework_MockObject_MockObject
1779
     */
1780 View Code Duplication
    protected function getLimitationServiceMock($methods = [])
1781
    {
1782
        if ($this->limitationServiceMock === null) {
1783
            $this->limitationServiceMock = $this
1784
                ->getMockBuilder('eZ\\Publish\\Core\\Repository\\Helper\\LimitationService')
1785
                ->setMethods($methods)
1786
                ->disableOriginalConstructor()
1787
                ->getMock();
1788
        }
1789
1790
        return $this->limitationServiceMock;
1791
    }
1792
}
1793