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

nette / security / 21812889120

09 Feb 2026 04:55AM UTC coverage: 92.414% (-0.5%) from 92.919%
21812889120

push

github

dg
added CLAUDE.md

536 of 580 relevant lines covered (92.41%)

0.92 hits per line

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

77.78
/src/Bridges/SecurityHttp/SessionStorage.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\Bridges\SecurityHttp;
11

12
use Nette;
13
use Nette\Http\Session;
14
use Nette\Http\SessionSection;
15
use Nette\Security\IIdentity;
16
use Nette\Security\User;
17
use function is_bool, time;
18

19

20
/**
21
 * Session storage for Nette\Security\User object.
22
 */
23
final class SessionStorage implements Nette\Security\UserStorage
24
{
25
        private string $namespace = '';
26
        private ?SessionSection $sessionSection = null;
27
        private ?int $expireTime = null;
28
        private bool $expireIdentity = false;
29

30

31
        public function __construct(
1✔
32
                private readonly Session $sessionHandler,
33
        ) {
34
        }
1✔
35

36

37
        public function saveAuthentication(IIdentity $identity): void
1✔
38
        {
39
                $section = $this->getSessionSection();
1✔
40
                $section->set('authenticated', true);
1✔
41
                $section->set('reason', null);
1✔
42
                $section->set('authTime', time()); // informative value
1✔
43
                $section->set('identity', $identity);
1✔
44
                $this->setupExpiration();
1✔
45

46
                // Session Fixation defence
47
                $this->sessionHandler->regenerateId();
1✔
48
        }
1✔
49

50

51
        public function clearAuthentication(bool $clearIdentity): void
52
        {
53
                $section = $this->getSessionSection();
×
54
                $section->set('authenticated', false);
×
55
                $section->set('reason', User::LogoutManual);
×
56
                $section->set('authTime', null);
×
57
                if ($clearIdentity === true) {
×
58
                        $section->set('identity', null);
×
59
                }
60

61
                // Session Fixation defence
62
                $this->sessionHandler->regenerateId();
×
63
        }
64

65

66
        public function getState(): array
67
        {
68
                $section = $this->getSessionSection();
1✔
69
                return [(bool) $section->get('authenticated'), $section->get('identity'), $section->get('reason')];
1✔
70
        }
71

72

73
        public function setExpiration(?string $time, bool $clearIdentity = false): void
1✔
74
        {
75
                $this->expireTime = $time ? (int) Nette\Utils\DateTime::from($time)->format('U') : null;
1✔
76
                $this->expireIdentity = $clearIdentity;
1✔
77

78
                if ($this->sessionSection && $this->sessionSection->get('authenticated')) {
1✔
79
                        $this->setupExpiration();
1✔
80
                }
81
        }
1✔
82

83

84
        private function setupExpiration(): void
85
        {
86
                $section = $this->sessionSection;
1✔
87
                if ($this->expireTime) {
1✔
88
                        $section->set('expireTime', $this->expireTime);
1✔
89
                        $section->set('expireDelta', $this->expireTime - time());
1✔
90
                } else {
91
                        $section->remove(['expireTime', 'expireDelta']);
1✔
92
                }
93

94
                $section->set('expireIdentity', $this->expireIdentity);
1✔
95
                $section->setExpiration((string) $this->expireTime, 'foo'); // time check
1✔
96
        }
1✔
97

98

99
        /**
100
         * Changes namespace; allows more users to share a session.
101
         */
102
        public function setNamespace(string $namespace): static
103
        {
104
                if ($this->namespace !== $namespace) {
×
105
                        $this->namespace = $namespace;
×
106
                        $this->sessionSection = null;
×
107
                }
108

109
                return $this;
×
110
        }
111

112

113
        /**
114
         * Returns current namespace.
115
         */
116
        public function getNamespace(): string
117
        {
118
                return $this->namespace;
×
119
        }
120

121

122
        /**
123
         * Returns and initializes $this->sessionSection.
124
         */
125
        private function getSessionSection(): SessionSection
126
        {
127
                if ($this->sessionSection !== null) {
1✔
128
                        return $this->sessionSection;
1✔
129
                }
130

131
                $this->sessionSection = $section = $this->sessionHandler->getSection('Nette.Http.UserStorage/' . $this->namespace);
1✔
132

133
                if (!$section->get('identity') instanceof IIdentity || !is_bool($section->get('authenticated'))) {
1✔
134
                        $section->remove();
1✔
135
                }
136

137
                if ($section->get('authenticated') && $section->get('expireDelta') > 0) { // check time expiration
1✔
138
                        if ($section->get('expireTime') < time()) {
1✔
139
                                $section->set('reason', User::LogoutInactivity);
1✔
140
                                $section->set('authenticated', false);
1✔
141
                                if ($section->get('expireIdentity')) {
1✔
142
                                        $section->remove('identity');
1✔
143
                                }
144
                        } else {
145
                                $section->set('expireTime', time() + $section->get('expireDelta')); // sliding expiration
1✔
146
                        }
147
                }
148

149
                if (!$section->get('authenticated')) {
1✔
150
                        $section->remove(['expireTime', 'expireDelta', 'expireIdentity', 'authTime']);
1✔
151
                }
152

153
                return $this->sessionSection;
1✔
154
        }
155
}
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