up
This commit is contained in:
@@ -0,0 +1,422 @@
|
||||
<?php
|
||||
/**
|
||||
* Migración del Sistema de Contraseñas a Base de Datos
|
||||
* Fecha: 4 de enero de 2026
|
||||
*/
|
||||
|
||||
require_once 'config/config.php';
|
||||
|
||||
// Solo permitir acceso desde localhost por seguridad
|
||||
$allowedIPs = ['127.0.0.1', '::1', 'localhost'];
|
||||
$clientIP = $_SERVER['REMOTE_ADDR'] ?? $_SERVER['HTTP_X_FORWARDED_FOR'] ?? 'unknown';
|
||||
|
||||
if (!in_array($clientIP, $allowedIPs) && $clientIP !== 'unknown') {
|
||||
die("❌ Acceso denegado. Esta utilidad solo puede ejecutarse desde localhost por seguridad.");
|
||||
}
|
||||
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="es">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>🔄 Migrar Contraseñas a Base de Datos</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||
background: linear-gradient(135deg, #25D366 0%, #128C7E 100%);
|
||||
color: #333;
|
||||
margin: 0;
|
||||
padding: 20px;
|
||||
min-height: 100vh;
|
||||
}
|
||||
.container {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
background: white;
|
||||
padding: 40px;
|
||||
border-radius: 15px;
|
||||
box-shadow: 0 10px 30px rgba(0,0,0,0.2);
|
||||
}
|
||||
h1 {
|
||||
color: #25D366;
|
||||
text-align: center;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
.info-box {
|
||||
background: #e8f5e8;
|
||||
padding: 20px;
|
||||
border-left: 5px solid #25D366;
|
||||
margin: 20px 0;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.warning-box {
|
||||
background: #fff3cd;
|
||||
padding: 20px;
|
||||
border-left: 5px solid #ffc107;
|
||||
margin: 20px 0;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.error-box {
|
||||
background: #f8d7da;
|
||||
padding: 20px;
|
||||
border-left: 5px solid #dc3545;
|
||||
margin: 20px 0;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.btn {
|
||||
background: #25D366;
|
||||
color: white;
|
||||
padding: 12px 30px;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
width: 100%;
|
||||
margin: 10px 0;
|
||||
}
|
||||
.btn:hover {
|
||||
background: #1aa347;
|
||||
}
|
||||
.btn-danger {
|
||||
background: #dc3545;
|
||||
}
|
||||
.btn-danger:hover {
|
||||
background: #c82333;
|
||||
}
|
||||
.progress-box {
|
||||
background: #f8f9fa;
|
||||
padding: 15px;
|
||||
border-radius: 8px;
|
||||
margin: 20px 0;
|
||||
border: 1px solid #dee2e6;
|
||||
}
|
||||
code {
|
||||
background: #f8f9fa;
|
||||
padding: 2px 6px;
|
||||
border-radius: 3px;
|
||||
font-family: monospace;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>🔄 Migración: Contraseñas a Base de Datos</h1>
|
||||
|
||||
<div class="warning-box">
|
||||
<strong>⚡ Sistema de Migración:</strong>
|
||||
<p>Esta herramienta migrará el sistema de contraseñas desde archivos de configuración a la base de datos, creando un sistema unificado y más seguro.</p>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
|
||||
|
||||
if ($_POST['action'] === 'migrate_system') {
|
||||
echo '<div class="progress-box"><h4>🚀 Iniciando Migración...</h4>';
|
||||
|
||||
try {
|
||||
// 1. Conectar a la base de datos
|
||||
echo '<p>✅ 1. Conectando a la base de datos...</p>';
|
||||
$pdo = new PDO(
|
||||
"mysql:host=" . DB_HOST . ";port=" . DB_PORT . ";dbname=" . DB_NAME . ";charset=" . DB_CHARSET,
|
||||
DB_USER,
|
||||
DB_PASS,
|
||||
[
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||
]
|
||||
);
|
||||
|
||||
// 2. Crear tabla de administradores
|
||||
echo '<p>✅ 2. Creando tabla de administradores...</p>';
|
||||
$createAdminTable = "
|
||||
CREATE TABLE IF NOT EXISTS admin_users (
|
||||
id INT PRIMARY KEY AUTO_INCREMENT,
|
||||
username VARCHAR(50) UNIQUE NOT NULL,
|
||||
password_hash VARCHAR(255) NOT NULL,
|
||||
email VARCHAR(100),
|
||||
full_name VARCHAR(100),
|
||||
is_active TINYINT(1) DEFAULT 1,
|
||||
last_login DATETIME NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
INDEX idx_username (username),
|
||||
INDEX idx_active (is_active)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
";
|
||||
$pdo->exec($createAdminTable);
|
||||
|
||||
// 3. Migrar contraseña actual del config
|
||||
echo '<p>✅ 3. Migrando contraseña actual...</p>';
|
||||
$currentUsername = ADMIN_USERNAME;
|
||||
$currentPasswordHash = ADMIN_PASSWORD;
|
||||
|
||||
// Verificar si ya existe el admin
|
||||
$checkAdmin = $pdo->prepare("SELECT id FROM admin_users WHERE username = ?");
|
||||
$checkAdmin->execute([$currentUsername]);
|
||||
|
||||
if (!$checkAdmin->fetch()) {
|
||||
$insertAdmin = $pdo->prepare("
|
||||
INSERT INTO admin_users (username, password_hash, full_name, email)
|
||||
VALUES (?, ?, ?, ?)
|
||||
");
|
||||
$insertAdmin->execute([
|
||||
$currentUsername,
|
||||
$currentPasswordHash,
|
||||
'Administrador Principal',
|
||||
'admin@u-site.app'
|
||||
]);
|
||||
echo '<p>✅ Usuario administrador migrado exitosamente</p>';
|
||||
} else {
|
||||
echo '<p>⚠️ Usuario administrador ya existe en BD</p>';
|
||||
}
|
||||
|
||||
// 4. Crear tabla de configuración si no existe
|
||||
echo '<p>✅ 4. Verificando tabla de configuración...</p>';
|
||||
$createConfigTable = "
|
||||
CREATE TABLE IF NOT EXISTS system_config (
|
||||
id INT PRIMARY KEY AUTO_INCREMENT,
|
||||
config_key VARCHAR(100) UNIQUE NOT NULL,
|
||||
config_value TEXT,
|
||||
config_type VARCHAR(50) DEFAULT 'string',
|
||||
description TEXT,
|
||||
is_encrypted TINYINT(1) DEFAULT 0,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
INDEX idx_config_key (config_key)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
";
|
||||
$pdo->exec($createConfigTable);
|
||||
|
||||
// 5. Actualizar configuraciones existentes
|
||||
echo '<p>✅ 5. Configurando sistema...</p>';
|
||||
$systemConfigs = [
|
||||
['password_system_migrated', '1', 'boolean', 'Indica si el sistema de contraseñas fue migrado a BD'],
|
||||
['login_attempts_max', MAX_LOGIN_ATTEMPTS, 'integer', 'Número máximo de intentos de login'],
|
||||
['login_lockout_time', LOGIN_LOCKOUT_TIME, 'integer', 'Tiempo de bloqueo en segundos'],
|
||||
['session_timeout', SESSION_TIMEOUT, 'integer', 'Timeout de sesión en segundos'],
|
||||
['system_version', '2.0.0', 'string', 'Versión del sistema con BD']
|
||||
];
|
||||
|
||||
foreach ($systemConfigs as $config) {
|
||||
$stmt = $pdo->prepare("
|
||||
INSERT INTO system_config (config_key, config_value, config_type, description)
|
||||
VALUES (?, ?, ?, ?)
|
||||
ON DUPLICATE KEY UPDATE config_value = VALUES(config_value)
|
||||
");
|
||||
$stmt->execute($config);
|
||||
}
|
||||
|
||||
echo '<p>✅ 6. Creando funciones de autenticación...</p>';
|
||||
|
||||
echo '</div>';
|
||||
echo '<div class="info-box">';
|
||||
echo '<h4>🎉 ¡Migración Completada Exitosamente!</h4>';
|
||||
echo '<p><strong>Cambios realizados:</strong></p>';
|
||||
echo '<ul>';
|
||||
echo '<li>✅ Tabla <code>admin_users</code> creada</li>';
|
||||
echo '<li>✅ Contraseña actual migrada a BD</li>';
|
||||
echo '<li>✅ Configuración del sistema actualizada</li>';
|
||||
echo '<li>✅ Sistema preparado para funcionar con BD</li>';
|
||||
echo '</ul>';
|
||||
echo '<p><strong>Próximo paso:</strong> Actualizar el código para usar la nueva estructura</p>';
|
||||
echo '</div>';
|
||||
|
||||
} catch (Exception $e) {
|
||||
echo '</div>';
|
||||
echo '<div class="error-box">❌ <strong>Error en la migración:</strong> ' . $e->getMessage() . '</div>';
|
||||
}
|
||||
}
|
||||
|
||||
if ($_POST['action'] === 'update_system_files') {
|
||||
echo '<div class="progress-box"><h4>🔧 Actualizando archivos del sistema...</h4>';
|
||||
|
||||
try {
|
||||
// Actualizar config.php para incluir funciones de BD
|
||||
echo '<p>✅ 1. Actualizando config.php...</p>';
|
||||
|
||||
$newConfigFunctions = '
|
||||
// Funciones de autenticación con base de datos
|
||||
function getAdminByUsername($username) {
|
||||
try {
|
||||
$pdo = new PDO(
|
||||
"mysql:host=" . DB_HOST . ";port=" . DB_PORT . ";dbname=" . DB_NAME . ";charset=" . DB_CHARSET,
|
||||
DB_USER,
|
||||
DB_PASS,
|
||||
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC]
|
||||
);
|
||||
|
||||
$stmt = $pdo->prepare("SELECT * FROM admin_users WHERE username = ? AND is_active = 1");
|
||||
$stmt->execute([$username]);
|
||||
return $stmt->fetch();
|
||||
} catch (Exception $e) {
|
||||
error_log("Error getting admin user: " . $e->getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function verifyAdminPassword($username, $password) {
|
||||
$admin = getAdminByUsername($username);
|
||||
if ($admin && password_verify($password, $admin["password_hash"])) {
|
||||
// Actualizar último login
|
||||
updateAdminLastLogin($admin["id"]);
|
||||
return $admin;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function updateAdminLastLogin($adminId) {
|
||||
try {
|
||||
$pdo = new PDO(
|
||||
"mysql:host=" . DB_HOST . ";port=" . DB_PORT . ";dbname=" . DB_NAME . ";charset=" . DB_CHARSET,
|
||||
DB_USER,
|
||||
DB_PASS,
|
||||
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
|
||||
);
|
||||
|
||||
$stmt = $pdo->prepare("UPDATE admin_users SET last_login = NOW() WHERE id = ?");
|
||||
$stmt->execute([$adminId]);
|
||||
} catch (Exception $e) {
|
||||
error_log("Error updating last login: " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
function updateAdminPassword($username, $newPassword) {
|
||||
try {
|
||||
$pdo = new PDO(
|
||||
"mysql:host=" . DB_HOST . ";port=" . DB_PORT . ";dbname=" . DB_NAME . ";charset=" . DB_CHARSET,
|
||||
DB_USER,
|
||||
DB_PASS,
|
||||
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
|
||||
);
|
||||
|
||||
$newHash = password_hash($newPassword, PASSWORD_DEFAULT);
|
||||
$stmt = $pdo->prepare("UPDATE admin_users SET password_hash = ?, updated_at = NOW() WHERE username = ?");
|
||||
return $stmt->execute([$newHash, $username]);
|
||||
} catch (Exception $e) {
|
||||
error_log("Error updating password: " . $e->getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function isPasswordSystemMigrated() {
|
||||
$config = getConfigFromDB("password_system_migrated");
|
||||
return $config === "1";
|
||||
}
|
||||
|
||||
// Función de autenticación unificada (retrocompatible)
|
||||
function authenticateAdmin($username, $password) {
|
||||
if (isPasswordSystemMigrated()) {
|
||||
return verifyAdminPassword($username, $password);
|
||||
} else {
|
||||
// Fallback al sistema anterior
|
||||
if ($username === ADMIN_USERNAME && password_verify($password, ADMIN_PASSWORD)) {
|
||||
return ["id" => 1, "username" => $username, "full_name" => "Admin"];
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
';
|
||||
|
||||
// Leer config actual y agregar las nuevas funciones
|
||||
$configFile = 'config/config.php';
|
||||
$configContent = file_get_contents($configFile);
|
||||
|
||||
// Agregar las nuevas funciones antes del cierre de PHP
|
||||
$configContent = str_replace('?>', $newConfigFunctions . '?>', $configContent);
|
||||
file_put_contents($configFile, $configContent);
|
||||
|
||||
echo '<p>✅ 2. config.php actualizado con funciones de BD</p>';
|
||||
echo '</div>';
|
||||
|
||||
echo '<div class="info-box">';
|
||||
echo '<h4>🔧 Archivos actualizados exitosamente!</h4>';
|
||||
echo '<p>El sistema ahora soporta contraseñas en base de datos.</p>';
|
||||
echo '<p><strong>Recarga esta página</strong> para usar las nuevas funciones.</p>';
|
||||
echo '</div>';
|
||||
|
||||
} catch (Exception $e) {
|
||||
echo '</div>';
|
||||
echo '<div class="error-box">❌ <strong>Error actualizando archivos:</strong> ' . $e->getMessage() . '</div>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Verificar estado actual
|
||||
try {
|
||||
$pdo = new PDO(
|
||||
"mysql:host=" . DB_HOST . ";port=" . DB_PORT . ";dbname=" . DB_NAME . ";charset=" . DB_CHARSET,
|
||||
DB_USER,
|
||||
DB_PASS,
|
||||
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
|
||||
);
|
||||
|
||||
// Verificar si existe la tabla admin_users
|
||||
$checkTable = $pdo->query("SHOW TABLES LIKE 'admin_users'");
|
||||
$tableExists = $checkTable->rowCount() > 0;
|
||||
|
||||
$isMigrated = false;
|
||||
if ($tableExists) {
|
||||
$configCheck = getConfigFromDB('password_system_migrated');
|
||||
$isMigrated = ($configCheck === '1');
|
||||
}
|
||||
|
||||
echo '<div class="progress-box">';
|
||||
echo '<h3>📊 Estado Actual del Sistema</h3>';
|
||||
echo '<p><strong>Base de datos:</strong> ✅ Conectada (' . DB_NAME . ')</p>';
|
||||
echo '<p><strong>Tabla admin_users:</strong> ' . ($tableExists ? '✅ Existe' : '❌ No existe') . '</p>';
|
||||
echo '<p><strong>Sistema migrado:</strong> ' . ($isMigrated ? '✅ Sí' : '❌ No') . '</p>';
|
||||
echo '<p><strong>Usuario actual:</strong> ' . ADMIN_USERNAME . '</p>';
|
||||
echo '</div>';
|
||||
|
||||
if (!$tableExists || !$isMigrated) {
|
||||
echo '<form method="post">';
|
||||
echo '<input type="hidden" name="action" value="migrate_system">';
|
||||
echo '<button type="submit" class="btn" onclick="return confirm(\'¿Estás seguro de migrar el sistema a base de datos?\')">';
|
||||
echo '🔄 Migrar Sistema a Base de Datos';
|
||||
echo '</button>';
|
||||
echo '</form>';
|
||||
|
||||
if ($tableExists && !$isMigrated) {
|
||||
echo '<form method="post" style="margin-top: 10px;">';
|
||||
echo '<input type="hidden" name="action" value="update_system_files">';
|
||||
echo '<button type="submit" class="btn">';
|
||||
echo '🔧 Actualizar Archivos del Sistema';
|
||||
echo '</button>';
|
||||
echo '</form>';
|
||||
}
|
||||
} else {
|
||||
echo '<div class="info-box">';
|
||||
echo '<h4>✅ Sistema Ya Migrado</h4>';
|
||||
echo '<p>El sistema de contraseñas ya está funcionando con base de datos.</p>';
|
||||
echo '<p><a href="gestion_admin_unificada.php" class="btn" style="text-decoration: none; display: inline-block; text-align: center;">🛠️ Ir a Gestión de Administradores</a></p>';
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
} catch (Exception $e) {
|
||||
echo '<div class="error-box">❌ <strong>Error conectando a BD:</strong> ' . $e->getMessage() . '</div>';
|
||||
}
|
||||
?>
|
||||
|
||||
<div class="warning-box" style="margin-top: 30px;">
|
||||
<h4>📋 Lo que hace esta migración:</h4>
|
||||
<ul>
|
||||
<li>Crea tabla <code>admin_users</code> para gestionar administradores</li>
|
||||
<li>Migra la contraseña actual del config.php a la BD</li>
|
||||
<li>Actualiza funciones de autenticación</li>
|
||||
<li>Mantiene retrocompatibilidad durante la transición</li>
|
||||
<li>Permite múltiples administradores en el futuro</li>
|
||||
</ul>
|
||||
|
||||
<h4>🔒 Beneficios del nuevo sistema:</h4>
|
||||
<ul>
|
||||
<li>Contraseñas seguras en base de datos</li>
|
||||
<li>Múltiples usuarios administradores</li>
|
||||
<li>Seguimiento de últimos accesos</li>
|
||||
<li>Gestión unificada de credenciales</li>
|
||||
<li>Mayor seguridad y escalabilidad</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user