From 7cc3c1f669535db71e13017d0ec84ea37aaf0b99 Mon Sep 17 00:00:00 2001 From: Ferdinand Thiessen Date: Sat, 20 Sep 2025 12:56:20 +0200 Subject: [PATCH] fix(encryption): do not setup filesystem without permissions If the current request does not have permissions for the filesystem we must not try to setup the filesystem. Signed-off-by: Ferdinand Thiessen --- .../lib/Listeners/UserEventsListener.php | 7 ++++ .../Listeners/UserEventsListenersTest.php | 40 +++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/apps/encryption/lib/Listeners/UserEventsListener.php b/apps/encryption/lib/Listeners/UserEventsListener.php index 3f61fde599b01..16879fe648bfc 100644 --- a/apps/encryption/lib/Listeners/UserEventsListener.php +++ b/apps/encryption/lib/Listeners/UserEventsListener.php @@ -21,6 +21,7 @@ use OCP\IUser; use OCP\IUserManager; use OCP\IUserSession; +use OCP\Lockdown\ILockdownManager; use OCP\User\Events\BeforePasswordUpdatedEvent; use OCP\User\Events\PasswordUpdatedEvent; use OCP\User\Events\UserCreatedEvent; @@ -43,6 +44,7 @@ public function __construct( private IUserSession $userSession, private SetupManager $setupManager, private PassphraseService $passphraseService, + private ILockdownManager $lockdownManager, ) { } @@ -70,6 +72,11 @@ public function handle(Event $event): void { * Startup encryption backend upon user login */ private function onUserLogin(IUser $user, ?string $password): void { + // Do not try to setup filesystem if the current request does not have permissions to access it + if (!$this->lockdownManager->canAccessFilesystem()) { + return; + } + // ensure filesystem is loaded $this->setupManager->setupForUser($user); if ($this->util->isMasterKeyEnabled() === false) { diff --git a/apps/encryption/tests/Listeners/UserEventsListenersTest.php b/apps/encryption/tests/Listeners/UserEventsListenersTest.php index cb31523f105f8..5c2cdb1e6ddcb 100644 --- a/apps/encryption/tests/Listeners/UserEventsListenersTest.php +++ b/apps/encryption/tests/Listeners/UserEventsListenersTest.php @@ -20,6 +20,7 @@ use OCP\IUser; use OCP\IUserManager; use OCP\IUserSession; +use OCP\Lockdown\ILockdownManager; use OCP\User\Events\BeforePasswordUpdatedEvent; use OCP\User\Events\PasswordUpdatedEvent; use OCP\User\Events\UserCreatedEvent; @@ -41,6 +42,7 @@ class UserEventsListenersTest extends TestCase { protected IUserManager&MockObject $userManager; protected IUserSession&MockObject $userSession; protected SetupManager&MockObject $setupManager; + protected ILockdownManager&MockObject $lockdownManager; protected PassphraseService&MockObject $passphraseService; protected UserEventsListener $instance; @@ -55,6 +57,7 @@ public function setUp(): void { $this->userManager = $this->createMock(IUserManager::class); $this->userSession = $this->createMock(IUserSession::class); $this->setupManager = $this->createMock(SetupManager::class); + $this->lockdownManager = $this->createMock(ILockdownManager::class); $this->passphraseService = $this->createMock(PassphraseService::class); $this->instance = new UserEventsListener( @@ -66,10 +69,14 @@ public function setUp(): void { $this->userSession, $this->setupManager, $this->passphraseService, + $this->lockdownManager, ); } public function testLogin(): void { + $this->lockdownManager->expects(self::once()) + ->method('canAccessFilesystem') + ->willReturn(true); $this->userSetup->expects(self::once()) ->method('setupUser') ->willReturn(true); @@ -96,6 +103,9 @@ public function testLogin(): void { } public function testLoginMasterKey(): void { + $this->lockdownManager->expects(self::once()) + ->method('canAccessFilesystem') + ->willReturn(true); $this->util->method('isMasterKeyEnabled')->willReturn(true); $this->userSetup->expects(self::never()) @@ -121,6 +131,36 @@ public function testLoginMasterKey(): void { $this->instance->handle($event); } + public function testLoginNoFilesystemAccess(): void { + $this->lockdownManager->expects(self::once()) + ->method('canAccessFilesystem') + ->willReturn(false); + + $this->userSetup->expects(self::never()) + ->method('setupUser'); + + $this->setupManager->expects(self::never()) + ->method('setupForUser'); + + $this->keyManager->expects(self::never()) + ->method('init'); + + $user = $this->createMock(IUser::class); + $user->expects(self::any()) + ->method('getUID') + ->willReturn('testUser'); + + $event = $this->createMock(UserLoggedInEvent::class); + $event->expects(self::atLeastOnce()) + ->method('getUser') + ->willReturn($user); + $event->expects(self::atLeastOnce()) + ->method('getPassword') + ->willReturn('password'); + + $this->instance->handle($event); + } + public function testLogout(): void { $this->session->expects(self::once()) ->method('clear');