[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/plugins/system/webauthn/src/PluginTraits/ -> AjaxHandlerCreate.php (source)

   1  <?php
   2  
   3  /**
   4   * @package     Joomla.Plugin
   5   * @subpackage  System.Webauthn
   6   *
   7   * @copyright   (C) 2020 Open Source Matters, Inc. <https://www.joomla.org>
   8   * @license     GNU General Public License version 2 or later; see LICENSE.txt
   9   */
  10  
  11  namespace Joomla\Plugin\System\Webauthn\PluginTraits;
  12  
  13  use Exception;
  14  use Joomla\CMS\Event\Plugin\System\Webauthn\AjaxCreate;
  15  use Joomla\CMS\Factory;
  16  use Joomla\CMS\Language\Text;
  17  use Joomla\CMS\Layout\FileLayout;
  18  use Joomla\CMS\User\UserFactoryInterface;
  19  use Joomla\Event\Event;
  20  use RuntimeException;
  21  use Webauthn\PublicKeyCredentialSource;
  22  
  23  // phpcs:disable PSR1.Files.SideEffects
  24  \defined('_JEXEC') or die;
  25  // phpcs:enable PSR1.Files.SideEffects
  26  
  27  /**
  28   * Ajax handler for akaction=create
  29   *
  30   * Handles the browser postback for the credentials creation flow
  31   *
  32   * @since   4.0.0
  33   */
  34  trait AjaxHandlerCreate
  35  {
  36      /**
  37       * Handle the callback to add a new WebAuthn authenticator
  38       *
  39       * @param   AjaxCreate  $event  The event we are handling
  40       *
  41       * @return  void
  42       *
  43       * @throws  Exception
  44       * @since   4.0.0
  45       */
  46      public function onAjaxWebauthnCreate(AjaxCreate $event): void
  47      {
  48          /**
  49           * Fundamental sanity check: this callback is only allowed after a Public Key has been created server-side and
  50           * the user it was created for matches the current user.
  51           *
  52           * This is also checked in the validateAuthenticationData() so why check here? In case we have the wrong user
  53           * I need to fail early with a Joomla error page instead of falling through the code and possibly displaying
  54           * someone else's Webauthn configuration thus mitigating a major privacy and security risk. So, please, DO NOT
  55           * remove this sanity check!
  56           */
  57          $session = $this->getApplication()->getSession();
  58          $storedUserId = $session->get('plg_system_webauthn.registration_user_id', 0);
  59          $thatUser     = empty($storedUserId) ?
  60              Factory::getApplication()->getIdentity() :
  61              Factory::getContainer()->get(UserFactoryInterface::class)->loadUserById($storedUserId);
  62          $myUser = Factory::getApplication()->getIdentity();
  63  
  64          if ($thatUser->guest || ($thatUser->id != $myUser->id)) {
  65              // Unset the session variables used for registering authenticators (security precaution).
  66              $session->set('plg_system_webauthn.registration_user_id', null);
  67              $session->set('plg_system_webauthn.publicKeyCredentialCreationOptions', null);
  68  
  69              // Politely tell the presumed hacker trying to abuse this callback to go away.
  70              throw new RuntimeException(Text::_('PLG_SYSTEM_WEBAUTHN_ERR_CREATE_INVALID_USER'));
  71          }
  72  
  73          // Get the credentials repository object. It's outside the try-catch because I also need it to display the GUI.
  74          $credentialRepository = $this->authenticationHelper->getCredentialsRepository();
  75  
  76          // Try to validate the browser data. If there's an error I won't save anything and pass the message to the GUI.
  77          try {
  78              $input = $this->getApplication()->input;
  79  
  80              // Retrieve the data sent by the device
  81              $data = $input->get('data', '', 'raw');
  82  
  83              $publicKeyCredentialSource = $this->authenticationHelper->validateAttestationResponse($data);
  84  
  85              if (!\is_object($publicKeyCredentialSource) || !($publicKeyCredentialSource instanceof PublicKeyCredentialSource)) {
  86                  throw new RuntimeException(Text::_('PLG_SYSTEM_WEBAUTHN_ERR_CREATE_NO_ATTESTED_DATA'));
  87              }
  88  
  89              $credentialRepository->saveCredentialSource($publicKeyCredentialSource);
  90          } catch (Exception $e) {
  91              $error                  = $e->getMessage();
  92              $publicKeyCredentialSource = null;
  93          }
  94  
  95          // Unset the session variables used for registering authenticators (security precaution).
  96          $session->set('plg_system_webauthn.registration_user_id', null);
  97          $session->set('plg_system_webauthn.publicKeyCredentialCreationOptions', null);
  98  
  99          // Render the GUI and return it
 100          $layoutParameters = [
 101              'user'                => $thatUser,
 102              'allow_add'           => $thatUser->id == $myUser->id,
 103              'credentials'         => $credentialRepository->getAll($thatUser->id),
 104              'knownAuthenticators' => $this->authenticationHelper->getKnownAuthenticators(),
 105              'attestationSupport'  => $this->authenticationHelper->hasAttestationSupport(),
 106          ];
 107  
 108          if (isset($error) && !empty($error)) {
 109              $layoutParameters['error'] = $error;
 110          }
 111  
 112          $layout = new FileLayout('plugins.system.webauthn.manage', JPATH_SITE . '/plugins/system/webauthn/layout');
 113  
 114          $event->addResult($layout->render($layoutParameters));
 115      }
 116  }


Generated: Wed Sep 7 05:41:13 2022 Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer