NonceContainer::getCspValue()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 2
dl 0
loc 3
ccs 0
cts 2
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * SEOmatic plugin for Craft CMS 3.x
4
 *
5
 * A turnkey SEO implementation for Craft CMS that is comprehensive, powerful,
6
 * and flexible
7
 *
8
 * @link      https://nystudio107.com
9
 * @copyright Copyright (c) 2017 nystudio107
10
 */
11
12
namespace nystudio107\seomatic\base;
13
14
use Craft;
15
use nystudio107\seomatic\helpers\Dependency;
16
use nystudio107\seomatic\models\MetaJsonLdContainer;
17
use nystudio107\seomatic\models\MetaScriptContainer;
18
19
use nystudio107\seomatic\Seomatic;
20
21
/**
22
 * @author    nystudio107
23
 * @package   Seomatic
24
 * @since     3.3.11
25
 */
26
abstract class NonceContainer extends MetaContainer implements NonceContainerInterface
27
{
28
    // Traits
29
    // =========================================================================
30
31
    use NonceContainerTrait;
32
33
    // Constants
34
    // =========================================================================
35
36
    const CSP_HEADERS = [
37
        'Content-Security-Policy',
38
        'X-Content-Security-Policy',
39
        'X-WebKit-CSP',
40
    ];
41
42
    const CSP_DIRECTIVE = 'script-src';
43
44
    // Public Methods
45
    // =========================================================================
46
47
    /**
48
     * @inheritDoc
49
     */
50
    public function addNonceTags(array $cspNonces)
51
    {
52
        if (!empty(Seomatic::$settings->cspNonce) && Seomatic::$settings->cspNonce === 'tag' && !empty($cspNonces)) {
53
            $serializedNonces = implode(" ", $cspNonces);
54
            $cspHeader = self::CSP_HEADERS[0];
55
            $cspDirective = self::CSP_DIRECTIVE;
56
            $cspValue = "{$cspDirective} {$serializedNonces};";
57
            $metaTag = Seomatic::$plugin->tag->create([
0 ignored issues
show
Unused Code introduced by
The assignment to $metaTag is dead and can be removed.
Loading history...
58
                'key' => md5($cspValue),
59
                'httpEquiv' => $cspHeader,
60
                'content' => $cspValue,
61
            ]);
62
        }
63
    }
64
65
    /**
66
     * @inheritDoc
67
     */
68
    public function addNonceHeaders(array $cspNonces)
69
    {
70
        if (!empty(Seomatic::$settings->cspNonce) && Seomatic::$settings->cspNonce === 'header' && !empty($cspNonces)) {
71
            $serializedNonces = implode(" ", $cspNonces);
72
            $cspDirective = self::CSP_DIRECTIVE;
73
            $cspValue = "{$cspDirective} {$serializedNonces};";
74
            foreach (self::CSP_HEADERS as $cspHeader) {
75
                Craft::$app->getResponse()->getHeaders()->add($cspHeader, $cspValue);
76
            }
77
        }
78
    }
79
80
    /**
81
     * @inheritDoc
82
     */
83
    public function getCspNonces(): array
84
    {
85
        $cspNonces = [];
86
        /** @var NonceItem $metaItemModel */
87
        foreach ($this->data as $metaItemModel) {
88
            if ($metaItemModel->include && !empty($metaItemModel->nonce)) {
0 ignored issues
show
Bug Best Practice introduced by
The property nonce does not exist on nystudio107\seomatic\base\MetaItem. Since you implemented __get, consider adding a @property annotation.
Loading history...
89
                $dependencies = [];
90
                $nonce = $metaItemModel->nonce;
91
                if ($this instanceof MetaScriptContainer) {
92
                    $dependencies = [
93
                        Dependency::SCRIPT_DEPENDENCY => [$metaItemModel->key],
94
                    ];
95
                }
96
                if ($this instanceof MetaJsonLdContainer) {
97
                    $dependencies = [
98
                        Dependency::JSONLD_DEPENDENCY => [$metaItemModel->key],
99
                    ];
100
                }
101
                $cspNonce = "'nonce-{$nonce}'";
102
                if (Dependency::validateDependencies($dependencies) && !in_array($cspNonce, $cspNonces, true)) {
103
                    $cspNonces[] = $cspNonce;
104
                }
105
            }
106
        }
107
108
        return $cspNonces;
109
    }
110
111
    // Protected Methods
112
    // =========================================================================
113
114
115
    /**
116
     * Return a CSP value for inclusion in header or meta tag
117
     *
118
     * @param string $nonce
119
     * @param string $cspDirective
120
     * @return string
121
     */
122
    protected function getCspValue(string $nonce, string $cspDirective): string
123
    {
124
        return "{$cspDirective} 'nonce-$nonce'";
125
    }
126
}
127