complete_user_login($user); \core\session\manager::apply_concurrent_login_limit($user->id, session_id()); // sets the username cookie if (!empty($CFG->nolastloggedin)) { // do not store last logged in user in cookie // auth plugins can temporarily override this from loginpage_hook() // do not save $CFG->nolastloggedin in database! } else { if (empty($CFG->rememberusername) or $CFG->rememberusername == 2 and empty($frm->rememberusername)) { // no permanent cookies, delete old one if exists set_moodle_cookie(''); } else { set_moodle_cookie($USER->username); } } $urltogo = core_login_get_return_url(); /// check if user password has expired /// Currently supported only for ldap-authentication module $userauth = get_auth_plugin($USER->auth); if (!empty($userauth->config->expiration) and $userauth->config->expiration == 1) { if ($userauth->can_change_password()) { $passwordchangeurl = $userauth->change_password_url(); if (!$passwordchangeurl) { $passwordchangeurl = $CFG->httpswwwroot . '/login/change_password.php'; } } else { $passwordchangeurl = $CFG->httpswwwroot . '/login/change_password.php'; } $days2expire = $userauth->password_expire($USER->username); $PAGE->set_title("{$site->fullname}: {$loginsite}"); $PAGE->set_heading("{$site->fullname}");
/** * Call to complete the user login process after authenticate_user_login() * has succeeded. It will setup the $USER variable and other required bits * and pieces. * * NOTE: * - It will NOT log anything -- up to the caller to decide what to log. * - this function does not set any cookies any more! * * @param stdClass $user * @return stdClass A {@link $USER} object - BC only, do not use */ function complete_user_login($user) { global $CFG, $USER, $SESSION; \core\session\manager::login_user($user); // Reload preferences from DB. unset($USER->preference); check_user_preferences_loaded($USER); // Update login times. update_user_login_times(); // Extra session prefs init. set_login_session_preferences(); // Trigger login event. $event = \core\event\user_loggedin::create(array('userid' => $USER->id, 'objectid' => $USER->id, 'other' => array('username' => $USER->username))); $event->trigger(); if (isguestuser()) { // No need to continue when user is THE guest. return $USER; } if (CLI_SCRIPT) { // We can redirect to password change URL only in browser. return $USER; } // Select password change url. $userauth = get_auth_plugin($USER->auth); // Check whether the user should be changing password. if (get_user_preferences('auth_forcepasswordchange', false)) { if ($userauth->can_change_password()) { if ($changeurl = $userauth->change_password_url()) { redirect($changeurl); } else { $SESSION->wantsurl = core_login_get_return_url(); redirect($CFG->httpswwwroot . '/login/change_password.php'); } } else { print_error('nopasswordchangeforced', 'auth'); } } return $USER; }
/** * Handle an authorization request response received from the configured OP. * * @param array $authparams Received parameters. */ protected function handleauthresponse(array $authparams) { global $DB, $CFG, $SESSION, $STATEADDITIONALDATA, $USER; if (!isset($authparams['code'])) { \auth_oidc\utils::debug('No auth code received.', 'authcode::handleauthresponse', $authparams); throw new \moodle_exception('errorauthnoauthcode', 'auth_oidc'); } if (!isset($authparams['state'])) { \auth_oidc\utils::debug('No state received.', 'authcode::handleauthresponse', $authparams); throw new \moodle_exception('errorauthunknownstate', 'auth_oidc'); } // Validate and expire state. $staterec = $DB->get_record('auth_oidc_state', ['state' => $authparams['state']]); if (empty($staterec)) { throw new \moodle_exception('errorauthunknownstate', 'auth_oidc'); } $orignonce = $staterec->nonce; $additionaldata = []; if (!empty($staterec->additionaldata)) { $additionaldata = @unserialize($staterec->additionaldata); if (!is_array($additionaldata)) { $additionaldata = []; } } $STATEADDITIONALDATA = $additionaldata; $DB->delete_records('auth_oidc_state', ['id' => $staterec->id]); // Get token from auth code. $client = $this->get_oidcclient(); $tokenparams = $client->tokenrequest($authparams['code']); if (!isset($tokenparams['id_token'])) { throw new \moodle_exception('errorauthnoidtoken', 'auth_oidc'); } // Decode and verify idtoken. list($oidcuniqid, $idtoken) = $this->process_idtoken($tokenparams['id_token'], $orignonce); // Check restrictions. $passed = $this->checkrestrictions($idtoken); if ($passed !== true) { $errstr = 'User prevented from logging in due to restrictions.'; \auth_oidc\utils::debug($errstr, 'handleauthresponse', $idtoken); throw new \moodle_exception('errorrestricted', 'auth_oidc'); } // This is for setting the system API user. if (isset($SESSION->auth_oidc_justevent)) { unset($SESSION->auth_oidc_justevent); $eventdata = ['other' => ['authparams' => $authparams, 'tokenparams' => $tokenparams]]; $event = \auth_oidc\event\user_authed::create($eventdata); $event->trigger(); return true; } // Check if OIDC user is already migrated. $tokenrec = $DB->get_record('auth_oidc_token', ['oidcuniqid' => $oidcuniqid]); if (isloggedin() === true && (empty($tokenrec) || isset($USER->auth) && $USER->auth !== 'oidc')) { // If the user is already logged in we can treat this as a "migration" - a user switching to OIDC. $connectiononly = false; if (isset($SESSION->auth_oidc_connectiononly)) { $connectiononly = true; unset($SESSION->auth_oidc_connectiononly); } if (isset($STATEADDITIONALDATA['connectiononly']) && $STATEADDITIONALDATA['connectiononly'] === true) { $connectiononly = true; } $this->handlemigration($oidcuniqid, $authparams, $tokenparams, $idtoken, $connectiononly); $redirect = !empty($additionaldata['redirect']) ? $additionaldata['redirect'] : '/auth/oidc/ucp.php'; redirect(new \moodle_url($redirect)); } else { // Otherwise it's a user logging in normally with OIDC. $this->handlelogin($oidcuniqid, $authparams, $tokenparams, $idtoken); redirect(core_login_get_return_url()); } }
/** * 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); } }