You are here

openid_connect.module in OpenID Connect / OAuth client 8

Same filename and directory in other branches
  1. 7 openid_connect.module
  2. 2.x openid_connect.module

Hook implementations of the OpenID Connect module.

File

openid_connect.module
View source
<?php

/**
 * @file
 * Hook implementations of the OpenID Connect module.
 */

/* @noinspection PhpUnnecessaryFullyQualifiedNameInspection */

/* @noinspection PhpUnused */
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Url;
use Drupal\user\UserInterface;

/**
 * Implements hook_help().
 */
function openid_connect_help($route_name, RouteMatchInterface $route_match) {
  $output = '';
  switch ($route_name) {

    // Main module help for the keycloak module.
    case 'help.page.openid_connect':
      $output .= '<h3>' . t('About') . '</h3>';
      $output .= '<p>' . t('A pluggable client implementation for the OpenID Connect protocol. You can enable available OpenID Connect clients within the <a href=":settings">OpenID Connect settings</a> page. For more information, see the <a href=":documentation">online documentation for the OpenID Connect module</a>.', [
        ':settings' => Url::fromRoute('openid_connect.admin_settings')
          ->toString(),
        ':documentation' => 'https://www.drupal.org/docs/8/modules/openid-connect',
      ]) . '</p>';
      $output .= '<h3>' . t('Uses') . '</h3>';
      $output .= '<dl>';
      $output .= '<dt>' . t('Login to Drupal using OpenID Connect/OAuth2 providers') . '</dt>';
      $output .= '<dd>' . t('Drupal users can use external OpenID Connect authentication providers to register and login to the Drupal site.') . '</dd>';
      $output .= '<dt>' . t('Default providers') . '</dt>';
      $output .= '<dd>' . t('The default clients provided by the module for Google, Facebook, Github, LinkedIn and Okta can be used out-of-the box.') . '</dd>';
      $output .= '<dt>' . t('Custom OpenID Connect/OAuth2 providers') . '</dt>';
      $output .= '<dd>' . t('Easily add an own provider by using the provided Generic client, or use a custom provider client plugin.') . '</dd>';
      $output .= '<dt>' . t('Synchronize user properties/fields with OpenID Connect claims') . '</dt>';
      $output .= '<dd>' . t("During login and user registration user attributes can optionally be synchronized with the OpenID Connect claims mapping.") . '</dd>';
      $output .= '</dl>';
  }
  return $output;
}

/**
 * Implements hook_entity_property_info_alter().
 */
function openid_connect_entity_property_info_alter(&$info) {
  $properties =& $info['user']['properties'];
  if (!isset($properties['timezone'])) {

    // Adds the missing timezone property.
    $properties['timezone'] = [
      'label' => t('Time zone'),
      'description' => t("The user's time zone."),
      'options list' => 'system_time_zones',
      'getter callback' => 'entity_property_verbatim_get',
      'setter callback' => 'entity_property_verbatim_set',
      'schema field' => 'timezone',
    ];
  }
}

/**
 * Implements hook_user_insert().
 */
function openid_connect_user_insert(EntityInterface $entity) {
  if (isset($entity->openid_connect_client) && isset($entity->openid_connect_sub)) {
    \Drupal::service('openid_connect.authmap')
      ->createAssociation($entity, $entity->openid_connect_client, $entity->openid_connect_sub);
  }
}

/**
 * Implements hook_user_cancel().
 */
function openid_connect_user_cancel($edit, $account, $method) {
  $authmap = \Drupal::service('openid_connect.authmap');
  $authmap
    ->deleteAssociation($account
    ->id());
}

/**
 * Implements hook_ENTITY_TYPE_delete() for user.
 */
function openid_connect_user_delete(EntityInterface $entity) {
  $authmap = \Drupal::service('openid_connect.authmap');
  $authmap
    ->deleteAssociation($entity
    ->id());
}

/**
 * Implements hook_user_format_name_alter().
 */
function openid_connect_user_format_name_alter(&$name, $account) {

  // Ensure that usernames are not displayed if they are email addresses, or if
  // they are generated names starting with 'oidc_'.
  $oidc_name = \Drupal::service('user.data')
    ->get('openid_connect', $account
    ->id(), 'oidc_name');
  if (!empty($oidc_name) && strpos($name, 'oidc_') !== 0 && strpos($name, '@') !== FALSE) {
    $name = $oidc_name;
  }
}

/**
 * Implements hook_form_FORM_ID_alter() for form_user_form.
 */
function openid_connect_form_user_form_alter(&$form, &$form_state) {

  // Whether the current user is allowed to change its password.
  if (\Drupal::service('openid_connect.openid_connect')
    ->hasSetPasswordAccess()) {
    return;
  }
  if (isset($form['account'])) {
    $account_form =& $form['account'];
  }
  else {
    $account_form =& $form;
  }
  $account_form['current_pass']['#access'] = FALSE;
  $account_form['current_pass_required_values']['#value'] = [];
  $account_form['pass']['#access'] = FALSE;
  $account_form['pass']['#required'] = FALSE;
}

/**
 * Implements hook_form_FORM_ID_alter().
 */
function openid_connect_form_user_profile_form_alter(&$form, &$form_state) {
  if (isset($form['account'])) {
    $account_form =& $form['account'];
  }
  else {
    $account_form =& $form;
  }
  $account = \Drupal::currentUser();
  if (!empty($account_form['pass']['#access']) && !\Drupal::service('openid_connect.openid_connect')
    ->hasSetPasswordAccess($account)) {
    $account_form['current_pass']['#access'] = FALSE;
    $account_form['current_pass_required_values']['#value'] = [];
    $account_form['pass']['#access'] = FALSE;
  }
}

/**
 * Implements hook_form_FORM_ID_alter().
 */
function openid_connect_form_user_pass_alter(array &$form, FormStateInterface &$form_state) {
  $form['#validate'][] = '_openid_connect_user_pass_form_validate';
}

/**
 * Validate user password reset form on existing connections with openid.
 *
 * @param array $form
 *   An associative array containing the structure of the form.
 * @param \Drupal\Core\Form\FormStateInterface $form_state
 *   The current state of the form.
 */
function _openid_connect_user_pass_form_validate(array &$form, FormStateInterface $form_state) {
  $name = $form_state
    ->getValue('name');
  if (empty($name)) {
    return;
  }

  // Try to load by email.
  $user = user_load_by_mail($name);
  if (empty($user)) {

    // No success, try to load by name.
    $user = user_load_by_name($name);
  }
  if (!empty($user) && !\Drupal::service('openid_connect.openid_connect')
    ->hasSetPasswordAccess($user)) {
    $form_state
      ->setErrorByName('name', t('%name is connected to an external authentication system.', [
      '%name' => $name,
    ]));
  }
}

/**
 * Implements hook_form_FORM_ID_alter().
 */
function openid_connect_form_user_login_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  $user_login_display = \Drupal::config('openid_connect.settings')
    ->get('user_login_display');
  if ($user_login_display != 'hidden') {
    $openid_form = \Drupal::formBuilder()
      ->getForm('Drupal\\openid_connect\\Form\\OpenIDConnectLoginForm');
    switch ($user_login_display) {
      case 'above':
        $form['#prefix'] = \Drupal::service('renderer')
          ->render($openid_form);
        break;
      case 'below':
        $form['#suffix'] = \Drupal::service('renderer')
          ->render($openid_form);
        break;
      case 'replace':

        // Do nothing in case the query contains the 'showcore' parameter.
        $query = \Drupal::request()->query;
        if (!$query
          ->has('showcore')) {

          // Replace the user login form with the IDP login button.
          $form = $openid_form;
        }
        $form['#cache']['contexts'][] = 'url.query_args:showcore';
        break;
    }
  }
}

/**
 * Saves user profile information into a user account.
 *
 * @param \Drupal\user\UserInterface $account
 *   An user account object.
 * @param array $userinfo
 *   An array with information about the user.
 *
 * @deprecated in openid_connect:8.x-1.0-beta6 and is removed from openid_connect:8.x-2.0.
 *   Use Drupal\openid_connect\OpenIDConnect::saveUserinfo() or
 *   \Drupal::service('openid_connect.openid_connect')->saveUserinfo() instead.
 * @see https://www.drupal.org/project/openid_connect/issues/2961938
 */
function openid_connect_save_userinfo(UserInterface $account, array $userinfo) {
  @trigger_error("openid_connect_save_userinfo() is deprecated in openid_connect:8.x-1.0-beta6 and is removed from openid_connect:8.x-2.0.  Use Drupal\\openid_connect\\OpenIDConnect::saveUserinfo() or \\Drupal::service('openid_connect.openid_connect')->saveUserinfo() instead. See https://www.drupal.org/project/openid_connect/issues/2961938", E_USER_DEPRECATED);
  \Drupal::service('openid_connect.openid_connect')
    ->saveUserinfo($account, $userinfo);
}

/**
 * Logs in a user.
 *
 * @param \Drupal\user\UserInterface $account
 *   The user account.
 *
 * @deprecated in openid_connect:8.x-1.0-beta6 and is removed from openid_connect:8.x-2.0.
 *   Use Drupal\openid_connect\OpenIDConnect::loginUser() or
 *   user_login_finalize() instead.
 * @see https://www.drupal.org/project/openid_connect/issues/2961938
 */
function openid_connect_login_user(UserInterface $account) {
  @trigger_error("openid_connect_login_user() is deprecated in openid_connect:8.x-1.0-beta6 and is removed from openid_connect:8.x-2.0. Use Drupal\\openid_connect\\OpenIDConnect::loginUser() or user_login_finalize() instead. See https://www.drupal.org/project/openid_connect/issues/2961938", E_USER_DEPRECATED);
  user_login_finalize($account);
}

/**
 * Save the current path in the session, for redirecting after authorization.
 *
 * @deprecated in openid_connect:8.x-1.0-beta6 and is removed from openid_connect:8.x-2.0.
 *   Use Drupal\openid_connect\OpenIDConnectSession::saveDestination() or
 *   \Drupal::service('openid_connect.session')->saveDestination() instead.
 * @see https://www.drupal.org/project/openid_connect/issues/2961938
 */
function openid_connect_save_destination() {
  @trigger_error("openid_connect_save_destination() is deprecated in openid_connect:8.x-1.0-beta6 and is removed from openid_connect:8.x-2.0. Use Drupal\\openid_connect\\OpenIDConnectSession::saveDestination() or \\Drupal::service('openid_connect.session')->saveDestination() instead. See https://www.drupal.org/project/openid_connect/issues/2961938", E_USER_DEPRECATED);
  \Drupal::service('openid_connect.session')
    ->saveDestination();
}

/**
 * Creates a user indicating sub-id and login provider.
 *
 * @param string $sub
 *   The subject identifier.
 * @param array $userinfo
 *   The user claims, containing at least 'email'.
 * @param string $client_name
 *   The machine name of the client.
 * @param int $status
 *   The initial user status.
 *
 * @return object|false
 *   The user object or FALSE on failure.
 *
 * @deprecated in openid_connect:8.x-1.0-beta6 and is removed from openid_connect:8.x-2.0.
 *   Use Drupal\openid_connect\OpenIDConnect::createUser() or
 *   \Drupal::service('openid_connect.openid_connect')->createUser() instead.
 * @see https://www.drupal.org/project/openid_connect/issues/2961938
 */
function openid_connect_create_user($sub, array $userinfo, $client_name, $status = 1) {
  @trigger_error("openid_connect_create_user() is deprecated in openid_connect:8.x-1.0-beta6 and is removed from openid_connect:8.x-2.0. Use Drupal\\openid_connect\\OpenIDConnect::createUser() or \\Drupal::service('openid_connect.openid_connect')->createUser() instead. See https://www.drupal.org/project/openid_connect/issues/2961938", E_USER_DEPRECATED);
  return \Drupal::service('openid_connect.openid_connect')
    ->createUser($sub, $userinfo, $client_name, $status);
}

/**
 * Generate a username for a new account.
 *
 * @param string $sub
 *   The subject identifier.
 * @param array $userinfo
 *   The user claims.
 * @param string $client_name
 *   The client identifier.
 *
 * @return string
 *   A unique username.
 *
 * @deprecated in openid_connect:8.x-1.0-beta6 and is removed from openid_connect:8.x-2.0.
 *   No replacement is intended. The new method
 *   Drupal\openid_connect\OpenIDConnect::generateUsername() or
 *   \Drupal::service('openid_connect.openid_connect')->generateUsername()
 *   will be set protected for the OpenID Connect service.
 * @see https://www.drupal.org/project/openid_connect/issues/2961938
 */
function openid_connect_generate_username($sub, array $userinfo, $client_name) {
  @trigger_error("openid_connect_generate_username() is deprecated in openid_connect:8.x-1.0-beta6 and is removed from openid_connect:8.x-2.0. No replacement is intended. The new method Drupal\\openid_connect\\OpenIDConnect::generateUsername() or \\Drupal::service('openid_connect.openid_connect')->generateUsername() will be set protected for the OpenID Connect service. See https://www.drupal.org/project/openid_connect/issues/2961938", E_USER_DEPRECATED);
  return \Drupal::service('openid_connect.openid_connect')
    ->generateUsername($sub, $userinfo, $client_name);
}

/**
 * Check if a user name already exists.
 *
 * @param string $name
 *   A name to test.
 *
 * @return bool
 *   TRUE if a user exists with the given name, FALSE otherwise.
 *
 * @deprecated in openid_connect:8.x-1.0-beta6 and is removed from openid_connect:8.x-2.0.
 *   No replacement is intended. The new method
 *   Drupal\openid_connect\OpenIDConnect::usernameExists() or
 *   \Drupal::service('openid_connect.openid_connect')->usernameExists()
 *   will be set protected for the OpenID Connect service.
 * @see https://www.drupal.org/project/openid_connect/issues/2961938
 */
function openid_connect_username_exists($name) {
  @trigger_error("openid_connect_username_exists() is deprecated in openid_connect:8.x-1.0-beta6 and is removed from openid_connect:8.x-2.0. No replacement is intended. The new method Drupal\\openid_connect\\OpenIDConnect::usernameExists() or \\Drupal::service('openid_connect.openid_connect')->usernameExists() will be set protected for the OpenID Connect service. See https://www.drupal.org/project/openid_connect/issues/2961938", E_USER_DEPRECATED);
  return \Drupal::service('openid_connect.openid_connect')
    ->usernameExists($name);
}

/**
 * Find whether the user is allowed to change their own password.
 *
 * @param object $account
 *   A user account object.
 *
 * @return bool
 *   TRUE if access is granted, FALSE otherwise.
 *
 * @deprecated in openid_connect:8.x-1.0-beta6 and is removed from openid_connect:8.x-2.0.
 *   Use Drupal\openid_connect\OpenIDConnect::hasSetPasswordAccess() or
 *   \Drupal::service('openid_connect.openid_connect')->hasSetPasswordAccess()
 *   instead.
 * @see https://www.drupal.org/project/openid_connect/issues/2961938
 */
function openid_connect_set_password_access($account) {
  @trigger_error("openid_connect_set_password_access() is deprecated in openid_connect:8.x-1.0-beta6 and is removed from openid_connect:8.x-2.0. Use Drupal\\openid_connect\\OpenIDConnect::hasSetPasswordAccess() or \\Drupal::service('openid_connect.openid_connect')->hasSetPasswordAccess() instead. See https://www.drupal.org/project/openid_connect/issues/2961938", E_USER_DEPRECATED);
  return \Drupal::service('openid_connect.openid_connect')
    ->hasSetPasswordAccess($account);
}

/**
 * Connect an external OpenID Connect account to a Drupal user account.
 *
 * @param object $account
 *   The Drupal user object.
 * @param string $client_name
 *   The client machine name.
 * @param string $sub
 *   The 'sub' property identifying the external account.
 *
 * @deprecated in openid_connect:8.x-1.0-beta6 and is removed from openid_connect:8.x-2.0.
 *   Use Drupal\openid_connect\OpenIDConnectAuthmap::createAssociation() or
 *   \Drupal::service('openid_connect.authmap')->createAssociation() instead.
 * @see https://www.drupal.org/project/openid_connect/issues/2961938
 */
function openid_connect_connect_account($account, $client_name, $sub) {
  @trigger_error("openid_connect_connect_account() is deprecated in openid_connect:8.x-1.0-beta6 and is removed from openid_connect:8.x-2.0. Use Drupal\\openid_connect\\OpenIDConnectAuthmap::createAssociation() or \\Drupal::service('openid_connect.authmap')->createAssociation() instead. See https://www.drupal.org/project/openid_connect/issues/2961938", E_USER_DEPRECATED);
  \Drupal::service('openid_connect.authmap')
    ->createAssociation($account, $client_name, $sub);
}

/**
 * Disconnect an external OpenID Connect account from a Drupal user account.
 *
 * @param object $account
 *   The Drupal user object.
 * @param string $client_name
 *   The client machine name.
 *
 * @deprecated in openid_connect:8.x-1.0-beta6 and is removed from openid_connect:8.x-2.0.
 *   Use Drupal\openid_connect\OpenIDConnectAuthmap::deleteAssociation() or
 *   \Drupal::service('openid_connect.authmap')->deleteAssociation() instead.
 * @see https://www.drupal.org/project/openid_connect/issues/2961938
 */
function openid_connect_disconnect_account($account, $client_name) {
  @trigger_error("openid_connect_disconnect_account() is deprecated in openid_connect:8.x-1.0-beta6 and is removed from openid_connect:8.x-2.0. Use Drupal\\openid_connect\\OpenIDConnectAuthmap::deleteAssociation() or \\Drupal::service('openid_connect.authmap')->deleteAssociation() instead. See https://www.drupal.org/project/openid_connect/issues/2961938", E_USER_DEPRECATED);
  \Drupal::service('openid_connect.authmap')
    ->deleteAssociation($account
    ->id(), $client_name);
}

/**
 * Get the 'sub' property from the user data and/or user claims.
 *
 * The 'sub' (Subject Identifier) is a unique ID for the external provider to
 * identify the user.
 *
 * @param array $user_data
 *   The user data as returned from
 *   OpenIDConnectClientInterface::decodeIdToken().
 * @param array $userinfo
 *   The user claims as returned from
 *   OpenIDConnectClientInterface::retrieveUserInfo().
 *
 * @return string|false
 *   The sub, or FALSE if there was an error.
 *
 * @deprecated in openid_connect:8.x-1.0-beta6 and is removed from openid_connect:8.x-2.0.
 *   Use Drupal\openid_connect\OpenIDConnect::extractSub() or
 *   \Drupal::service('openid_connect.openid_connect')->extractSub() instead.
 * @see https://www.drupal.org/project/openid_connect/issues/2961938
 */
function openid_connect_extract_sub(array $user_data, array $userinfo) {
  @trigger_error("openid_connect_extract_sub() is deprecated in openid_connect:8.x-1.0-beta6 and is removed from openid_connect:8.x-2.0. Use Drupal\\openid_connect\\OpenIDConnect::extractSub() or \\Drupal::service('openid_connect.openid_connect')->extractSub() instead. See https://www.drupal.org/project/openid_connect/issues/2961938", E_USER_DEPRECATED);
  return \Drupal::service('openid_connect.openid_connect')
    ->extractSub($user_data, $userinfo);
}

/**
 * Complete the authorization after tokens have been retrieved.
 *
 * @param object $client
 *   The client.
 * @param array $tokens
 *   The tokens as returned from OpenIDConnectClientInterface::retrieveTokens().
 * @param string|array $destination
 *   The path to redirect to after authorization.
 *
 * @return bool
 *   TRUE on success, FALSE on failure.
 *
 * @deprecated in openid_connect:8.x-1.0-beta6 and is removed from openid_connect:8.x-2.0.
 *   Use Drupal\openid_connect\OpenIDConnect::completeAuthorization() or
 *   \Drupal::service('openid_connect.openid_connect')->completeAuthorization()
 *   instead.
 * @see https://www.drupal.org/project/openid_connect/issues/2961938
 */
function openid_connect_complete_authorization($client, array $tokens, &$destination) {
  @trigger_error("openid_connect_complete_authorization() is deprecated in openid_connect:8.x-1.0-beta6 and is removed from openid_connect:8.x-2.0. Use Drupal\\openid_connect\\OpenIDConnect::completeAuthorization() or \\Drupal::service('openid_connect.openid_connect')->completeAuthorization() instead. See https://www.drupal.org/project/openid_connect/issues/2961938", E_USER_DEPRECATED);
  return \Drupal::service('openid_connect.openid_connect')
    ->completeAuthorization($client, $tokens, $destination);
}

/**
 * Connect the current user's account to an external provider.
 *
 * @param object $client
 *   The client.
 * @param array $tokens
 *   The tokens as returned from OpenIDConnectClientInterface::retrieveTokens().
 *
 * @return bool
 *   TRUE on success, FALSE on failure.
 *
 * @deprecated in openid_connect:8.x-1.0-beta6 and is removed from openid_connect:8.x-2.0.
 *   Use Drupal\openid_connect\OpenIDConnect::connectCurrentUser() or
 *   \Drupal::service('openid_connect.openid_connect')->connectCurrentUser()
 *   instead.
 * @see https://www.drupal.org/project/openid_connect/issues/2961938
 */
function openid_connect_connect_current_user($client, array $tokens) {
  @trigger_error("openid_connect_connect_current_user() is deprecated in openid_connect:8.x-1.0-beta6 and is removed from openid_connect:8.x-2.0. Use Drupal\\openid_connect\\OpenIDConnect::connectCurrentUser() or \\Drupal::service('openid_connect.openid_connect')->connectCurrentUser() instead. See https://www.drupal.org/project/openid_connect/issues/2961938", E_USER_DEPRECATED);
  return \Drupal::service('openid_connect.openid_connect')
    ->connectCurrentUser($client, $tokens);
}

Functions

Namesort descending Description
openid_connect_complete_authorization Deprecated Complete the authorization after tokens have been retrieved.
openid_connect_connect_account Deprecated Connect an external OpenID Connect account to a Drupal user account.
openid_connect_connect_current_user Deprecated Connect the current user's account to an external provider.
openid_connect_create_user Deprecated Creates a user indicating sub-id and login provider.
openid_connect_disconnect_account Deprecated Disconnect an external OpenID Connect account from a Drupal user account.
openid_connect_entity_property_info_alter Implements hook_entity_property_info_alter().
openid_connect_extract_sub Deprecated Get the 'sub' property from the user data and/or user claims.
openid_connect_form_user_form_alter Implements hook_form_FORM_ID_alter() for form_user_form.
openid_connect_form_user_login_form_alter Implements hook_form_FORM_ID_alter().
openid_connect_form_user_pass_alter Implements hook_form_FORM_ID_alter().
openid_connect_form_user_profile_form_alter Implements hook_form_FORM_ID_alter().
openid_connect_generate_username Deprecated Generate a username for a new account.
openid_connect_help Implements hook_help().
openid_connect_login_user Deprecated Logs in a user.
openid_connect_save_destination Deprecated Save the current path in the session, for redirecting after authorization.
openid_connect_save_userinfo Deprecated Saves user profile information into a user account.
openid_connect_set_password_access Deprecated Find whether the user is allowed to change their own password.
openid_connect_username_exists Deprecated Check if a user name already exists.
openid_connect_user_cancel Implements hook_user_cancel().
openid_connect_user_delete Implements hook_ENTITY_TYPE_delete() for user.
openid_connect_user_format_name_alter Implements hook_user_format_name_alter().
openid_connect_user_insert Implements hook_user_insert().
_openid_connect_user_pass_form_validate Validate user password reset form on existing connections with openid.