Passed
Push — master ( c9e762...dcd9a4 )
by Jean-Christophe
07:19
created

ContentSecurityManager::defaultUbiquityDebug()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 1
c 1
b 0
f 1
dl 0
loc 2
rs 10
cc 1
nc 1
nop 2
1
<?php
2
namespace Ubiquity\security\csp;
3
4
use Ubiquity\utils\http\URequest;
5
6
/**
7
 * Manage Content Security Policies.
8
 * Ubiquity\security\csp$ContentSecurityManager
9
 * This class is part of Ubiquity
10
 *
11
 * @author jc
12
 * @version 1.0.0
13
 *
14
 */
15
class ContentSecurityManager {
16
17
	private static NonceGenerator $nonceGenerator;
18
19
	private static array $csp = [];
20
21
	private static bool $reportOnly;
22
23
	private static string $hashAlgo = 'sha256';
24
25
	private static $onGenerate;
26
27
	/**
28
	 * Starts the Content Security Policies manager.
29
	 *
30
	 * @param string|null $nonceGeneratorClass
31
	 *        	The class used for generating nonces.
32
	 * @param bool $reportOnly
33
	 * @param callable|null $onGenerate
34
	 */
35
	public static function start(string $nonceGeneratorClass = null, bool $reportOnly = false, ?callable $onGenerate = null): void {
36
		$nonceGeneratorClass ??= NonceGenerator::class;
37
		self::$onGenerate = $onGenerate;
38
		self::$nonceGenerator = new $nonceGeneratorClass($onGenerate);
39
		self::$reportOnly = $reportOnly;
40
	}
41
42
	/**
43
	 * Returns a new or an existing nonce.
44
	 *
45
	 * @param string $name
46
	 *        	The nonce to create
47
	 * @return string
48
	 */
49
	public static function getNonce(string $name): string {
50
		return self::$nonceGenerator->getNonce($name);
51
	}
52
53
	/**
54
	 * Generates a hash and add it to a directive.
55
	 *
56
	 * @param string $name
57
	 * @param string $code
58
	 * @param string $algo
59
	 *        	default sha256, possible value sha384,sha512
60
	 * @return string
61
	 */
62
	public static function getHash(string $name, string $code, string $algo = 'sha256'): string {
63
		$code = \preg_replace('/\r\n/', '\n', $code);
64
		$hash = \base64_encode(\hash($algo, $code, true));
65
		$hash = "$algo-$hash";
66
		if (isset(self::$onGenerate) && ! URequest::isAjax()) {
67
			$onG = self::$onGenerate;
68
			$onG($name, $hash, $algo);
69
		}
70
		return $hash;
71
	}
72
73
	/**
74
	 *
75
	 * @param string $name
76
	 * @return bool
77
	 */
78
	public static function hasNonce(string $name): bool {
79
		if (isset(self::$nonceGenerator)) {
80
			return self::$nonceGenerator->hasNonce($name);
81
		}
82
		return false;
83
	}
84
85
	/**
86
	 * Checks if the manager is started.
87
	 *
88
	 * @return bool
89
	 */
90
	public static function isStarted(): bool {
91
		return isset(self::$nonceGenerator);
92
	}
93
94
	/**
95
	 * Creates and returns a new ContentSecurity object.
96
	 *
97
	 * @param bool|null $reportOnly
98
	 * @return ContentSecurity
99
	 */
100
	public static function addCsp(?bool $reportOnly = null): ContentSecurity {
101
		return self::$csp[] = new ContentSecurity($reportOnly ?? self::$reportOnly);
102
	}
103
104
	/**
105
	 * Returns a default ContentSecurity object.
106
	 *
107
	 * @param bool $reportOnly
108
	 * @return ContentSecurity
109
	 */
110
	public static function defaultCsp(?bool $reportOnly = null): ContentSecurity {
111
		return self::$csp['default'] ??= new ContentSecurity($reportOnly ?? self::$reportOnly);
112
	}
113
114
	/**
115
	 * Removes all CSP objects.
116
	 */
117
	public static function clearCsp(): void {
118
		self::$csp = [];
119
	}
120
121
	/**
122
	 * Creates a new ContentSecurity object for Ubiquity Webtools.
123
	 *
124
	 * @param bool|null $reportOnly
125
	 * @return ContentSecurity
126
	 */
127
	public static function defaultUbiquity(?bool $reportOnly = null): ContentSecurity {
128
		return self::$csp['defaultUbiquity'] ??= ContentSecurity::defaultUbiquity()->reportOnly($reportOnly);
129
	}
130
131
	/**
132
	 * Creates a new ContentSecurity object for Ubiquity Webtools in debug mode.
133
	 *
134
	 * @param bool|null $reportOnly
135
	 * @param string $livereloadServer
136
	 * @return ContentSecurity
137
	 */
138
	public static function defaultUbiquityDebug(?bool $reportOnly = null, string $livereloadServer = '127.0.0.1:35729'): ContentSecurity {
139
		return self::$csp['defaultUbiquity'] ??= ContentSecurity::defaultUbiquityDebug($livereloadServer)->reportOnly($reportOnly);
140
	}
141
142
	/**
143
	 * Adds all Content security policies to headers.
144
	 *
145
	 * @param bool|null $reportOnly
146
	 */
147
	public static function addHeadersToResponse(?bool $reportOnly = null): void {
148
		$reportOnly ??= self::$reportOnly;
149
		foreach (self::$csp as $csp) {
150
			$csp->addHeaderToResponse($reportOnly);
151
		}
152
	}
153
154
	/**
155
	 * Returns the NonceGenerator instance.
156
	 *
157
	 * @return NonceGenerator
158
	 */
159
	public static function getNonceGenerator(): NonceGenerator {
160
		return self::$nonceGenerator;
161
	}
162
163
	/**
164
	 *
165
	 * @return array
166
	 */
167
	public static function getCsp(): array {
168
		return self::$csp;
169
	}
170
171
	/**
172
	 * Returns true if reportOnly header is activated.
173
	 *
174
	 * @return bool
175
	 */
176
	public static function isReportOnly(): bool {
177
		return self::$reportOnly;
178
	}
179
180
	/**
181
	 *
182
	 * @return string
183
	 */
184
	public static function getHashAlgo(): string {
185
		return ContentSecurityManager::$hashAlgo;
186
	}
187
188
	/**
189
	 *
190
	 * @param string $hashAlgo
191
	 */
192
	public static function setHashAlgo(string $hashAlgo) {
193
		ContentSecurityManager::$hashAlgo = $hashAlgo;
194
	}
195
196
	/**
197
	 *
198
	 * @param callable $onGenerate
199
	 */
200
	public static function setOnGenerate(callable $onGenerate) {
201
		ContentSecurityManager::$onGenerate = $onGenerate;
202
	}
203
}
204