WebAuthnController.php 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  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\OpenAPI;
  13. use OCP\AppFramework\Http\JSONResponse;
  14. use OCP\IRequest;
  15. use OCP\ISession;
  16. use OCP\IUserSession;
  17. use Psr\Log\LoggerInterface;
  18. use Webauthn\PublicKeyCredentialCreationOptions;
  19. #[OpenAPI(scope: OpenAPI::SCOPE_IGNORE)]
  20. class WebAuthnController extends Controller {
  21. private const WEBAUTHN_REGISTRATION = 'webauthn_registration';
  22. public function __construct(
  23. IRequest $request,
  24. private LoggerInterface $logger,
  25. private Manager $manager,
  26. private IUserSession $userSession,
  27. private ISession $session,
  28. ) {
  29. parent::__construct(Application::APP_ID, $request);
  30. }
  31. /**
  32. * @NoAdminRequired
  33. * @NoSubAdminRequired
  34. * @PasswordConfirmationRequired
  35. * @UseSession
  36. * @NoCSRFRequired
  37. */
  38. public function startRegistration(): JSONResponse {
  39. $this->logger->debug('Starting WebAuthn registration');
  40. $credentialOptions = $this->manager->startRegistration($this->userSession->getUser(), $this->request->getServerHost());
  41. // Set this in the session since we need it on finish
  42. $this->session->set(self::WEBAUTHN_REGISTRATION, $credentialOptions);
  43. return new JSONResponse($credentialOptions);
  44. }
  45. /**
  46. * @NoAdminRequired
  47. * @NoSubAdminRequired
  48. * @PasswordConfirmationRequired
  49. * @UseSession
  50. */
  51. public function finishRegistration(string $name, string $data): JSONResponse {
  52. $this->logger->debug('Finishing WebAuthn registration');
  53. if (!$this->session->exists(self::WEBAUTHN_REGISTRATION)) {
  54. $this->logger->debug('Trying to finish WebAuthn registration without session data');
  55. return new JSONResponse([], Http::STATUS_BAD_REQUEST);
  56. }
  57. // Obtain the publicKeyCredentialOptions from when we started the registration
  58. $publicKeyCredentialCreationOptions = PublicKeyCredentialCreationOptions::createFromArray($this->session->get(self::WEBAUTHN_REGISTRATION));
  59. $this->session->remove(self::WEBAUTHN_REGISTRATION);
  60. return new JSONResponse($this->manager->finishRegister($publicKeyCredentialCreationOptions, $name, $data));
  61. }
  62. /**
  63. * @NoAdminRequired
  64. * @NoSubAdminRequired
  65. * @PasswordConfirmationRequired
  66. */
  67. public function deleteRegistration(int $id): JSONResponse {
  68. $this->logger->debug('Finishing WebAuthn registration');
  69. $this->manager->deleteRegistration($this->userSession->getUser(), $id);
  70. return new JSONResponse([]);
  71. }
  72. }