Skip to content

Commit 2004e7a

Browse files
committed
feat(auth): Add IAlternativeLoginProvider
IAlternativeLogin has a fatal flaw in that it is not possible to register multiple alternative login dynamically but only statically. IAlternativeLoginProvider fixes this limitation as the provider can then provider multiple IAlternativeLogin. Signed-off-by: Carl Schwan <carlschwan@kde.org>
1 parent 14472cb commit 2004e7a

File tree

6 files changed

+106
-1
lines changed

6 files changed

+106
-1
lines changed

lib/composer/composer/autoload_classmap.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@
168168
'OCP\\Authentication\\Exceptions\\PasswordUnavailableException' => $baseDir . '/lib/public/Authentication/Exceptions/PasswordUnavailableException.php',
169169
'OCP\\Authentication\\Exceptions\\WipeTokenException' => $baseDir . '/lib/public/Authentication/Exceptions/WipeTokenException.php',
170170
'OCP\\Authentication\\IAlternativeLogin' => $baseDir . '/lib/public/Authentication/IAlternativeLogin.php',
171+
'OCP\\Authentication\\IAlternativeLoginProvider' => $baseDir . '/lib/public/Authentication/IAlternativeLoginProvider.php',
171172
'OCP\\Authentication\\IApacheBackend' => $baseDir . '/lib/public/Authentication/IApacheBackend.php',
172173
'OCP\\Authentication\\IProvideUserSecretBackend' => $baseDir . '/lib/public/Authentication/IProvideUserSecretBackend.php',
173174
'OCP\\Authentication\\LoginCredentials\\ICredentials' => $baseDir . '/lib/public/Authentication/LoginCredentials/ICredentials.php',

lib/composer/composer/autoload_static.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
209209
'OCP\\Authentication\\Exceptions\\PasswordUnavailableException' => __DIR__ . '/../../..' . '/lib/public/Authentication/Exceptions/PasswordUnavailableException.php',
210210
'OCP\\Authentication\\Exceptions\\WipeTokenException' => __DIR__ . '/../../..' . '/lib/public/Authentication/Exceptions/WipeTokenException.php',
211211
'OCP\\Authentication\\IAlternativeLogin' => __DIR__ . '/../../..' . '/lib/public/Authentication/IAlternativeLogin.php',
212+
'OCP\\Authentication\\IAlternativeLoginProvider' => __DIR__ . '/../../..' . '/lib/public/Authentication/IAlternativeLoginProvider.php',
212213
'OCP\\Authentication\\IApacheBackend' => __DIR__ . '/../../..' . '/lib/public/Authentication/IApacheBackend.php',
213214
'OCP\\Authentication\\IProvideUserSecretBackend' => __DIR__ . '/../../..' . '/lib/public/Authentication/IProvideUserSecretBackend.php',
214215
'OCP\\Authentication\\LoginCredentials\\ICredentials' => __DIR__ . '/../../..' . '/lib/public/Authentication/LoginCredentials/ICredentials.php',

lib/private/AppFramework/Bootstrap/RegistrationContext.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use OCP\AppFramework\Middleware;
1717
use OCP\AppFramework\Services\InitialStateProvider;
1818
use OCP\Authentication\IAlternativeLogin;
19+
use OCP\Authentication\IAlternativeLoginProvider;
1920
use OCP\Calendar\ICalendarProvider;
2021
use OCP\Calendar\Resource\IBackend as IResourceBackend;
2122
use OCP\Calendar\Room\IBackend as IRoomBackend;
@@ -44,6 +45,7 @@
4445
use OCP\TextProcessing\IProvider as ITextProcessingProvider;
4546
use OCP\Translation\ITranslationProvider;
4647
use OCP\UserMigration\IMigrator as IUserMigrator;
48+
use Override;
4749
use Psr\Log\LoggerInterface;
4850
use RuntimeException;
4951
use Throwable;
@@ -95,6 +97,9 @@ class RegistrationContext {
9597
/** @var ServiceRegistration<IAlternativeLogin>[] */
9698
private $alternativeLogins = [];
9799

100+
/** @var ServiceRegistration<IAlternativeLoginProvider>[] */
101+
private array $alternativeLoginProviders = [];
102+
98103
/** @var ServiceRegistration<InitialStateProvider>[] */
99104
private $initialStates = [];
100105

@@ -251,6 +256,14 @@ public function registerAlternativeLogin(string $class): void {
251256
);
252257
}
253258

259+
#[Override]
260+
public function registerAlternativeLoginProvider(string $class): void {
261+
$this->context->registerAlternativeLoginProvider(
262+
$this->appId,
263+
$class
264+
);
265+
}
266+
254267
public function registerInitialStateProvider(string $class): void {
255268
$this->context->registerInitialState(
256269
$this->appId,
@@ -495,6 +508,10 @@ public function registerAlternativeLogin(string $appId, string $class): void {
495508
$this->alternativeLogins[] = new ServiceRegistration($appId, $class);
496509
}
497510

511+
public function registerAlternativeLoginProvider(string $appId, string $class): void {
512+
$this->alternativeLoginProviders[] = new ServiceRegistration($appId, $class);
513+
}
514+
498515
public function registerInitialState(string $appId, string $class): void {
499516
$this->initialStates[] = new ServiceRegistration($appId, $class);
500517
}
@@ -828,6 +845,13 @@ public function getAlternativeLogins(): array {
828845
return $this->alternativeLogins;
829846
}
830847

848+
/**
849+
* @return ServiceRegistration<IAlternativeLoginProvider>[]
850+
*/
851+
public function getAlternativeLoginProviders(): array {
852+
return $this->alternativeLoginProviders;
853+
}
854+
831855
/**
832856
* @return ServiceRegistration<InitialStateProvider>[]
833857
*/

lib/private/legacy/OC_App.php

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use OCP\App\AppPathNotFoundException;
2020
use OCP\App\IAppManager;
2121
use OCP\Authentication\IAlternativeLogin;
22+
use OCP\Authentication\IAlternativeLoginProvider;
2223
use OCP\BackgroundJob\IJobList;
2324
use OCP\EventDispatcher\IEventDispatcher;
2425
use OCP\IAppConfig;
@@ -41,6 +42,8 @@
4142
* upgrading and removing apps.
4243
*/
4344
class OC_App {
45+
46+
/** @var list<array{name: string, href: string, class: string}> */
4447
private static array $altLogin = [];
4548
private static array $alreadyRegistered = [];
4649
public const supportedApp = 300;
@@ -300,12 +303,54 @@ public static function registerLogIn(array $entry): void {
300303
}
301304

302305
/**
303-
* @return array
306+
* @return list<array{name: string, href: string, class: string}>
304307
*/
305308
public static function getAlternativeLogIns(): array {
306309
/** @var Coordinator $bootstrapCoordinator */
307310
$bootstrapCoordinator = Server::get(Coordinator::class);
308311

312+
foreach ($bootstrapCoordinator->getRegistrationContext()->getAlternativeLoginProviders() as $registration) {
313+
if (!in_array(IAlternativeLoginProvider::class, class_implements($registration->getService()), true)) {
314+
Server::get(LoggerInterface::class)->error('Alternative login option {option} does not implement {interface} and is therefore ignored.', [
315+
'option' => $registration->getService(),
316+
'interface' => IAlternativeLoginProvider::class,
317+
'app' => $registration->getAppId(),
318+
]);
319+
continue;
320+
}
321+
322+
try {
323+
/** @var IAlternativeLoginProvider $provider */
324+
$provider = Server::get($registration->getService());
325+
} catch (ContainerExceptionInterface $e) {
326+
Server::get(LoggerInterface::class)->error('Alternative login option {option} can not be initialized.',
327+
[
328+
'exception' => $e,
329+
'option' => $registration->getService(),
330+
'app' => $registration->getAppId(),
331+
]);
332+
}
333+
334+
foreach ($provider->getAlternativeLogins() as $alternativeLogin) {
335+
try {
336+
$alternativeLogin->load();
337+
338+
self::$altLogin[] = [
339+
'name' => $alternativeLogin->getLabel(),
340+
'href' => $alternativeLogin->getLink(),
341+
'class' => $alternativeLogin->getClass(),
342+
];
343+
} catch (Throwable $e) {
344+
Server::get(LoggerInterface::class)->error('Alternative login option {option} had an error while loading.',
345+
[
346+
'exception' => $e,
347+
'option' => $registration->getService(),
348+
'app' => $registration->getAppId(),
349+
]);
350+
}
351+
}
352+
}
353+
309354
foreach ($bootstrapCoordinator->getRegistrationContext()->getAlternativeLogins() as $registration) {
310355
if (!in_array(IAlternativeLogin::class, class_implements($registration->getService()), true)) {
311356
Server::get(LoggerInterface::class)->error('Alternative login option {option} does not implement {interface} and is therefore ignored.', [

lib/public/AppFramework/Bootstrap/IRegistrationContext.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,9 +161,21 @@ public function registerSearchProvider(string $class): void;
161161
* @return void
162162
*
163163
* @since 20.0.0
164+
* @deprecated 34.0.0 Use registerAlternativeLoginProvider instead.
164165
*/
165166
public function registerAlternativeLogin(string $class): void;
166167

168+
/**
169+
* Register an alternative login options provider
170+
*
171+
* It is allowed to register more than one option per app.
172+
*
173+
* @param class-string<\OCP\Authentication\IAlternativeLoginProvider> $class
174+
*
175+
* @since 34.0.0
176+
*/
177+
public function registerAlternativeLoginProvider(string $class): void;
178+
167179
/**
168180
* Register an initialstate provider
169181
*
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
7+
* SPDX-License-Identifier: AGPL-3.0-or-later
8+
*/
9+
namespace OCP\Authentication;
10+
11+
/**
12+
* Provider exposing one or multiple IAlternativeLogin.
13+
*
14+
* @since 34.0.0
15+
*/
16+
interface IAlternativeLoginProvider {
17+
/**
18+
* @return list<IAlternativeLogin>
19+
* @since 34.0.0
20+
*/
21+
public function getAlternativeLogins(): array;
22+
}

0 commit comments

Comments
 (0)