Redis + tu proyecto. No mires solutions.md hasta entregar.
Ejercicio 1 — Token bucket con y sin atomicidad
- Implementa
allow(key, capacity, refill)con HGETALL/HSET como la lección. Demuestra la raza: 20 threads concurrentes pidiendo con capacity=5: ¿cuántos pasan? (deberían pasar 5; anota cuántos pasaron de verdad). - Arregla con un script Lua (o
django-ratelimit): repite la prueba. ¿Ahora sí son exactamente 5? - Configura los límites reales de TicketFlow: login 5/min por usuario+IP, checkout 10/min por usuario, API pública 60/min por IP. ¿Dónde pondrías 429 y qué cabecera mandas?
Ejercicio 2 — Secretos en tu repo
- Corre
trufflehogogit-secrets(ogitleaks) sobre tu historial: ¿apareció algo? (la 05 hizo limpieza; verifica). - Inventa la rotación de la clave de pasarela: escribe el runbook paso a paso con rotación dual (aceptar dos claves → cambiar de usar vieja a nueva → revocar vieja) y qué código lo permite (setting con lista de claves válidas).
- ¿Dónde viviría
GATEWAY_SECRETen tu despliegue ideal (nube/vault/env del orquestador) y por qué no en la imagen Docker?
Ejercicio 3 — Derechos RGPD en tu API
GET /api/me/export/: JSON con perfil + reservas + pagos del usuario autenticado (solo el suyo, obviamente). ¿Qué forma le darías: un JSON gigante o un job con download? Justifica con el volumen esperado.DELETE /api/me/→ anonimización: email → f"{uuid}@anonymized", nombre → "Usuario eliminado", state de la cuenta → DELETED, sin borrar reservas/pagos. Implementa al menos el modelo y la transacción (10: atómica).- ¿Qué pasa con su MFA, sus tokens y su membresía de organizador al anonimizar? Enumera y decide.
Ejercicio 4 — Audit log mínimo
- Modelo
AuditLog(actor, action, object_type, object_id, before JSONB, after JSONB, created_at)append-only. Escribe el helperaudit(user, "role.change", user_obj, before, after). - Conéctalo al cambio de rol de la 21 (staff endpoint) y al reembolso. ¿Cómo garantizas append-only (sin UPDATE/DELETE desde la app)? (permisos de BD o señal que lo impida).
- Consulta: "quién cambió roles en marzo": escribe la query que respondería en un incidente.
Ejercicio 5 — Minimización
- Audita tu modelo User/Reservation: ¿qué campo sobra o debería ser opcional? Propón la eliminación con migración (11) y justifica con el Art. 5 (minimización).
- Escribe la política de retención: ¿cuánto viven los PENDING expirados, los tokens de reset, los logs de acceso? Propón el job que purga (el cron de la 31).
Entrega
Pega el conteo de threads que pasaron (antes/después), el runbook de rotación y la anonimización. Cierra el módulo de seguridad; después Lección 24 — SOLID e inyección de dependencias.