Files
soft_usite/rest/middlewares/auth_servicio_pago.go
T
Lizandro GuarnizoandClaude Opus 5 c75a6d7deb fix(api-keys): la restricción por IP comparaba contra la IP del proxy, no la del cliente
c.IP() detrás del proxy del hosting devuelve la IP interna del contenedor que
reenvía (10.x.x.x). Contra eso, ninguna IP pública cargada en una llave podía
coincidir: toda API key con restricción de IP daba 403, que es exactamente lo
que le pasó a la integración de vCard.

Ahora se lee X-Forwarded-For, y se toma la ÚLTIMA entrada, no la primera: con
un proxy adelante esa es la que escribió el proxy. Si quien llama manda su
propio X-Forwarded-For, el proxy le agrega la IP real al final — quedarse con
la primera sería dejar que cada uno declare su IP y la restricción no valdría
nada. El test fija ese caso.

Mismo arreglo en la autenticación de Pagos Externos, que comparaba igual.

El 403 ahora dice qué IP se vio y cuál está permitida: sin eso, del otro lado
se prueba a ciegas.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 21:02:45 -05:00

34 lines
1.2 KiB
Go

package middlewares
import (
"strings"
"github.com/gofiber/fiber/v2"
"github.com/sujit-baniya/fiber-boilerplate/pkg/models"
)
// AuthServicioPago protege los endpoints públicos de la API de pagos externos
// (/api/v1/pagos-externos/*). Es independiente de la sesión/JWT interna: el
// caller es una aplicación de un tercero que solo tiene un token largo
// (Bearer) y opcionalmente está restringido a una o varias IPs/CIDRs. Si pasa,
// deja el *models.ServicioPagoExterno resuelto en Locals("servicio_pago").
func AuthServicioPago(c *fiber.Ctx) error {
auth := c.Get("Authorization")
token := strings.TrimSpace(strings.TrimPrefix(auth, "Bearer "))
if token == "" || token == auth {
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": true, "message": "Falta el header Authorization: Bearer <token>"})
}
servicio, err := models.FindServicioPagoExternoActivoByToken(token)
if err != nil {
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": true, "message": "Token inválido o servicio inactivo"})
}
if !servicio.IPPermitida(IPDelCliente(c)) {
return c.Status(fiber.StatusForbidden).JSON(fiber.Map{"error": true, "message": "IP no autorizada para este servicio"})
}
c.Locals("servicio_pago", servicio)
return c.Next()
}