diff --git a/AUTHORS b/AUTHORS index fe478401fddb4..6af579f94a9f8 100644 --- a/AUTHORS +++ b/AUTHORS @@ -629,6 +629,7 @@ - zorn-v - zulan - Łukasz Buśko + - Michał Roszak - Nextcloud GmbH - ownCloud GmbH - ownCloud, Inc. diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php index 0b6dd29f2040b..b11bca1ff63c2 100644 --- a/lib/composer/composer/autoload_classmap.php +++ b/lib/composer/composer/autoload_classmap.php @@ -181,6 +181,7 @@ 'OCP\\Authentication\\TwoFactorAuth\\IProvidesIcons' => $baseDir . '/lib/public/Authentication/TwoFactorAuth/IProvidesIcons.php', 'OCP\\Authentication\\TwoFactorAuth\\IProvidesPersonalSettings' => $baseDir . '/lib/public/Authentication/TwoFactorAuth/IProvidesPersonalSettings.php', 'OCP\\Authentication\\TwoFactorAuth\\IRegistry' => $baseDir . '/lib/public/Authentication/TwoFactorAuth/IRegistry.php', + 'OCP\\Authentication\\TwoFactorAuth\\IStatelessProvider' => $baseDir . '/lib/public/Authentication/TwoFactorAuth/IStatelessProvider.php', 'OCP\\Authentication\\TwoFactorAuth\\RegistryEvent' => $baseDir . '/lib/public/Authentication/TwoFactorAuth/RegistryEvent.php', 'OCP\\Authentication\\TwoFactorAuth\\TwoFactorException' => $baseDir . '/lib/public/Authentication/TwoFactorAuth/TwoFactorException.php', 'OCP\\Authentication\\TwoFactorAuth\\TwoFactorProviderChallengeFailed' => $baseDir . '/lib/public/Authentication/TwoFactorAuth/TwoFactorProviderChallengeFailed.php', diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php index 9c34d2cd4debd..89a1569fdb03d 100644 --- a/lib/composer/composer/autoload_static.php +++ b/lib/composer/composer/autoload_static.php @@ -222,6 +222,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2 'OCP\\Authentication\\TwoFactorAuth\\IProvidesIcons' => __DIR__ . '/../../..' . '/lib/public/Authentication/TwoFactorAuth/IProvidesIcons.php', 'OCP\\Authentication\\TwoFactorAuth\\IProvidesPersonalSettings' => __DIR__ . '/../../..' . '/lib/public/Authentication/TwoFactorAuth/IProvidesPersonalSettings.php', 'OCP\\Authentication\\TwoFactorAuth\\IRegistry' => __DIR__ . '/../../..' . '/lib/public/Authentication/TwoFactorAuth/IRegistry.php', + 'OCP\\Authentication\\TwoFactorAuth\\IStatelessProvider' => __DIR__ . '/../../..' . '/lib/public/Authentication/TwoFactorAuth/IStatelessProvider.php', 'OCP\\Authentication\\TwoFactorAuth\\RegistryEvent' => __DIR__ . '/../../..' . '/lib/public/Authentication/TwoFactorAuth/RegistryEvent.php', 'OCP\\Authentication\\TwoFactorAuth\\TwoFactorException' => __DIR__ . '/../../..' . '/lib/public/Authentication/TwoFactorAuth/TwoFactorException.php', 'OCP\\Authentication\\TwoFactorAuth\\TwoFactorProviderChallengeFailed' => __DIR__ . '/../../..' . '/lib/public/Authentication/TwoFactorAuth/TwoFactorProviderChallengeFailed.php', diff --git a/lib/private/Authentication/TwoFactorAuth/ProviderManager.php b/lib/private/Authentication/TwoFactorAuth/ProviderManager.php index 5ce4c5981546f..dedf2cd604e30 100644 --- a/lib/private/Authentication/TwoFactorAuth/ProviderManager.php +++ b/lib/private/Authentication/TwoFactorAuth/ProviderManager.php @@ -13,6 +13,7 @@ use OCP\Authentication\TwoFactorAuth\IDeactivatableByAdmin; use OCP\Authentication\TwoFactorAuth\IProvider; use OCP\Authentication\TwoFactorAuth\IRegistry; +use OCP\Authentication\TwoFactorAuth\IStatelessProvider; use OCP\IUser; class ProviderManager { @@ -47,7 +48,9 @@ private function getProvider(string $providerId, IUser $user): IProvider { public function tryEnableProviderFor(string $providerId, IUser $user): bool { $provider = $this->getProvider($providerId, $user); - if ($provider instanceof IActivatableByAdmin) { + if ($provider instanceof IActivatableByAdmin + && !($provider instanceof IStatelessProvider) + ) { $provider->enableFor($user); $this->providerRegistry->enableProviderFor($provider, $user); return true; @@ -66,7 +69,9 @@ public function tryEnableProviderFor(string $providerId, IUser $user): bool { public function tryDisableProviderFor(string $providerId, IUser $user): bool { $provider = $this->getProvider($providerId, $user); - if ($provider instanceof IDeactivatableByAdmin) { + if ($provider instanceof IDeactivatableByAdmin + && !($provider instanceof IStatelessProvider) + ) { $provider->disableFor($user); $this->providerRegistry->disableProviderFor($provider, $user); return true; diff --git a/lib/private/Authentication/TwoFactorAuth/Registry.php b/lib/private/Authentication/TwoFactorAuth/Registry.php index 544f60c4f97ec..6d9142e606875 100644 --- a/lib/private/Authentication/TwoFactorAuth/Registry.php +++ b/lib/private/Authentication/TwoFactorAuth/Registry.php @@ -11,6 +11,7 @@ use OC\Authentication\TwoFactorAuth\Db\ProviderUserAssignmentDao; use OCP\Authentication\TwoFactorAuth\IProvider; use OCP\Authentication\TwoFactorAuth\IRegistry; +use OCP\Authentication\TwoFactorAuth\IStatelessProvider; use OCP\Authentication\TwoFactorAuth\RegistryEvent; use OCP\Authentication\TwoFactorAuth\TwoFactorProviderDisabled; use OCP\Authentication\TwoFactorAuth\TwoFactorProviderForUserRegistered; @@ -37,6 +38,10 @@ public function getProviderStates(IUser $user): array { } public function enableProviderFor(IProvider $provider, IUser $user) { + if ($provider instanceof IStatelessProvider) { + return; + } + $this->assignmentDao->persist($provider->getId(), $user->getUID(), 1); $event = new RegistryEvent($provider, $user); @@ -45,6 +50,10 @@ public function enableProviderFor(IProvider $provider, IUser $user) { } public function disableProviderFor(IProvider $provider, IUser $user) { + if ($provider instanceof IStatelessProvider) { + return; + } + $this->assignmentDao->persist($provider->getId(), $user->getUID(), 0); $event = new RegistryEvent($provider, $user); diff --git a/lib/public/Authentication/TwoFactorAuth/IStatelessProvider.php b/lib/public/Authentication/TwoFactorAuth/IStatelessProvider.php new file mode 100644 index 0000000000000..79109dace19e5 --- /dev/null +++ b/lib/public/Authentication/TwoFactorAuth/IStatelessProvider.php @@ -0,0 +1,22 @@ +registry->enableProviderFor($provider, $user); } + public function testEnableStatelessProvider(): void { + $user = $this->createMock(IUser::class); + $provider = $this->createMock(IStatelessProvider::class); + + $this->dao->expects($this->never())->method('persist'); + + $this->dispatcher->expects($this->never())->method('dispatch'); + $this->dispatcher->expects($this->never())->method('dispatchTyped'); + + $this->registry->enableProviderFor($provider, $user); + } + public function testDisableProvider(): void { $user = $this->createMock(IUser::class); $provider = $this->createMock(IProvider::class); @@ -108,6 +121,18 @@ public function testDisableProvider(): void { $this->registry->disableProviderFor($provider, $user); } + public function testDisableStatelessProvider(): void { + $user = $this->createMock(IUser::class); + $provider = $this->createMock(IStatelessProvider::class); + + $this->dao->expects($this->never())->method('persist'); + + $this->dispatcher->expects($this->never())->method('dispatch'); + $this->dispatcher->expects($this->never())->method('dispatchTyped'); + + $this->registry->disableProviderFor($provider, $user); + } + public function testDeleteUserData(): void { $user = $this->createMock(IUser::class); $user->expects($this->once())->method('getUID')->willReturn('user123');