public function UserFieldsEventSubscriber::onUserLink in SAML Authentication 8.3
Same name and namespace in other branches
- 4.x modules/samlauth_user_fields/src/EventSubscriber/UserFieldsEventSubscriber.php \Drupal\samlauth_user_fields\EventSubscriber\UserFieldsEventSubscriber::onUserLink()
Tries to link an existing user based on SAML attribute values.
Parameters
\Drupal\samlauth\Event\SamlauthUserLinkEvent $event: The event being dispatched.
File
- modules/
samlauth_user_fields/ src/ EventSubscriber/ UserFieldsEventSubscriber.php, line 95
Class
- UserFieldsEventSubscriber
- Synchronizes SAML attributes into user fields / links new users during login.
Namespace
Drupal\samlauth_user_fields\EventSubscriberCode
public function onUserLink(SamlauthUserLinkEvent $event) {
$match_expressions = $this
->getMatchExpressions($event
->getAttributes());
$config = $this->configFactory
->get(static::CONFIG_OBJECT_NAME);
foreach ($match_expressions as $match_expression) {
$query = $this->entityTypeManager
->getStorage('user')
->getQuery();
if ($config
->get('ignore_blocked')) {
$query
->condition('status', 1);
}
foreach ($match_expression as $field_name => $value) {
$query
->condition($field_name, $value);
}
$results = $query
->execute();
// @todo we should figure out what we want to do with users that are
// already 'linked' in the authmap table. Maybe we want to exclude
// them from the query results; maybe we want to include them and
// (optionally) give an error if we encounter them. At this point, we
// include them without error. The main module will just "link" this
// user, which will silently fail (because of the existing link) and
// be repeated on the next login. This is consistent with existing
// behavior for name/email. I may want to wait with refining this
// behavior, until the behavior of ExternalAuth::linkExistingAccount()
// is clear and stable. (IMHO it currently is not / I think there are
// outstanding issues which will influence its behavior.)
// @todo when we change that, change "existing (local|Drupal)? user" to
// "existing non-linked (local|Drupal)? user" in descriptions.
$count = count($results);
if ($count) {
if ($count > 1) {
$query = [];
foreach ($match_expression as $field_name => $value) {
$query[] = "{$field_name}={$value}";
}
if ($config
->get('ignore_blocked')) {
$query[] = "status=1";
}
if (!$config
->get('link_first_user')) {
$this->logger
->error("Denying login because SAML data match is ambiguous: @count matching users (@uids) found for @query", [
'@count' => $count,
'@uids' => implode(',', $results),
'@query' => implode(',', $query),
]);
throw new UserVisibleException('It is unclear which user should be logged in. Please contact an administrator.');
}
$this->logger
->notice("Selecting first of @count matching users to link (@uids) for @query", [
'@count' => $count,
'@uids' => implode(',', $results),
'@query' => implode(',', $query),
]);
}
$account = $this->entityTypeManager
->getStorage('user')
->load(reset($results));
if (!$account) {
throw new \RuntimeException('Found user %uid to link on login, but it cannot be loaded.');
}
$event
->setLinkedAccount($account);
break;
}
}
}