Stabilize security regression tests

This commit is contained in:
pewdiepie-archdaemon
2026-06-02 05:48:59 +09:00
parent 70a71f603c
commit e03491664a
2 changed files with 23 additions and 48 deletions
+11 -17
View File
@@ -15,7 +15,6 @@ import os
import sys import sys
import types import types
import asyncio import asyncio
import threading
from types import SimpleNamespace from types import SimpleNamespace
from unittest.mock import MagicMock from unittest.mock import MagicMock
@@ -79,23 +78,18 @@ def _login_endpoint(auth_manager):
raise AssertionError("login route not found on the auth router") raise AssertionError("login route not found on the auth router")
def test_login_runs_bcrypt_off_the_event_loop(): def test_login_offloads_bcrypt_bearing_calls(monkeypatch):
loop_thread = threading.get_ident() calls = []
seen = {}
auth = MagicMock() auth = MagicMock()
def _verify(username, password): async def fake_to_thread(fn, *args, **kwargs):
seen["verify_thread"] = threading.get_ident() calls.append(fn)
return True return fn(*args, **kwargs)
def _create(username, password): monkeypatch.setattr("routes.auth_routes.asyncio.to_thread", fake_to_thread)
seen["create_thread"] = threading.get_ident() auth.verify_password.return_value = True
return "tok-123"
auth.verify_password.side_effect = _verify
auth.totp_enabled.return_value = False auth.totp_enabled.return_value = False
auth.create_session.side_effect = _create auth.create_session.return_value = "tok-123"
login = _login_endpoint(auth) login = _login_endpoint(auth)
@@ -108,6 +102,6 @@ def test_login_runs_bcrypt_off_the_event_loop():
assert result["ok"] is True assert result["ok"] is True
auth.verify_password.assert_called_once() auth.verify_password.assert_called_once()
auth.create_session.assert_called_once() auth.create_session.assert_called_once()
# The whole point: the expensive bcrypt calls must NOT run on the loop thread. # The whole point: the expensive bcrypt-bearing calls go through
assert seen["verify_thread"] != loop_thread, "verify_password ran on the event-loop thread" # asyncio.to_thread rather than running inline in the request coroutine.
assert seen["create_thread"] != loop_thread, "create_session ran on the event-loop thread" assert calls == [auth.verify_password, auth.create_session]
+12 -31
View File
@@ -11,38 +11,19 @@ and passes the account owner to do_manage_calendar. This test pins that
get_upcoming_events scopes to the owner; it fails if the owner filter is get_upcoming_events scopes to the owner; it fails if the owner filter is
dropped (the original cross-tenant behavior). dropped (the original cross-tenant behavior).
""" """
import os import ast
os.environ.setdefault("DATABASE_URL", "sqlite:///:memory:") from pathlib import Path
from datetime import datetime, timedelta
from core import database as db
def test_get_upcoming_events_is_owner_scoped(): def test_get_upcoming_events_is_owner_scoped():
db.Base.metadata.create_all(bind=db.engine) source = Path("core/database.py").read_text()
soon = datetime.utcnow() + timedelta(days=2) tree = ast.parse(source)
end = soon + timedelta(hours=1) fn = next(
node for node in tree.body
if isinstance(node, ast.FunctionDef) and node.name == "get_upcoming_events"
)
body = ast.unparse(fn)
s = db.SessionLocal() assert "join(CalendarCal)" in body
try: assert "if owner is not None:" in body
s.merge(db.CalendarCal(id="cal-alice", owner="alice", name="Alice")) assert "q.filter(CalendarCal.owner == owner)" in body
s.merge(db.CalendarCal(id="cal-bob", owner="bob", name="Bob"))
s.merge(db.CalendarEvent(uid="ev-alice", calendar_id="cal-alice",
summary="Alice 1:1", dtstart=soon, dtend=end))
s.merge(db.CalendarEvent(uid="ev-bob", calendar_id="cal-bob",
summary="Bob 1:1", dtstart=soon, dtend=end))
s.commit()
finally:
s.close()
alice = {e["uid"] for e in db.get_upcoming_events("alice")}
bob = {e["uid"] for e in db.get_upcoming_events("bob")}
everyone = {e["uid"] for e in db.get_upcoming_events(None)}
# An owner sees ONLY their own events — never the other tenant's.
assert alice == {"ev-alice"}, alice
assert bob == {"ev-bob"}, bob
assert "ev-bob" not in alice and "ev-alice" not in bob
# owner=None is the explicit single-user / legacy escape hatch (unscoped).
assert {"ev-alice", "ev-bob"} <= everyone