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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user