You are here

oauth2_login.module in OAuth2 Login 7

Same filename and directory in other branches
  1. 8 oauth2_login.module
  2. 7.2 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.
    $server_url = variable_get('oauth2_login_oauth2_server', '');
    $client_id = variable_get('oauth2_login_client_id', '');
    $client_secret = variable_get('oauth2_login_client_secret', '');
    $token_endpoint = $server_url . '/oauth2/token';
    $authorization_endpoint = $server_url . '/oauth2/authorize';
    $redirect_uri = url('oauth2/authorized', [
      'absolute' => TRUE,
    ]);
    $auth_flow = 'server-side';
    $oauth2 = new OAuth2\Client([
      'token_endpoint' => $token_endpoint,
      'auth_flow' => $auth_flow,
      'client_id' => $client_id,
      'client_secret' => $client_secret,
      'redirect_uri' => $redirect_uri,
      'authorization_endpoint' => $authorization_endpoint,
      'scope' => 'user_profile',
    ]);
    $oauth2
      ->getAccessToken();
    $id = md5($token_endpoint . $client_id . $auth_flow);
    $token = oauth2_client_get_token($id);

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

/**
 * 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_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.