security(07.2-02): add user_nbf Redis NBF check to get_current_user

- Added import logging + _logger = logging.getLogger(__name__) to deps/auth.py
- Inserted user_nbf Redis check block after decode_access_token in get_current_user
- Check reads user_nbf:{payload['sub']} from Redis; rejects if payload['iat'] < stored timestamp
- Uses strict < comparison (token issued exactly at event second is allowed — D-02)
- Handles both bytes and str returns from Redis for FakeRedis/aioredis compatibility
- except HTTPException: raise guard precedes broad except Exception (T-7.2-02 Pitfall 1)
- Broad except logs warning and fails open (D-04 — Redis outage must not block requests)
- Promoted all 3 Wave 0 NBF xfail stubs to passing assertions in test_auth_deps.py
This commit is contained in:
curo1305
2026-06-05 19:19:06 +02:00
parent c00c1fbaa7
commit 30ad9fd015
2 changed files with 34 additions and 9 deletions
+6 -9
View File
@@ -186,7 +186,6 @@ def test_deps_auth_has_http_403():
# by replacing `assert False, "stub"` with the actual assertion logic.
@pytest.mark.xfail(strict=False, reason="Phase 7.2 Wave 1 — NBF check not yet implemented in get_current_user")
@pytest.mark.asyncio
async def test_get_current_user_rejects_token_when_iat_before_user_nbf(auth_client, db_session):
"""Token with iat < user_nbf in Redis should return 401 'Session invalidated'."""
@@ -204,11 +203,11 @@ async def test_get_current_user_rejects_token_when_iat_before_user_nbf(auth_clie
resp = await auth_client.get(
"/test/me", headers={"Authorization": f"Bearer {token}"}
)
# Wave 1 will implement the NBF check; this assertion is the target behaviour
assert False, "stub — Wave 1 will fill in: assert resp.status_code == 401 and 'Session invalidated' in resp.json()['detail']"
assert resp.status_code == 401
assert resp.json()["detail"] == "Session invalidated"
assert resp.headers.get("WWW-Authenticate") == "Bearer"
@pytest.mark.xfail(strict=False, reason="Phase 7.2 Wave 1 — NBF check not yet implemented in get_current_user")
@pytest.mark.asyncio
async def test_get_current_user_allows_token_when_iat_after_user_nbf(auth_client, db_session):
"""Token with iat > user_nbf in Redis should return 200 (token is valid)."""
@@ -226,11 +225,9 @@ async def test_get_current_user_allows_token_when_iat_after_user_nbf(auth_client
resp = await auth_client.get(
"/test/me", headers={"Authorization": f"Bearer {token}"}
)
# Wave 1 will implement the NBF check; this assertion is the target behaviour
assert False, "stub — Wave 1 will fill in: assert resp.status_code == 200"
assert resp.status_code == 200
@pytest.mark.xfail(strict=False, reason="Phase 7.2 Wave 1 — NBF check not yet implemented in get_current_user")
@pytest.mark.asyncio
async def test_get_current_user_failopen_on_redis_error(auth_client, db_session):
"""Redis error during NBF check must fail-open (return 200, not crash)."""
@@ -249,5 +246,5 @@ async def test_get_current_user_failopen_on_redis_error(auth_client, db_session)
resp = await auth_client.get(
"/test/me", headers={"Authorization": f"Bearer {token}"}
)
# Wave 1 will implement fail-open (D-04): assert resp.status_code == 200
assert False, "stub — Wave 1 will fill in: assert resp.status_code == 200"
# D-04: Redis outage must fail-open; request proceeds normally
assert resp.status_code == 200