From 01db6f89adfe4e41fbb31c01d438eed1849211ac Mon Sep 17 00:00:00 2001 From: Derrick Austin Date: Thu, 15 Oct 2026 16:35:50 -0500 Subject: [PATCH] Restore session use in Auth\Manager::once() when authentication throws once() turned session persistence off, authenticated, then turned it back on with a hard-coded true. An exception from authenticate() skipped the restore and left the singleton with sessions disabled for the rest of the process. It now restores the previous value in a finally block. --- src/Auth/Manager.php | 11 ++++-- tests/Auth/ManagerOnceTest.php | 62 ++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 3 deletions(-) create mode 100644 tests/Auth/ManagerOnceTest.php diff --git a/src/Auth/Manager.php b/src/Auth/Manager.php index 02935431..bc031037 100644 --- a/src/Auth/Manager.php +++ b/src/Auth/Manager.php @@ -622,11 +622,16 @@ public function id() */ public function once(array $credentials = []) { - $this->useSession = false; + $previousUseSession = $this->useSession; - $user = $this->authenticate($credentials); + $this->useSession = false; - $this->useSession = true; + try { + $user = $this->authenticate($credentials); + } + finally { + $this->useSession = $previousUseSession; + } return !!$user; } diff --git a/tests/Auth/ManagerOnceTest.php b/tests/Auth/ManagerOnceTest.php new file mode 100644 index 00000000..a31c922e --- /dev/null +++ b/tests/Auth/ManagerOnceTest.php @@ -0,0 +1,62 @@ +assertTrue($this->getUseSession($manager)); + + try { + $manager->once(['login' => 'someone', 'password' => 'secret']); + $this->fail('The exception from authenticate() should propagate.'); + } + catch (RuntimeException $ex) { + // Expected. + } + + $this->assertTrue($this->getUseSession($manager)); + } + + public function testOnceRestoresThePreviousValueRatherThanTrue() + { + $manager = ManagerOnceTestThrowingManager::instance(); + (new ReflectionProperty($manager, 'useSession'))->setValue($manager, false); + + try { + $manager->once(['login' => 'someone', 'password' => 'secret']); + } + catch (RuntimeException $ex) { + // Expected. + } + + $this->assertFalse($this->getUseSession($manager)); + } + + protected function getUseSession(AuthManager $manager): bool + { + return (new ReflectionProperty($manager, 'useSession'))->getValue($manager); + } +} + +class ManagerOnceTestThrowingManager extends AuthManager +{ + public function authenticate(array $credentials, $remember = true) + { + throw new RuntimeException('authentication failed'); + } +}