diff options
Diffstat (limited to 'apps/settings/lib/Settings/Personal/Security')
4 files changed, 289 insertions, 0 deletions
diff --git a/apps/settings/lib/Settings/Personal/Security/Authtokens.php b/apps/settings/lib/Settings/Personal/Security/Authtokens.php new file mode 100644 index 00000000000..e0509b22a9c --- /dev/null +++ b/apps/settings/lib/Settings/Personal/Security/Authtokens.php @@ -0,0 +1,82 @@ +<?php + +declare(strict_types=1); + +/** + * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ +namespace OCA\Settings\Settings\Personal\Security; + +use OC\Authentication\Token\INamedToken; +use OC\Authentication\Token\IProvider as IAuthTokenProvider; +use OC\Authentication\Token\IToken; +use OCP\AppFramework\Http\TemplateResponse; +use OCP\AppFramework\Services\IInitialState; +use OCP\Authentication\Exceptions\InvalidTokenException; +use OCP\ISession; +use OCP\IUserSession; +use OCP\Session\Exceptions\SessionNotAvailableException; +use OCP\Settings\ISettings; +use function array_map; + +class Authtokens implements ISettings { + + public function __construct( + private IAuthTokenProvider $tokenProvider, + private ISession $session, + private IUserSession $userSession, + private IInitialState $initialState, + private ?string $userId, + ) { + } + + public function getForm(): TemplateResponse { + $this->initialState->provideInitialState( + 'app_tokens', + $this->getAppTokens() + ); + + $this->initialState->provideInitialState( + 'can_create_app_token', + $this->userSession->getImpersonatingUserID() === null + ); + + return new TemplateResponse('settings', 'settings/personal/security/authtokens'); + } + + public function getSection(): string { + return 'security'; + } + + public function getPriority(): int { + return 100; + } + + private function getAppTokens(): array { + $tokens = $this->tokenProvider->getTokenByUser($this->userId); + + try { + $sessionId = $this->session->getId(); + } catch (SessionNotAvailableException $ex) { + return []; + } + try { + $sessionToken = $this->tokenProvider->getToken($sessionId); + } catch (InvalidTokenException $ex) { + return []; + } + + return array_map(function (IToken $token) use ($sessionToken) { + $data = $token->jsonSerialize(); + $data['canDelete'] = true; + $data['canRename'] = $token instanceof INamedToken && $data['type'] !== IToken::WIPE_TOKEN; + if ($sessionToken->getId() === $token->getId()) { + $data['canDelete'] = false; + $data['canRename'] = false; + $data['current'] = true; + } + return $data; + }, $tokens); + } +} diff --git a/apps/settings/lib/Settings/Personal/Security/Password.php b/apps/settings/lib/Settings/Personal/Security/Password.php new file mode 100644 index 00000000000..8184dae9560 --- /dev/null +++ b/apps/settings/lib/Settings/Personal/Security/Password.php @@ -0,0 +1,42 @@ +<?php + +declare(strict_types=1); + +/** + * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ +namespace OCA\Settings\Settings\Personal\Security; + +use OCP\AppFramework\Http\TemplateResponse; +use OCP\IUserManager; +use OCP\Settings\ISettings; + +class Password implements ISettings { + + public function __construct( + private IUserManager $userManager, + private ?string $userId, + ) { + } + + public function getForm(): TemplateResponse { + $user = $this->userManager->get($this->userId); + $passwordChangeSupported = false; + if ($user !== null) { + $passwordChangeSupported = $user->canChangePassword(); + } + + return new TemplateResponse('settings', 'settings/personal/security/password', [ + 'passwordChangeSupported' => $passwordChangeSupported, + ]); + } + + public function getSection(): string { + return 'security'; + } + + public function getPriority(): int { + return 10; + } +} diff --git a/apps/settings/lib/Settings/Personal/Security/TwoFactor.php b/apps/settings/lib/Settings/Personal/Security/TwoFactor.php new file mode 100644 index 00000000000..0c419cb6fa7 --- /dev/null +++ b/apps/settings/lib/Settings/Personal/Security/TwoFactor.php @@ -0,0 +1,108 @@ +<?php + +declare(strict_types=1); + +/** + * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ +namespace OCA\Settings\Settings\Personal\Security; + +use Exception; +use OC\Authentication\TwoFactorAuth\MandatoryTwoFactor; +use OC\Authentication\TwoFactorAuth\ProviderLoader; +use OCA\TwoFactorBackupCodes\Provider\BackupCodesProvider; +use OCP\AppFramework\Http\TemplateResponse; +use OCP\Authentication\TwoFactorAuth\IProvider; +use OCP\Authentication\TwoFactorAuth\IProvidesPersonalSettings; +use OCP\IConfig; +use OCP\IUserSession; +use OCP\Settings\ISettings; +use function array_filter; +use function array_map; +use function is_null; + +class TwoFactor implements ISettings { + + /** @var ProviderLoader */ + private $providerLoader; + + /** @var MandatoryTwoFactor */ + private $mandatoryTwoFactor; + + public function __construct( + ProviderLoader $providerLoader, + MandatoryTwoFactor $mandatoryTwoFactor, + private IUserSession $userSession, + private IConfig $config, + private ?string $userId, + ) { + $this->providerLoader = $providerLoader; + $this->mandatoryTwoFactor = $mandatoryTwoFactor; + } + + public function getForm(): TemplateResponse { + return new TemplateResponse('settings', 'settings/personal/security/twofactor', [ + 'twoFactorProviderData' => $this->getTwoFactorProviderData(), + ]); + } + + public function getSection(): ?string { + if (!$this->shouldShow()) { + return null; + } + return 'security'; + } + + public function getPriority(): int { + return 15; + } + + private function shouldShow(): bool { + $user = $this->userSession->getUser(); + if (is_null($user)) { + // Actually impossible, but still … + return false; + } + + // Anyone who's supposed to use 2FA should see 2FA settings + if ($this->mandatoryTwoFactor->isEnforcedFor($user)) { + return true; + } + + // If there is at least one provider with personal settings but it's not + // the backup codes provider, then these settings should show. + try { + $providers = $this->providerLoader->getProviders($user); + } catch (Exception $e) { + // Let's hope for the best + return true; + } + foreach ($providers as $provider) { + if ($provider instanceof IProvidesPersonalSettings + && !($provider instanceof BackupCodesProvider)) { + return true; + } + } + return false; + } + + private function getTwoFactorProviderData(): array { + $user = $this->userSession->getUser(); + if (is_null($user)) { + // Actually impossible, but still … + return []; + } + + return [ + 'providers' => array_map(function (IProvidesPersonalSettings $provider) use ($user) { + return [ + 'provider' => $provider, + 'settings' => $provider->getPersonalSettings($user) + ]; + }, array_filter($this->providerLoader->getProviders($user), function (IProvider $provider) { + return $provider instanceof IProvidesPersonalSettings; + })) + ]; + } +} diff --git a/apps/settings/lib/Settings/Personal/Security/WebAuthn.php b/apps/settings/lib/Settings/Personal/Security/WebAuthn.php new file mode 100644 index 00000000000..a6ba4e9522a --- /dev/null +++ b/apps/settings/lib/Settings/Personal/Security/WebAuthn.php @@ -0,0 +1,57 @@ +<?php + +declare(strict_types=1); + +/** + * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ +namespace OCA\Settings\Settings\Personal\Security; + +use OC\Authentication\WebAuthn\Db\PublicKeyCredentialMapper; +use OC\Authentication\WebAuthn\Manager; +use OCA\Settings\AppInfo\Application; +use OCP\AppFramework\Http\TemplateResponse; +use OCP\IInitialStateService; +use OCP\Settings\ISettings; + +class WebAuthn implements ISettings { + + /** @var PublicKeyCredentialMapper */ + private $mapper; + + /** @var Manager */ + private $manager; + + public function __construct( + PublicKeyCredentialMapper $mapper, + private string $userId, + private IInitialStateService $initialStateService, + Manager $manager, + ) { + $this->mapper = $mapper; + $this->manager = $manager; + } + + public function getForm() { + $this->initialStateService->provideInitialState( + Application::APP_ID, + 'webauthn-devices', + $this->mapper->findAllForUid($this->userId) + ); + + return new TemplateResponse('settings', 'settings/personal/security/webauthn'); + } + + public function getSection(): ?string { + if (!$this->manager->isWebAuthnAvailable()) { + return null; + } + + return 'security'; + } + + public function getPriority(): int { + return 20; + } +} |