Completed
Push — master ( 5e6851...19dbb1 )
by Mathieu
12:22
created

Authorizer::acl()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
namespace Charcoal\User;
4
5
use \InvalidArgumentException;
6
7
// Dependencies from `zendframework/zend-permissions`
8
use \Zend\Permissions\Acl\Acl;
9
10
// Dependencies from 'PSR-3' (Logging)
11
use \Psr\Log\LoggerAwareInterface;
12
use \Psr\Log\LoggerAwareTrait;
13
14
// Intra-module (`charcoal-base`) dependencies
15
use \Charcoal\User\UserInterface;
16
17
/**
18
 * Authorizer helps with user authorization (permission checking).
19
 *
20
 * ## Constructor dependencies
21
 *
22
 * Constructor dependencies are passed as an array of `key=>value` pair.
23
 * The required dependencies are:
24
 *
25
 * - `logger` A PSR3 logger instance.
26
 * - `acl` A Zend ACL (Access-Control-List) instance.
27
 * - `resource` The ACL resource identifier (string).
28
 *
29
 * ## Checking permissions
30
 *
31
 * To check if a given ACL (passed in constructor) allows a list of permissions (aka privileges):
32
 *
33
 * - `userAllowed(UserInterface $user, string[] $aclPermissions)`
34
 * - `rolesAllowed(string[] $roles, string[] $aclPermissions)`
35
 */
36
class Authorizer implements LoggerAwareInterface
37
{
38
    use LoggerAwareTrait;
39
40
    /**
41
     * @var Acl $acl
42
     */
43
    private $acl;
44
45
    /**
46
     * The ACL resource identifier
47
     * @var string $resource
48
     */
49
    private $resource;
50
51
    /**
52
     * @param array $data Class dependencies.
53
     */
54
    public function __construct(array $data)
55
    {
56
        $this->setLogger($data['logger']);
57
        $this->setAcl($data['acl']);
58
        $this->setResource($data['resource']);
59
    }
60
61
    /**
62
     * @param Acl $acl The ACL instance.
63
     * @return void
64
     */
65
    private function setAcl(Acl $acl)
66
    {
67
        $this->acl = $acl;
68
    }
69
70
    /**
71
     * @return Acl
72
     */
73
    protected function acl()
74
    {
75
        return $this->acl;
76
    }
77
78
    /**
79
     * @param string $resource The ACL resource identifier.
80
     * @throws InvalidArgumentException If the resource identifier is not a string.
81
     * @return void
82
     */
83
    private function setResource($resource)
84
    {
85
        if (!is_string($resource)) {
86
            throw new InvalidArgumentException(
87
                'ACL resource identifier must be a string.'
88
            );
89
        }
90
        $this->resource = $resource;
91
    }
92
93
    /**
94
     * @return string
95
     */
96
    protected function resource()
97
    {
98
        return $this->resource;
99
    }
100
101
    /**
102
     * @param string[] $aclRoles       The ACL roles to validate against.
103
     * @param string[] $aclPermissions The acl permissions to validate.
104
     * @return boolean Wether the permissions are allowed for a given list of roles.
105
     */
106
    public function rolesAllowed(array $aclRoles, array $aclPermissions)
107
    {
108
        $acl = $this->acl();
109
        $aclResource = $this->resource();
110
111
        foreach ($aclRoles as $aclRole) {
112
            foreach ($aclPermissions as $aclPermission) {
113
                if (!$acl->isAllowed($aclRole, $aclResource, $aclPermission)) {
114
                    $this->logger->error(
115
                        sprinft('Role "%s" is not allowed permission "%s"', $aclRole, $aclPermission)
116
                    );
117
                    return false;
118
                }
119
            }
120
        }
121
        return true;
122
    }
123
124
    /**
125
     * @param UserInterface $user           The user to validate against.
126
     * @param string[]      $aclPermissions The acl permissions to validate.
127
     * @return boolean Whether the permissions are allowed for a given user.
128
     */
129
    public function userAllowed(UserInterface $user, array $aclPermissions)
130
    {
131
        return $this->rolesAllowed($user->roles(), $aclPermissions);
132
    }
133
}
134