/** * To be called after failed user login. * @param stdClass $user */ function login_attempt_failed($user) { global $CFG; if ($user->mnethostid != $CFG->mnet_localhost_id) { return; } if (isguestuser($user)) { return; } $count = get_user_preferences('login_failed_count', 0, $user); $last = get_user_preferences('login_failed_last', 0, $user); $sincescuccess = get_user_preferences('login_failed_count_since_success', $count, $user); $sincescuccess = $sincescuccess + 1; set_user_preference('login_failed_count_since_success', $sincescuccess, $user); if (empty($CFG->lockoutthreshold)) { // No threshold means no lockout. // Always unlock here, there might be some race conditions or leftovers when switching threshold. login_unlock_account($user); return; } if (!empty($CFG->lockoutwindow) and time() - $last > $CFG->lockoutwindow) { $count = 0; } $count = $count + 1; set_user_preference('login_failed_count', $count, $user); set_user_preference('login_failed_last', time(), $user); if ($count >= $CFG->lockoutthreshold) { login_lock_account($user); } }
redirect($returnurl); } else { if ($unsuspend and confirm_sesskey()) { require_capability('moodle/user:update', $sitecontext); if ($user = $DB->get_record('user', array('id' => $unsuspend, 'mnethostid' => $CFG->mnet_localhost_id, 'deleted' => 0))) { if ($user->suspended != 0) { $user->suspended = 0; user_update_user($user, false); } } redirect($returnurl); } else { if ($unlock and confirm_sesskey()) { require_capability('moodle/user:update', $sitecontext); if ($user = $DB->get_record('user', array('id' => $unlock, 'mnethostid' => $CFG->mnet_localhost_id, 'deleted' => 0))) { login_unlock_account($user); } redirect($returnurl); } } } } } } // create the user filter form $ufiltering = new user_filtering(); echo $OUTPUT->header(); // Carry on with the user listing $context = context_system::instance(); $extracolumns = get_extra_user_fields($context); $columns = array_merge(array('firstname', 'lastname'), $extracolumns, array('city', 'country', 'lastaccess'));
public function test_lockout() { global $CFG; require_once "{$CFG->libdir}/authlib.php"; $this->resetAfterTest(); $oldlog = ini_get('error_log'); ini_set('error_log', "{$CFG->dataroot}/testlog.log"); // Prevent standard logging. set_config('lockoutthreshold', 0); set_config('lockoutwindow', 60 * 20); set_config('lockoutduration', 60 * 30); $user = $this->getDataGenerator()->create_user(); // Test lockout is disabled when threshold not set. $this->assertFalse(login_is_lockedout($user)); login_attempt_failed($user); login_attempt_failed($user); login_attempt_failed($user); login_attempt_failed($user); $this->assertFalse(login_is_lockedout($user)); // Test lockout threshold works. set_config('lockoutthreshold', 3); login_attempt_failed($user); login_attempt_failed($user); $this->assertFalse(login_is_lockedout($user)); ob_start(); login_attempt_failed($user); $output = ob_get_clean(); $this->assertContains('noemailever', $output); $this->assertTrue(login_is_lockedout($user)); // Test unlock works. login_unlock_account($user); $this->assertFalse(login_is_lockedout($user)); // Test lockout window works. login_attempt_failed($user); login_attempt_failed($user); $this->assertFalse(login_is_lockedout($user)); set_user_preference('login_failed_last', time() - 60 * 20 - 10, $user); login_attempt_failed($user); $this->assertFalse(login_is_lockedout($user)); // Test valid login resets window. login_attempt_valid($user); $this->assertFalse(login_is_lockedout($user)); login_attempt_failed($user); login_attempt_failed($user); $this->assertFalse(login_is_lockedout($user)); // Test lock duration works. ob_start(); // Prevent nomailever notice. login_attempt_failed($user); $output = ob_get_clean(); $this->assertContains('noemailever', $output); $this->assertTrue(login_is_lockedout($user)); set_user_preference('login_lockout', time() - 60 * 30 + 10, $user); $this->assertTrue(login_is_lockedout($user)); set_user_preference('login_lockout', time() - 60 * 30 - 10, $user); $this->assertFalse(login_is_lockedout($user)); // Test lockout ignored pref works. set_user_preference('login_lockout_ignored', 1, $user); login_attempt_failed($user); login_attempt_failed($user); login_attempt_failed($user); login_attempt_failed($user); $this->assertFalse(login_is_lockedout($user)); ini_set('error_log', $oldlog); }
/** * This function processes a user's submitted token to validate the request to set a new password. * If the user's token is validated, they are prompted to set a new password. * @param string $token the one-use identifier which should verify the password reset request as being valid. * @return void */ function core_login_process_password_set($token) { global $DB, $CFG, $OUTPUT, $PAGE, $SESSION; $pwresettime = isset($CFG->pwresettime) ? $CFG->pwresettime : 1800; $sql = "SELECT u.*, upr.token, upr.timerequested, upr.id as tokenid\n FROM {user} u\n JOIN {user_password_resets} upr ON upr.userid = u.id\n WHERE upr.token = ?"; $user = $DB->get_record_sql($sql, array($token)); $forgotpasswordurl = "{$CFG->httpswwwroot}/login/forgot_password.php"; if (empty($user) or $user->timerequested < time() - $pwresettime - DAYSECS) { // There is no valid reset request record - not even a recently expired one. // (suspicious) // Direct the user to the forgot password page to request a password reset. echo $OUTPUT->header(); notice(get_string('noresetrecord'), $forgotpasswordurl); die; // Never reached. } if ($user->timerequested < time() - $pwresettime) { // There is a reset record, but it's expired. // Direct the user to the forgot password page to request a password reset. $pwresetmins = floor($pwresettime / MINSECS); echo $OUTPUT->header(); notice(get_string('resetrecordexpired', '', $pwresetmins), $forgotpasswordurl); die; // Never reached. } if ($user->auth === 'nologin' or !is_enabled_auth($user->auth)) { // Bad luck - user is not able to login, do not let them set password. echo $OUTPUT->header(); print_error('forgotteninvalidurl'); die; // Never reached. } // Check this isn't guest user. if (isguestuser($user)) { print_error('cannotresetguestpwd'); } // Token is correct, and unexpired. $mform = new login_set_password_form(null, null, 'post', '', 'autocomplete="yes"'); $data = $mform->get_data(); if (empty($data)) { // User hasn't submitted form, they got here directly from email link. // Next, display the form. $setdata = new stdClass(); $setdata->username = $user->username; $setdata->username2 = $user->username; $setdata->token = $user->token; $mform->set_data($setdata); $PAGE->verify_https_required(); echo $OUTPUT->header(); echo $OUTPUT->box(get_string('setpasswordinstructions'), 'generalbox boxwidthnormal boxaligncenter'); $mform->display(); echo $OUTPUT->footer(); return; } else { // User has submitted form. // Delete this token so it can't be used again. $DB->delete_records('user_password_resets', array('id' => $user->tokenid)); $userauth = get_auth_plugin($user->auth); if (!$userauth->user_update_password($user, $data->password)) { print_error('errorpasswordupdate', 'auth'); } // Reset login lockout (if present) before a new password is set. login_unlock_account($user); // Clear any requirement to change passwords. unset_user_preference('auth_forcepasswordchange', $user); unset_user_preference('create_password', $user); if (!empty($user->lang)) { // Unset previous session language - use user preference instead. unset($SESSION->lang); } complete_user_login($user); // Triggers the login event. $urltogo = core_login_get_return_url(); unset($SESSION->wantsurl); redirect($urltogo, get_string('passwordset'), 1); } }
$mform = new login_change_password_form(); $mform->set_data(array('id'=>$course->id)); $navlinks = array(); $navlinks[] = array('name' => $strparticipants, 'link' => "$CFG->wwwroot/user/index.php?id=$course->id", 'type' => 'misc'); if ($mform->is_cancelled()) { redirect($CFG->wwwroot.'/user/view.php?id='.$USER->id.'&course='.$course->id); } else if ($data = $mform->get_data()) { if (!$userauth->user_update_password($USER, $data->newpassword1)) { print_error('errorpasswordupdate', 'auth'); } // Reset login lockout - we want to prevent any accidental confusion here. login_unlock_account($USER); // register success changing password unset_user_preference('auth_forcepasswordchange', $USER); unset_user_preference('create_password', $USER); $strpasswordchanged = get_string('passwordchanged'); add_to_log($course->id, 'user', 'change password', "view.php?id=$USER->id&course=$course->id", "$USER->id"); $fullname = fullname($USER, true); $PAGE->navbar->add($fullname, new moodle_url('/user/view.php', array('id'=>$USER->id, 'course'=>$course->id))); $PAGE->navbar->add($strpasswordchanged); $PAGE->set_title($strpasswordchanged); $PAGE->set_heading($COURSE->fullname);