You are here

tokenauth.module in Token authentication 7

Same filename and directory in other branches
  1. 5 tokenauth.module
  2. 6.2 tokenauth.module
  3. 6 tokenauth.module

File

tokenauth.module
View source
<?php

/**
 * @file
 * Provides URL variable-based authentication to allowed pages.
 */
include_once 'tokenauth.inc';
define('TOKENAUTH_DEFAULT_TOKEN_LENGTH', 20);

/**
 * Implements hook_permission().
 */
function tokenauth_permission() {
  return array(
    'access tokenauth' => array(
      'title' => t('Use token authentication'),
      'description' => t('Use URL tokens to access configured paths.'),
    ),
    'administer tokenauth' => array(
      'title' => t('Administer token authentication'),
      'description' => t('Administer the configuration of Token Authentication.'),
    ),
  );
}

/**
 * Implements hook_menu().
 */
function tokenauth_menu() {
  $items['admin/config/services/tokenauth'] = array(
    'title' => 'Token authentication',
    'description' => 'Configure token behavior to allow users to authenticate per page-load via URL.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'tokenauth_admin_settings',
    ),
    'access arguments' => array(
      'administer tokenauth',
    ),
    'file' => 'tokenauth.pages.inc',
    'type' => MENU_NORMAL_ITEM,
  );
  $items['admin/config/services/tokenauth/reset'] = array(
    'title' => 'Reset tokens',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'tokenauth_reset_confirm',
    ),
    'access arguments' => array(
      'administer tokenauth',
    ),
    'file' => 'tokenauth.pages.inc',
    'type' => MENU_CALLBACK,
  );
  $items['user/%user/tokenauth'] = array(
    'title' => 'Token authentication',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'tokenauth_user_profile_form',
      1,
    ),
    'access callback' => 'tokenauth_profile_access',
    'access arguments' => array(
      1,
    ),
    'file' => 'tokenauth.pages.inc',
    'type' => MENU_LOCAL_TASK,
  );
  $items['user/%user/tokenauth/reset'] = array(
    'title' => 'Reset token',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'tokenauth_user_reset_confirm',
    ),
    'access callback' => 'tokenauth_profile_access',
    'access arguments' => array(
      1,
    ),
    'file' => 'tokenauth.pages.inc',
    'type' => MENU_CALLBACK,
  );
  return $items;
}

/**
 * Implements hook_help().
 */
function tokenauth_help($path, $arg) {
  switch ($path) {

    // Main help for tokenauth module.
    case 'admin/help#tokenauth':
      return '<p>' . t('Token Authentication provides URL-based authentication via an alphanumeric token unique to each user.') . '</p>';
  }
}

/**
 * Access callback for tokenauth view/edit.
 */
function tokenauth_profile_access($account) {
  return (user_access('administer users') || $GLOBALS['user']->uid == $account->uid) && user_access('access tokenauth') && $account->uid > 0;
}

/**
 * Implements hook_menu_get_item_alter().
 */
function tokenauth_menu_get_item_alter(&$router_item, $path, $original_map) {
  global $user;

  // Only set user for current page, and only if tokenauth was not already processed.
  // The latter is to prevent redundant token authentication if menu_get_item cache is reset later.
  if ($path != current_path() && !isset($_SESSION['tokenauth_auth'])) {
    return;
  }

  // Process any provided token and log in user
  $key = tokenauth_get_token_key();
  if (user_is_anonymous() && isset($_REQUEST[$key]) && tokenauth_allowed_pages(current_path())) {
    if ($uid = tokenauth_get_user($_REQUEST[$key])) {
      $account = user_load($uid);
      if (user_access('access tokenauth', $account)) {
        $user = $account;

        // Store the fact that this user authenticated via token. Needed for logout.
        $_SESSION['tokenauth_auth'] = TRUE;
        drupal_save_session(FALSE);
        watchdog('user', 'Page @page loaded for %name via token authentication.', array(
          '@page' => current_path(),
          '%name' => $account->name,
        ));
      }
    }

    // Supplied an invalid token
    if (empty($_SESSION['tokenauth_auth'])) {

      // Setting access denied inside the menu router system creates recursions.
      // Real-time equivalent of hook_menu_alter().
      $router_item['access_callback'] = 0;
    }
  }

  // Trigger tokenauth context condition.
  if (module_exists('context') && function_exists('context_get_plugin') && ($plugin = context_get_plugin('condition', 'tokenauth_auth'))) {
    $plugin
      ->execute((int) isset($_SESSION['tokenauth_auth']));
  }
}

/**
 * Implements hook_exit().
 *
 * Deliberately insure that this session will not be saved by sess_write(). Safety.
 * @see user_logout
 */
function tokenauth_exit() {
  global $user;
  if (isset($_SESSION['tokenauth_auth'])) {

    // Load the anonymous user
    $user = drupal_anonymous_user();
  }
}

/**
 * Implements hook_url_outbound_alter().
 *
 * Appends the current user's token to any path run through url()
 * that also passes tokenauth's allowed pages filter.
 */
function tokenauth_url_outbound_alter(&$path, &$options, $original_path) {
  $key = tokenauth_get_token_key();
  if (isset($_SESSION['tokenauth_auth']) && isset($_REQUEST[$key]) && $_REQUEST[$key] == ($token = tokenauth_get_token()) && tokenauth_allowed_pages($original_path)) {
    if (is_array($options['query'])) {
      $options['query'][$key] = $token;
    }
    elseif (!$options['query']) {
      $options['query'] = $key . '=' . $token;
    }
    else {
      $options['query'] .= '&' . $key . '=' . $token;
    }
  }
}

/**
 * Implements hook_user_update().
 */
function tokenauth_user_update(&$edit, $account, $category = NULL) {
  if (isset($account->tokenauth_token)) {
    tokenauth_reset_user($account->uid, $account->tokenauth_token);
  }
}

/**
 * Implements hook_user_insert().
 */
function tokenauth_user_insert(&$edit, $account, $category = NULL) {
  tokenauth_insert($account->uid);
}

/**
 * Implements hook_user_delete().
 */
function tokenauth_user_delete($account) {
  $sql = 'DELETE FROM {tokenauth_tokens} WHERE uid = :uid';
  db_query($sql, array(
    ':uid' => $account->uid,
  ));
}

/**
 * Get the URL querystring key.
 *
 * @return string
 */
function tokenauth_get_token_key() {
  return variable_get('tokenauth_token_key', 'token');
}

/// Token Integration ///

/**
 * Implements hook_token_info().
 */
function tokenauth_token_info() {
  $user['tokenauth-token'] = array(
    'name' => t('Token Authentication token'),
    'description' => t('The url authentication token value.'),
  );
  return array(
    'tokens' => array(
      'user' => $user,
    ),
  );
}

/**
 * Implements hook_tokens().
 */
function tokenauth_tokens($type, $tokens, array $data = array(), array $options = array()) {
  $replacements = array();
  if ($type == 'user' && !empty($data['user'])) {
    if (isset($tokens['tokenauth-token'])) {
      $replacements[$tokens['tokenauth-token']] = tokenauth_get_token($data['user']->uid);
    }
  }
  return $replacements;
}

/// Context Integration ///

/**
 * Implements hook_ctools_plugin_api().
 */
function tokenauth_ctools_plugin_api($module, $api) {
  if ($module == 'context' && $api == 'plugins') {
    return array(
      'version' => 3,
    );
  }
}

/**
 * Implements hook_context_registry().
 */
function tokenauth_context_registry() {
  $registry = array();
  $registry['conditions'] = array(
    'tokenauth_auth' => array(
      'title' => t('Token Authentication'),
      'description' => t('Set this context based on whether or not the user is logged in via the Token Authentication module.'),
      'plugin' => 'tokenauth_context_condition_tokenauth',
    ),
  );
  return $registry;
}

/**
 * Implements hook_context_plugins().
 */
function tokenauth_context_plugins() {
  $plugins = array();
  $plugins['tokenauth_context_condition_tokenauth'] = array(
    'handler' => array(
      'path' => drupal_get_path('module', 'tokenauth') . '/plugins',
      'file' => 'tokenauth_context_condition_tokenauth.inc',
      'class' => 'tokenauth_context_condition_tokenauth',
      'parent' => 'context_condition',
    ),
  );
  return $plugins;
}