Passed
Push — master ( 86c3d2...1ebd3c )
by Gabor
07:26
created

IsAllowedHelper::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 17
Code Lines 15

Duplication

Lines 17
Ratio 100 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 17
loc 17
ccs 0
cts 17
cp 0
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 15
nc 1
nop 7
crap 2
1
<?php
2
/**
3
 * WebHemi.
4
 *
5
 * PHP version 7.1
6
 *
7
 * @copyright 2012 - 2017 Gixx-web (http://www.gixx-web.com)
8
 * @license   https://opensource.org/licenses/MIT The MIT License (MIT)
9
 *
10
 * @link      http://www.gixx-web.com
11
 */
12
declare(strict_types = 1);
13
14
namespace WebHemi\Renderer\Helper;
15
16
use WebHemi\Adapter\Acl\AclAdapterInterface;
17
use WebHemi\Adapter\Auth\AuthAdapterInterface;
18
use WebHemi\Adapter\Renderer\RendererHelperInterface;
19
use WebHemi\Application\EnvironmentManager;
20
use WebHemi\Config\ConfigInterface;
21
use WebHemi\Data\Entity\AccessManagement\ResourceEntity;
22
use WebHemi\Data\Entity\ApplicationEntity;
23
use WebHemi\Data\Entity\User\UserEntity;
24
use WebHemi\Data\Storage\AccessManagement\ResourceStorage;
25
use WebHemi\Data\Storage\ApplicationStorage;
26
use WebHemi\Data\Storage\User\UserStorage;
27
28
/**
29
 * Class IsAllowedHelper
30
 */
31
class IsAllowedHelper implements RendererHelperInterface
32
{
33
    /** @var ConfigInterface */
34
    private $configuration;
35
    /** @var EnvironmentManager */
36
    private $environmentManager;
37
    /** @var AclAdapterInterface */
38
    private $aclAdapter;
39
    /** @var AuthAdapterInterface */
40
    private $authAdapter;
41
    /** @var UserStorage */
42
    private $userStorage;
43
    /** @var ResourceStorage */
44
    private $resourceStorage;
45
    /** @var ApplicationStorage */
46
    private $applicationStorage;
47
48
    /**
49
     * Should return the name of the helper.
50
     *
51
     * @return string
52
     * @codeCoverageIgnore - plain text
53
     */
54
    public static function getName() : string
55
    {
56
        return 'isAllowed';
57
    }
58
59
    /**
60
     * Should return the name of the helper.
61
     *
62
     * @return string
63
     * @codeCoverageIgnore - plain text
64
     */
65
    public static function getDefinition() : string
66
    {
67
        return 'isAllowed(string resourceName = null, string applicationName = null) : bool';
68
    }
69
70
    /**
71
     * Should return a description text.
72
     *
73
     * @return string
74
     * @codeCoverageIgnore - plain text
75
     */
76
    public static function getDescription() : string
77
    {
78
        return 'Checks if the given user has access to the given resource in the given application.';
79
    }
80
81
    /**
82
     * IsAllowedHelper constructor.
83
     *
84
     * @param ConfigInterface $configuration
85
     * @param EnvironmentManager $environmentManager
86
     * @param AclAdapterInterface $aclAdapter
87
     * @param AuthAdapterInterface $authAdapter
88
     * @param UserStorage $userStorage
89
     * @param ResourceStorage $resourceStorage
90
     * @param ApplicationStorage $applicationStorage
91
     */
92 View Code Duplication
    public function __construct(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
93
        ConfigInterface $configuration,
94
        EnvironmentManager $environmentManager,
95
        AclAdapterInterface $aclAdapter,
96
        AuthAdapterInterface $authAdapter,
97
        UserStorage $userStorage,
98
        ResourceStorage $resourceStorage,
99
        ApplicationStorage $applicationStorage
100
    ) {
101
        $this->configuration = $configuration;
102
        $this->environmentManager = $environmentManager;
103
        $this->aclAdapter = $aclAdapter;
104
        $this->authAdapter = $authAdapter;
105
        $this->userStorage = $userStorage;
106
        $this->resourceStorage = $resourceStorage;
107
        $this->applicationStorage = $applicationStorage;
108
    }
109
110
    /**
111
     * A renderer helper should be called with its name.
112
     *
113
     * @return bool
114
     */
115
    public function __invoke() : bool
116
    {
117
        /** @var UserEntity $userEntity */
118
        $userEntity = $this->authAdapter->getIdentity();
119
        // Without user, access should be denied.
120
        if (!$userEntity) {
121
            return false;
122
        }
123
124
        $arguments = func_get_args();
125
        $resourceName = $arguments[0] ?? '';
126
        $this->checkResourceNameAgainstRouting($resourceName);
127
        /** @var null|ResourceEntity $resourceEntity */
128
        $resourceEntity = $this->resourceStorage->getResourceByName($resourceName);
129
        $applicationName = $arguments[1] ?? $this->environmentManager->getSelectedApplication();
130
        /** @var null|ApplicationEntity $applicationEntity */
131
        $applicationEntity = $this->applicationStorage->getApplicationByName($applicationName);
132
133
        return $this->aclAdapter->isAllowed($userEntity, $resourceEntity, $applicationEntity);
134
    }
135
136
    /**
137
     * Matches the given resource name against router URLs and if found, changes it to the assigned middleware name.
138
     * @TODO: make sure it is not possible to give a custom resource with a name that can match against a router path.
139
     *
140
     * @param $resourceName
141
     */
142
    private function checkResourceNameAgainstRouting(&$resourceName) : void
143
    {
144
        $applicationConfig = $this->configuration
145
            ->getData('applications/'.$this->environmentManager->getSelectedApplication());
146
147
        $applicationRouteConfig = $this->configuration
148
            ->getData('router/'.$applicationConfig['module']);
149
150
        $tempName = $resourceName;
151
        $tempName = '/'.trim($tempName, '/');
152
153
        foreach ($applicationRouteConfig as $route) {
154
            if (preg_match('@^'.$route['path'].'?$@', $tempName)) {
155
                $resourceName = $route['middleware'];
156
                break;
157
            }
158
        }
159
    }
160
}
161