left4me/l4d2web/routes
mwiegand 0e2a78e065
secure(l4d2web): block non-admin writes on system overlays; last-admin guard on deactivate
_load_files_overlay docs already promised "owner or admin" for mutations, but the check only filtered by overlay.type — system overlays (user_id IS NULL) were writable by any logged-in user. Add the explicit 403 for non-admins; read-only routes remain open across all overlay types.

Mirror the delete-route last-admin guard on /admin/users/<id>/deactivate so a future auth-model change (service accounts bypassing require_admin, etc.) can't accidentally lock out the system.
2026-05-14 22:24:19 +02:00
..
__init__.py chore(l4d2): flatten component layout 2026-05-05 23:47:06 +02:00
auth_routes.py harden(l4d2web): auth/session — clear on login+logout, constant-time CSRF, role-change invalidation 2026-05-14 22:18:46 +02:00
blueprint_routes.py feat(l4d2-web): blueprint rename moves to footer modal — matches overlay/server pattern 2026-05-09 01:37:29 +02:00
console_routes.py refactor(l4d2-web): tighten console route limit test and dedupe is_error 2026-05-14 21:35:22 +02:00
files_routes.py secure(l4d2web): block non-admin writes on system overlays; last-admin guard on deactivate 2026-05-14 22:24:19 +02:00
job_routes.py feat(l4d2-web): managed global map overlays with daily refresh 2026-05-08 08:05:14 +02:00
log_routes.py feat(l4d2-web): server identity by id, name as display label 2026-05-08 19:22:09 +02:00
overlay_routes.py feat(files-overlay): user-managed file content as a third overlay type 2026-05-09 18:59:32 +02:00
page_routes.py secure(l4d2web): block non-admin writes on system overlays; last-admin guard on deactivate 2026-05-14 22:24:19 +02:00
profile_routes.py profile: happy-path + cross-session invalidation tests 2026-05-11 21:58:26 +02:00
server_routes.py feat(l4d2-web): accept hostname on server update, default empty on create 2026-05-13 14:29:53 +02:00
workshop_routes.py workshop_routes: narrow refresh's steam exception handler 2026-05-11 23:08:41 +02:00