ProviderLoader.php 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
  5. * SPDX-License-Identifier: AGPL-3.0-or-later
  6. */
  7. namespace OC\Authentication\TwoFactorAuth;
  8. use Exception;
  9. use OC\AppFramework\Bootstrap\Coordinator;
  10. use OCP\App\IAppManager;
  11. use OCP\AppFramework\QueryException;
  12. use OCP\Authentication\TwoFactorAuth\IProvider;
  13. use OCP\IUser;
  14. class ProviderLoader {
  15. public const BACKUP_CODES_APP_ID = 'twofactor_backupcodes';
  16. public function __construct(
  17. private IAppManager $appManager,
  18. private Coordinator $coordinator,
  19. ) {
  20. }
  21. /**
  22. * Get the list of 2FA providers for the given user
  23. *
  24. * @return IProvider[]
  25. * @throws Exception
  26. */
  27. public function getProviders(IUser $user): array {
  28. $allApps = $this->appManager->getEnabledAppsForUser($user);
  29. $providers = [];
  30. foreach ($allApps as $appId) {
  31. $info = $this->appManager->getAppInfo($appId);
  32. if (isset($info['two-factor-providers'])) {
  33. /** @var string[] $providerClasses */
  34. $providerClasses = $info['two-factor-providers'];
  35. foreach ($providerClasses as $class) {
  36. try {
  37. $this->loadTwoFactorApp($appId);
  38. $provider = \OCP\Server::get($class);
  39. $providers[$provider->getId()] = $provider;
  40. } catch (QueryException $exc) {
  41. // Provider class can not be resolved
  42. throw new Exception("Could not load two-factor auth provider $class");
  43. }
  44. }
  45. }
  46. }
  47. $registeredProviders = $this->coordinator->getRegistrationContext()?->getTwoFactorProviders() ?? [];
  48. foreach ($registeredProviders as $provider) {
  49. try {
  50. $this->loadTwoFactorApp($provider->getAppId());
  51. $providerInstance = \OCP\Server::get($provider->getService());
  52. $providers[$providerInstance->getId()] = $providerInstance;
  53. } catch (QueryException $exc) {
  54. // Provider class can not be resolved
  55. throw new Exception('Could not load two-factor auth provider ' . $provider->getService());
  56. }
  57. }
  58. return $providers;
  59. }
  60. /**
  61. * Load an app by ID if it has not been loaded yet
  62. */
  63. protected function loadTwoFactorApp(string $appId): void {
  64. if (!$this->appManager->isAppLoaded($appId)) {
  65. $this->appManager->loadApp($appId);
  66. }
  67. }
  68. }