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

nette / security / 22292327079

23 Feb 2026 03:53AM UTC coverage: 91.812% (-0.01%) from 91.826%
22292327079

push

github

dg
User: deprecated magic properties (BC break)

527 of 574 relevant lines covered (91.81%)

0.92 hits per line

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

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

10
use Nette;
11
use Nette\Utils\Arrays;
12
use function func_get_args;
13

14

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

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

35
        /** @deprecated use User::LogoutManual */
36
        public const LOGOUT_MANUAL = self::LogoutManual;
37

38
        /** @deprecated use User::LogoutManual */
39
        public const MANUAL = self::LogoutManual;
40

41
        /** @deprecated use User::LogoutInactivity */
42
        public const LOGOUT_INACTIVITY = self::LogoutInactivity;
43

44
        /** @deprecated use User::LogoutInactivity */
45
        public const INACTIVITY = self::LogoutInactivity;
46

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

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

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

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

59
        private ?IIdentity $identity = null;
60
        private ?bool $authenticated = null;
61
        private ?int $logoutReason = null;
62

63

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

71

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

77

78
        /********************* Authentication ****************d*g**/
79

80

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

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

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

110

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

124
                $this->identity = $clearIdentity ? null : $this->identity;
1✔
125
        }
1✔
126

127

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

137
                return (bool) $this->authenticated;
1✔
138
        }
139

140

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

150
                return $this->identity;
1✔
151
        }
152

153

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

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

168

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

178

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

184

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

194

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

204
                return $this->authenticator;
1✔
205
        }
206

207

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

216

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

223

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

233

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

242

243
        /********************* Authorization ****************d*g**/
244

245

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

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

260

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

272
                return false;
1✔
273
        }
274

275

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

288
                return false;
1✔
289
        }
290

291

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

301

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

311
                return $this->authorizator;
1✔
312
        }
313

314

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

323

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