- 🇺🇸United States John Franklin
Looking to current External Authentication codebase, I see no routes, not configurations, no forms. That's great! It's pure API and it should stay as it is.
The need to validate claims, both per se and against existing users, is a common enough use case that the functionality should exist. I'm running into this same issue on my own projects. Yes, the Drupal API allows for users with missing or duplicate email addresses, and the UI does a lot of the user validation work. However, with External Auth, that validation is bypassed, and it falls on each module building on External Auth to add it back in, which strikes me as duplication of effort.
I can see the merits of keeping External Auth as an API-only module. That said, just as External Auth handles the common parts of any external authentication solution, IMHO it should also provide that common validation, while allowing it to be optional.
There are two major ways I can see the optional validation happening while keeping External Auth as an API-only module:
1) provide hooks/functions/API parameters/etc. to allow calling modules to trigger the validation.
2) provide a separate sub-module that implements the validation which site builders can optionally enable if they need it.The first favors module developers who need to add a
'#validate' => TRUE
somewhere, or need to call$this->externalAuth->validateData()
(or similar). The second favors site builders, but may require some refactoring of the events triggered by External Auth, perhaps incorporated into ✨ Redo authmap_alter / register events. Needs review .Thoughts?
p.s. I'm intentionally not re-opening this without a clearer idea of where the community wants to go.
- 🇨🇴Colombia julianmancera
To accomplish this you can add an event subscriber to AUTHMAP_ALTER event like:
<?php namespace Drupal\my_module\EventSubscriber; use Drupal\Core\Database\Connection; use Drupal\externalauth\Event\ExternalAuthAuthmapAlterEvent; use Drupal\externalauth\Event\ExternalAuthEvents; use Symfony\Component\EventDispatcher\EventSubscriberInterface; /** * Class ExternalAuthSubscriber. * * @package Drupal\my_module\EventSubscriber */ class ExternalAuthSubscriber implements EventSubscriberInterface { /** * The database connection. * * @var \Drupal\Core\Database\Connection */ protected Connection $database; /** * Constructor. * * We use dependency injection. * * @param \Drupal\Core\Database\Connection $database * The database service. */ public function __construct(Connection $database) { $this->database = $database; } /** * {@inheritdoc} */ public static function getSubscribedEvents() { return [ // Static class constant => method on this class. ExternalAuthEvents::AUTHMAP_ALTER => 'onUserRegisterMapAlter', ]; } /** * Subscribe to the external auth map event dispatched. * * @param \Drupal\externalauth\Event\ExternalAuthAuthmapAlterEvent $event * Mapping event object. */ public function onUserRegisterMapAlter(ExternalAuthAuthmapAlterEvent $event) { $account = $event->getAuthname(); // Looking for user email. $query = $this->database->select('users_field_data', 'ufs') ->fields('ufs', ['name']) ->range(0, 1) ->condition('mail', $email) ->execute(); $user_account = $query->fetchObject(); if ($user_account) { $event->setUsername($user_account->name); } } }
Though some times you have different username that the authname, for such case you can use the patch attached