• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

LM-Commons / LmcRbacMvc / 9213709239

23 May 2024 07:23PM UTC coverage: 92.785% (+5.5%) from 87.306%
9213709239

push

github

web-flow
Merge pull request #78 from visto9259/4.x

Merged documentation from master

128 of 135 new or added lines in 42 files covered. (94.81%)

10 existing lines in 3 files now uncovered.

643 of 693 relevant lines covered (92.78%)

5.17 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

89.47
/src/Service/AuthorizationService.php
1
<?php
2
/*
3
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
 *
15
 * This software consists of voluntary contributions made by many individuals
16
 * and is licensed under the MIT license.
17
 */
18

19
namespace LmcRbacMvc\Service;
20

21
use Laminas\Permissions\Rbac\Rbac;
22
use LmcRbacMvc\Permission\PermissionInterface;
23
use LmcRbacMvc\Assertion\AssertionPluginManager;
24
use LmcRbacMvc\Assertion\AssertionInterface;
25
use LmcRbacMvc\Exception;
26
use LmcRbacMvc\Identity\IdentityInterface;
27

28
/**
29
 * Authorization service is a simple service that internally uses Rbac to check if identity is
30
 * granted a permission
31
 *
32
 * @author  Michaƫl Gallego <mic.gallego@gmail.com>
33
 * @license MIT
34
 */
35
class AuthorizationService implements AuthorizationServiceInterface
36
{
37
    /**
38
     * @var RoleService
39
     */
40
    protected RoleService $roleService;
41

42
    /**
43
     * @var AssertionPluginManager
44
     */
45
    protected AssertionPluginManager $assertionPluginManager;
46

47
    /**
48
     * @var array
49
     */
50
    protected array $assertions = [];
51

52
    /**
53
     * Constructor
54
     *
55
     * @param RoleService            $roleService
56
     * @param AssertionPluginManager $assertionPluginManager
57
     */
58
    public function __construct(RoleService $roleService, AssertionPluginManager $assertionPluginManager)
12✔
59
    {
60
        $this->roleService            = $roleService;
12✔
61
        $this->assertionPluginManager = $assertionPluginManager;
12✔
62
    }
63

64
    /**
65
     * Set an assertion
66
     *
67
     * @param string|PermissionInterface $permission
68
     * @param callable|string|AssertionInterface $assertion
69
     * @return void
70
     */
71
    public function setAssertion(PermissionInterface|string $permission, callable|AssertionInterface|string $assertion): void
1✔
72
    {
73
        $this->assertions[(string) $permission] = $assertion;
1✔
74
    }
75

76
    /**
77
     * Set assertions
78
     *
79
     * @param array $assertions
80
     * @return void
81
     */
82
    public function setAssertions(array $assertions): void
8✔
83
    {
84
        $this->assertions = $assertions;
8✔
85
    }
86

87
    /**
88
     * Checks if a assertion exists
89
     *
90
     * @param string|PermissionInterface $permission
91
     * @return bool
92
     */
93
    public function hasAssertion(PermissionInterface|string $permission): bool
6✔
94
    {
95
        return isset($this->assertions[(string) $permission]);
6✔
96
    }
97

98
    /**
99
     * Get the current identity from the role service
100
     *
101
     * @return IdentityInterface|null
102
     */
103
    public function getIdentity(): ?IdentityInterface
1✔
104
    {
105
        return $this->roleService->getIdentity();
1✔
106
    }
107

108
    /**
109
     * Check if the permission is granted to the current identity
110
     *
111
     * @param string $permission
112
     * @param mixed|null $context
113
     * @return bool
114
     */
115
    public function isGranted(string $permission, mixed $context = null): bool
9✔
116
    {
117
        $roles = $this->roleService->getIdentityRoles();
9✔
118

119
        if (empty($roles)) {
9✔
120
            return false;
1✔
121
        }
122

123
        // Create a RBAC container and populate with the identity's roles
124
        $rbac = new Rbac();
8✔
125
        foreach ($roles as $role) {
8✔
126
            $rbac->addRole($role);
8✔
127
        }
128

129
        // Iterate through roles
130
        $allowed = false;
8✔
131
        foreach ($roles as $role) {
8✔
132
            if ($rbac->isGranted($role, $permission)) {
8✔
133
                $allowed = true;
5✔
134
            }
135
        }
136
        if (!$allowed) return false;
8✔
137

138
        if ($this->hasAssertion($permission)) {
5✔
139
            return $this->assert($this->assertions[(string) $permission], $context);
3✔
140
        }
141

142
        return true;
2✔
143
    }
144

145
    /**
146
     * @param callable|string|AssertionInterface $assertion
147
     * @param mixed|null $context
148
     * @return bool
149
     * @throws Exception\InvalidArgumentException If an invalid assertion is passed
150
     */
151
    protected function assert(callable|AssertionInterface|string $assertion, mixed $context = null): bool
3✔
152
    {
153
        if (is_callable($assertion)) {
3✔
154
            return $assertion($this, $context);
1✔
155
        } elseif ($assertion instanceof AssertionInterface) {
3✔
156
            return $assertion->assert($this, $context);
1✔
157
        } elseif (is_string($assertion)) {
2✔
158
            $assertion = $this->assertionPluginManager->get($assertion);
2✔
159

160
            return $assertion->assert($this, $context);
2✔
161
        }
162

UNCOV
163
        throw new Exception\InvalidArgumentException(sprintf(
×
UNCOV
164
            'Assertion must be callable, string or implement ZfcRbac\Assertion\AssertionInterface, "%s" given',
×
UNCOV
165
            is_object($assertion) ? get_class($assertion) : gettype($assertion)
×
UNCOV
166
        ));
×
167
    }
168
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc