- Agregar editor visual de configuración avanzada con protección por contraseña
- Implementar rangos de IPs administrativas personalizados por segmento
- Crear AdminRangeHelper.php para procesamiento de JSON por segmento
- Agregar botón ⚙️ de acceso rápido al editor
- Implementar modal de autenticación con validación de contraseña
- Agregar fallback inteligente a rangos globales para segmentos no configurados
Configuración avanzada:
- 3 campos nuevos en manifest.json (checkbox, JSON textarea, password)
- Editor visual completo con formularios dinámicos
- Agregar/eliminar segmentos y rangos en tiempo real
- Tabla de segmentos configurados con acciones
- Validación de cambios sin guardar
- Mensaje de éxito al guardar configuración
Backend:
- AdminRangeHelper.php: getSegmentLimits(), isAdminIpCustom(), validateConfigJson()
- IpSearchService.php: soporte para rangos personalizados con fallback
- Handler POST para guardar configuración JSON
Frontend:
- ~250 líneas de JavaScript para gestión del editor
- CSS responsive con soporte para temas claro/oscuro
- Interfaz amigable para usuarios no técnicos
Lógica de fallback:
- Checkbox desactivado → rangos globales para todos
- Checkbox activado + segmento en JSON → rangos del JSON
- Checkbox activado + segmento NO en JSON → fallback a rangos globales
Archivos creados:
- src/AdminRangeHelper.php
Archivos modificados:
- manifest.json: 3 campos nuevos, versión 1.5.0
- src/IpSearchService.php: lógica de fallback
- public.php: editor completo, modal, JavaScript
- CHANGELOG.md: entrada v1.5.0
- README.md: documentación de nuevos campos"
131 lines
4.5 KiB
PHP
131 lines
4.5 KiB
PHP
<?php
|
|
|
|
namespace SiipAvailableIps;
|
|
|
|
/**
|
|
* Helper class para manejar rangos de IPs administrativas personalizados por segmento
|
|
*/
|
|
class AdminRangeHelper
|
|
{
|
|
/**
|
|
* Obtiene los límites de IPs administrativas para un segmento específico
|
|
*
|
|
* @param string|int $segmentNumber Número del segmento (ej: 18 para 172.16.18.x)
|
|
* @param string $jsonData JSON con configuración de rangos
|
|
* @return array|null Array con límites o null si el segmento no existe
|
|
*/
|
|
public static function getSegmentLimits($segmentNumber, $jsonData)
|
|
{
|
|
if (empty($jsonData)) {
|
|
return null;
|
|
}
|
|
|
|
$data = json_decode($jsonData, true);
|
|
|
|
if (!isset($data['segmentos']) || !is_array($data['segmentos'])) {
|
|
return null;
|
|
}
|
|
|
|
foreach ($data['segmentos'] as $segmento) {
|
|
if ($segmento['segmento'] == $segmentNumber) {
|
|
// Última IP del bloque inicial
|
|
$ultimoInicial = 0;
|
|
if (isset($segmento['administrativas_iniciales']) && is_array($segmento['administrativas_iniciales'])) {
|
|
foreach ($segmento['administrativas_iniciales'] as $rango) {
|
|
if (isset($rango['hasta']) && $rango['hasta'] > $ultimoInicial) {
|
|
$ultimoInicial = $rango['hasta'];
|
|
}
|
|
}
|
|
}
|
|
|
|
// Primera IP del bloque final
|
|
$primerFinal = 999;
|
|
if (isset($segmento['administrativas_finales']) && is_array($segmento['administrativas_finales'])) {
|
|
foreach ($segmento['administrativas_finales'] as $rango) {
|
|
if (isset($rango['inicio']) && $rango['inicio'] < $primerFinal) {
|
|
$primerFinal = $rango['inicio'];
|
|
}
|
|
}
|
|
}
|
|
|
|
return [
|
|
'ultimo_inicial_reservado' => $ultimoInicial,
|
|
'primer_final_reservado' => $primerFinal,
|
|
'rangos_iniciales' => $segmento['administrativas_iniciales'] ?? [],
|
|
'rangos_finales' => $segmento['administrativas_finales'] ?? []
|
|
];
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Verifica si una IP es administrativa según configuración JSON personalizada
|
|
*
|
|
* @param string $ip Dirección IP completa (ej: 172.16.18.45)
|
|
* @param string $jsonData JSON con configuración de rangos
|
|
* @return bool True si es IP administrativa
|
|
*/
|
|
public static function isAdminIpCustom($ip, $jsonData)
|
|
{
|
|
$parts = explode('.', $ip);
|
|
if (count($parts) !== 4) {
|
|
return false;
|
|
}
|
|
|
|
$segment = $parts[2];
|
|
$lastOctet = (int)$parts[3];
|
|
|
|
$limits = self::getSegmentLimits($segment, $jsonData);
|
|
if (!$limits) {
|
|
return false;
|
|
}
|
|
|
|
// Verificar rangos iniciales
|
|
if (isset($limits['rangos_iniciales']) && is_array($limits['rangos_iniciales'])) {
|
|
foreach ($limits['rangos_iniciales'] as $rango) {
|
|
if ($lastOctet >= $rango['inicio'] && $lastOctet <= $rango['hasta']) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Verificar rangos finales
|
|
if (isset($limits['rangos_finales']) && is_array($limits['rangos_finales'])) {
|
|
foreach ($limits['rangos_finales'] as $rango) {
|
|
if ($lastOctet >= $rango['inicio'] && $lastOctet <= $rango['hasta']) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Valida el formato del JSON de configuración
|
|
*
|
|
* @param string $jsonData JSON a validar
|
|
* @return array Array con 'valid' (bool) y 'error' (string|null)
|
|
*/
|
|
public static function validateConfigJson($jsonData)
|
|
{
|
|
if (empty($jsonData)) {
|
|
return ['valid' => false, 'error' => 'JSON vacío'];
|
|
}
|
|
|
|
$data = json_decode($jsonData, true);
|
|
|
|
if (json_last_error() !== JSON_ERROR_NONE) {
|
|
return ['valid' => false, 'error' => 'JSON inválido: ' . json_last_error_msg()];
|
|
}
|
|
|
|
if (!isset($data['segmentos']) || !is_array($data['segmentos'])) {
|
|
return ['valid' => false, 'error' => 'Falta el array "segmentos"'];
|
|
}
|
|
|
|
return ['valid' => true, 'error' => null];
|
|
}
|
|
}
|