14
14
namespace Nelmio \SecurityBundle \EventListener ;
15
15
16
16
use Nelmio \SecurityBundle \ContentSecurityPolicy \DirectiveSet ;
17
+ use Nelmio \SecurityBundle \ContentSecurityPolicy \DirectiveSetBuilderInterface ;
18
+ use Nelmio \SecurityBundle \ContentSecurityPolicy \LegacyDirectiveSetBuilder ;
17
19
use Nelmio \SecurityBundle \ContentSecurityPolicy \NonceGeneratorInterface ;
18
20
use Nelmio \SecurityBundle \ContentSecurityPolicy \ShaComputerInterface ;
19
21
use Symfony \Component \HttpFoundation \Request ;
24
26
25
27
final class ContentSecurityPolicyListener extends AbstractContentTypeRestrictableListener
26
28
{
27
- private DirectiveSet $ report ;
28
- private DirectiveSet $ enforce ;
29
+ private DirectiveSetBuilderInterface $ reportDirectiveSetBuilder ;
30
+ private DirectiveSetBuilderInterface $ enforceDirectiveSetBuilder ;
29
31
private bool $ compatHeaders ;
30
32
31
33
/**
@@ -45,12 +47,14 @@ final class ContentSecurityPolicyListener extends AbstractContentTypeRestrictabl
45
47
private ?RequestMatcherInterface $ requestMatcher ;
46
48
47
49
/**
48
- * @param list<string> $hosts
49
- * @param list<string> $contentTypes
50
+ * @param DirectiveSetBuilderInterface|DirectiveSet $reportDirectiveSetBuilder
51
+ * @param DirectiveSetBuilderInterface|DirectiveSet $enforceDirectiveSetBuilder
52
+ * @param list<string> $hosts
53
+ * @param list<string> $contentTypes
50
54
*/
51
55
public function __construct (
52
- DirectiveSet $ report ,
53
- DirectiveSet $ enforce ,
56
+ $ reportDirectiveSetBuilder ,
57
+ $ enforceDirectiveSetBuilder ,
54
58
NonceGeneratorInterface $ nonceGenerator ,
55
59
ShaComputerInterface $ shaComputer ,
56
60
bool $ compatHeaders = true ,
@@ -59,8 +63,8 @@ public function __construct(
59
63
?RequestMatcherInterface $ requestMatcher = null
60
64
) {
61
65
parent ::__construct ($ contentTypes );
62
- $ this ->report = $ report ;
63
- $ this ->enforce = $ enforce ;
66
+ $ this ->reportDirectiveSetBuilder = $ this -> ensureDirectiveSetBuilder ( $ reportDirectiveSetBuilder ) ;
67
+ $ this ->enforceDirectiveSetBuilder = $ this -> ensureDirectiveSetBuilder ( $ enforceDirectiveSetBuilder ) ;
64
68
$ this ->compatHeaders = $ compatHeaders ;
65
69
$ this ->hosts = $ hosts ;
66
70
$ this ->nonceGenerator = $ nonceGenerator ;
@@ -110,14 +114,20 @@ public function addStyle(string $html): void
110
114
$ this ->sha ['style-src ' ][] = $ this ->shaComputer ->computeForStyle ($ html );
111
115
}
112
116
117
+ /**
118
+ * @deprecated Use `nelmio_security.directive_set_builder.report` instead.
119
+ */
113
120
public function getReport (): DirectiveSet
114
121
{
115
- return $ this ->report ;
122
+ return $ this ->reportDirectiveSetBuilder -> buildDirectiveSet () ;
116
123
}
117
124
125
+ /**
126
+ * @deprecated Use `nelmio_security.directive_set_builder.enforce` instead.
127
+ */
118
128
public function getEnforcement (): DirectiveSet
119
129
{
120
- return $ this ->enforce ;
130
+ return $ this ->enforceDirectiveSetBuilder -> buildDirectiveSet () ;
121
131
}
122
132
123
133
public function getNonce (string $ usage ): string
@@ -169,10 +179,10 @@ public function onKernelResponse(ResponseEvent $e): void
169
179
}
170
180
171
181
if (!$ response ->headers ->has ('Content-Security-Policy-Report-Only ' )) {
172
- $ response ->headers ->add ($ this ->buildHeaders ($ request , $ this ->report , true , $ this ->compatHeaders , $ signatures ));
182
+ $ response ->headers ->add ($ this ->buildHeaders ($ request , $ this ->reportDirectiveSetBuilder -> buildDirectiveSet () , true , $ this ->compatHeaders , $ signatures ));
173
183
}
174
184
if (!$ response ->headers ->has ('Content-Security-Policy ' )) {
175
- $ response ->headers ->add ($ this ->buildHeaders ($ request , $ this ->enforce , false , $ this ->compatHeaders , $ signatures ));
185
+ $ response ->headers ->add ($ this ->buildHeaders ($ request , $ this ->enforceDirectiveSetBuilder -> buildDirectiveSet () , false , $ this ->compatHeaders , $ signatures ));
176
186
}
177
187
}
178
188
@@ -233,4 +243,31 @@ private function buildHeaders(
233
243
234
244
return $ headers ;
235
245
}
246
+
247
+ /**
248
+ * @param DirectiveSetBuilderInterface|DirectiveSet $builderOrDirectiveSet
249
+ */
250
+ private function ensureDirectiveSetBuilder ($ builderOrDirectiveSet ): DirectiveSetBuilderInterface
251
+ {
252
+ if ($ builderOrDirectiveSet instanceof DirectiveSetBuilderInterface) {
253
+ return $ builderOrDirectiveSet ;
254
+ }
255
+
256
+ if ($ builderOrDirectiveSet instanceof DirectiveSet) {
257
+ trigger_deprecation (
258
+ 'nelmio/security-bundle ' ,
259
+ '3.5 ' ,
260
+ sprintf (
261
+ 'Passing %s directly to the %s constructor is deprecated and will be removed in 4.0. Pass a %s instead. ' ,
262
+ DirectiveSet::class,
263
+ self ::class,
264
+ DirectiveSetBuilderInterface::class
265
+ )
266
+ );
267
+
268
+ return new LegacyDirectiveSetBuilder ($ builderOrDirectiveSet );
269
+ }
270
+
271
+ throw new \InvalidArgumentException (sprintf ('The %s constructor %s expects a or %s. ' , self ::class, DirectiveSetBuilderInterface::class, DirectiveSet::class));
272
+ }
236
273
}
0 commit comments