Test Failed
Push — master ( f3c992...c67ae5 )
by Daniel
04:30
created

RoutableVoter::voteOnAttribute()   B

Complexity

Conditions 7
Paths 8

Size

Total Lines 26
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 56

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 7
eloc 14
c 2
b 0
f 0
nc 8
nop 3
dl 0
loc 26
ccs 0
cts 1
cp 0
crap 56
rs 8.8333
1
<?php
2
3
/*
4
 * This file is part of the Silverback API Components Bundle Project
5
 *
6
 * (c) Daniel West <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace Silverback\ApiComponentsBundle\Security\Voter;
15
16
use ApiPlatform\Core\Security\ResourceAccessCheckerInterface;
17
use Silverback\ApiComponentsBundle\Entity\Core\Page;
18
use Silverback\ApiComponentsBundle\Entity\Core\RoutableInterface;
19
use Silverback\ApiComponentsBundle\Repository\Core\AbstractPageDataRepository;
20
use Silverback\ApiComponentsBundle\Security\EventListener\DenyAccessListener;
21
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
22
use Symfony\Component\Security\Core\Security;
23
24
/**
25
 * If a routable object does not have a route, implement the security configuration. Usually admin only access.
26
 *
27
 * @author Daniel West <[email protected]>
28
 */
29
final class RoutableVoter extends AbstractRoutableVoter
30
{
31
    private ?string $securityStr;
32
    private ResourceAccessCheckerInterface $resourceAccessChecker;
33
    private Security $security;
34
    private AbstractPageDataRepository $pageDataRepository;
35
    private DenyAccessListener $denyAccessListener;
36
37
    public function __construct(?string $securityStr, ResourceAccessCheckerInterface $resourceAccessChecker, Security $security, AbstractPageDataRepository $pageDataRepository, DenyAccessListener $denyAccessListener)
38
    {
39
        $this->securityStr = $securityStr;
40
        $this->resourceAccessChecker = $resourceAccessChecker;
41
        $this->security = $security;
42
        $this->pageDataRepository = $pageDataRepository;
43
        $this->denyAccessListener = $denyAccessListener;
44
    }
45
46
    /**
47
     * @param RoutableInterface $routable
48
     */
49
    protected function voteOnAttribute(string $attribute, $routable, TokenInterface $token): bool
50
    {
51
        if (!$this->securityStr) {
52
            return true;
53
        }
54
55
        if ($route = $routable->getRoute()) {
56
            $isGranted = $this->security->isGranted(RouteVoter::READ_ROUTE, $route);
57
            if ($isGranted) {
58
                return true;
59
            }
60
        }
61
62
        if ($routable instanceof Page) {
63
            $pageData = $this->pageDataRepository->findBy([
64
                'page' => $routable,
65
            ]);
66
            foreach ($pageData as $pageDatum) {
67
                $isGranted = $this->denyAccessListener->isPageDataAllowedByRoute($pageDatum);
68
                if ($isGranted) {
69
                    return true;
70
                }
71
            }
72
        }
73
74
        return $this->resourceAccessChecker->isGranted(\get_class($routable), $this->securityStr);
75
    }
76
}
77