Rev 1 | Ir a la última revisión | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |
<?php// Este archivo es parte de Moodle - http://moodle.org///// Moodle es software libre: puedes redistribuirlo y/o modificarlo// bajo los términos de la Licencia Pública General GNU publicada por// la Free Software Foundation, ya sea la versión 3 de la Licencia, o// (a tu elección) cualquier versión posterior.//// Moodle se distribuye con la esperanza de que sea útil,// pero SIN NINGUNA GARANTÍA; sin siquiera la garantía implícita de// COMERCIABILIDAD o IDONEIDAD PARA UN PROPÓSITO PARTICULAR. Ver la// Licencia Pública General GNU para más detalles.//// Deberías haber recibido una copia de la Licencia Pública General GNU// junto con Moodle. Si no, ve <http://www.gnu.org/licenses/>./*** Página principal de inicio de sesión de Moodle.* Este archivo maneja todo el proceso de autenticación de usuarios,* incluyendo la validación de credenciales, manejo de sesiones,* redirecciones y mensajes de error.** @package core* @subpackage auth* @copyright 1999 onwards Martin Dougiamas http://dougiamas.com* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later*/// Incluir archivos de configuración y librerías necesariasrequire('../config.php');require_once('lib.php');// Verificar si se requiere una actualización mayor del sistema// Si es así, redirigir al usuario a la página de actualizaciónredirect_if_major_upgrade_required();// ============================================================================// PARÁMETROS DE LA PÁGINA DE INICIO DE SESIÓN// ============================================================================// Parámetros opcionales que controlan el comportamiento del inicio de sesión$testsession = optional_param('testsession', 0, PARAM_INT); // Verifica el funcionamiento correcto de la sesión$anchor = optional_param('anchor', '', PARAM_RAW); // Mantiene la posición del ancla en la URL de destino$loginredirect = optional_param('loginredirect', 1, PARAM_BOOL); // Controla la redirección a URL de login alternativo$resendconfirmemail = optional_param('resendconfirmemail', false, PARAM_BOOL); // Permite reenviar email de confirmación// Verificación especial para sitios Behat (entorno de pruebas)// Esto podría ser seguro para sitios no-Behat, pero por ahora solo lo permitimos en sitios Behatif (defined('BEHAT_SITE_RUNNING') && BEHAT_SITE_RUNNING) {$wantsurl = optional_param('wantsurl', '', PARAM_LOCALURL); // Sobrescribe $SESSION->wantsurl si se proporcionaif ($wantsurl !== '') {$SESSION->wantsurl = (new moodle_url($wantsurl))->out(false);}}// Configuración del contexto y la página$context = context_system::instance();$PAGE->set_url("$CFG->wwwroot/login/index.php");$PAGE->set_context($context);$PAGE->set_pagelayout('login');// ============================================================================// CONFIGURACIÓN INICIAL Y VARIABLES// ============================================================================// Inicialización de variables para el manejo de mensajes y errores$errormsg = ''; // Almacena mensajes de error para mostrar al usuario$infomsg = ''; // Almacena mensajes informativos para mostrar al usuario$errorcode = 0; // Código numérico que identifica el tipo de error// ============================================================================// VERIFICACIÓN DE SESIÓN// ============================================================================// Prueba de funcionamiento de la sesiónif ($testsession) {if ($testsession == $USER->id) {// Si la sesión es válida, redirigir a la URL deseadaif (isset($SESSION->wantsurl)) {$urltogo = $SESSION->wantsurl;} else {$urltogo = $CFG->wwwroot . '/';}unset($SESSION->wantsurl);redirect($urltogo);} else {// Si la sesión no es válida, mostrar error de cookies$errormsg = get_string("cookiesnotenabled");$errorcode = 1;}}// ============================================================================// MANEJO DE SESIONES EXPIRADAS// ============================================================================// Verificar si la sesión actual ha expiradoif (!empty($SESSION->has_timed_out)) {$session_has_timed_out = true;unset($SESSION->has_timed_out);} else {$session_has_timed_out = false;}// Inicialización de variables para el formulario y usuario$frm = false;$user = false;// Obtener la secuencia de plugins de autenticación habilitados$authsequence = get_enabled_auth_plugins();foreach ($authsequence as $authname) {$authplugin = get_auth_plugin($authname);// El hook loginpage_hook() del plugin de autenticación puede establecer $frm y/o $user$authplugin->loginpage_hook();}// ============================================================================// CONFIGURACIÓN DEL SITIO Y NAVEGACIÓN// ============================================================================// Obtener información del sitio$site = get_site();// Ignorar páginas activas en la navegación/configuración$PAGE->navbar->ignore_active();$loginsite = get_string("loginsite");$PAGE->navbar->add($loginsite);// ============================================================================// PROCESO DE AUTENTICACIÓN// ============================================================================// Verificar si algún plugin de autenticación ya proporcionó el usuario completoif ($user !== false or $frm !== false or $errormsg !== '') {// El plugin de autenticación ya proporcionó el usuario completo, datos del formulario falso// o impidió el inicio de sesión con mensaje de error} else if (!empty($SESSION->wantsurl) && file_exists($CFG->dirroot . '/login/weblinkauth.php')) {// Maneja el caso de otro sitio Moodle vinculando a una página en este sitioinclude($CFG->dirroot . '/login/weblinkauth.php');if (function_exists('weblink_auth')) {$user = weblink_auth($SESSION->wantsurl);}if ($user) {$frm->username = $user->username;} else {$frm = data_submitted();}} else {$frm = data_submitted();}// Restaurar el #anchor a la wantsurl originalif ($anchor && isset($SESSION->wantsurl) && strpos($SESSION->wantsurl, '#') === false) {$wantsurl = new moodle_url($SESSION->wantsurl);$wantsurl->set_anchor(substr($anchor, 1));$SESSION->wantsurl = $wantsurl->out();}// ============================================================================// VERIFICACIÓN DE CREDENCIALES// ============================================================================// Verificar si el usuario ha enviado datos de inicio de sesiónif ($frm and isset($frm->username)) {// Normalizar el nombre de usuario$frm->username = trim(core_text::strtolower($frm->username));// Verificar la autenticación 'none' si está habilitadaif (is_enabled_auth('none')) {if ($frm->username !== core_user::clean_field($frm->username, 'username')) {$errormsg = get_string('username') . ': ' . get_string("invalidusername");$errorcode = 2;$user = null;}}// Verificar si el usuario es invitadoif ($user) {// El plugin de autenticación ya proporcionó el usuario} else if (($frm->username == 'guest') and empty($CFG->guestloginbutton)) {$user = false; // No se puede iniciar sesión como invitado si el botón de invitado está deshabilitado$frm = false;} else {if (empty($errormsg)) {// Intentar autenticar al usuario$logintoken = isset($frm->logintoken) ? $frm->logintoken : '';$loginrecaptcha = login_captcha_enabled() ? $frm->{'g-recaptcha-response'} ?? '' : false;$user = authenticate_user_login($frm->username, $frm->password, false, $errorcode, $logintoken, $loginrecaptcha);}}// ============================================================================// MANEJO DE USUARIOS RESTAURADOS// ============================================================================// Procesar usuarios que han sido restaurados desde una copia de seguridadif (!$user and $frm and is_restored_user($frm->username)) {$PAGE->set_title(get_string('restoredaccount'));$PAGE->set_heading($site->fullname);echo $OUTPUT->header();echo $OUTPUT->heading(get_string('restoredaccount'));echo $OUTPUT->box(get_string('restoredaccountinfo'), 'generalbox boxaligncenter');require_once('restored_password_form.php');$form = new login_forgot_password_form('forgot_password.php', array('username' => $frm->username));$form->display();echo $OUTPUT->footer();die;}// ============================================================================// CONFIRMACIÓN DE CUENTA// ============================================================================if ($user) {// Configuración del idiomaif (isguestuser($user)) {// Sin idioma predefinido para invitados - usar sesión existente o idioma predeterminado del sitiounset($user->lang);} else if (!empty($user->lang)) {// Desactivar idioma de sesión anterior - usar preferencia del usuariounset($SESSION->lang);}// Verificar si la cuenta nunca fue confirmadaif (empty($user->confirmed)) {$PAGE->set_title(get_string("mustconfirm"));$PAGE->set_heading($site->fullname);echo $OUTPUT->header();echo $OUTPUT->heading(get_string("mustconfirm"));if ($resendconfirmemail) {if (!send_confirmation_email($user)) {echo $OUTPUT->notification(get_string('emailconfirmsentfailure'), \core\output\notification::NOTIFY_ERROR);} else {echo $OUTPUT->notification(get_string('emailconfirmsentsuccess'), \core\output\notification::NOTIFY_SUCCESS);}}echo $OUTPUT->box(get_string("emailconfirmsent", "", s($user->email)), "generalbox boxaligncenter");$resendconfirmurl = new moodle_url('/login/index.php',['username' => $frm->username,'password' => $frm->password,'resendconfirmemail' => true,'logintoken' => \core\session\manager::get_login_token()]);echo $OUTPUT->single_button($resendconfirmurl, get_string('emailconfirmationresend'));echo $OUTPUT->footer();die;}// ============================================================================// COMPLETAR INICIO DE SESIÓN// ============================================================================// Completar el proceso de inicio de sesióncomplete_user_login($user);// Aplicar límite de inicio de sesión concurrente\core\session\manager::apply_concurrent_login_limit($user->id, session_id());// Configurar cookie de nombre de usuarioif (!empty($CFG->nolastloggedin)) {// No almacenar último usuario conectado en cookie} else if (empty($CFG->rememberusername)) {// Sin cookies permanentes, eliminar la anterior si existeset_moodle_cookie('');} else {set_moodle_cookie($USER->username);}// Obtener URL de redirección$urltogo = core_login_get_return_url();// ============================================================================// VERIFICACIÓN DE CONTRASEÑAS EXPIRADAS// ============================================================================// Verificar si la contraseña del usuario ha expirado (solo para autenticación LDAP)$userauth = get_auth_plugin($USER->auth);if (!isguestuser() and !empty($userauth->config->expiration) and $userauth->config->expiration == 1) {$externalchangepassword = false;if ($userauth->can_change_password()) {$passwordchangeurl = $userauth->change_password_url();if (!$passwordchangeurl) {$passwordchangeurl = $CFG->wwwroot . '/login/change_password.php';} else {$externalchangepassword = true;}} else {$passwordchangeurl = $CFG->wwwroot . '/login/change_password.php';}$days2expire = $userauth->password_expire($USER->username);$PAGE->set_title($loginsite);$PAGE->set_heading("$site->fullname");if (intval($days2expire) > 0 && intval($days2expire) < intval($userauth->config->expiration_warning)) {echo $OUTPUT->header();echo $OUTPUT->confirm(get_string('auth_passwordwillexpire', 'auth', $days2expire), $passwordchangeurl, $urltogo);echo $OUTPUT->footer();exit;} elseif (intval($days2expire) < 0) {if ($externalchangepassword) {// Cerrar sesión si el formulario de cambio de contraseña es externorequire_logout();} else {// Forzar cambio de contraseña si se usa el formulario estándarset_user_preference('auth_forcepasswordchange', 1, $USER);}echo $OUTPUT->header();echo $OUTPUT->confirm(get_string('auth_passwordisexpired', 'auth'), $passwordchangeurl, $urltogo);echo $OUTPUT->footer();exit;}}// Limpiar mensajes de error antes de la última redirecciónunset($SESSION->loginerrormsg);unset($SESSION->logininfomsg);// Descartar loginredirect si estamos redirigiendounset($SESSION->loginredirect);// Probar que la sesión funciona redirigiendo a sí mismo$SESSION->wantsurl = $urltogo;redirect(new moodle_url(get_login_url(), array('testsession' => $USER->id)));} else {// Manejo de errores de autenticaciónif (empty($errormsg)) {if ($errorcode == AUTH_LOGIN_UNAUTHORISED) {$errormsg = get_string("unauthorisedlogin", "", $frm->username);} else if ($errorcode == AUTH_LOGIN_FAILED_RECAPTCHA) {$errormsg = get_string('missingrecaptchachallengefield');} else {$errormsg = get_string("invalidlogin");$errorcode = 3;}}}}// ============================================================================// DETECCIÓN DE PROBLEMAS CON SESIONES// ============================================================================// Detectar problemas con sesiones con tiempo de espera agotadoif ($session_has_timed_out and !data_submitted()) {$errormsg = get_string('sessionerroruser', 'error');$errorcode = 4;}// ============================================================================// MANEJO DE URL DE DESTINO// ============================================================================// Recordar dónde estaba intentando llegar el usuario antes de llegar aquíif (empty($SESSION->wantsurl)) {$SESSION->wantsurl = null;$referer = get_local_referer(false);if ($referer &&$referer != $CFG->wwwroot &&$referer != $CFG->wwwroot . '/' &&$referer != $CFG->wwwroot . '/login/' &&strpos($referer, $CFG->wwwroot . '/login/?') !== 0 &&strpos($referer, $CFG->wwwroot . '/login/index.php') !== 0) {$SESSION->wantsurl = $referer;}}// Verificar si loginredirect está establecido en la SESSIONif ($errorcode && isset($SESSION->loginredirect)) {$loginredirect = $SESSION->loginredirect;}$SESSION->loginredirect = $loginredirect;// ============================================================================// REDIRECCIÓN A URL DE INICIO DE SESIÓN ALTERNATIVA// ============================================================================// Redirigir a URL de inicio de sesión alternativa si es necesarioif (!empty($CFG->alternateloginurl) && $loginredirect) {$loginurl = new moodle_url($CFG->alternateloginurl);$loginurlstr = $loginurl->out(false);if ($SESSION->wantsurl != '' && strpos($SESSION->wantsurl, $loginurlstr) === 0) {// No queremos volver a la URL alternativa$SESSION->wantsurl = null;}// Si hay código de error, agregarlo a la URLif ($errorcode) {$loginurl->param('errorcode', $errorcode);}redirect($loginurl->out(false));}// ============================================================================// GENERACIÓN DE LA PÁGINA DE INICIO DE SESIÓN// ============================================================================// Inicializar el objeto del formulario si no existeif (!isset($frm) or !is_object($frm)) {$frm = new stdClass();}// Configurar valores predeterminados del formularioif (empty($frm->username) && $authsequence[0] != 'shibboleth') {if (!empty($_GET["username"])) {$frm->username = clean_param($_GET["username"], PARAM_RAW);} else {$frm->username = get_moodle_cookie();}$frm->password = "";}// Manejar mensajes de error e informaciónif (!empty($SESSION->loginerrormsg) || !empty($SESSION->logininfomsg)) {$errormsg = $SESSION->loginerrormsg ?? '';$infomsg = $SESSION->logininfomsg ?? '';unset($SESSION->loginerrormsg);unset($SESSION->logininfomsg);} else if ($testsession) {unset($SESSION->loginerrormsg);unset($SESSION->logininfomsg);} else if ($errormsg or !empty($frm->password)) {if ($errormsg) {$SESSION->loginerrormsg = $errormsg;}$loginurl = new moodle_url('/login/index.php');$loginurl->param('loginredirect', $SESSION->loginredirect);redirect($loginurl->out(false));}// ============================================================================// RENDERIZADO DE LA PÁGINA// ============================================================================// Configurar título y encabezado de la página$PAGE->set_title($loginsite);$PAGE->set_heading("$site->fullname");// Mostrar el encabezado de la páginaecho $OUTPUT->header();// Verificar el estado de la sesión del usuarioif (isloggedin() and !isguestuser()) {// Si el usuario ya está conectado, mostrar mensaje y opcionesecho $OUTPUT->box_start();$logout = new single_button(new moodle_url('/login/logout.php', array('sesskey' => sesskey(), 'loginpage' => 1)), get_string('logout'), 'post');$continue = new single_button(new moodle_url('/'), get_string('cancel'), 'get');echo $OUTPUT->confirm(get_string('alreadyloggedin', 'error', fullname($USER)), $logout, $continue);echo $OUTPUT->box_end();} else {// Mostrar el formulario de inicio de sesión$loginform = new \core_auth\output\login($authsequence, $frm->username);$loginform->set_error($errormsg);$loginform->set_info($infomsg);echo $OUTPUT->render($loginform);}// Mostrar el pie de páginaecho $OUTPUT->footer();