You are here

shib_auth.module in Shibboleth Authentication 5.2

File

shib_auth.module
View source
<?php

/**
* Display help and module information
* @param path which path of the site we're displaying help
* @param arg array that holds the current path as would be returned from arg() function
* @return help text for the path
*/
function shib_auth_help($section) {
  $output = '';
  switch ($section) {
    case 'admin/help#shib_auth':

      //TODO
      $output = '<p>' . t("The Shibboleth authentication module let you utilize the advantages of the Single Sign On (SSO) methods.") . '</p>';
      break;
    case 'admin/settings/shib_auth':
      $output = t('');
  }
  return $output;
}

// function shib_auth_help

/**
* Create a new user based on informations from the Shibboleth handler if it's necessary or log in.
*/
function shib_auth_init() {
  global $user;
  $uname = $_SERVER[variable_get('shib_auth_username_variable', 'REMOTE_USER')];
  $umail = $_SERVER[variable_get('shib_auth_username_email', 'HTTP_SHIB_MAIL')];

  // If the mail attribute is multi value, then we use only the first value
  $umail = preg_replace('/;.*/', '', $umail);

  // If
  // - The user isn't logged in
  // - There is Shibboleth authentication in the background
  // - The settings are fine and there has been a valid username setted up
  // - The settings are fine and there has been a valid user email address setted up
  if (!$user->uid && ($_SERVER['HTTP_SHIB_IDENTITY_PROVIDER'] || $_SERVER['Shib-Identity-Provider'])) {
    if ($uname && $umail) {
      user_external_login_register($uname, "shib_auth");
    }
    else {
      drupal_set_message(t("Username or e-mail address is missing. Maybe the Shibboleth configuration is not perfect."), "error");
    }
  }
  if ($user->uid && ($_SERVER['HTTP_SHIB_IDENTITY_PROVIDER'] || $_SERVER['Shib-Identity-Provider'])) {
    $account = user_save($user, array(
      'mail' => $umail,
    ));

    // Terminate if an error occured during user_save().
    if (!$account) {
      drupal_set_message(t("Error saving user account."), 'error');
      return;
    }
    $user = $account;
  }
}

// function shib_auth_init()

/**
* Let the user exit from the Shibboleth authority when he/she log out from the actual Drupal site.
* @param op What kind of action is being performed.
* @param edit The array of form values submitted by the user.
* @param account The user object on which the operation is being performed.
* @param category The active category of user information being edited.
*/
function shib_auth_user($op, &$edit, &$account, $category = NULL) {
  global $base_url, $user;
  if ($op == 'logout') {
    $handlerURL = variable_get('shib_auth_handler_url', '/Shibboleth.sso');
    $handlerProtocol = variable_get('shib_auth_handler_protocol', 'https');
    if (ereg("^http[s]{0,1}://", $handlerURL)) {

      // If handlerURL is an absolute path
      $logoutHandler = $handlerURL . "/Logout";
    }
    else {

      // Else, if the handlerURL is a relative path
      // If the WAYF's URI doesn't start with slash then extend it
      if (!ereg("^/", $handlerURL)) {
        $handlerURL = "/" . $handlerURL;
      }
      $logoutHandler = $handlerProtocol . "://" . $_SERVER['HTTP_HOST'] . $handlerURL . "/Logout";
    }
    drupal_goto("{$logoutHandler}?return={$base_url}");
  }
}

// function shib_auth_user(logout)

/**
* Valid permissions for this module
* @return array An array of valid permissions for the shib_auth module
*/
function shib_auth_perm() {
  return array(
    'administer shibboleth authentication',
  );
}

// function shib_auth_perm()

/**
* Generate the login text in HTML format using the 't' function
* @returns HTML text of the login form
*/
function generate_login_text() {
  global $base_url, $user;
  if (!$user->uid) {
    $handlerURL = variable_get('shib_auth_handler_url', '/Shibboleth.sso');
    $handlerProtocol = variable_get('shib_auth_handler_protocol', 'https');
    $wayfURI = variable_get('shib_auth_wayf_uri', '/WAYF/HREF');

    // If the WAYF's URI doesn't start with slash then extend it
    if (!ereg("^/", $wayfURI)) {
      $wayfURI = "/" . $wayfURI;
    }
    $handler = '';
    $block_content = '';
    if (ereg("^http[s]{0,1}://", $handlerURL)) {

      // If handlerURL is an absolute path
      $handler = $handlerURL . $wayfURI;
    }
    else {

      // Else, if the handlerURL is a relative path
      // If the WAYF's URI doesn't start with slash then extend it
      if (!ereg("^/", $handlerURL)) {
        $handlerURL = "/" . $handlerURL;
      }
      $handler = $handlerProtocol . "://" . $_SERVER['HTTP_HOST'] . $handlerURL . $wayfURI;
    }

    //$actualLocation: the path where the Shibboleth should return
    $actualLocation = (isset($_SERVER['HTTPS']) ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];

    // If there is no session yet then we should put the login text into the block
    $block_content .= "<p><b><a href=\"{$handler}?target={$actualLocation}\">" . variable_get('auth_link_text', 'Click here to login via Shibboleth!') . "</a></b></p>";
    return $block_content;
  }
}

// function generate_login_text()

/**
* Generate the HTML text for the shib_auth login block
* @param op the operation from the URL
* @param delta offset
* @returns block HTML 
*/
function shib_auth_block($op = 'list', $delta = 0, $edit = array()) {

  // listing of blocks, such as on the admin/block page
  switch ($op) {
    case 'list':
      $blocks[0] = array(
        'info' => t('Shibboleth authentication'),
        'status' => TRUE,
        'visibility' => 1,
        'weight' => 0,
        'region' => 'left',
      );
      return $blocks;
    case 'configure':
      $form = array();
      switch ($delta) {
        case 0:
          $form['auth_link_text'] = array(
            '#type' => 'textfield',
            '#title' => t('Text of the auth link'),
            '#require' => TRUE,
            '#size' => 60,
            '#description' => t('Here you can replace the text of the authentication link.'),
            '#default_value' => variable_get('auth_link_text', t('Click here to login via Shibboleth!')),
          );
      }
      return $form;
    case 'save':
      switch ($delta) {
        case 0:
          variable_set('auth_link_text', $edit['auth_link_text']);
      }
      break;
    case 'view':
    default:
      switch ($delta) {
        case 0:
          $block = array(
            'subject' => t('Shibboleth login'),
            'content' => generate_login_text(),
          );
          break;
      }
      return $block;
  }
}

// function shib_auth_block()

/**
* Generate the administration form of the Shibboleth authentication module
* @returns HTML text of the administration form
*/
function shib_auth_admin() {
  $form = array();
  $form['shib_handler_settings'] = array(
    '#type' => 'fieldset',
    '#title' => t('Shibboleth handler settings'),
    '#weight' => 0,
    '#collapsible' => FALSE,
  );
  $form['shib_attribute_settings'] = array(
    '#type' => 'fieldset',
    '#title' => t('Attribute settings'),
    '#weight' => 0,
    '#collapsible' => FALSE,
  );
  $form['shib_handler_settings']['shib_auth_handler_url'] = array(
    '#type' => 'textfield',
    '#title' => t('The Shibboleth handler\'s URL'),
    '#default_value' => variable_get('shib_auth_handler_url', '/Shibboleth.sso'),
    '#description' => t('The URL can be absolute or relative to the server base url: http://www.example.com/Shibboleth.sso; /Shibboleth.sso'),
  );
  $form['shib_handler_settings']['shib_auth_handler_protocol'] = array(
    '#type' => 'select',
    '#title' => t('The Shibboleth handler\'s protocol'),
    '#default_value' => variable_get('shib_auth_handler_protocol', 'https'),
    '#options' => array(
      'http' => t('HTTP'),
      'https' => t('HTTPS'),
    ),
    '#description' => t('This option will be effective just if the handler URL is a relative path.'),
  );
  $form['shib_handler_settings']['shib_auth_wayf_uri'] = array(
    '#type' => 'textfield',
    '#title' => t('The WAYF\'s location'),
    '#default_value' => variable_get('shib_auth_wayf_uri', '/WAYF/HREF'),
  );
  $form['shib_attribute_settings']['shib_auth_username_variable'] = array(
    '#type' => 'textfield',
    '#title' => t('Server variable whick stores the username'),
    '#default_value' => variable_get('shib_auth_username_variable', 'REMOTE_USER'),
  );
  $form['shib_attribute_settings']['shib_auth_username_email'] = array(
    '#type' => 'textfield',
    '#title' => t('Server variable whick stores the e-mail address'),
    '#default_value' => variable_get('shib_auth_username_email', 'HTTP_SHIB_MAIL'),
  );
  return system_settings_form($form);
}

// function shib_auth_admin()

/**
* Generate the menu element to access the Shibboleth authentication module's administration page
* @returns HTML text of the administer menu element
*/
function shib_auth_menu($may_cache) {
  $items = array();
  if ($may_cache) {
  }
  else {
    $items[] = array(
      'path' => 'admin/settings/shib_auth',
      'title' => t('Shibboleth settings'),
      'description' => t('Control the various settings of the shibboleth authentication module'),
      'callback' => 'drupal_get_form',
      'callback arguments' => 'shib_auth_admin',
      'access' => user_access('administer shibboleth authentication'),
      'type' => MENU_NORMAL_ITEM,
    );
  }
  return $items;
}

// function shib_auth_menu()

/**
 * Alters forms for the shibboleth authentication module.
 *
 * @param $form_id The form ID.
 * @param $form The form.
 */
function shib_auth_form_alter($form_id, &$form) {
  if ($form_id == 'user_login') {
    $form['shibboleth'] = array(
      '#type' => 'hidden',
      '#weight' => -1,
      '#prefix' => generate_login_text(),
      '#suffix' => '',
    );
  }
}

/**
 * Helper function for authentication modules. Either login in or registers the
 * current user, based on username. Either way, the global $user object is
 * populated based on $name.
 * 
 * Backport this function from user.module of Drupal 6.x.
 *
 * @param $name The user's name.
 * @param $module Name of the module which process the authetication.
 */
function user_external_login_register($name, $module) {
  global $user;

  // Try to load the user
  $user = user_load(array(
    'name' => $name,
  ));
  if (!isset($user->uid)) {

    // Register this new user.
    $userinfo = array(
      'name' => $name,
      'pass' => user_password(),
      'init' => $name,
      'status' => 1,
      "authname_{$module}" => $name,
      'access' => time(),
    );
    $account = user_save('', $userinfo);

    // Terminate if an error occured during user_save().
    if (!$account) {
      drupal_set_message(t("Error saving user account."), 'error');
      return;
    }
    $user = $account;
    watchdog('user', 'New external user: %name using module %module.', array(
      '%name' => $name,
      '%module' => $module,
    ), WATCHDOG_NOTICE, l(t('edit'), 'user/' . $user->uid . '/edit'));
  }
}

Functions

Namesort descending Description
generate_login_text Generate the login text in HTML format using the 't' function @returns HTML text of the login form
shib_auth_admin Generate the administration form of the Shibboleth authentication module @returns HTML text of the administration form
shib_auth_block Generate the HTML text for the shib_auth login block
shib_auth_form_alter Alters forms for the shibboleth authentication module.
shib_auth_help Display help and module information
shib_auth_init Create a new user based on informations from the Shibboleth handler if it's necessary or log in.
shib_auth_menu Generate the menu element to access the Shibboleth authentication module's administration page @returns HTML text of the administer menu element
shib_auth_perm Valid permissions for this module
shib_auth_user Let the user exit from the Shibboleth authority when he/she log out from the actual Drupal site.
user_external_login_register Helper function for authentication modules. Either login in or registers the current user, based on username. Either way, the global $user object is populated based on $name.