Service::can()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 9
ccs 4
cts 4
cp 1
rs 9.6666
c 0
b 0
f 0
cc 2
eloc 5
nc 2
nop 3
crap 2
1
<?php
2
declare(strict_types=1);
3
/**
4
 * Caridea
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
7
 * use this file except in compliance with the License. You may obtain a copy of
8
 * the License at
9
 *
10
 * http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15
 * License for the specific language governing permissions and limitations under
16
 * the License.
17
 *
18
 * @copyright 2015-2018 LibreWorks contributors
19
 * @license   Apache-2.0
20
 */
21
namespace Caridea\Acl;
22
23
/**
24
 * Service for working with permissions.
25
 *
26
 * @copyright 2015-2018 LibreWorks contributors
27
 * @license   Apache-2.0
28
 */
29
class Service
30
{
31
    /**
32
     * @var Strategy The loading strategy
33
     */
34
    private $strategy;
35
36
    /**
37
     * Creates a new Service.
38
     *
39
     * @param \Caridea\Acl\Strategy $strategy The loading strategy
40
     */
41 9
    public function __construct(Strategy $strategy)
42
    {
43 9
        $this->strategy = $strategy;
44 9
    }
45
46
    /**
47
     * Asserts that one of the provided subjects can verb the Target.
48
     *
49
     * @param Subject[] $subjects An array of `Subject`s
50
     * @param string $verb The verb (e.g. `read`, `create`, `delete`)
51
     * @param \Caridea\Acl\Target $target The target
52
     * @throws Exception\Forbidden if the subject cannot *verb* the Target
53
     */
54 3
    public function assert(array $subjects, string $verb, Target $target): void
55
    {
56
        try {
57 3
            if ($this->get($target, $subjects)->can($subjects, $verb)) {
58 2
                return;
59
            }
60 1
        } catch (\Exception $ex) {
61 1
            throw new Exception\Forbidden("Access denied to $verb the target", 0, $ex);
62
        }
63 1
        throw new Exception\Forbidden("Access denied to $verb the target");
64
    }
65
66
    /**
67
     * Whether any of the provided subjects has permission to verb the Target.
68
     *
69
     * @param Subject[] $subjects An array of `Subject`s
70
     * @param string $verb The verb (e.g. `read`, `create`, `delete`)
71
     * @param \Caridea\Acl\Target $target The target
72
     * @return bool Whether one of the subjects can *verb* the provided Target
73
     */
74 2
    public function can(array $subjects, string $verb, Target $target): bool
75
    {
76
        try {
77 2
            return $this->get($target, $subjects)->can($subjects, $verb);
78 1
        } catch (\Exception $ex) {
79
            // just return false below
80
        }
81 1
        return false;
82
    }
83
84
    /**
85
     * Gets an access control list for a Target.
86
     *
87
     * @param Target $target The Target whose ACL will be loaded
88
     * @param Subject[] $subjects An array of `Subject`s
89
     * @return Acl The Acl found
90
     * @throws Exception\Unloadable If the target provided is invalid
91
     * @throws \InvalidArgumentException If the `subjects` argument contains invalid values
92
     */
93 6
    public function get(Target $target, array $subjects): Acl
94
    {
95 6
        return $this->strategy->load($target, $subjects, $this);
96
    }
97
98
    /**
99
     * Gets access control lists for several Targets.
100
     *
101
     * @since 2.1.0
102
     * @param \Caridea\Acl\Target[] $targets The `Target` whose ACL will be loaded
103
     * @param \Caridea\Acl\Subject[] $subjects An array of `Subject`s
104
     * @return array<string,\Caridea\Acl\Acl> The loaded ACLs
105
     * @throws \Caridea\Acl\Exception\Unloadable If the target provided is invalid
106
     * @throws \InvalidArgumentException If the `targets` or `subjects` argument contains invalid values
107
     */
108 3
    public function getAll(array $targets, array $subjects): array
109
    {
110 3
        $acls = [];
111 3
        if ($this->strategy instanceof MultiStrategy) {
112 2
            $acls = $this->strategy->loadAll($targets, $subjects, $this);
113
        } else {
114 1
            foreach ($targets as $target) {
115 1
                $acls[(string)$target] = $this->strategy->load($target, $subjects, $this);
116
            }
117
        }
118 3
        $missing = array_diff(array_map(function ($a) {
119 3
            return (string) $a;
120 3
        }, $targets), array_keys($acls));
121
        // Check every requested target was found
122 3
        if (!empty($missing)) {
123 1
            throw new Exception\Unloadable("Unable to load ACL for " . implode(", ", $missing));
124
        }
125 2
        return $acls;
126
    }
127
}
128