You are here

function simplesamlphp_auth_init in simpleSAMLphp Authentication 7.2

Same name and namespace in other branches
  1. 6.3 simplesamlphp_auth.module \simplesamlphp_auth_init()
  2. 6.2 simplesamlphp_auth.module \simplesamlphp_auth_init()
  3. 7.3 simplesamlphp_auth.module \simplesamlphp_auth_init()
  4. 7 simplesamlphp_auth.module \simplesamlphp_auth_init()

Implements hook_init().

File

./simplesamlphp_auth.module, line 185
simpleSAMLphp authentication module for Drupal.

Code

function simplesamlphp_auth_init() {
  global $user;
  global $_simplesamlphp_auth_as;
  global $_simplesamlphp_auth_saml_attributes;
  global $_simplesamlphp_auth_saml_config;
  global $_simplesamlphp_auth_saml_version;
  if (drupal_is_cli() || !_simplesamlphp_auth_isEnabled(TRUE)) {

    // Exit without initializing.
    return;
  }

  // Get the simplesamlphp session.
  $basedir = variable_get('simplesamlphp_auth_installdir', '/var/simplesamlphp');
  if (file_exists($basedir . '/lib/_autoload.php')) {
    require_once $basedir . '/lib/_autoload.php';
  }
  else {
    return;
  }
  $_simplesamlphp_auth_saml_config = SimpleSAML_Configuration::getInstance();
  $_simplesamlphp_auth_saml_version = $_simplesamlphp_auth_saml_config
    ->getVersion();

  // Load simpleSAMLphp, configuration and metadata.
  $_simplesamlphp_auth_as = new SimpleSAML_Auth_Simple(variable_get('simplesamlphp_auth_authsource', 'default-sp'));
  $_simplesamlphp_auth_saml_attributes = $_simplesamlphp_auth_as
    ->getAttributes();
  if ($user->uid == 0) {

    // User is not logged in to Drupal.
    if ($_simplesamlphp_auth_as
      ->isAuthenticated()) {

      // User is logged in - SimpleSAMLphp (but not Drupal).
      // Get unique identifier from saml attributes.
      $authname = _simplesamlphp_auth_get_authname();
      _simplesaml_auth_debug(t('Authname is [%authname] userid is [%uid]', array(
        '%authname' => $authname,
        '%uid' => $user->uid,
      )));
      if (!empty($authname)) {

        // User is logged in with SAML authentication and we got the unique
        // identifier and try to log into Drupal.
        _simplesaml_auth_debug(t('Load user [%authname]', array(
          '%authname' => $authname,
        )));

        // Retrieve user mapping and attempt to log the user in.
        $ext_user = user_external_load($authname);
        $skip_user_finalization = FALSE;
        if (!$ext_user) {

          // First we check the admin settings for simpleSAMLphp and find out
          // if we are allowed to register users.
          if (variable_get('simplesamlphp_auth_registerusers', TRUE)) {

            // We are allowed to register new users.
            _simplesaml_auth_debug(t('Register [%authname]', array(
              '%authname' => $authname,
            )));
            user_external_login_register($authname, 'simplesamlphp_auth');
            $skip_user_finalization = TRUE;
            if (!empty($user->uid)) {

              // Populate roles based on configuration setting.
              $roles = _simplesamlphp_auth_rolepopulation(variable_get('simplesamlphp_auth_rolepopulation', ''));
              $userinfo = array(
                'roles' => $roles,
              );

              // @todo Removed role here as it errors when roles are not set.
              $user = user_save($user, $userinfo);
            }
            else {

              // We were unable to register this new user on the site.
              // We let the user know about this, log an error, and redirect to the home page.
              $msg = t("We are sorry. While you have successfully authenticated, we were unable to create an account for you on this site. Please ask the site administrator to provision access for you.");
              drupal_set_message(check_plain($msg));
              watchdog('simplesamlphp_auth', 'Unable to register %authname using simplesamlphp_auth', array(
                '%authname' => $authname,
              ), WATCHDOG_ERROR);
              $_simplesamlphp_auth_as
                ->logout(base_path());
            }
          }
          else {

            // We are not allowed to register new users on the site through
            // simpleSAML. We let the user know about this and redirect to the
            // user/login page.
            $msg = t("We are sorry. While you have successfully authenticated, you are not yet entitled to access this site. Please ask the site administrator to provision access for you.");
            drupal_set_message(check_plain($msg));
            $_simplesamlphp_auth_as
              ->logout(base_path());
          }
        }
        else {

          // If successfully logged into Drupal.
          // See if we're supposed to re-evaluate role assignments.
          if (variable_get('simplesamlphp_auth_roleevaleverytime', 0)) {

            // If the user is already registered...
            // Update the roles.
            // Populate roles based on configuration setting.
            _simplesaml_auth_debug(t('User already registered [%authname] updating roles.', array(
              '%authname' => $authname,
            )));
            $roles = _simplesamlphp_auth_rolepopulation(variable_get('simplesamlphp_auth_rolepopulation', ''));
            $userinfo = array(
              'roles' => $roles,
            );

            // Save the updated roles and populate the user object.
            $user = user_save($ext_user, $userinfo);
          }
          else {

            // No need to evaluate roles, populate the user object.
            $user = $ext_user;
          }
          if (module_exists('rules')) {
            rules_invoke_all('simplesamlphp_auth_rules_event_login', $user);
          }
        }

        // Finalizing the login, calls hook_user op login.
        // user_external_login_register() calls this for us.
        if (!$skip_user_finalization) {
          $edit = array();
          user_login_finalize($edit);
        }
      }
    }
  }
  else {

    // The user is already logged into Drupal.
    // If we forbid users from logging in using local accounts.
    if (FALSE == variable_get('simplesamlphp_auth_allowdefaultlogin', TRUE)) {

      // If the user has NOT been authenticated via simpleSAML...
      if (!$_simplesamlphp_auth_as
        ->isAuthenticated()) {

        // :FYI: Until Drupal issue #754560 is corrected this message will
        // never be seen by the user.
        drupal_set_message(t("We are sorry, users are not permitted to log in using local accounts."));

        // Destroy the user's session (log them out).
        _simplesamlphp_auth_destroy_drupal_session();
      }
    }
    else {

      // If we are allowing users to log in with local accounts.
      // If the user has NOT been authenticated via simpleSAML.
      if (!$_simplesamlphp_auth_as
        ->isAuthenticated()) {

        // See if we limit this privilege to specified users.
        $string_allow_def_log_users = variable_get('simplesamlphp_auth_allowdefaultloginusers', '');
        $array_allow_def_log_users = array();

        // See if we limit this privilege to specified roles.
        $array_allow_def_log_roles = variable_get('simplesamlphp_auth_allowdefaultloginroles', array());

        // If user IDs or roles are specified, we let them in. Everyone else
        // gets logged out.
        if (drupal_strlen($string_allow_def_log_users) || $array_allow_def_log_roles) {

          // Convert the string into an array.
          // @todo Perform a test to make sure that only numbers, spaces, or
          // commas are in the string.
          $array_allow_def_log_users = explode(',', $string_allow_def_log_users);

          // If we still have something to work with.
          if (0 < count($array_allow_def_log_users) || 0 < count($array_allow_def_log_roles)) {

            // Log the user out of Drupal if:
            // 1) the current user's uid is NOT in the list of allowed uids
            // 2) or their role does not match and allowed mixed mode role.
            $match_roles = array_intersect(array_keys($user->roles), $array_allow_def_log_roles);
            if (!in_array($user->uid, $array_allow_def_log_users) && count($match_roles) == 0) {

              // User is logged into Drupal, but may not be logged into
              // simpleSAML. If this is the case we're supposed to log the
              // user out of Drupal.
              // :FYI: Until Drupal issue #754560 is corrected this message
              // will never be seen by the user.
              drupal_set_message(t('We are sorry, you are not permitted to log in using a local account.'));

              // Write to the watchdog so someone will know what is happening.
              watchdog('simplesamlphp_auth', 'User %name not authorized to log in using local account.', array(
                '%name' => $user->name,
              ));
              _simplesamlphp_auth_destroy_drupal_session();
            }
          }
        }
      }
    }
  }
}