• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

nette / security / 26320370796

23 May 2026 01:54AM UTC coverage: 91.851% (+0.04%) from 91.812%
26320370796

push

github

dg
User: deprecated magic properties (BC break)

541 of 589 relevant lines covered (91.85%)

0.92 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

94.59
/src/Bridges/SecurityDI/SecurityExtension.php
1
<?php declare(strict_types=1);
2

3
/**
4
 * This file is part of the Nette Framework (https://nette.org)
5
 * Copyright (c) 2004 David Grudl (https://davidgrudl.com)
6
 */
7

8
namespace Nette\Bridges\SecurityDI;
9

10
use Nette;
11
use Nette\Schema\Expect;
12
use Tracy;
13
use function is_array;
14

15

16
/**
17
 * Security extension for Nette DI.
18
 *
19
 * @property object{
20
 *     debugger: bool|null,
21
 *     users: array<string, string|array{password: string, roles?: string|list<string>, data?: array<string, mixed>}>,
22
 *     roles: array<string, string|list<string>|null>,
23
 *     resources: array<string, string|null>,
24
 *     authentication: object{
25
 *         storage: 'session'|'cookie',
26
 *         expiration: string|null,
27
 *         persistIdentity: bool,
28
 *         cookieName: string|null,
29
 *         cookieDomain: string|null,
30
 *         cookieSamesite: 'Lax'|'Strict'|'None'|null,
31
 *     },
32
 * } $config
33
 */
34
class SecurityExtension extends Nette\DI\CompilerExtension
35
{
36
        public function __construct(
1✔
37
                private readonly bool $debugMode = false,
38
        ) {
39
        }
1✔
40

41

42
        public function getConfigSchema(): Nette\Schema\Schema
43
        {
44
                return Expect::structure([
1✔
45
                        'debugger' => Expect::bool(),
1✔
46
                        'users' => Expect::arrayOf(
1✔
47
                                Expect::anyOf(
1✔
48
                                        Expect::string()->dynamic(), // user => password
1✔
49
                                        Expect::structure([ // user => password + roles + data
1✔
50
                                                'password' => Expect::string()->dynamic(),
1✔
51
                                                'roles' => Expect::anyOf(Expect::string(), Expect::listOf('string')),
1✔
52
                                                'data' => Expect::array(),
1✔
53
                                        ])->castTo('array'),
1✔
54
                                ),
55
                        ),
56
                        'roles' => Expect::arrayOf('string|array|null'), // role => parent(s)
1✔
57
                        'resources' => Expect::arrayOf('string|null'), // resource => parent
1✔
58
                        'authentication' => Expect::structure([
1✔
59
                                'storage' => Expect::anyOf('session', 'cookie')->default('session'),
1✔
60
                                'expiration' => Expect::string()->dynamic(),
1✔
61
                                'persistIdentity' => Expect::bool(true),
1✔
62
                                'cookieName' => Expect::string(),
1✔
63
                                'cookieDomain' => Expect::string(),
1✔
64
                                'cookieSamesite' => Expect::anyOf('Lax', 'Strict', 'None'),
1✔
65
                        ]),
66
                ]);
67
        }
68

69

70
        public function loadConfiguration(): void
71
        {
72
                $config = $this->config;
1✔
73
                $builder = $this->getContainerBuilder();
1✔
74

75
                $builder->addDefinition($this->prefix('passwords'))
1✔
76
                        ->setFactory(Nette\Security\Passwords::class);
1✔
77

78
                $auth = $config->authentication;
1✔
79
                $storage = $builder->addDefinition($this->prefix('userStorage'))
1✔
80
                        ->setType(Nette\Security\UserStorage::class)
1✔
81
                        ->setFactory([
1✔
82
                                'session' => Nette\Bridges\SecurityHttp\SessionStorage::class,
83
                                'cookie' => Nette\Bridges\SecurityHttp\CookieStorage::class,
84
                        ][$auth->storage]);
1✔
85

86
                if ($auth->storage === 'cookie') {
1✔
87
                        $cookieDomain = $auth->cookieDomain === 'domain'
1✔
88
                                ? $builder::literal('$this->getByType(Nette\Http\IRequest::class)->getUrl()->getDomain(2)')
1✔
89
                                : $auth->cookieDomain;
×
90

91
                        $storage->addSetup('setCookieParameters', [$auth->cookieName, $cookieDomain, $auth->cookieSamesite]);
1✔
92
                }
93

94
                $user = $builder->addDefinition($this->prefix('user'))
1✔
95
                        ->setFactory(Nette\Security\User::class);
1✔
96

97
                if ($auth->expiration) {
1✔
98
                        $user->addSetup('setExpiration', [$auth->expiration]);
1✔
99
                }
100

101
                if (!$auth->persistIdentity) {
1✔
102
                        $user->addSetup('$persistIdentity', [false]);
1✔
103
                }
104

105
                if ($config->users) {
1✔
106
                        $usersList = $usersRoles = $usersData = [];
1✔
107
                        foreach ($config->users as $username => $data) {
1✔
108
                                $data = is_array($data) ? $data : ['password' => $data];
1✔
109
                                $usersList[$username] = $data['password'];
1✔
110
                                $usersRoles[$username] = $data['roles'] ?? null;
1✔
111
                                $usersData[$username] = $data['data'] ?? [];
1✔
112
                        }
113

114
                        $builder->addDefinition($this->prefix('authenticator'))
1✔
115
                                ->setType(Nette\Security\Authenticator::class)
1✔
116
                                ->setFactory(Nette\Security\SimpleAuthenticator::class, [$usersList, $usersRoles, $usersData]);
1✔
117

118
                        if ($this->name === 'security') {
1✔
119
                                $builder->addAlias('nette.authenticator', $this->prefix('authenticator'));
1✔
120
                        }
121
                }
122

123
                if ($config->roles || $config->resources) {
1✔
124
                        $authorizator = $builder->addDefinition($this->prefix('authorizator'))
1✔
125
                                ->setType(Nette\Security\Authorizator::class)
1✔
126
                                ->setFactory(Nette\Security\Permission::class);
1✔
127

128
                        foreach ($config->roles as $role => $parents) {
1✔
129
                                $authorizator->addSetup('addRole', [$role, $parents]);
1✔
130
                        }
131

132
                        foreach ($config->resources as $resource => $parents) {
1✔
133
                                $authorizator->addSetup('addResource', [$resource, $parents]);
1✔
134
                        }
135

136
                        if ($this->name === 'security') {
1✔
137
                                $builder->addAlias('nette.authorizator', $this->prefix('authorizator'));
1✔
138
                        }
139
                }
140

141
                if ($this->name === 'security') {
1✔
142
                        $builder->addAlias('user', $this->prefix('user'));
1✔
143
                        $builder->addAlias('nette.userStorage', $this->prefix('userStorage'));
1✔
144
                }
145
        }
1✔
146

147

148
        public function beforeCompile(): void
149
        {
150
                $builder = $this->getContainerBuilder();
1✔
151

152
                if (
153
                        $this->debugMode &&
1✔
154
                        ($this->config->debugger ?? $builder->getByType(Tracy\Bar::class))
1✔
155
                ) {
156
                        $definition = $builder->getDefinition($this->prefix('user'));
×
157
                        assert($definition instanceof Nette\DI\Definitions\ServiceDefinition);
158
                        $definition->addSetup('@Tracy\Bar::addPanel', [
×
159
                                new Nette\DI\Definitions\Statement(Nette\Bridges\SecurityTracy\UserPanel::class),
×
160
                        ]);
161
                }
162
        }
1✔
163
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc