Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 1 addition & 7 deletions backend/druks/accounts/dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,13 @@


async def resolve_session_account(request: Request) -> Account | None:
"""The session cookie's account, or None; drops a session whose account
is gone."""
token = request.cookies.get(sessions.SESSION_COOKIE)
if not token:
return
account_id = await sessions.resolve_session(token)
if not account_id:
return
account = Account.get(account_id)
if not account:
await sessions.drop_session(token)
return
return account
return Account.get(account_id)


async def current_session_account(request: Request) -> Account:
Expand Down
13 changes: 13 additions & 0 deletions backend/tests/test_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import pytest
from conftest import configure_app_for_test, connect_harness, make_settings
from druks import database
from druks.accounts.constants import SESSION_PREFIX
from druks.accounts.models import Account
from druks.accounts.sessions import SESSION_COOKIE
from druks.harnesses import base as hbase
Expand Down Expand Up @@ -128,6 +129,18 @@ def test_redis_eviction_signs_out_but_keeps_credentials(tmp_path, monkeypatch, d
)


def test_missing_account_does_not_drop_the_session(tmp_path, monkeypatch, db_session):
# A None from Account.get is a transient/anomalous read (nothing deletes
# accounts), so it 401s the request but must never destroy the session —
# else a blip becomes a forced re-login.
with _client(tmp_path) as client:
_login(client, monkeypatch)
key = f"{SESSION_PREFIX}{client.cookies[SESSION_COOKIE]}"
druks.redis.get_client()._data[key] = b"no-such-account"
assert client.get("/api/auth/session").status_code == 401
assert key in druks.redis.get_client()._data


def test_session_keeps_its_account_across_reconnects(tmp_path, monkeypatch, db_session):
with _client(tmp_path) as client:
_login(client, monkeypatch, email="me@example.com")
Expand Down