WebAuthnController.php 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
  5. * SPDX-License-Identifier: AGPL-3.0-or-later
  6. */
  7. namespace OCA\Settings\Controller;
  8. use OC\Authentication\WebAuthn\Manager;
  9. use OCA\Settings\AppInfo\Application;
  10. use OCP\AppFramework\Controller;
  11. use OCP\AppFramework\Http;
  12. use OCP\AppFramework\Http\Attribute\NoAdminRequired;
  13. use OCP\AppFramework\Http\Attribute\NoCSRFRequired;
  14. use OCP\AppFramework\Http\Attribute\OpenAPI;
  15. use OCP\AppFramework\Http\Attribute\PasswordConfirmationRequired;
  16. use OCP\AppFramework\Http\Attribute\UseSession;
  17. use OCP\AppFramework\Http\JSONResponse;
  18. use OCP\IRequest;
  19. use OCP\ISession;
  20. use OCP\IUserSession;
  21. use Psr\Log\LoggerInterface;
  22. use Webauthn\PublicKeyCredentialCreationOptions;
  23. #[OpenAPI(scope: OpenAPI::SCOPE_IGNORE)]
  24. class WebAuthnController extends Controller {
  25. private const WEBAUTHN_REGISTRATION = 'webauthn_registration';
  26. public function __construct(
  27. IRequest $request,
  28. private LoggerInterface $logger,
  29. private Manager $manager,
  30. private IUserSession $userSession,
  31. private ISession $session,
  32. ) {
  33. parent::__construct(Application::APP_ID, $request);
  34. }
  35. /**
  36. * @NoSubAdminRequired
  37. */
  38. #[NoAdminRequired]
  39. #[PasswordConfirmationRequired]
  40. #[UseSession]
  41. #[NoCSRFRequired]
  42. public function startRegistration(): JSONResponse {
  43. $this->logger->debug('Starting WebAuthn registration');
  44. $credentialOptions = $this->manager->startRegistration($this->userSession->getUser(), $this->request->getServerHost());
  45. // Set this in the session since we need it on finish
  46. $this->session->set(self::WEBAUTHN_REGISTRATION, $credentialOptions);
  47. return new JSONResponse($credentialOptions);
  48. }
  49. /**
  50. * @NoSubAdminRequired
  51. */
  52. #[NoAdminRequired]
  53. #[PasswordConfirmationRequired]
  54. #[UseSession]
  55. public function finishRegistration(string $name, string $data): JSONResponse {
  56. $this->logger->debug('Finishing WebAuthn registration');
  57. if (!$this->session->exists(self::WEBAUTHN_REGISTRATION)) {
  58. $this->logger->debug('Trying to finish WebAuthn registration without session data');
  59. return new JSONResponse([], Http::STATUS_BAD_REQUEST);
  60. }
  61. // Obtain the publicKeyCredentialOptions from when we started the registration
  62. $publicKeyCredentialCreationOptions = PublicKeyCredentialCreationOptions::createFromArray($this->session->get(self::WEBAUTHN_REGISTRATION));
  63. $this->session->remove(self::WEBAUTHN_REGISTRATION);
  64. return new JSONResponse($this->manager->finishRegister($publicKeyCredentialCreationOptions, $name, $data));
  65. }
  66. /**
  67. * @NoSubAdminRequired
  68. */
  69. #[NoAdminRequired]
  70. #[PasswordConfirmationRequired]
  71. public function deleteRegistration(int $id): JSONResponse {
  72. $this->logger->debug('Finishing WebAuthn registration');
  73. $this->manager->deleteRegistration($this->userSession->getUser(), $id);
  74. return new JSONResponse([]);
  75. }
  76. }