package com.sigem.gis.security; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.web.bind.annotation.*; import com.sigem.gis.service.FdwService; import java.util.List; import java.util.Map; @RestController @RequestMapping("/api/auth") public class AuthController { @Autowired private JwtUtil jwtUtil; @Autowired @Qualifier("masterJdbcTemplate") private JdbcTemplate masterJdbcTemplate; @Autowired @Qualifier("gisJdbcTemplate") private JdbcTemplate gisJdbcTemplate; @Autowired private FdwService fdwService; @PostMapping("/login") public ResponseEntity login(@RequestBody AuthRequest request) { try { // 1. Validar existencia de entidad en directorio maestro (en el .254) String sqlEntidades = "SELECT sigem_site, sigem_dbname, lat, lng, zoom, minzoom, maxzoom, mapa_base, boundno, boundse FROM public.entidades WHERE activo= TRUE AND entidad = ?"; List> entidades = masterJdbcTemplate.queryForList(sqlEntidades, Integer.parseInt(request.getEntidad())); if (entidades.isEmpty()) { return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(new AuthResponse(null, null, "Entidad Inactiva o No Encontrada")); } Map entidadData = entidades.get(0); // 2. Asegurar Infraestructura FDW (Regla 16: Solo crea si no existe) fdwService.setupFdw(request.getEntidad()); String schemaName = "fdw_" + request.getEntidad(); System.out.println("Validando usuario vía FDW local para entidad: " + request.getEntidad()); // 3. Buscar Usuario en el esquema FDW local (en el .123) String sqlUser = "SELECT usu_nom, usu_ape, activo, pgp_sym_decrypt(usu_clave_a::bytea, '510580', 'compress-algo=0, cipher-algo=aes256')::text as clave_desencriptada " + "FROM " + schemaName + ".usuarios " + "WHERE usu_alias = ? AND ejer_fisca = date_part('year', now())"; List> usuarios = gisJdbcTemplate.queryForList(sqlUser, request.getUsername()); if (!usuarios.isEmpty()) { Map userData = usuarios.get(0); boolean isActivo = (boolean) userData.get("activo"); String claveDesencriptada = (String) userData.get("clave_desencriptada"); // 4. Validación Final y Generación de Token if (isActivo && request.getPassword().equals(claveDesencriptada)) { String token = jwtUtil.generateToken(request.getUsername(), request.getEntidad()); String nombreCompleto = userData.get("usu_nom") + " " + userData.get("usu_ape"); // Metadatos georreferenciados de la entidad Double lat = parseDouble(entidadData.get("lat"), -25.456443); Double lng = parseDouble(entidadData.get("lng"), -56.446949); Integer zoom = parseInteger(entidadData.get("zoom"), 14); Integer minZoom = parseInteger(entidadData.get("minzoom"), 5); Integer maxZoom = parseInteger(entidadData.get("maxzoom"), 20); String mapaBase = String.valueOf(entidadData.getOrDefault("mapa_base", "osm")); String bounds = String.valueOf(entidadData.getOrDefault("boundno", "")) + "|" + String.valueOf(entidadData.getOrDefault("boundse", "")); return ResponseEntity.ok(new AuthResponse(token, nombreCompleto, "Login Exitoso", lat, lng, zoom, minZoom, maxZoom, mapaBase, bounds)); } } return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(new AuthResponse(null, null, "Credenciales Inválidas o Cuenta de Baja")); } catch (Exception e) { e.printStackTrace(); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(new AuthResponse(null, null, "Fallo interno en el Microservicio SaaS: " + e.toString())); } } private Double parseDouble(Object val, Double def) { if (val == null) return def; try { return Double.parseDouble(String.valueOf(val).trim()); } catch (Exception e) { return def; } } private Integer parseInteger(Object val, Integer def) { if (val == null) return def; try { return Integer.parseInt(String.valueOf(val)); } catch (Exception e) { return def; } } }