You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

61 lines
2.6 KiB
Python

# backend/tests/test_multiuser_isolation.py — per-user 격리(IDOR 404 + 도메인 스코프). 가장 중요.
import pytest
def _login(c, email, pw="demo-1234"):
return c.post("/api/auth/login", json={"email": email, "password": pw})
def test_user_b_cannot_see_user_a_task(client_auth):
_login(client_auth, "jiwoo@lumi.co")
a_task = client_auth.post(
"/api/tasks", json={"title": "A의 비밀 작업", "project_id": "me"}
).json()
client_auth.post("/api/auth/logout")
_login(client_auth, "hyunwoo@lumi.co")
# 직접 id 조회 → 404(존재 숨김)
assert client_auth.get(f"/api/tasks/{a_task['id']}").status_code == 404
# B 의 목록(스코프=현우, 데이터 없음)에 A 작업 없음
flat = client_auth.get("/api/tasks").json()
assert all(t["id"] != a_task["id"] for t in flat)
def test_create_owner_is_current_user_not_body(client_auth):
# 바디에 user_id 를 넣어도 무시(질량 할당/IDOR 방어) — current_user 가 소유자
_login(client_auth, "hyunwoo@lumi.co")
t = client_auth.post(
"/api/tasks", json={"title": "현우 작업", "project_id": "me", "user_id": "jiwoo"}
).json()
# 현우 목록엔 보이고
assert any(x["id"] == t["id"] for x in client_auth.get("/api/tasks").json())
# 지우 목록엔 없음
client_auth.post("/api/auth/logout")
_login(client_auth, "jiwoo@lumi.co")
assert all(x["id"] != t["id"] for x in client_auth.get("/api/tasks").json())
def test_b_starts_empty_a_full(client_auth):
# 시드 데이터는 전부 지우 소유 → 현우는 빈 상태에서 시작
_login(client_auth, "jiwoo@lumi.co")
assert len(client_auth.get("/api/tasks").json()) > 0 # 지우는 시드 작업 보임
client_auth.post("/api/auth/logout")
_login(client_auth, "hyunwoo@lumi.co")
assert client_auth.get("/api/tasks").json() == []
assert client_auth.get("/api/inbox").json() == []
assert client_auth.get("/api/mail").json() == []
assert client_auth.get("/api/research/home").json()["collections"] == []
assert client_auth.get("/api/trip/upcoming").status_code == 404 # 현우 여행 없음
notif = client_auth.get("/api/notifications").json()
assert notif["now"] == [] and notif["later"] == [] and notif["held"] == []
@pytest.mark.parametrize(
"path", ["/api/tasks", "/api/inbox", "/api/mail", "/api/research/home", "/api/notifications"]
)
def test_b_lists_scoped_no_a_leak(client_auth, path):
_login(client_auth, "hyunwoo@lumi.co")
r = client_auth.get(path)
assert r.status_code == 200 # 빈 스코프여도 200(빈 응답)