The root logger previously had no handler at all, so every module's logger.info() call (user creation, claims, password resets, ...) was silently dropped, not just unviewable. Adds a RotatingFileHandler writing into the existing /data volume so log content also survives container restarts/redeploys, plus /admin/logs (tail + line-count picker + full-file download) alongside the existing Users & Frames admin page.
61 lines
2.1 KiB
Python
61 lines
2.1 KiB
Python
"""Permission boundary + basic content checks for the admin log viewer
|
|
(routers/pages.py's admin_logs_page/admin_logs_download) -- see
|
|
CLAUDE.md's note that anything gated by an admin/permission check needs
|
|
a same-shape test: admin, non-admin logged in, logged out."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import logging
|
|
|
|
from app.logging_setup import LOG_PATH
|
|
|
|
from .conftest import login, make_user
|
|
|
|
|
|
def _setup_admin_and_user(client, db_session) -> None:
|
|
client.post("/setup", data={"username": "alice", "password": "hunter22"})
|
|
make_user(db_session, "bob")
|
|
|
|
|
|
def test_admin_can_view_logs(client, db_session):
|
|
_setup_admin_and_user(client, db_session)
|
|
login(client, "alice", "hunter22")
|
|
logging.getLogger("app.test").info("marker-line-for-test")
|
|
resp = client.get("/admin/logs")
|
|
assert resp.status_code == 200
|
|
assert "marker-line-for-test" in resp.text
|
|
|
|
|
|
def test_non_admin_forbidden_from_logs(client, db_session):
|
|
_setup_admin_and_user(client, db_session)
|
|
login(client, "bob")
|
|
resp = client.get("/admin/logs")
|
|
assert resp.status_code == 403
|
|
resp = client.get("/admin/logs/download")
|
|
assert resp.status_code == 403
|
|
|
|
|
|
def test_logged_out_redirected_from_logs_page(client, db_session):
|
|
_setup_admin_and_user(client, db_session)
|
|
client.cookies.clear() # /setup itself logs alice in
|
|
resp = client.get("/admin/logs")
|
|
assert resp.status_code == 303
|
|
assert resp.headers["location"] == "/login"
|
|
|
|
|
|
def test_admin_can_download_log_file(client, db_session):
|
|
_setup_admin_and_user(client, db_session)
|
|
login(client, "alice", "hunter22")
|
|
logging.getLogger("app.test").info("marker-line-for-download")
|
|
resp = client.get("/admin/logs/download")
|
|
assert resp.status_code == 200
|
|
assert b"marker-line-for-download" in resp.content
|
|
|
|
|
|
def test_download_404s_before_any_log_written(client, db_session, monkeypatch):
|
|
_setup_admin_and_user(client, db_session)
|
|
login(client, "alice", "hunter22")
|
|
monkeypatch.setattr("app.routers.pages.LOG_PATH", LOG_PATH.parent / "does-not-exist.log")
|
|
resp = client.get("/admin/logs/download")
|
|
assert resp.status_code == 404
|