Complete Section 1 security/auth hardening
This commit is contained in:
32
tests/test_auth_scope.py
Normal file
32
tests/test_auth_scope.py
Normal file
@@ -0,0 +1,32 @@
|
||||
from pathlib import Path
|
||||
import sys
|
||||
|
||||
import pytest
|
||||
from fastapi import HTTPException
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
|
||||
|
||||
from app.core.auth import ( # noqa: E402
|
||||
AuthContext,
|
||||
ensure_website_scope_matches,
|
||||
require_website_auth,
|
||||
)
|
||||
|
||||
|
||||
def test_require_website_auth_returns_scoped_website_for_allowed_role():
|
||||
auth = AuthContext(website_id=5, role="admin", wp_user_id=None)
|
||||
website_id = require_website_auth(auth, allowed_roles={"admin", "system_admin"})
|
||||
assert website_id == 5
|
||||
|
||||
|
||||
def test_require_website_auth_rejects_disallowed_role():
|
||||
auth = AuthContext(website_id=5, role="student", wp_user_id="u1")
|
||||
with pytest.raises(HTTPException) as exc_info:
|
||||
require_website_auth(auth, allowed_roles={"admin", "system_admin"})
|
||||
assert exc_info.value.status_code == 403
|
||||
|
||||
|
||||
def test_cross_website_payload_mismatch_is_blocked():
|
||||
with pytest.raises(HTTPException) as exc_info:
|
||||
ensure_website_scope_matches(auth_website_id=10, payload_website_id=11)
|
||||
assert exc_info.value.status_code == 403
|
||||
50
tests/test_auth_tokens.py
Normal file
50
tests/test_auth_tokens.py
Normal file
@@ -0,0 +1,50 @@
|
||||
from pathlib import Path
|
||||
import sys
|
||||
import time
|
||||
|
||||
import pytest
|
||||
from fastapi import HTTPException
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
|
||||
|
||||
from app.core.auth import decode_access_token, issue_access_token # noqa: E402
|
||||
|
||||
|
||||
def test_issue_and_decode_access_token_round_trip():
|
||||
token = issue_access_token(
|
||||
website_id=42,
|
||||
role="student",
|
||||
wp_user_id="wp-1001",
|
||||
expires_in_seconds=3600,
|
||||
)
|
||||
auth = decode_access_token(token)
|
||||
assert auth.website_id == 42
|
||||
assert auth.role == "student"
|
||||
assert auth.wp_user_id == "wp-1001"
|
||||
|
||||
|
||||
def test_decode_access_token_rejects_tampered_signature():
|
||||
token = issue_access_token(
|
||||
website_id=7,
|
||||
role="admin",
|
||||
wp_user_id=None,
|
||||
expires_in_seconds=3600,
|
||||
)
|
||||
payload, signature = token.split(".", 1)
|
||||
tampered_token = f"{payload}.{'A' if signature[0] != 'A' else 'B'}{signature[1:]}"
|
||||
with pytest.raises(HTTPException) as exc_info:
|
||||
decode_access_token(tampered_token)
|
||||
assert exc_info.value.status_code == 401
|
||||
|
||||
|
||||
def test_decode_access_token_rejects_expired_token():
|
||||
token = issue_access_token(
|
||||
website_id=9,
|
||||
role="student",
|
||||
wp_user_id="u-1",
|
||||
expires_in_seconds=-1,
|
||||
)
|
||||
time.sleep(0.01)
|
||||
with pytest.raises(HTTPException) as exc_info:
|
||||
decode_access_token(token)
|
||||
assert exc_info.value.status_code == 401
|
||||
Reference in New Issue
Block a user