Redis + your project. Don't look at solutions.md before submitting.
Exercise 1 — Token bucket with and without atomicity
- Implement
allow(key, capacity, refill)with HGETALL/HSET as in the lesson. Demonstrate the race: 20 concurrent threads requesting with capacity=5: how many get through? (5 should get through; note how many actually did). - Fix it with a Lua script (or
django-ratelimit): repeat the test. Now exactly 5? - Configure TicketFlow's real limits: login 5/min per user+IP, checkout 10/min per user, public API 60/min per IP. Where would you return 429 and which header do you send?
Exercise 2 — Secrets in your repo
- Run
trufflehogorgit-secrets(orgitleaks) over your history: did anything show up? (05 cleaned up; verify). - Simulate the gateway key rotation: write the step-by-step runbook with dual rotation (accept two keys → switch from old to new → revoke old) and which code enables it (a setting with a list of valid keys).
- Where would
GATEWAY_SECRETlive in your ideal deployment (cloud/vault/orchestrator env) and why not in the Docker image?
Exercise 3 — GDPR rights in your API
GET /api/me/export/: JSON with the authenticated user's profile + reservations + payments (only their own, obviously). What shape would you give it: one giant JSON or a job with download? Justify with the expected volume.DELETE /api/me/→ anonymization: email → f"{uuid}@anonymized", name → "Deleted user", account state → DELETED, without deleting reservations/payments. Implement at least the model and the transaction (10: atomic).- What happens to their MFA, their tokens and their organizer membership when anonymizing? Enumerate and decide.
Exercise 4 — Minimal audit log
- An append-only
AuditLog(actor, action, object_type, object_id, before JSONB, after JSONB, created_at)model. Write theaudit(user, "role.change", user_obj, before, after)helper. - Wire it to 21's role change (staff endpoint) and to the refund. How do you guarantee append-only (no UPDATE/DELETE from the app)? (DB permissions or a signal that prevents it).
- Query: "who changed roles in March": write the query that would answer it during an incident.
Exercise 5 — Minimization
- Audit your User/Reservation model: which field is superfluous or should be optional? Propose its removal with a migration (11) and justify it with Art. 5 (minimization).
- Write the retention policy: how long do expired PENDING ones, reset tokens and access logs live? Propose the purge job (31's cron).
Submit
Paste the count of threads that got through (before/after), the rotation runbook and the anonymization. This closes the security module; next Lesson 24 — SOLID and dependency injection.