the function user_external_login_register is great but the developper doesn't know which operation has been performed. Like drupal_write_record, this function should return USER_CREATED or USER_LOGGED_IN in order to perform other operations after login.

For instance you can create a row for an OAuth token if user is created, but only update the token if user already exists. I think this is a bug in the API since this function provides two distinct functionnalities but doesn't provides any information on which one was effectively processed. Does it makes sense ?

CommentFileSizeAuthor
#1 issue990800.patch1.18 KBsylvain lecoy

Comments

sylvain lecoy’s picture

StatusFileSize
new1.18 KB

Attached a patch proposing a solution.

damien tournoud’s picture

Well, I consider this function deprecated, and it sends the wrong message.

See http://api.drupal.org/api/drupal/modules--openid--openid.module/function... for a correct implementation of the same process.

sylvain lecoy’s picture

Oops yes you right, swap USER_CREATED and USER_LOGGED_IN in the patch provided.

Why this function is deprecated ? It seems a new function but you say it's already deprecated ?

So you mean instead of using build in function, we need to write our own function like in the openid module for each module which implements an external authentication ?

sylvain lecoy’s picture

Here is my implementation for OAuth based authentication. As this routine delegate implementation to a concrete consumer module, this can serve as a base to put in user module for external module as a tentative to unify the external logging API (ref http://drupal.org/node/817118#comment-4380390).

<?php
function oauth_authenticate($module, $response) {
  $oauth_info = module_invoke($module, 'oauth_info');
  $authname = $response[$oauth_info['mapping']['authname']];
  $username = $response[$oauth_info['mapping']['username']];
  
  $account = user_external_load("$authname@$module"); // '@module' is because {authmap}.authname is unique..!
  if (isset($account->uid)) {
    if (!variable_get('user_email_verification', TRUE) || $account->login) {
      // Check if user is blocked.
      $state['values']['name'] = $account->name;
      user_login_name_validate(array(), $state);
      if (!form_get_errors()) {
        // Load global $user and perform final login tasks.
        $form_state['uid'] = $account->uid;
        user_login_submit(array(), $form_state);
        
        // Refresh*
        // TODO: put in a hook_oauth_user_info_refresh().
        // then can be called from user dashboard and in update functions.
        // in cron as well. The refresh should also refresh tokens.
        // -> Find a better name.
        db_update('authmap')
          ->condition('uid', $account->uid)
          ->condition('module', $module)
          ->fields(array('username' => $username))
          ->execute();
      }
    }
    else {
      drupal_set_message(
      t('You must validate your email address for this account before logging in via @module.',
      array('@module' => $oauth_info['name'])
      ));
    }
  }
  elseif (variable_get('user_register', USER_REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL)) {
    // Register new user.

    // Save response for use in MODULE_form_user_register_form_alter().
    $_SESSION[$module]['response'] = $response;

    $form_state['values'] = array();
    $form_state['values']['op'] = t('Create new account');
    drupal_form_submit('user_register_form', $form_state);

//    if (!empty($form_state['user']))

    $message = drupal_get_messages('error');
    if (empty($form_state['values']['name']) || empty($form_state['values']['mail'])) {
      // If the Service provider did not provide both a user name and an email
      // address, ask the user to complete the registration manually instead of
      // showing the error messages about the missing values generated by FAPI.
      drupal_set_message(t('Complete the registration by filling out the form below. If you already have an account, you can <a href="@login">log in</a> now and add your @module under "My account".', array('@login' => url('user/login'), '@module' => ucfirst($module))), 'warning');
    }
    else {
      drupal_set_message(t('Account registration using the information provided by your @module provider failed due to the reasons listed below. Complete the registration by filling out the form below. If you already have an account, you can <a href="@login">log in</a> now and add your @module under "My account".', array('@login' => url('user/login'), '@module' => ucfirst($module))), 'warning');
      // Append form validation errors below the above warning.
      foreach ($messages['error'] as $message) {
        drupal_set_message($message, 'error');
      }
    }

    // We were unable to register a valid new user. Redirect to the normal
    // registration page and prefill with the values we received.
    drupal_goto('user/register');
  }
  else {
    drupal_set_message(t('Only site administrators can create new user accounts.'), 'error');
  }
  drupal_goto();
}
?>

And here is the openid implementation:

<?php
function openid_authentication($response) {
  $identity = $response['openid.claimed_id'];

  $account = user_external_load($identity);
  if (isset($account->uid)) {
    if (!variable_get('user_email_verification', TRUE) || $account->login) {
      // Check if user is blocked.
      $state['values']['name'] = $account->name;
      user_login_name_validate(array(), $state);
      if (!form_get_errors()) {
        // Load global $user and perform final login tasks.
        $form_state['uid'] = $account->uid;
        user_login_submit(array(), $form_state);
        // Let other modules act on OpenID login
        module_invoke_all('openid_response', $response, $account);
      }
    }
    else {
      drupal_set_message(t('You must validate your email address for this account before logging in via OpenID.'));
    }
  }
  elseif (variable_get('user_register', USER_REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL)) {
    // Register new user.

    // Save response for use in openid_form_user_register_form_alter().
    $_SESSION['openid']['response'] = $response;

    $form_state['values'] = array();
    $form_state['values']['op'] = t('Create new account');
    drupal_form_submit('user_register_form', $form_state);

    if (!empty($form_state['user'])) {
      module_invoke_all('openid_response', $response, $form_state['user']);
      drupal_goto();
    }

    $messages = drupal_get_messages('error');
    if (empty($form_state['values']['name']) || empty($form_state['values']['mail'])) {
      // If the OpenID provider did not provide both a user name and an email
      // address, ask the user to complete the registration manually instead of
      // showing the error messages about the missing values generated by FAPI.
      drupal_set_message(t('Complete the registration by filling out the form below. If you already have an account, you can <a href="@login">log in</a> now and add your OpenID under "My account".', array('@login' => url('user/login'))), 'warning');
    }
    else {
      drupal_set_message(t('Account registration using the information provided by your OpenID provider failed due to the reasons listed below. Complete the registration by filling out the form below. If you already have an account, you can <a href="@login">log in</a> now and add your OpenID under "My account".', array('@login' => url('user/login'))), 'warning');
      // Append form validation errors below the above warning.
      foreach ($messages['error'] as $message) {
        drupal_set_message( $message, 'error');
      }
    }

    // We were unable to register a valid new user. Redirect to the normal
    // registration page and prefill with the values we received.
    $destination = drupal_get_destination();
    unset($_GET['destination']);
    drupal_goto('user/register', array('query' => $destination));
  }
  else {
    drupal_set_message(t('Only site administrators can create new user accounts.'), 'error');
  }
  drupal_goto();
}
?>

That speaks volume about code duplication.

sylvain lecoy’s picture

tagging it

traviscarden’s picture

Re-tagging.

Status: Active » Closed (outdated)

Automatically closed because Drupal 7 security and bugfix support has ended as of 5 January 2025. If the issue verifiably applies to later versions, please reopen with details and update the version.