Skip to content

Commit f57890f

Browse files
Merge pull request #51 from SmartFrame-Technologies/1.13.x
Add auto_regenerate option to CacheSessionPersistence
2 parents 3346c3a + c78750d commit f57890f

6 files changed

+62
-12
lines changed

docs/book/v1/manual.md

+6-2
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,10 @@ The following details the constructor of the `Mezzio\Session\Cache\CacheSessionP
3636
* @param string $cookieSameSite The same-site rule to apply to the persisted
3737
* cookie. Options include "Lax", "Strict", and "None".
3838
* Available since 1.4.0
39-
*
39+
* @param bool $autoRegenerate Whether or not the session ID should be
40+
* regenerated on session data changes
41+
* Available since 1.13.0
42+
*
4043
* @todo reorder these arguments so they make more sense and are in an
4144
* order of importance
4245
*/
@@ -51,7 +54,8 @@ public function __construct(
5154
string $cookieDomain = null,
5255
bool $cookieSecure = false,
5356
bool $cookieHttpOnly = false,
54-
string $cookieSameSite = 'Lax'
57+
string $cookieSameSite = 'Lax',
58+
bool $autoRegenerate = true,
5559
) {
5660
```
5761

psalm-baseline.xml

+2-3
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,10 @@
2222
<code>$cacheService</code>
2323
<code><![CDATA[$container->get($cacheService)]]></code>
2424
<code>$cookieDomain</code>
25-
<code>$cookieHttpOnly</code>
2625
<code>$cookieName</code>
2726
<code>$cookiePath</code>
2827
<code>$cookieSameSite</code>
29-
<code>$cookieSecure</code>
3028
<code>$lastModified</code>
31-
<code>$persistent</code>
3229
</MixedArgument>
3330
<MixedArrayAccess>
3431
<code><![CDATA[$config['cache_expire']]]></code>
@@ -43,6 +40,7 @@
4340
<code><![CDATA[$config['last_modified']]]></code>
4441
<code><![CDATA[$config['mezzio-session-cache']]]></code>
4542
<code><![CDATA[$config['persistent']]]></code>
43+
<code><![CDATA[$config['auto_regenerate']]]></code>
4644
</MixedArrayAccess>
4745
<MixedAssignment>
4846
<code>$cacheExpire</code>
@@ -58,6 +56,7 @@
5856
<code>$cookieSecure</code>
5957
<code>$lastModified</code>
6058
<code>$persistent</code>
59+
<code>$autoRegenerate</code>
6160
</MixedAssignment>
6261
</file>
6362
<file src="test/Asset/TestHandler.php">

src/CacheSessionPersistence.php

+9-3
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class CacheSessionPersistence implements SessionPersistenceInterface
3434
private CacheItemPoolInterface $cache;
3535

3636
private bool $persistent;
37+
private bool $autoRegenerate;
3738

3839
/**
3940
* Prepare session cache and default HTTP caching headers.
@@ -67,6 +68,8 @@ class CacheSessionPersistence implements SessionPersistenceInterface
6768
* be accessed by client-side apis.
6869
* @param string $cookieSameSite The same-site rule to apply to the persisted
6970
* cookie. Options include "Lax", "Strict", and "None".
71+
* @param bool $autoRegenerate Whether or not the session ID should be
72+
* regenerated on session data changes
7073
* @todo reorder the constructor arguments
7174
*/
7275
public function __construct(
@@ -80,7 +83,8 @@ public function __construct(
8083
?string $cookieDomain = null,
8184
bool $cookieSecure = false,
8285
bool $cookieHttpOnly = false,
83-
string $cookieSameSite = 'Lax'
86+
string $cookieSameSite = 'Lax',
87+
bool $autoRegenerate = true
8488
) {
8589
$this->cache = $cache;
8690

@@ -112,6 +116,8 @@ public function __construct(
112116
: $this->getLastModified();
113117

114118
$this->persistent = $persistent;
119+
120+
$this->autoRegenerate = $autoRegenerate;
115121
}
116122

117123
public function initializeSessionFromRequest(ServerRequestInterface $request): SessionInterface
@@ -139,8 +145,8 @@ public function persistSession(SessionInterface $session, ResponseInterface $res
139145
// Regenerate the session if:
140146
// - we have no session identifier
141147
// - the session is marked as regenerated
142-
// - the session has changed (data is different)
143-
if ('' === $id || $session->isRegenerated() || $session->hasChanged()) {
148+
// - the session has changed (data is different) and autoRegenerate is turned on (default) in the configuration
149+
if ('' === $id || $session->isRegenerated() || ($this->autoRegenerate && $session->hasChanged())) {
144150
$id = $this->regenerateSession($id);
145151
}
146152

src/CacheSessionPersistenceFactory.php

+6-4
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ public function __invoke(ContainerInterface $container)
3434
$cacheExpire = $config['cache_expire'] ?? 10800;
3535
$lastModified = $config['last_modified'] ?? null;
3636
$persistent = $config['persistent'] ?? false;
37+
$autoRegenerate = $config['auto_regenerate'] ?? true;
3738

3839
return new CacheSessionPersistence(
3940
$container->get($cacheService),
@@ -42,11 +43,12 @@ public function __invoke(ContainerInterface $container)
4243
$cacheLimiter,
4344
$cacheExpire,
4445
$lastModified,
45-
$persistent,
46+
(bool) $persistent,
4647
$cookieDomain,
47-
$cookieSecure,
48-
$cookieHttpOnly,
49-
$cookieSameSite
48+
(bool) $cookieSecure,
49+
(bool) $cookieHttpOnly,
50+
$cookieSameSite,
51+
(bool) $autoRegenerate
5052
);
5153
}
5254
}

test/CacheSessionPersistenceFactoryTest.php

+3
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ public function testFactoryUsesSaneDefaultsForConstructorArguments(): void
7474
$this->assertAttributeSame(10800, 'cacheExpire', $persistence);
7575
$this->assertAttributeNotEmpty('lastModified', $persistence);
7676
$this->assertAttributeSame(false, 'persistent', $persistence);
77+
$this->assertAttributeSame(true, 'autoRegenerate', $persistence);
7778
}
7879

7980
public function testFactoryAllowsConfiguringAllConstructorArguments(): void
@@ -95,6 +96,7 @@ public function testFactoryAllowsConfiguringAllConstructorArguments(): void
9596
'cache_expire' => 300,
9697
'last_modified' => $lastModified,
9798
'persistent' => true,
99+
'auto_regenerate' => false,
98100
],
99101
]);
100102

@@ -115,6 +117,7 @@ public function testFactoryAllowsConfiguringAllConstructorArguments(): void
115117
$persistence
116118
);
117119
$this->assertAttributeSame(true, 'persistent', $persistence);
120+
$this->assertAttributeSame(false, 'autoRegenerate', $persistence);
118121
}
119122

120123
public function testFactoryAllowsConfiguringCacheAdapterServiceName(): void

test/CacheSessionPersistenceIntegrationTest.php

+36
Original file line numberDiff line numberDiff line change
@@ -111,4 +111,40 @@ public function testThatAChangedSessionWillCauseRegenerationAndASetCookieHeader(
111111
$value = $item->get();
112112
self::assertNull($value, 'The previous session data should have been deleted');
113113
}
114+
115+
public function testThatAChangedSessionWillNotCauseRegenerationWhenAutoRegenerateIsFalse(): void
116+
{
117+
$this->storage = new CacheSessionPersistence(
118+
$this->cache,
119+
cookieName: 'Session',
120+
autoRegenerate: false,
121+
);
122+
123+
$item = $this->cache->getItem('foo');
124+
$item->set(['foo' => 'bar']);
125+
$this->cache->save($item);
126+
127+
$request = (new ServerRequest())->withHeader('Cookie', 'Session=foo;');
128+
$middleware = new SessionMiddleware($this->storage);
129+
$handler = new TestHandler();
130+
$handler->setSessionVariable('something', 'groovy');
131+
$response = $middleware->process($request, $handler);
132+
133+
$setCookie = SetCookies::fromResponse($response);
134+
$cookie = $setCookie->get('Session');
135+
self::assertNotNull($cookie);
136+
137+
$id = $cookie->getValue();
138+
self::assertNotNull($id);
139+
140+
self::assertSame('foo', $id);
141+
self::assertNotSame($handler->response, $response);
142+
143+
$item = $this->cache->getItem('foo');
144+
$value = $item->get();
145+
self::assertSame([
146+
'foo' => 'bar',
147+
'something' => 'groovy',
148+
], $value, 'The session data should have been updated');
149+
}
114150
}

0 commit comments

Comments
 (0)