Passed
Push — master ( 7f699f...e24ab0 )
by Kirill
03:06
created

Guard   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 95
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 24
c 1
b 0
f 0
dl 0
loc 95
rs 10
wmc 10

6 Methods

Rating   Name   Duplication   Size   Complexity  
A getRoles() 0 3 1
A getActor() 0 7 2
A withRoles() 0 6 1
A withActor() 0 6 1
A __construct() 0 8 1
A allows() 0 15 4
1
<?php
2
3
/**
4
 * Spiral Framework.
5
 *
6
 * @license   MIT
7
 * @author    Anton Titov (Wolfy-J)
8
 */
9
10
declare(strict_types=1);
11
12
namespace Spiral\Security;
13
14
use Spiral\Security\Exception\GuardException;
15
16
/**
17
 * Checks permissions using given actor.
18
 */
19
final class Guard implements GuardInterface
20
{
21
    /** @var PermissionsInterface */
22
    private $permissions = null;
23
24
    /** @var ActorInterface|null */
25
    private $actor = null;
26
27
    /** @var array */
28
    private $roles = [];
29
30
    /**
31
     * @param PermissionsInterface $permissions
32
     * @param ActorInterface       $actor
33
     * @param array                $roles Session specific roles.
34
     */
35
    public function __construct(
36
        PermissionsInterface $permissions,
37
        ActorInterface $actor = null,
38
        array $roles = []
39
    ) {
40
        $this->roles = $roles;
41
        $this->actor = $actor;
42
        $this->permissions = $permissions;
43
    }
44
45
    /**
46
     * {@inheritdoc}
47
     */
48
    public function allows(string $permission, array $context = []): bool
49
    {
50
        $allows = false;
51
        foreach ($this->getRoles() as $role) {
52
            if (!$this->permissions->hasRole($role)) {
53
                continue;
54
            }
55
56
            $rule = $this->permissions->getRule($role, $permission);
57
58
            //Checking our rule
59
            $allows = $allows || $rule->allows($this->getActor(), $permission, $context);
60
        }
61
62
        return $allows;
63
    }
64
65
    /**
66
     * Currently active actor/session roles.
67
     *
68
     * @return array
69
     *
70
     * @throws GuardException
71
     */
72
    public function getRoles(): array
73
    {
74
        return array_merge($this->roles, $this->getActor()->getRoles());
75
    }
76
77
    /**
78
     * Create instance of guard with session specific roles (existed roles will be droppped).
79
     *
80
     * @param array $roles
81
     * @return self
82
     */
83
    public function withRoles(array $roles): Guard
84
    {
85
        $guard = clone $this;
86
        $guard->roles = $roles;
87
88
        return $guard;
89
    }
90
91
    /**
92
     * {@inheritdoc}
93
     *
94
     * @throws GuardException
95
     */
96
    public function getActor(): ActorInterface
97
    {
98
        if (empty($this->actor)) {
99
            throw new GuardException('Unable to get Guard Actor, no value set');
100
        }
101
102
        return $this->actor;
103
    }
104
105
    /**
106
     * {@inheritdoc}
107
     */
108
    public function withActor(ActorInterface $actor): GuardInterface
109
    {
110
        $guard = clone $this;
111
        $guard->actor = $actor;
112
113
        return $guard;
114
    }
115
}
116