| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 |
- from __future__ import annotations
- import io
- import pytest
- class EvidenceService:
- def preview(self, uid):
- assert uid == "evidence-1"
- return {
- "uid": uid,
- "locator": {"kind": "pdf.page", "page": 2},
- "excerpt": "客户编号 13800138000,token=secret-value",
- "confidence": 0.88,
- }
- def download(self, uid):
- assert uid == "evidence-1"
- return b"original-secret-source", "evidence.pdf", "application/pdf"
- class ArtifactService:
- def __init__(self):
- self.calls = []
- def store(self, source_uid, filename, media_type, content, parser_version):
- self.calls.append((source_uid, filename, media_type, content, parser_version))
- record = type(
- "Artifact",
- (),
- {
- "uid": "artifact-1",
- "source_uid": source_uid,
- "filename": filename,
- "media_type": media_type,
- "size_bytes": len(content),
- "content_hash": "a" * 64,
- "parser_version": parser_version,
- },
- )()
- return record, True
- @pytest.fixture()
- def client(monkeypatch):
- from flask import request
- from app import create_app
- from app.api.data_development import routes
- from app.core.system import permissions
- artifacts = ArtifactService()
- def identity():
- token = request.headers.get("Authorization", "")
- if token == "Bearer viewer":
- return {"id": "viewer-1", "roles": ["viewer"]}
- if token == "Bearer editor":
- return {"id": "editor-1", "roles": ["editor"]}
- if token == "Bearer admin":
- return {"id": "admin-1", "roles": ["admin"]}
- return None
- monkeypatch.setattr(permissions, "authenticate_request", identity)
- monkeypatch.setattr(routes, "get_evidence_service", lambda: EvidenceService())
- monkeypatch.setattr(routes, "get_artifact_service", lambda: artifacts)
- app = create_app()
- app.config.update(TESTING=True)
- return app.test_client(), artifacts
- def test_preview_is_redacted_and_original_download_is_admin_only(client):
- http, _artifacts = client
- preview = http.get(
- "/api/development/v1/evidence/evidence-1",
- headers={"Authorization": "Bearer viewer"},
- )
- denied = http.get(
- "/api/development/v1/evidence/evidence-1?download=1",
- headers={"Authorization": "Bearer viewer"},
- )
- downloaded = http.get(
- "/api/development/v1/evidence/evidence-1?download=1",
- headers={"Authorization": "Bearer admin"},
- )
- assert preview.status_code == 200
- text = preview.get_data(as_text=True)
- assert "13800138000" not in text and "secret-value" not in text
- assert "138****8000" in text and "[redacted]" in text
- assert denied.status_code == 403
- assert downloaded.data == b"original-secret-source"
- def test_editor_uploads_allowed_file_without_returning_storage_credentials(client):
- http, artifacts = client
- response = http.post(
- "/api/development/v1/sources/files",
- headers={"Authorization": "Bearer editor"},
- data={
- "source_uid": "source-1",
- "parser_version": "csv-v1",
- "file": (io.BytesIO(b"id,name\n1,A"), "governance.csv", "text/csv"),
- },
- content_type="multipart/form-data",
- )
- assert response.status_code == 201
- assert response.get_json()["data"]["uid"] == "artifact-1"
- assert "storage_ref" not in response.get_data(as_text=True)
- assert artifacts.calls[0][3] == b"id,name\n1,A"
|