Evaluator::parseStatements()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 11
ccs 7
cts 7
cp 1
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 6
nc 3
nop 1
crap 3
1
<?php
2
3
namespace tomzx\PolicyEvaluator;
4
5
class Evaluator
6
{
7
    /**
8
     * @var array
9
     */
10
    private $policies;
11
12
    /**
13
     * @var array
14
     */
15
    private $variables;
16
17
    /**
18
     * @var Statement[]
19
     */
20
    private $statements;
21
22
    /**
23
     * @param array $policies
24
     */
25 12
    public function __construct(array $policies, array $variables = [])
26
    {
27 12
        $this->policies = $policies;
28 12
        $this->variables = $variables;
29
30 12
        if ( ! isset($this->policies['Statement'])) {
31 1
            throw new \InvalidArgumentException('The policy must have at least one statement.');
32
        }
33
34 11
        $this->parseStatements($this->policies['Statement']);
35 9
    }
36
37
    /**
38
     * @return array
39
     */
40
    public function getStatements()
41
    {
42
        return $this->statements;
43
    }
44
45
    /**
46
     * @return array
47
     */
48
    public function getVariables()
49
    {
50
        return $this->variables;
51
    }
52
53
    /**
54
     * @param string $action
55
     * @param string $resource
56
     * @param array $variables
57
     * @return bool
58
     */
59 8
    public function canExecuteActionOnResource($action, $resource, array $variables = [])
60
    {
61
        // TODO([email protected]): Validate action and resource are in valid format
62 8
        $statements = $this->matchStatement($action, $resource, $variables);
63
64 8
        foreach ($statements as $statement) {
65
            // If we found a matching statement with an explicit deny, deny right away
66 6
            if ($statement->getEffect()->isDeny()) {
67 6
                return false;
68
            }
69
        }
70
71 6
        return ! empty($statements);
72
    }
73
74
    /**
75
     * @param string $document
76
     * @return \tomzx\PolicyEvaluator\Evaluator
77
     */
78
    public static function fromJsonString($document)
79
    {
80
        return new self(json_decode($document, true));
81
    }
82
83
    /**
84
     * @param array $statements
85
     */
86 11
    private function parseStatements(array $statements)
87
    {
88 11
        if (empty($statements)) {
89 1
            throw new \InvalidArgumentException('The policy must have at least one statement.');
90
        }
91
92 10
        foreach ($statements as $statement) {
93 10
            $statement = $this->makeStatement($statement);
94 9
            $this->statements[] = $statement;
95
        }
96 9
    }
97
98
    /**
99
     * @param array $statement
100
     * @return \tomzx\PolicyEvaluator\Statement
101
     */
102 10
    protected function makeStatement(array $statement)
103
    {
104 10
        return new Statement($statement);
105
    }
106
107
    /**
108
     * @param string $action
109
     * @param string $resource
110
     * @param array $variables
111
     * @return array
112
     */
113 8
    public function matchStatement($action, $resource, array $variables = [])
114
    {
115 8
        $variables += $this->variables;
116 8
        $statements = [];
117 8
        foreach ($this->statements as $statement) {
118 8
            if ( ! $statement->matchesAction($action)) {
119 1
                continue;
120
            }
121
122 7
            if ( ! $statement->matchesResource($resource, $variables)) {
123 1
                continue;
124
            }
125
126 6
            $statements[] = $statement;
127
        }
128 8
        return $statements;
129
    }
130
}
131