TwoFactor.php 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
  5. * SPDX-License-Identifier: AGPL-3.0-or-later
  6. */
  7. namespace OCA\Settings\Settings\Personal\Security;
  8. use Exception;
  9. use OC\Authentication\TwoFactorAuth\MandatoryTwoFactor;
  10. use OC\Authentication\TwoFactorAuth\ProviderLoader;
  11. use OCA\TwoFactorBackupCodes\Provider\BackupCodesProvider;
  12. use OCP\AppFramework\Http\TemplateResponse;
  13. use OCP\Authentication\TwoFactorAuth\IProvider;
  14. use OCP\Authentication\TwoFactorAuth\IProvidesPersonalSettings;
  15. use OCP\IConfig;
  16. use OCP\IUserSession;
  17. use OCP\Settings\ISettings;
  18. use function array_filter;
  19. use function array_map;
  20. use function is_null;
  21. class TwoFactor implements ISettings {
  22. /** @var ProviderLoader */
  23. private $providerLoader;
  24. /** @var MandatoryTwoFactor */
  25. private $mandatoryTwoFactor;
  26. public function __construct(
  27. ProviderLoader $providerLoader,
  28. MandatoryTwoFactor $mandatoryTwoFactor,
  29. private IUserSession $userSession,
  30. private IConfig $config,
  31. private ?string $userId,
  32. ) {
  33. $this->providerLoader = $providerLoader;
  34. $this->mandatoryTwoFactor = $mandatoryTwoFactor;
  35. }
  36. public function getForm(): TemplateResponse {
  37. return new TemplateResponse('settings', 'settings/personal/security/twofactor', [
  38. 'twoFactorProviderData' => $this->getTwoFactorProviderData(),
  39. ]);
  40. }
  41. public function getSection(): ?string {
  42. if (!$this->shouldShow()) {
  43. return null;
  44. }
  45. return 'security';
  46. }
  47. public function getPriority(): int {
  48. return 15;
  49. }
  50. private function shouldShow(): bool {
  51. $user = $this->userSession->getUser();
  52. if (is_null($user)) {
  53. // Actually impossible, but still …
  54. return false;
  55. }
  56. // Anyone who's supposed to use 2FA should see 2FA settings
  57. if ($this->mandatoryTwoFactor->isEnforcedFor($user)) {
  58. return true;
  59. }
  60. // If there is at least one provider with personal settings but it's not
  61. // the backup codes provider, then these settings should show.
  62. try {
  63. $providers = $this->providerLoader->getProviders($user);
  64. } catch (Exception $e) {
  65. // Let's hope for the best
  66. return true;
  67. }
  68. foreach ($providers as $provider) {
  69. if ($provider instanceof IProvidesPersonalSettings
  70. && !($provider instanceof BackupCodesProvider)) {
  71. return true;
  72. }
  73. }
  74. return false;
  75. }
  76. private function getTwoFactorProviderData(): array {
  77. $user = $this->userSession->getUser();
  78. if (is_null($user)) {
  79. // Actually impossible, but still …
  80. return [];
  81. }
  82. return [
  83. 'providers' => array_map(function (IProvidesPersonalSettings $provider) use ($user) {
  84. return [
  85. 'provider' => $provider,
  86. 'settings' => $provider->getPersonalSettings($user)
  87. ];
  88. }, array_filter($this->providerLoader->getProviders($user), function (IProvider $provider) {
  89. return $provider instanceof IProvidesPersonalSettings;
  90. }))
  91. ];
  92. }
  93. }