diff -ur -x .svn logintoboggan/logintoboggan.module /home/sgifford/tmp/logintoboggan/logintoboggan.module --- logintoboggan/logintoboggan.module 2009-05-07 03:04:43.000000000 +0000 +++ /home/sgifford/tmp/logintoboggan/logintoboggan.module 2009-05-08 04:48:22.000000000 +0000 @@ -237,7 +237,7 @@ * * @ingroup logintoboggan_form */ -function logintoboggan_user_register_submit($form_id, $form_values) { +function logintoboggan_user_register_submit($form_id, $form_values, &$ret = NULL) { global $base_url; $mail = $form_values['mail']; @@ -279,7 +279,9 @@ } $account = user_save('', array_merge($form_values, array('pass' => $pass, 'init' => $mail, 'roles' => $roles, 'status' => $status))); - + if (isset($ret)) { + $ret['account'] = $account; + } watchdog('user', t('New user: %name %email.', array('%name' => $name, '%email' => "<$mail>")), WATCHDOG_NOTICE, l(t('edit'), 'user/'. $account->uid .'/edit')); $login_url = variable_get('user_register', 1) == 1 ? logintoboggan_eml_validate_url($account) : user_pass_reset_url($account); @@ -330,7 +332,7 @@ drupal_set_message($message); // where do we need to redirect after registration? - $redirect = _logintoboggan_process_redirect(variable_get('toboggan_redirect_on_register', ''), $account); + $redirect = _logintoboggan_process_redirect(variable_get('toboggan_redirect_on_register', ''), $account->uid); //log the user in if they created the account and immediate login is enabled. if($reg_pass_set) { @@ -747,12 +749,15 @@ return variable_get('toboggan_role', DRUPAL_AUTHENTICATED_RID); } +define('LOGINTOBOGGAN_VALIDATE_EMAIL_OK', 0); +define('LOGINTOBOGGAN_VALIDATE_EMAIL_FAILED', -1); +define('LOGINTOBOGGAN_VALIDATE_EMAIL_REPEAT', 1); +define('LOGINTOBOGGAN_VALIDATE_EMAIL_DENIED', 1); /** - * Menu callback; process validate the e-mail address as a one time URL, - * and redirects to the user page on success. + * Internal implementation of email validation. Returns one of the statuses above. */ -function logintoboggan_validate_email($uid, $timestamp, $hashed_pass, $action = 'login') { +function logintoboggan_validate_email_int($uid, $timestamp, $hashed_pass) { $current = time(); $uid = (int) $uid; @@ -767,7 +772,8 @@ watchdog('user', t('E-mail validation URL used for %name with timestamp @timestamp.', array('%name' => $account->name, '@timestamp' => $timestamp))); // Update the user table noting user has logged in. // And this also makes this hashed password a one-time-only login. - db_query("UPDATE {users} SET login = '%d' WHERE uid = %d", time(), $account->uid); + if (!db_query("UPDATE {users} SET login = '%d' WHERE uid = %d", time(), $account->uid)) + return LOGINTOBOGGAN_VALIDATE_EMAIL_FAILED; // Test here for a valid pre-auth -- if the pre-auth is set to the auth user, we // handle things a bit differently. @@ -777,7 +783,9 @@ // Remove the pre-auth role from the user, unless they haven't been approved yet. if ($account->status) { if ($pre_auth) { - db_query("DELETE FROM {users_roles} WHERE uid = %d AND rid = %d", $account->uid, $validating_id); + if (!db_query("DELETE FROM {users_roles} WHERE uid = %d AND rid = %d", $account->uid, $validating_id)) + return LOGINTOBOGGAN_VALIDATE_EMAIL_FAILED; + // Since we're passing $account around to the update hook, remove // the pre-auth role from the roles array, and add in the auth user // role. @@ -788,53 +796,94 @@ $edit = array(); $account->logintoboggan_email_validated = TRUE; user_module_invoke('update', $edit, $account); + + // user has new permissions, so we clear their menu cache + cache_clear_all($account->uid .':', 'cache_menu', TRUE); + + return LOGINTOBOGGAN_VALIDATE_EMAIL_OK; + } else { + return LOGINTOBOGGAN_VALIDATE_EMAIL_DENIED; } + + } + else { + return LOGINTOBOGGAN_VALIDATE_EMAIL_REPEAT; + } + } + + // Deny access, no more clues. + // Everything will be in the watchdog's URL for the administrator to check. + return LOGINTOBOGGAN_VALIDATE_EMAIL_DENIED; +} +/** + * Menu callback; process validate the e-mail address as a one time URL, + * and redirects to the user page on success. + */ +function logintoboggan_validate_email($uid, $timestamp, $hashed_pass, $action = 'login') { + $status = logintoboggan_validate_email_int($uid, $timestamp, $hashed_pass); + switch($status) { + case LOGINTOBOGGAN_VALIDATE_EMAIL_OK: // Where do we redirect after confirming the account? - $redirect = _logintoboggan_process_redirect(variable_get('toboggan_redirect_on_confirm', ''), $account); + $redirect = _logintoboggan_process_redirect(variable_get('toboggan_redirect_on_confirm', ''), $uid); switch ($action) { // Proceed with normal user login, as long as it's open registration and their // account hasn't been blocked. case 'login': // Only show the validated message if there's a valid pre-auth role. + $validating_id = logintoboggan_validating_id(); + $pre_auth = $validating_id != DRUPAL_AUTHENTICATED_RID; if ($pre_auth) { drupal_set_message(t('You have successfully validated your e-mail address.')); } - if (!$account->status) { - drupal_set_message(t('Your account is currently blocked -- login cancelled.'), 'error'); - drupal_goto(''); - } - else { - drupal_goto(logintoboggan_process_login($account, $redirect)); - } + $account = user_load(array('uid' => $uid)); + drupal_goto(logintoboggan_process_login($account, $redirect)); break; // Admin validation. case 'admin': - // user has new permissions, so we clear their menu cache - cache_clear_all($account->uid .':', 'cache_menu', TRUE); - - drupal_set_message(t('You have successfully validated %user.', array('%user' => $account->name))); - drupal_goto("user/$account->uid/edit"); + drupal_set_message(t('You have successfully validated UID %uid.', array('%uid' => $uid))); + drupal_goto("user/$uid/edit"); break; // Catch all. default: - // user has new permissions, so we clear their menu cache - cache_clear_all($account->uid .':', 'cache_menu', TRUE); - - drupal_set_message(t('You have successfully validated %user.', array('%user' => $account->name))); + drupal_set_message(t('You have successfully validated UID %uid.', array('%uid' => $uid))); drupal_goto(''); break; } - } - else { - drupal_set_message(t("Sorry, you can only use your validation link once for security reasons. Please !login with your username and password instead now.", array('!login' => l(t('login'),'user/login'))),'error'); - } - } + break; - // Deny access, no more clues. - // Everything will be in the watchdog's URL for the administrator to check. - drupal_access_denied(); + case LOGINTOBOGGAN_VALIDATE_EMAIL_REPEAT: + global $user; + $msg = t("Your email address has already been validated."); + + if (!$user->uid) { + # User is not logged in + $msg .= " ".t("Please log in below."); + } else if ($user->uid != $uid) { + # User is logged in as a different user + + $msg .= " ".t("Please log in below."); + + watchdog('user', 'Session closed for %name.', array('%name' => $user->name)); + + sess_regenerate(); + + module_invoke_all('user', 'logout', NULL, $user); + + // Load the anonymous user + $user = drupal_anonymous_user(); + } + + drupal_set_message($msg); + drupal_goto('user'); + break; + default: + // Deny access, no more clues. + // Everything will be in the watchdog's URL for the administrator to check. + drupal_access_denied(); + break; + } } /** @@ -962,8 +1011,8 @@ return (($_SERVER['HTTPS'] == 'on') ? 'https' : 'http'); } -function _logintoboggan_process_redirect($redirect, $account) { - $variables = array('%uid' => $account->uid); +function _logintoboggan_process_redirect($redirect, $uid) { + $variables = array('%uid' => $uid); $redirect = strtr($redirect, $variables); return $redirect;