ContentSecurityPolicyManager::getHeader()   C
last analyzed

Complexity

Conditions 13
Paths 16

Size

Total Lines 55
Code Lines 37

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 37
dl 0
loc 55
rs 6.6166
c 1
b 0
f 0
cc 13
nc 16
nop 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/******************************************************************************
3
 * Wikipedia Account Creation Assistance tool                                 *
4
 *                                                                            *
5
 * All code in this file is released into the public domain by the ACC        *
6
 * Development Team. Please see team.json for a list of contributors.         *
7
 ******************************************************************************/
8
9
namespace Waca\Security;
10
11
use Waca\SiteConfiguration;
12
13
class ContentSecurityPolicyManager
14
{
15
    private $policy = [
16
        'default-src'     => [],
17
        'script-src'      => ['self', 'nonce'],
18
        'script-src-elem' => ['self', 'nonce'],
19
        'script-src-attr' => [],
20
        'connect-src'     => ['self'],
21
        'style-src'       => ['self'],
22
        'style-src-elem'  => ['self'],
23
        'style-src-attr'  => [],
24
        'img-src'         => ['self', 'data:', 'https://upload.wikimedia.org', 'https://accounts-dev.wmflabs.org/'],
25
        'font-src'        => ['self'],
26
        'form-action'     => ['self', 'oauth'],
27
        'frame-ancestors' => ['self'],
28
        'frame-src'       => ['self'],
29
    ];
30
    private $nonce = null;
31
    private $reportOnly = false;
32
    /**
33
     * @var SiteConfiguration
34
     */
35
    private $configuration;
36
37
    /**
38
     * ContentSecurityPolicyManager constructor.
39
     *
40
     * @param SiteConfiguration $configuration
41
     */
42
    public function __construct(SiteConfiguration $configuration)
43
    {
44
        $this->configuration = $configuration;
45
    }
46
47
    public function getNonce()
48
    {
49
        if ($this->nonce === null) {
50
            $this->nonce = base64_encode(openssl_random_pseudo_bytes(32));
51
        }
52
53
        return $this->nonce;
54
    }
55
56
    public function getHeader(): string
57
    {
58
        $reportOnly = '';
59
        if ($this->reportOnly) {
60
            $reportOnly = '-Report-Only';
61
        }
62
63
        $constructedPolicy = "Content-Security-Policy{$reportOnly}: ";
64
65
        foreach ($this->policy as $item => $values) {
66
            $constructedPolicy .= $item . ' ';
67
            $policyIsSet = false;
68
69
            if (count($values) > 0) {
70
                foreach ($values as $value) {
71
                    switch ($value) {
72
                        case 'none':
73
                        case 'self':
74
                        case 'strict-dynamic':
75
                            $policyIsSet = true;
76
                            $constructedPolicy .= "'{$value}' ";
77
                            break;
78
                        case 'nonce':
79
                            if ($this->nonce !== null) {
80
                                $policyIsSet = true;
81
                                $constructedPolicy .= "'nonce-{$this->nonce}' ";
82
                            }
83
                            break;
84
                        case 'oauth':
85
                            $policyIsSet = true;
86
                            $constructedPolicy .= "{$this->configuration->getOauthMediaWikiCanonicalServer()} ";
87
                            break;
88
                        default:
89
                            $policyIsSet = true;
90
                            $constructedPolicy .= $value . ' ';
91
                            break;
92
                    }
93
                }
94
95
                if (!$policyIsSet) {
96
                    $constructedPolicy .= "'none' ";
97
                }
98
            }
99
            else {
100
                $constructedPolicy .= "'none' ";
101
            }
102
103
            $constructedPolicy .= '; ';
104
        }
105
106
        if ($this->configuration->getCspReportUri() !== null) {
107
            $constructedPolicy .= 'report-uri ' . $this->configuration->getCspReportUri();
108
        }
109
110
        return $constructedPolicy;
111
    }
112
}
113