You are here

public function Keycloak::retrieveUserInfo in Keycloak OpenID Connect 8

Retrieves user info: additional user profile data.

Parameters

string $access_token: Access token.

Return value

array|bool User profile information array, or FALSE if retrieval failed.

Overrides OpenIDConnectClientBase::retrieveUserInfo

File

src/Plugin/OpenIDConnectClient/Keycloak.php, line 367

Class

Keycloak
OpenID Connect client for Keycloak.

Namespace

Drupal\keycloak\Plugin\OpenIDConnectClient

Code

public function retrieveUserInfo($access_token) {
  $userinfo = parent::retrieveUserInfo($access_token);

  // Synchronize email addresses with Keycloak. This is safe as long as
  // Keycloak is the only identity broker, because - as Drupal - it allows
  // unique email addresses only within a single realm.
  if ($this->configuration['userinfo_update_email'] == 1 && is_array($userinfo) && ($sub = openid_connect_extract_sub([], $userinfo))) {

    // Try finding a connected user profile.
    $authmap = \Drupal::service('openid_connect.authmap');
    $account = $authmap
      ->userLoadBySub($sub, $this
      ->getPluginId());
    if ($account !== FALSE && $account
      ->getEmail() != $userinfo['email']) {
      $set_email = TRUE;

      // Check whether the e-mail address is valid.
      if (!\Drupal::service('email.validator')
        ->isValid($userinfo['email'])) {
        \Drupal::messenger()
          ->addError(t('The e-mail address is not valid: @email', [
          '@email' => $userinfo['email'],
        ]));
        $set_email = FALSE;
      }

      // Check whether there is an e-mail address conflict.
      $user = user_load_by_mail($userinfo['email']);
      if ($user && $account
        ->id() != $user
        ->id()) {
        \Drupal::messenger()
          ->addError(t('The e-mail address is already taken: @email', [
          '@email' => $userinfo['email'],
        ]));
        return FALSE;
      }

      // Only change the email, if no validation error occurred.
      if ($set_email) {
        $account
          ->setEmail($userinfo['email']);
        $account
          ->save();
      }
    }
  }

  // Whether to 'translate' locale attribute.
  if (!empty($userinfo['locale']) && $this->keycloak
    ->isI18nEnabled()) {

    // Map Keycloak locale identifier to Drupal language code.
    // This is required for some languages, as Drupal uses IETF
    // script codes, while Keycloak may use IETF region codes for
    // localization.
    $languages = $this->keycloak
      ->getI18nMapping(TRUE);
    if (!empty($languages[$userinfo['locale']])) {
      $userinfo['locale'] = $languages[$userinfo['locale']]['language_id'];
    }
  }
  return $userinfo;
}