Passed
Push — master ( e72a08...1fd564 )
by Jean-Christophe
01:13
created

ContentSecurityManager::getNonceGenerator()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 2
rs 10
cc 1
nc 1
nop 0
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 ?callable $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
		if (isset(self::$onGenerate) && ! URequest::isAjax()) {
66
			$onG = self::$onGenerate;
67
			$onG($name, $hash, $algo);
68
		}
69
		return $hash;
70
	}
71
72
	/**
73
	 *
74
	 * @param string $name
75
	 * @return bool
76
	 */
77
	public static function hasNonce(string $name): bool {
78
		if (isset(self::$nonceGenerator)) {
79
			return self::$nonceGenerator->hasNonce($name);
80
		}
81
		return false;
82
	}
83
84
	/**
85
	 * Checks if the manager is started.
86
	 *
87
	 * @return bool
88
	 */
89
	public static function isStarted(): bool {
90
		return isset(self::$nonceGenerator);
91
	}
92
93
	/**
94
	 * Creates and returns a new ContentSecurity object.
95
	 *
96
	 * @param bool|null $reportOnly
97
	 * @return ContentSecurity
98
	 */
99
	public static function addCsp(?bool $reportOnly = null): ContentSecurity {
100
		return self::$csp[] = new ContentSecurity($reportOnly ?? self::$reportOnly);
101
	}
102
103
	/**
104
	 * Removes all CSP objects.
105
	 */
106
	public static function clearCsp(): void {
107
		self::$csp = [];
108
	}
109
110
	/**
111
	 * Creates a new ContentSecurity object for Ubiquity Webtools.
112
	 *
113
	 * @param bool|null $reportOnly
114
	 * @return ContentSecurity
115
	 */
116
	public static function defaultUbiquity(?bool $reportOnly = null): ContentSecurity {
117
		return self::$csp[] = ContentSecurity::defaultUbiquity()->reportOnly($reportOnly);
118
	}
119
120
	/**
121
	 * Creates a new ContentSecurity object for Ubiquity Webtools in debug mode.
122
	 *
123
	 * @param bool|null $reportOnly
124
	 * @param string $livereloadServer
125
	 * @return ContentSecurity
126
	 */
127
	public static function defaultUbiquityDebug(?bool $reportOnly = null, string $livereloadServer = '127.0.0.1:35729'): ContentSecurity {
128
		return self::$csp[] = ContentSecurity::defaultUbiquityDebug($livereloadServer)->reportOnly($reportOnly);
129
	}
130
131
	/**
132
	 * Adds all Content security policies to headers.
133
	 *
134
	 * @param bool|null $reportOnly
135
	 */
136
	public static function addHeadersToResponse(?bool $reportOnly = null): void {
137
		$reportOnly ??= self::$reportOnly;
138
		foreach (self::$csp as $csp) {
139
			$csp->addHeaderToResponse($reportOnly);
140
		}
141
	}
142
143
	/**
144
	 * Returns the NonceGenerator instance.
145
	 *
146
	 * @return NonceGenerator
147
	 */
148
	public static function getNonceGenerator(): NonceGenerator {
149
		return self::$nonceGenerator;
150
	}
151
152
	/**
153
	 *
154
	 * @return array
155
	 */
156
	public static function getCsp(): array {
157
		return self::$csp;
158
	}
159
160
	/**
161
	 * Returns true if reportOnly header is activated.
162
	 *
163
	 * @return bool
164
	 */
165
	public static function isReportOnly(): bool {
166
		return self::$reportOnly;
167
	}
168
169
	/**
170
	 *
171
	 * @return string
172
	 */
173
	public static function getHashAlgo(): string {
174
		return ContentSecurityManager::$hashAlgo;
175
	}
176
177
	/**
178
	 *
179
	 * @param string $hashAlgo
180
	 */
181
	public static function setHashAlgo(string $hashAlgo) {
182
		ContentSecurityManager::$hashAlgo = $hashAlgo;
183
	}
184
185
	/**
186
	 *
187
	 * @param callable $onGenerate
188
	 */
189
	public static function setOnGenerate(callable $onGenerate) {
190
		ContentSecurityManager::$onGenerate = $onGenerate;
191
	}
192
}
193