Skip to content

Commit 51a304f

Browse files
committed
DI extensions: are using configuration Schema
1 parent 76ad266 commit 51a304f

File tree

3 files changed

+64
-52
lines changed

3 files changed

+64
-52
lines changed

composer.json

+3
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
"nette/tester": "^2.0",
2424
"tracy/tracy": "^2.4"
2525
},
26+
"conflict": {
27+
"nette/di": "<3.0"
28+
},
2629
"suggest": {
2730
"ext-fileinfo": "to detect type of uploaded files",
2831
"nette/security": "allows use Nette\\Http\\UserStorage"

src/Bridges/HttpDI/HttpExtension.php

+31-26
Original file line numberDiff line numberDiff line change
@@ -11,26 +11,14 @@
1111

1212
use Nette;
1313
use Nette\PhpGenerator\Helpers;
14+
use Nette\Schema\Expect;
1415

1516

1617
/**
1718
* HTTP extension for Nette DI.
1819
*/
1920
class HttpExtension extends Nette\DI\CompilerExtension
2021
{
21-
public $defaults = [
22-
'proxy' => [],
23-
'headers' => [
24-
'X-Powered-By' => 'Nette Framework 3',
25-
'Content-Type' => 'text/html; charset=utf-8',
26-
],
27-
'frames' => 'SAMEORIGIN', // X-Frame-Options
28-
'csp' => [], // Content-Security-Policy
29-
'cspReportOnly' => [], // Content-Security-Policy-Report-Only
30-
'featurePolicy' => [], // Feature-Policy
31-
'cookieSecure' => 'auto', // true|false|auto Whether the cookie is available only through HTTPS
32-
];
33-
3422
/** @var bool */
3523
private $cliMode;
3624

@@ -41,25 +29,42 @@ public function __construct(bool $cliMode = false)
4129
}
4230

4331

32+
public function getConfigSchema(): Nette\Schema\Schema
33+
{
34+
return Expect::structure([
35+
'proxy' => Expect::arrayOf('string')->dynamic(),
36+
'headers' => Expect::arrayOf('scalar|null')->default([
37+
'X-Powered-By' => 'Nette Framework 3',
38+
'Content-Type' => 'text/html; charset=utf-8',
39+
]),
40+
'frames' => Expect::anyOf(Expect::string(), Expect::bool(), null)->default('SAMEORIGIN'), // X-Frame-Options
41+
'csp' => Expect::arrayOf('array|scalar|null'), // Content-Security-Policy
42+
'cspReportOnly' => Expect::arrayOf('array|scalar|null'), // Content-Security-Policy-Report-Only
43+
'featurePolicy' => Expect::arrayOf('array|scalar|null'), // Feature-Policy
44+
'cookieSecure' => Expect::anyOf(null, true, false, 'auto'), // true|false|auto Whether the cookie is available only through HTTPS
45+
]);
46+
}
47+
48+
4449
public function loadConfiguration()
4550
{
4651
$builder = $this->getContainerBuilder();
47-
$config = $this->validateConfig($this->defaults);
52+
$config = $this->config;
4853

4954
$builder->addDefinition($this->prefix('requestFactory'))
5055
->setFactory(Nette\Http\RequestFactory::class)
51-
->addSetup('setProxy', [$config['proxy']]);
56+
->addSetup('setProxy', [$config->proxy]);
5257

5358
$builder->addDefinition($this->prefix('request'))
5459
->setFactory('@Nette\Http\RequestFactory::createHttpRequest');
5560

5661
$response = $builder->addDefinition($this->prefix('response'))
5762
->setFactory(Nette\Http\Response::class);
5863

59-
if (isset($config['cookieSecure'])) {
60-
$value = $config['cookieSecure'] === 'auto'
64+
if ($config->cookieSecure !== null) {
65+
$value = $config->cookieSecure === 'auto'
6166
? $builder::literal('$this->getService(?)->isSecured()', [$this->prefix('request')])
62-
: (bool) $config['cookieSecure'];
67+
: $config->cookieSecure;
6368
$response->addSetup('$cookieSecure', [$value]);
6469
}
6570

@@ -78,11 +83,11 @@ public function afterCompile(Nette\PhpGenerator\ClassType $class)
7883
}
7984

8085
$initialize = $class->getMethod('initialize');
81-
$config = $this->getConfig();
82-
$headers = array_map('strval', $config['headers']);
86+
$config = $this->config;
87+
$headers = array_map('strval', $config->headers);
8388

84-
if (isset($config['frames']) && $config['frames'] !== true && !isset($headers['X-Frame-Options'])) {
85-
$frames = $config['frames'];
89+
if (isset($config->frames) && $config->frames !== true && !isset($headers['X-Frame-Options'])) {
90+
$frames = $config->frames;
8691
if ($frames === false) {
8792
$frames = 'DENY';
8893
} elseif (preg_match('#^https?:#', $frames)) {
@@ -93,10 +98,10 @@ public function afterCompile(Nette\PhpGenerator\ClassType $class)
9398

9499
$code = [];
95100
foreach (['csp', 'cspReportOnly'] as $key) {
96-
if (empty($config[$key])) {
101+
if (empty($config->$key)) {
97102
continue;
98103
}
99-
$value = self::buildPolicy($config[$key]);
104+
$value = self::buildPolicy($config->$key);
100105
if (strpos($value, "'nonce'")) {
101106
$code[0] = '$cspNonce = base64_encode(random_bytes(16));';
102107
$value = Nette\DI\ContainerBuilder::literal(
@@ -107,8 +112,8 @@ public function afterCompile(Nette\PhpGenerator\ClassType $class)
107112
$headers['Content-Security-Policy' . ($key === 'csp' ? '' : '-Report-Only')] = $value;
108113
}
109114

110-
if (!empty($config['featurePolicy'])) {
111-
$headers['Feature-Policy'] = self::buildPolicy($config['featurePolicy']);
115+
if (!empty($config->featurePolicy)) {
116+
$headers['Feature-Policy'] = self::buildPolicy($config->featurePolicy);
112117
}
113118

114119
$code[] = Helpers::formatArgs('$response = $this->getService(?);', [$this->prefix('response')]);

src/Bridges/HttpDI/SessionExtension.php

+30-26
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,14 @@
1010
namespace Nette\Bridges\HttpDI;
1111

1212
use Nette;
13+
use Nette\Schema\Expect;
1314

1415

1516
/**
1617
* Session extension for Nette DI.
1718
*/
1819
class SessionExtension extends Nette\DI\CompilerExtension
1920
{
20-
public $defaults = [
21-
'debugger' => false,
22-
'autoStart' => 'smart', // true|false|smart
23-
'expiration' => null,
24-
'handler' => null,
25-
];
26-
2721
/** @var bool */
2822
private $debugMode;
2923

@@ -38,40 +32,51 @@ public function __construct(bool $debugMode = false, bool $cliMode = false)
3832
}
3933

4034

35+
public function getConfigSchema(): Nette\Schema\Schema
36+
{
37+
return Expect::structure([
38+
'debugger' => Expect::bool(false),
39+
'autoStart' => Expect::anyOf('smart', true, false)->default('smart'),
40+
'expiration' => Expect::string()->dynamic(),
41+
'handler' => Expect::string()->dynamic(),
42+
])->otherItems('mixed');
43+
}
44+
45+
4146
public function loadConfiguration()
4247
{
4348
$builder = $this->getContainerBuilder();
44-
$config = $this->getConfig() + $this->defaults;
45-
$this->setConfig($config);
49+
$config = $this->config;
4650

4751
$session = $builder->addDefinition($this->prefix('session'))
4852
->setFactory(Nette\Http\Session::class);
4953

50-
if ($config['expiration']) {
51-
$session->addSetup('setExpiration', [$config['expiration']]);
54+
if ($config->expiration) {
55+
$session->addSetup('setExpiration', [$config->expiration]);
5256
}
53-
if ($config['handler']) {
54-
$session->addSetup('setHandler', [$config['handler']]);
57+
if ($config->handler) {
58+
$session->addSetup('setHandler', [$config->handler]);
5559
}
56-
if (($config['cookieDomain'] ?? null) === 'domain') {
57-
$config['cookieDomain'] = $builder::literal('$this->getByType(Nette\Http\IRequest::class)->getUrl()->getDomain(2)');
60+
if (($config->cookieDomain ?? null) === 'domain') {
61+
$config->cookieDomain = $builder::literal('$this->getByType(Nette\Http\IRequest::class)->getUrl()->getDomain(2)');
5862
}
59-
if (($config['cookieSecure'] ?? null) === 'auto') {
60-
$config['cookieSecure'] = $builder::literal('$this->getByType(Nette\Http\IRequest::class)->isSecured()');
63+
if (($config->cookieSecure ?? null) === 'auto') {
64+
$config->cookieSecure = $builder::literal('$this->getByType(Nette\Http\IRequest::class)->isSecured()');
6165
}
62-
if (($config['cookieSamesite'] ?? null) === true) {
63-
$config['cookieSamesite'] = 'Lax';
66+
if (($config->cookieSamesite ?? null) === true) {
67+
$config->cookieSamesite = 'Lax';
6468
}
6569

66-
if ($this->debugMode && $config['debugger']) {
70+
if ($this->debugMode && $config->debugger) {
6771
$session->addSetup('@Tracy\Bar::addPanel', [
6872
new Nette\DI\Definitions\Statement(Nette\Bridges\HttpTracy\SessionPanel::class),
6973
]);
7074
}
7175

72-
unset($config['expiration'], $config['handler'], $config['autoStart'], $config['debugger']);
73-
if (!empty($config)) {
74-
$session->addSetup('setOptions', [$config]);
76+
$options = (array) $config;
77+
unset($options['expiration'], $options['handler'], $options['autoStart'], $options['debugger']);
78+
if (!empty($options)) {
79+
$session->addSetup('setOptions', [$options]);
7580
}
7681

7782
if ($this->name === 'session') {
@@ -87,13 +92,12 @@ public function afterCompile(Nette\PhpGenerator\ClassType $class)
8792
}
8893

8994
$initialize = $class->getMethod('initialize');
90-
$config = $this->getConfig();
9195
$name = $this->prefix('session');
9296

93-
if ($config['autoStart'] === 'smart') {
97+
if ($this->config->autoStart === 'smart') {
9498
$initialize->addBody('$this->getService(?)->exists() && $this->getService(?)->start();', [$name, $name]);
9599

96-
} elseif ($config['autoStart']) {
100+
} elseif ($this->config->autoStart) {
97101
$initialize->addBody('$this->getService(?)->start();', [$name]);
98102
}
99103
}

0 commit comments

Comments
 (0)