Passed
Push — master ( b9383b...052ac9 )
by Jean-Christophe
01:25
created

ContentSecurity::addNonce()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 5
c 1
b 0
f 1
dl 0
loc 8
rs 10
cc 2
nc 2
nop 2
1
<?php
2
namespace Ubiquity\security\csp;
3
4
use Ubiquity\utils\http\UResponse;
5
6
/**
7
 * Creates a Content Security Policy object.
8
 * Ubiquity\security\csp$ContentSecurity
9
 * This class is part of Ubiquity
10
 *
11
 * @author jc
12
 * @version 1.0.0
13
 *
14
 */
15
class ContentSecurity {
16
17
	const HEADER = 'Content-Security-Policy';
18
19
	const DEBUG_HEADER = 'Content-Security-Policy-Report-Only';
20
21
	private array $policies = [];
22
23
	private $header = self::HEADER;
24
25
	public function addPolicy(string $directive, string ...$values): self {
26
		$policies = $this->policies[$directive] ?? [];
27
		foreach ($values as $v) {
28
			if (\in_array($v, CspValues::QUOTED)) {
29
				$v = "'$v'";
30
			}
31
			$policies[$v] = true;
32
		}
33
		$this->policies[$directive] = $policies;
34
		return $this;
35
	}
36
37
	public function addNonce(string $nonce, string ...$directives): self {
38
		$directives ??= [
39
			CspDirectives::DEFAULT_SRC
40
		];
41
		foreach ($directives as $directive) {
42
			$this->policies[$directive]["'nonce-$nonce'"] = true;
43
		}
44
		return $this;
45
	}
46
47
	public function setDefaultSrc(string ...$policies) {
48
		return $this->addPolicy(CspDirectives::DEFAULT_SRC, ...$policies);
49
	}
50
51
	public function generate(): string {
52
		$strs = '';
53
		foreach ($this->policies as $directive => $policy) {
54
			$policies = \array_keys($policy);
55
			$strs .= $directive . ' ' . \implode(' ', $policies) . ';';
56
		}
57
		return $strs;
58
	}
59
60
	public function reportOnly(bool $reportOnly = true): self {
61
		$this->header = $reportOnly ? self::DEBUG_HEADER : self::HEADER;
62
		return $this;
63
	}
64
65
	public function addHeaderToResponse(): void {
66
		UResponse::header($this->header, $this->generate());
67
	}
68
69
	public static function nonce($nonce, string ...$directives): void {
70
		$csp = new self();
71
		$csp->addNonce($nonce, ...$directives);
72
		$csp->addHeaderToResponse();
73
	}
74
}
75
76