Metadata-Version: 2.4
Name: auth-guardian
Version: 0.1.0
Summary: Reusable Keycloak SDK for auth-service and microservices
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: httpx<0.29,>=0.28
Requires-Dist: python-jose[cryptography]<4,>=3.5
Provides-Extra: redis
Requires-Dist: redis>=5.0.0; extra == "redis"
Provides-Extra: fastapi
Requires-Dist: fastapi<0.119,>=0.118; extra == "fastapi"
Provides-Extra: dev
Requires-Dist: build<2,>=1.3; extra == "dev"
Requires-Dist: mypy<2,>=1.10; extra == "dev"
Requires-Dist: pytest<9,>=8.3; extra == "dev"
Requires-Dist: pytest-asyncio<2,>=1.2; extra == "dev"
Requires-Dist: respx<0.23,>=0.22; extra == "dev"
Requires-Dist: ruff<0.15,>=0.14; extra == "dev"
Requires-Dist: twine<7,>=6.2; extra == "dev"

# Auth Guardian 

**Auth Guardian** es un SDK extremadamente simple, *plug-and-play* y agnóstico, diseñado para proteger aplicaciones y microservicios en Python utilizando Keycloak (u otros proveedores OIDC compatibles).

Ha sido diseñado para evitar configuraciones redundantes: con un par de variables de entorno, tu aplicación tendrá flujos de login, logout, callbacks y validación de roles y permisos automáticamente.

---

##  Instalación

```bash
pip install auth-guardian
```

---

##  Configuración (Plug-and-Play)

`AuthGuardian` es lo suficientemente inteligente como para configurarse por sí mismo. Solo necesitas definir las siguientes variables de entorno:

```env
AUTH_BASE_URL=https://auth.tu-dominio.com
AUTH_REALM=tu-realm
AUTH_CLIENT_ID=tu-cliente
```

> **Nota:** También soporta las variables legacy `KEYCLOAK_BASE_URL`, `KEYCLOAK_REALM` y `KEYCLOAK_CLIENT_ID` de forma automática.

---

##  Uso en FastAPI

### 1. Inyectando Rutas Automáticas (Login, Logout, Callback)
Para aplicaciones frontend/Fullstack, `AuthGuardian` puede inyectar los endpoints completos del flujo OIDC (`/login`, `/logout`, `/oidc/callback`) para que no tengas que escribirlos:

```python
from fastapi import FastAPI
from auth_guardian import AuthGuardian, create_auth_router

app = FastAPI()

# 1. Instancia el guardián
auth = AuthGuardian()

# 2. Crea el router que manejará automáticamente login, callback y logout
auth_router = create_auth_router(
    auth=auth,
    login_redirect_url="/dashboard", # Dónde enviar al usuario tras loguearse
    logout_redirect_url="/login"     # Dónde enviar al usuario tras desloguearse
)

# 3. Registra el router en tu app
app.include_router(auth_router)
```

**¡Eso es todo!** Automáticamente tienes:
- `GET /login` -> Redirige al login de Keycloak.
- `GET /oidc/callback` -> Maneja el intercambio de código, genera las cookies seguras e inicia la sesión local.
- `GET /logout` -> Elimina cookies y redirige al cierre de sesión de Keycloak.

### 2. Protegiendo tus Endpoints (Para Principiantes)
En FastAPI, "proteger" una ruta significa que si alguien entra sin haber iniciado sesión, el sistema le bloqueará el acceso automáticamente.

Para lograr esto, FastAPI usa algo llamado `Depends` (Dependencias). Si agregas `Depends(auth.get_current_user)` en tu función, AuthGuardian se encargará de verificar si el usuario tiene sesión activa antes de ejecutar el código.

**Ejemplo 1: Bloquear acceso a usuarios no logueados**
```python
from fastapi import Depends

@app.get("/recurso-seguro")
async def get_seguro(user: dict = Depends(auth.get_current_user)):
    # Si llega aquí, es porque el usuario SÍ está logueado.
    # 'user' contendrá la información de su perfil.
    return {
        "mensaje": f"Hola {user.get('preferred_username')}",
        "email": user.get('email')
    }
```

**Ejemplo 2: Bloquear acceso según el Rol del usuario**
Si tienes zonas exclusivas (como un panel de administrador), puedes usar `auth.require_role("nombre_del_rol")`.

```python
@app.get("/zona-admin")
async def get_admin(user: dict = Depends(auth.require_role("admin"))):
    # Solo entrarán usuarios que se hayan logueado y que tengan el rol "admin"
    return {"mensaje": "¡Bienvenido, administrador!"}
```

---

##  Opciones Avanzadas

### Validación Manual de Tokens
Si no usas FastAPI o necesitas validar un token manualmente, el SDK expone internamente el validador:

```python
payload = await auth.validator.decode_access_token("eyJhbGciOiJIUz...")
print(payload)
```

### Hook Personalizado de Login
Al usar `create_auth_router`, puedes inyectar un hook que se ejecute justo cuando el usuario hace login exitosamente (por ejemplo, para guardar/actualizar el usuario en tu base de datos):

```python
async def sync_user_in_db(payload: dict):
    email = payload.get("email")
    print(f"Sincronizando usuario {email} en base de datos...")

auth_router = create_auth_router(
    auth=auth,
    on_login_success=sync_user_in_db # Se ejecuta después del callback, antes de redirigir
)
```

---

##  Contrato Público API

El contrato público exportado es estable y mantenido a través del `__init__.py`.

- `AuthGuardian`: Clase principal y Facade de autenticación.
- `create_auth_router`: Constructor automático de endpoints OIDC para FastAPI.
- `extract_client_roles(payload, client_id)`: Función helper para extraer los roles.
- `AuthConfig`, `AuthTokenValidator`, `AuthOIDCClient`: Accesibles para usos complejos o manuales.
- Manejo de Errores: `KeycloakAuthError`, `TokenValidationError`, `KeycloakAPIError`.
