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

nette / security / 20848300136

09 Jan 2026 10:04AM UTC coverage: 92.348% (-0.01%) from 92.361%
20848300136

push

github

dg
User: deprecated magic properties (BC break)

531 of 575 relevant lines covered (92.35%)

0.92 hits per line

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

93.75
/src/Security/User.php
1
<?php
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
declare(strict_types=1);
9

10
namespace Nette\Security;
11

12
use Nette;
13
use Nette\Utils\Arrays;
14
use function func_get_args;
15

16

17
/**
18
 * User authentication and authorization.
19
 *
20
 * @property bool $loggedIn
21
 * @property IIdentity $identity
22
 * @property-deprecated string|int $id
23
 * @property-deprecated array $roles
24
 * @property-deprecated int $logoutReason
25
 * @property-deprecated Authenticator $authenticator
26
 * @property-deprecated Authorizator $authorizator
27
 */
28
class User
29
{
30
        use Nette\SmartObject;
31

32
        /** Log-out reason */
33
        public const
34
                LogoutManual = 1,
35
                LogoutInactivity = 2;
36

37
        /** @deprecated use User::LogoutManual */
38
        public const LOGOUT_MANUAL = self::LogoutManual;
39

40
        /** @deprecated use User::LogoutManual */
41
        public const MANUAL = self::LogoutManual;
42

43
        /** @deprecated use User::LogoutInactivity */
44
        public const LOGOUT_INACTIVITY = self::LogoutInactivity;
45

46
        /** @deprecated use User::LogoutInactivity */
47
        public const INACTIVITY = self::LogoutInactivity;
48

49
        /** default role for unauthenticated user */
50
        public string $guestRole = 'guest';
51

52
        /** default role for authenticated user without own identity */
53
        public string $authenticatedRole = 'authenticated';
54

55
        /** @var array<callable(self): void>  Occurs when the user is successfully logged in */
56
        public array $onLoggedIn = [];
57

58
        /** @var array<callable(self): void>  Occurs when the user is logged out */
59
        public array $onLoggedOut = [];
60

61
        private ?IIdentity $identity = null;
62
        private ?bool $authenticated = null;
63
        private ?int $logoutReason = null;
64

65

66
        public function __construct(
1✔
67
                private UserStorage $storage,
68
                private ?Authenticator $authenticator = null,
69
                private ?Authorizator $authorizator = null,
70
        ) {
71
        }
1✔
72

73

74
        final public function getStorage(): UserStorage
75
        {
76
                return $this->storage;
×
77
        }
78

79

80
        /********************* Authentication ****************d*g**/
81

82

83
        /**
84
         * Conducts the authentication process. Parameters are optional.
85
         * @param  string|IIdentity  $username  name or Identity
86
         * @throws AuthenticationException if authentication was not successful
87
         */
88
        public function login(
1✔
89
                string|IIdentity $username,
90
                #[\SensitiveParameter]
91
                ?string $password = null,
92
        ): void
93
        {
94
                $this->logout(clearIdentity: true);
1✔
95
                if ($username instanceof IIdentity) {
1✔
96
                        $this->identity = $username;
1✔
97
                } else {
98
                        $authenticator = $this->getAuthenticator();
1✔
99
                        $this->identity = $authenticator->authenticate(...func_get_args());
1✔
100
                }
101

102
                $id = $this->authenticator instanceof IdentityHandler
1✔
103
                        ? $this->authenticator->sleepIdentity($this->identity)
1✔
104
                        : $this->identity;
1✔
105

106
                $this->storage->saveAuthentication($id);
1✔
107
                $this->authenticated = true;
1✔
108
                $this->logoutReason = null;
1✔
109
                Arrays::invoke($this->onLoggedIn, $this);
1✔
110
        }
1✔
111

112

113
        /**
114
         * Logs out the user from the current session.
115
         */
116
        final public function logout(bool $clearIdentity = false): void
1✔
117
        {
118
                $logged = $this->isLoggedIn();
1✔
119
                $this->storage->clearAuthentication($clearIdentity);
1✔
120
                $this->authenticated = false;
1✔
121
                $this->logoutReason = self::LogoutManual;
1✔
122
                if ($logged) {
1✔
123
                        Arrays::invoke($this->onLoggedOut, $this);
1✔
124
                }
125

126
                $this->identity = $clearIdentity ? null : $this->identity;
1✔
127
        }
1✔
128

129

130
        /**
131
         * Is this user authenticated?
132
         */
133
        final public function isLoggedIn(): bool
134
        {
135
                if ($this->authenticated === null) {
1✔
136
                        $this->getStoredData();
1✔
137
                }
138

139
                return $this->authenticated;
1✔
140
        }
141

142

143
        /**
144
         * Returns current user identity, if any.
145
         */
146
        final public function getIdentity(): ?IIdentity
147
        {
148
                if ($this->authenticated === null) {
1✔
149
                        $this->getStoredData();
1✔
150
                }
151

152
                return $this->identity;
1✔
153
        }
154

155

156
        private function getStoredData(): void
157
        {
158
                (function (bool $state, ?IIdentity $id, ?int $reason) use (&$identity) {
1✔
159
                        $identity = $id;
1✔
160
                        $this->authenticated = $state;
1✔
161
                        $this->logoutReason = $reason;
1✔
162
                })(...$this->storage->getState());
1✔
163

164
                $this->identity = $identity && $this->authenticator instanceof IdentityHandler
1✔
165
                        ? $this->authenticator->wakeupIdentity($identity)
1✔
166
                        : $identity;
1✔
167
                $this->authenticated = $this->authenticated && $this->identity;
1✔
168
        }
1✔
169

170

171
        /**
172
         * Returns current user ID, if any.
173
         */
174
        public function getId(): string|int|null
175
        {
176
                $identity = $this->getIdentity();
1✔
177
                return $identity ? $identity->getId() : null;
1✔
178
        }
179

180

181
        final public function refreshStorage(): void
182
        {
183
                $this->identity = $this->authenticated = $this->logoutReason = null;
1✔
184
        }
1✔
185

186

187
        /**
188
         * Sets authentication handler.
189
         */
190
        public function setAuthenticator(Authenticator $handler): static
1✔
191
        {
192
                $this->authenticator = $handler;
1✔
193
                return $this;
1✔
194
        }
195

196

197
        /**
198
         * Returns authentication handler.
199
         */
200
        final public function getAuthenticator(): Authenticator
201
        {
202
                if (!$this->authenticator) {
1✔
203
                        throw new Nette\InvalidStateException('Authenticator has not been set.');
1✔
204
                }
205

206
                return $this->authenticator;
1✔
207
        }
208

209

210
        /**
211
         * Returns authentication handler.
212
         */
213
        final public function getAuthenticatorIfExists(): ?Authenticator
214
        {
215
                return $this->authenticator;
×
216
        }
217

218

219
        /** @deprecated */
220
        final public function hasAuthenticator(): bool
221
        {
222
                return (bool) $this->authenticator;
×
223
        }
224

225

226
        /**
227
         * Enables log out after inactivity (like '20 minutes').
228
         */
229
        public function setExpiration(?string $expire, bool $clearIdentity = false): static
1✔
230
        {
231
                $this->storage->setExpiration($expire, $clearIdentity);
1✔
232
                return $this;
1✔
233
        }
234

235

236
        /**
237
         * Why was user logged out? Returns LOGOUT_MANUAL or LOGOUT_INACTIVITY.
238
         */
239
        final public function getLogoutReason(): ?int
240
        {
241
                return $this->logoutReason;
1✔
242
        }
243

244

245
        /********************* Authorization ****************d*g**/
246

247

248
        /**
249
         * Returns a list of effective roles that a user has been granted.
250
         * @return string[]
251
         */
252
        public function getRoles(): array
253
        {
254
                if (!$this->isLoggedIn()) {
1✔
255
                        return [$this->guestRole];
1✔
256
                }
257

258
                $identity = $this->getIdentity();
1✔
259
                return $identity?->getRoles() ?? [$this->authenticatedRole];
1✔
260
        }
261

262

263
        /**
264
         * Is a user in the specified effective role?
265
         */
266
        final public function isInRole(string $role): bool
1✔
267
        {
268
                foreach ($this->getRoles() as $r) {
1✔
269
                        if ($role === ($r instanceof Role ? $r->getRoleId() : $r)) {
1✔
270
                                return true;
1✔
271
                        }
272
                }
273

274
                return false;
1✔
275
        }
276

277

278
        /**
279
         * Has a user effective access to the Resource?
280
         * If $resource is null, then the query applies to all resources.
281
         */
282
        public function isAllowed($resource = Authorizator::All, $privilege = Authorizator::All): bool
1✔
283
        {
284
                foreach ($this->getRoles() as $role) {
1✔
285
                        if ($this->getAuthorizator()->isAllowed($role, $resource, $privilege)) {
1✔
286
                                return true;
1✔
287
                        }
288
                }
289

290
                return false;
1✔
291
        }
292

293

294
        /**
295
         * Sets authorization handler.
296
         */
297
        public function setAuthorizator(Authorizator $handler): static
1✔
298
        {
299
                $this->authorizator = $handler;
1✔
300
                return $this;
1✔
301
        }
302

303

304
        /**
305
         * Returns current authorization handler.
306
         */
307
        final public function getAuthorizator(): Authorizator
308
        {
309
                if (!$this->authorizator) {
1✔
310
                        throw new Nette\InvalidStateException('Authorizator has not been set.');
1✔
311
                }
312

313
                return $this->authorizator;
1✔
314
        }
315

316

317
        /**
318
         * Returns current authorization handler.
319
         */
320
        final public function getAuthorizatorIfExists(): ?Authorizator
321
        {
322
                return $this->authorizator;
×
323
        }
324

325

326
        /** @deprecated */
327
        final public function hasAuthorizator(): bool
328
        {
329
                return (bool) $this->authorizator;
×
330
        }
331
}
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