Passed
Push — v4 ( 6305b5...61df73 )
by Andrew
15:54 queued 14s
created

BlacklistSecurityPolicy::__construct()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 2
eloc 4
nc 2
nop 1
dl 0
loc 7
rs 10
c 2
b 0
f 0
1
<?php
2
3
namespace nystudio107\crafttwigsandbox\twig;
4
5
use nystudio107\crafttwigsandbox\helpers\SecurityPolicy;
6
use Twig\Markup;
7
use Twig\Sandbox\SecurityNotAllowedFilterError;
8
use Twig\Sandbox\SecurityNotAllowedFunctionError;
9
use Twig\Sandbox\SecurityNotAllowedMethodError;
10
use Twig\Sandbox\SecurityNotAllowedPropertyError;
11
use Twig\Sandbox\SecurityNotAllowedTagError;
12
use Twig\Template;
13
use function get_class;
14
15
class BlacklistSecurityPolicy extends BaseSecurityPolicy
16
{
17
    // Public Methods
18
    // =========================================================================
19
20
    /**
21
     * @inheritDoc
22
     */
23
    public function __construct($config = [])
24
    {
25
        if (empty($config)) {
26
            $config = SecurityPolicy::getConfigFromFile('blacklist-sandbox', '@vendor/nystudio107/craft-twig-sandbox/src/config');
27
            unset($config['class']);
28
        }
29
        parent::__construct($config);
30
    }
31
32
    /**
33
     * @inheritDoc
34
     */
35
    public function checkSecurity($tags, $filters, $functions): void
36
    {
37
        foreach ($tags as $tag) {
38
            if (in_array($tag, $this->getTwigTags(), true)) {
39
                throw new SecurityNotAllowedTagError(sprintf('Tag "%s" is not allowed.', $tag), $tag);
40
            }
41
        }
42
43
        foreach ($filters as $filter) {
44
            if (in_array($filter, $this->getTwigFilters(), true)) {
45
                throw new SecurityNotAllowedFilterError(sprintf('Filter "%s" is not allowed.', $filter), $filter);
46
            }
47
        }
48
49
        foreach ($functions as $function) {
50
            if (in_array($function, $this->getTwigFunctions(), true)) {
51
                throw new SecurityNotAllowedFunctionError(sprintf('Function "%s" is not allowed.', $function), $function);
52
            }
53
        }
54
    }
55
56
    /**
57
     * @inheritDoc
58
     */
59
    public function checkMethodAllowed($obj, $method): void
60
    {
61
        if ($obj instanceof Template || $obj instanceof Markup) {
62
            return;
63
        }
64
65
        $method = strtr($method, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz');
66
        $allowed = true;
67
        foreach ($this->getTwigMethods() as $class => $methods) {
68
            if ($obj instanceof $class) {
69
                if ($methods[0] === '*' || in_array($method, $methods, true)) {
70
                    $allowed = false;
71
                    break;
72
                }
73
            }
74
        }
75
76
        if (!$allowed) {
77
            $class = get_class($obj);
78
            throw new SecurityNotAllowedMethodError(sprintf('Calling "%s" method on a "%s" object is not allowed.', $method, $class), $class, $method);
79
        }
80
    }
81
82
    /**
83
     * @inheritDoc
84
     */
85
    public function checkPropertyAllowed($obj, $property): void
86
    {
87
        $allowed = true;
88
        $property = strtr($property, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz');
89
        foreach ($this->getTwigProperties() as $class => $properties) {
90
            if ($obj instanceof $class) {
91
                if ($properties[0] === '*' || in_array($property, $properties, true)) {
92
                    $allowed = false;
93
                    break;
94
                }
95
            }
96
        }
97
98
        if (!$allowed) {
99
            $class = get_class($obj);
100
            throw new SecurityNotAllowedPropertyError(sprintf('Accessing "%s" property on a "%s" object is not allowed.', $property, $class), $class, $property);
101
        }
102
    }
103
}
104