You are here

oauth2_login.module in OAuth2 Login 7.2

Same filename and directory in other branches
  1. 8 oauth2_login.module
  2. 7 oauth2_login.module

Provides OAuth2 Login functionality.

File

oauth2_login.module
View source
<?php

/**
 * @file
 * Provides OAuth2 Login functionality.
 */

/**
 * Implements hook_help().
 */
function oauth2_login_help($path, $arg) {
  $help = '';
  switch ($path) {
    case 'admin/config/people/oauth2_login':
      $oauth2_server = variable_get('oauth2_login_oauth2_server', '');
      $help = t('<p>The module OAuth2 Login is used to allow the users
of another Drupal site to login to your site. This is done through OAuth2
authentication. On login the users are redirected to the login of the other
Drupal site, and after they login there, they are redirected back to this
site.</p>
<p>For this to work, the module
<a href="https://github.com/dashohoxha/oauth2_loginprovider" target="_blank">
OAuth2 Login Provider</a> must be installed on the other site, and a client
that corresponds to this site must be registered there (on the path
<a href="!oauth2_clients_config" target="_blank">admin/structure/oauth2-servers/manage/oauth2/clients</a>).
On that client, you must set the <strong>Redirect URI</strong> to:
<strong>!redirect_uri</strong></p>
<p>On the configuration of OAuth2 Login you should put the
<strong>Server URL</strong> (base url) of the remote site,
and the <strong>Client ID</strong> and <strong>Client secret</strong>
of the registered client.</p>
<p>To customize the details of login, play with the
<a href="hybridauth" target="_blank">settings of HybridAuth</a></p>', [
        '!oauth2_clients_config' => $oauth2_server . '/admin/structure/oauth2-servers/manage/oauth2/clients',
        '!redirect_uri' => url('oauth2/authorized', [
          'absolute' => TRUE,
        ]),
      ]);
      break;
  }
  return $help;
}

/**
 * Implements hook_menu().
 */
function oauth2_login_menu() {
  $items = [
    'admin/config/people/oauth2_login' => [
      'title' => 'OAuth2 Login',
      'description' => 'Login through the OAuth2 Login Provider of another Drupal site.',
      'page callback' => 'drupal_get_form',
      'page arguments' => [
        'oauth2_login_admin_settings',
      ],
      'access arguments' => [
        'administer site configuration',
      ],
      'file' => 'oauth2_login.admin.inc',
    ],
    'user/oauth2_login' => [
      'title' => 'Login',
      'description' => 'Login with OAuth2.',
      'page callback' => 'oauth2_login_callback',
      'access callback' => 'user_is_anonymous',
    ],
    'oauth2/proxy' => [
      'title' => 'OAuth2 Proxy',
      'description' => 'OAuth2 Proxy For Mobile Apps.',
      'page callback' => 'oauth2_proxy_callback',
      'access callback' => TRUE,
    ],
  ];
  return $items;
}

/**
 * Implements hook_url_outbound_alter().
 */
function oauth2_login_url_outbound_alter(&$path, &$options, $original_path) {

  // Keep track of the current page so that we can return back after login.
  switch ($path) {
    case 'user/login':
      $options['query']['destination'] = $_GET['q'];
      break;
    case 'user/oauth2_login':
      $options['query']['page'] = request_uri();
      break;
  }
}

/**
 * Callback function for the menu user/oauth2_login.
 */
function oauth2_login_callback() {
  oauth2_login($_GET['page']);
}

/**
 * Callback function for the menu oauth2/proxy.
 * The parameter $action can be: login|logout|refresh
 */
function oauth2_proxy_callback($action) {
  switch ($action) {
    case 'login':
      _oauth2_proxy_login();
      break;
    case 'logout':
      _oauth2_proxy_logout();
      break;
  }
}

/**
 * Function for: oauth2/proxy/login.
 */
function _oauth2_proxy_login() {
  if (user_is_anonymous()) {
    $query = [
      'proxy' => 'true',
    ] + $_GET;
    unset($query['q']);
    drupal_goto('user/oauth2_login', [
      'query' => $query,
    ]);
  }
  else {

    // Get the token.
    $oauth2 = new OAuth2\Client(oauth2_login_get_oauth2_settings());
    $oauth2
      ->getAccessToken();

    // Return the token to the mobile app.
    $json_token = json_encode($oauth2
      ->token());
    print "<script>opener.postMessage({$json_token}, '*');</script>";
    drupal_exit();
  }
}

/**
 * Return oauth2 settings.
 */
function oauth2_login_get_oauth2_settings() {
  $server_url = variable_get('oauth2_login_oauth2_server');
  $oauth2_settings = [
    'auth_flow' => 'server-side',
    'authorization_endpoint' => $server_url . '/oauth2/authorize',
    'token_endpoint' => $server_url . '/oauth2/token',
    'client_id' => variable_get('oauth2_login_client_id'),
    'client_secret' => variable_get('oauth2_login_client_secret'),
    'redirect_uri' => url('oauth2/authorized', [
      'absolute' => TRUE,
    ]),
    'scope' => 'user_profile',
    'skip-ssl-verification' => variable_get('oauth2_login_skipssl', FALSE),
  ];
  return $oauth2_settings;
}

/**
 * Get an access_token, or NULL if there is no valid token.
 *
 * The token returned may be a cached one or a refreshed token.
 * If the refresh_token has also expired, a redirection to the
 * oauth2 server will be made, in order to re-authenticate.
 * However the redirection will be skipped if the parameter
 * $redirect is FALSE, and NULL will be returned as access_token.
 */
function oauth2_login_get_access_token($redirect = TRUE) {
  $oauth2_settings = oauth2_login_get_oauth2_settings();
  $oauth2 = new OAuth2\Client($oauth2_settings);
  $access_token = $oauth2
    ->getAccessToken($redirect);
  return $access_token;
}

/**
 * Function for: oauth2/proxy/logout.
 */
function _oauth2_proxy_logout() {
  print "<script>window.close();</script>";
  if (user_is_anonymous()) {
    drupal_exit();
  }
  else {
    module_load_include('pages.inc', 'user');
    user_logout();
  }
}

/**
 * Login with OAuth2.
 */
function oauth2_login($destination = NULL, $destination_error = NULL) {
  $enabled = variable_get('oauth2_login_enabled', FALSE);
  if (!$enabled) {
    drupal_goto('user/login', [
      'query' => drupal_get_destination(),
    ]);
    return;
  }
  if ($destination === NULL) {
    $destination = drupal_get_destination();
    $destination = $destination['destination'];
  }
  if ($destination_error === NULL) {
    $destination_error = 'user/login';
  }
  $query = [
    'destination' => $destination,
    'destination_error' => $destination_error,
  ] + $_GET;
  unset($query['q']);
  drupal_goto('hybridauth/window/DrupalOAuth2', [
    'query' => $query,
  ]);
}

/**
 * Implements hook_hybridauth_provider_config_alter().
 */
function oauth2_login_hybridauth_provider_config_alter(&$hybridauth_config, $provider_id) {
  if ($provider_id != 'DrupalOAuth2') {
    return;
  }
  $state = md5(uniqid(rand(), TRUE));
  $hybridauth_config['state'] = $state;
  $hybridauth_config['redirect_uri'] = oauth2_client_get_redirect_uri();
  oauth2_client_set_redirect($state, [
    'uri' => 'hybridauth/endpoint',
    'params' => [
      'hauth.done' => 'DrupalOAuth2',
    ],
  ]);
}

/**
 * Implements hook_hybridauth_user_login().
 *
 * Invoked when a user has logged in through HybridAuth.
 * @param object $account
 *   User account object.
 * @param array $data
 *   HybridAuth identity data.
 */
function oauth2_login_hybridauth_user_login($account, $data) {
  $hybridauth = hybridauth_get_instance();
  if (!$hybridauth or !is_object($hybridauth)) {
    return;
  }
  try {
    $adapter = $hybridauth
      ->getAdapter('DrupalOAuth2');
  } catch (Exception $e) {
    return;
  }
  $oauth2 = $adapter->adapter;
  $token = [
    'access_token' => $oauth2->api->access_token,
    'refresh_token' => $oauth2->api->refresh_token,
    'expires_in' => $oauth2->api->access_token_expires_in,
    'expiration_time' => $oauth2->api->access_token_expires_at,
    'scope' => $oauth2->scope,
  ];
  if (isset($_GET['proxy']) and $_GET['proxy'] == 'true') {
    $json_token = json_encode($token);
    print "<script>opener.postMessage({$json_token}, '*');</script>";
    drupal_exit();
  }
  else {
    $token_endpoint = $oauth2->api->token_url;
    $client_id = $oauth2->api->client_id;
    $auth_flow = 'server-side';
    $id = md5($token_endpoint . $client_id . $auth_flow);
    oauth2_client_set_token($id, $token);
  }
}

/**
 * Implements hook_form_FORM_ID_alter() for hybridauth_admin_provider_settings.
 */
function oauth2_login_form_hybridauth_admin_provider_settings_alter(&$form, &$form_state, $form_id) {
  $provider_id = $form_state['build_info']['args'][0];
  if ($provider_id != 'DrupalOAuth2') {
    return;
  }

  // Add a callback function on submit.
  $form['#submit'][] = 'oauth2_login_admin_get_settings';
}

/**
 * Synchronize settings with hybridauth_DrupalOAuth2.
 */
function oauth2_login_admin_get_settings() {
  $oauth2_server = variable_get('hybridauth_provider_DrupalOAuth2_oauth2_server');
  $client_id = variable_get('hybridauth_provider_DrupalOAuth2_keys_id');
  $client_secret = variable_get('hybridauth_provider_DrupalOAuth2_keys_secret');
  $skipssl = variable_get('hybridauth_provider_DrupalOAuth2_skipssl');
  $proxy = variable_get('hybridauth_provider_DrupalOAuth2_proxy');
  variable_set('oauth2_login_oauth2_server', $oauth2_server);
  variable_set('oauth2_login_client_id', $client_id);
  variable_set('oauth2_login_client_secret', $client_secret);
  variable_set('oauth2_login_skipssl', $skipssl);
  variable_set('oauth2_login_proxy', $proxy);
}

/**
 * Implements hook_user_logout().
 */
function oauth2_login_user_logout($account) {

  // If the client and the server are on the same application
  // then no redirection needs to e done.
  $oauth2_server = variable_get('oauth2_login_oauth2_server', '');
  if (empty($oauth2_server)) {
    return;
  }
  $server_host = parse_url($oauth2_server, PHP_URL_HOST);
  $base_host = parse_url($GLOBALS['base_url'], PHP_URL_HOST);
  if ($server_host == $base_host) {
    return;
  }

  // Get the current access_token.
  $token_endpoint = $oauth2_server . '/oauth2/token';
  $client_id = variable_get('oauth2_login_client_id', '');
  $auth_flow = 'server-side';
  $id = md5($token_endpoint . $client_id . $auth_flow);
  $token = oauth2_client_get_token($id);
  drupal_register_shutdown_function('_logout_from_oauth2_server', $token['access_token']);
}

/**
 * Logout from the oauth2 server as well.
 */
function _logout_from_oauth2_server($token) {
  $oauth2_server = variable_get('oauth2_login_oauth2_server', '');
  drupal_goto($oauth2_server . '/user/logout', [
    'query' => [
      'token' => $token,
    ],
  ]);
}

Functions

Namesort descending Description
oauth2_login Login with OAuth2.
oauth2_login_admin_get_settings Synchronize settings with hybridauth_DrupalOAuth2.
oauth2_login_callback Callback function for the menu user/oauth2_login.
oauth2_login_form_hybridauth_admin_provider_settings_alter Implements hook_form_FORM_ID_alter() for hybridauth_admin_provider_settings.
oauth2_login_get_access_token Get an access_token, or NULL if there is no valid token.
oauth2_login_get_oauth2_settings Return oauth2 settings.
oauth2_login_help Implements hook_help().
oauth2_login_hybridauth_provider_config_alter Implements hook_hybridauth_provider_config_alter().
oauth2_login_hybridauth_user_login Implements hook_hybridauth_user_login().
oauth2_login_menu Implements hook_menu().
oauth2_login_url_outbound_alter Implements hook_url_outbound_alter().
oauth2_login_user_logout Implements hook_user_logout().
oauth2_proxy_callback Callback function for the menu oauth2/proxy. The parameter $action can be: login|logout|refresh
_logout_from_oauth2_server Logout from the oauth2 server as well.
_oauth2_proxy_login Function for: oauth2/proxy/login.
_oauth2_proxy_logout Function for: oauth2/proxy/logout.