From 529ce90d7200f8b8b6813d05963e5ccd95f0ee07 Mon Sep 17 00:00:00 2001 From: pushnanashi2 Date: Mon, 14 Sep 2026 21:13:16 +0900 Subject: [PATCH] fix(api): require authentication for case reads Signed-off-by: pushnanashi2 --- core/api_routers/cases.py | 6 ++- core/tests/test_api_routers/test_cases.py | 50 ++++++++++++++++++----- 2 files changed, 43 insertions(+), 13 deletions(-) diff --git a/core/api_routers/cases.py b/core/api_routers/cases.py index 523b847..19fd244 100644 --- a/core/api_routers/cases.py +++ b/core/api_routers/cases.py @@ -46,7 +46,8 @@ async def list_cases( assigned_to: Optional[str] = Query(None), limit: int = Query(100, ge=1, le=1000), offset: int = Query(0, ge=0), - db: Session = Depends(get_db) + db: Session = Depends(get_db), + current_user: dict = Depends(require_permission("cases", "read")) ): ''' list or search cases @@ -65,7 +66,8 @@ async def list_cases( @router.get("/cases/{case_id}", response_model=CaseResponse) async def get_case( case_id: UUID, - db: Session = Depends(get_db) + db: Session = Depends(get_db), + current_user: dict = Depends(require_permission("cases", "read")) ): ''' get case by id diff --git a/core/tests/test_api_routers/test_cases.py b/core/tests/test_api_routers/test_cases.py index ab98558..c15aa4f 100644 --- a/core/tests/test_api_routers/test_cases.py +++ b/core/tests/test_api_routers/test_cases.py @@ -6,9 +6,26 @@ import pytest from uuid import uuid4 from fastapi.testclient import TestClient +from core.auth import create_access_token +from core.db.connection import get_db +from core.fastapi_app import app -def test_create_case(test_client: TestClient): +@pytest.fixture +def auth_headers(): + token = create_access_token({"sub": "test-admin", "role": "admin"}) + return {"Authorization": f"Bearer {token}"} + + +@pytest.fixture +def unauthenticated_client(): + app.dependency_overrides[get_db] = lambda: object() + client = TestClient(app) + yield client + app.dependency_overrides.pop(get_db, None) + + +def test_create_case(test_client: TestClient, auth_headers: dict): ''' test creating a case ''' @@ -18,7 +35,7 @@ def test_create_case(test_client: TestClient): "severity": "high", "analyst_notes": "initial notes" } - response = test_client.post("/api/v1/cases", json=case_data) + response = test_client.post("/api/v1/cases", json=case_data, headers=auth_headers) assert response.status_code == 201 data = response.json() assert data["title"] == "test case" @@ -27,7 +44,7 @@ def test_create_case(test_client: TestClient): assert "id" in data -def test_list_cases(test_client: TestClient): +def test_list_cases(test_client: TestClient, auth_headers: dict): ''' test listing cases ''' @@ -37,17 +54,17 @@ def test_list_cases(test_client: TestClient): "description": "test", "severity": "medium" } - test_client.post("/api/v1/cases", json=case_data) + test_client.post("/api/v1/cases", json=case_data, headers=auth_headers) # list cases - response = test_client.get("/api/v1/cases") + response = test_client.get("/api/v1/cases", headers=auth_headers) assert response.status_code == 200 data = response.json() assert isinstance(data, list) assert len(data) > 0 -def test_get_case(test_client: TestClient): +def test_get_case(test_client: TestClient, auth_headers: dict): ''' test getting a case by id ''' @@ -57,18 +74,18 @@ def test_get_case(test_client: TestClient): "description": "test", "severity": "low" } - create_response = test_client.post("/api/v1/cases", json=case_data) + create_response = test_client.post("/api/v1/cases", json=case_data, headers=auth_headers) case_id = create_response.json()["id"] # get the case - response = test_client.get(f"/api/v1/cases/{case_id}") + response = test_client.get(f"/api/v1/cases/{case_id}", headers=auth_headers) assert response.status_code == 200 data = response.json() assert data["id"] == case_id assert data["title"] == "get test case" -def test_update_case(test_client: TestClient): +def test_update_case(test_client: TestClient, auth_headers: dict): ''' test updating a case ''' @@ -78,14 +95,25 @@ def test_update_case(test_client: TestClient): "description": "test", "severity": "medium" } - create_response = test_client.post("/api/v1/cases", json=case_data) + create_response = test_client.post("/api/v1/cases", json=case_data, headers=auth_headers) case_id = create_response.json()["id"] # update the case update_data = {"status": "investigating", "analyst_notes": "updated notes"} - response = test_client.patch(f"/api/v1/cases/{case_id}", json=update_data) + response = test_client.patch( + f"/api/v1/cases/{case_id}", json=update_data, headers=auth_headers + ) assert response.status_code == 200 data = response.json() assert data["status"] == "investigating" assert data["analyst_notes"] == "updated notes" + +@pytest.mark.parametrize("path", ["/api/v1/cases", f"/api/v1/cases/{uuid4()}"]) +def test_case_reads_require_authentication( + unauthenticated_client: TestClient, path: str +): + response = unauthenticated_client.get(path) + + assert response.status_code == 401 +