64 lines
2.9 KiB
Python
64 lines
2.9 KiB
Python
"""Test: IP protection — admin cannot see/edit secret persona fields; super_admin can."""
|
|
import os, sys, tempfile, warnings
|
|
from pathlib import Path
|
|
|
|
warnings.filterwarnings("ignore")
|
|
BACKEND = str(Path(__file__).resolve().parents[1])
|
|
sys.path.insert(0, BACKEND)
|
|
os.environ["APP_ENV"] = "test"
|
|
os.environ["BOOTSTRAP_ADMIN_PASSWORD"] = "test-bootstrap-password"
|
|
|
|
from app.factory import create_app
|
|
from app.config import Config
|
|
|
|
td = tempfile.mkdtemp()
|
|
Config.DATA_DIR = Path(td)
|
|
sys.path.insert(0, BACKEND + "/scripts")
|
|
from mock_llm import MockLLM
|
|
|
|
app = create_app()
|
|
app.extensions["llm"] = MockLLM()
|
|
C = app.test_client()
|
|
|
|
def tok(u, p): return C.post("/api/auth/login", json={"username": u, "password": p}).get_json()["token"]
|
|
|
|
AT = tok("admin", "test-bootstrap-password"); AH = {"Authorization": f"Bearer {AT}"}
|
|
C.post("/api/auth/setup", headers=AH, json={"username": "admin", "email": "a@b.co", "password": "admin-ready-password", "accepted_terms": True})
|
|
AT = tok("admin", "admin-ready-password"); AH = {"Authorization": f"Bearer {AT}"}
|
|
|
|
gid = C.post("/api/groups", headers=AH, json={"product": "CRM", "segment": "SME", "channel": "line", "language": "th"}).get_json()["group"]["id"]
|
|
C.post(f"/api/groups/{gid}/analyze", headers=AH)
|
|
personas = C.get(f"/api/groups/{gid}/personas", headers=AH).get_json()["personas"] # super_admin sees all
|
|
assert personas and "pains" in personas[0], "super_admin should see secret fields"
|
|
print("[ok] super_admin sees secret fields")
|
|
|
|
# create an admin (not super) user
|
|
C.post("/api/admin/users", headers=AH, json={"username": "adm", "name": "Adm", "password": "review-admin-password", "role": "admin"})
|
|
AT2 = tok("adm", "review-admin-password"); AH2 = {"Authorization": f"Bearer {AT2}"}
|
|
pid = personas[0]["id"]
|
|
|
|
# admin list_personas: secret fields stripped
|
|
admin_list = C.get(f"/api/groups/{gid}/personas", headers=AH2).get_json()["personas"]
|
|
assert "pains" not in admin_list[0] and "tolerance" not in admin_list[0], "admin list should strip secrets"
|
|
print("[ok] admin list strips secret fields")
|
|
|
|
# admin update with a secret field -> 403
|
|
r = C.put(f"/api/groups/{gid}/personas/{pid}", headers=AH2, json={"name": "X", "tolerance": 1})
|
|
assert r.status_code == 403, r.get_json()
|
|
print("[ok] admin cannot set secret field (403)")
|
|
|
|
# admin update of non-secret field -> ok, but response still strips secrets
|
|
r = C.put(f"/api/groups/{gid}/personas/{pid}", headers=AH2, json={"name": "Edited Name"})
|
|
assert r.status_code == 200, r.get_json()
|
|
body = r.get_json()["persona"]
|
|
assert body["name"] == "Edited Name"
|
|
assert "pains" not in body, "admin update response should strip secrets"
|
|
print("[ok] admin can edit non-secret field; response strips secrets")
|
|
|
|
# super_admin can update secret field
|
|
r = C.put(f"/api/groups/{gid}/personas/{pid}", headers=AH, json={"tolerance": 5})
|
|
assert r.status_code == 200, r.get_json()
|
|
print("[ok] super_admin can edit secret field")
|
|
|
|
print("ALL IP-PROTECTION TESTS PASSED")
|