File size: 2,899 Bytes
e6eb838
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
"""#77 β€” prune_persisted_upload: removes a persisted uploaded doc, is
path-safety-guarded (can NEVER escape UPLOADED_DOCS_DIR), supports exact
id + prefix, and never silently no-ops a traversal attempt."""
from __future__ import annotations

import sys
from pathlib import Path

import pytest

_REPO = Path(__file__).resolve().parent.parent
if str(_REPO) not in sys.path:
    sys.path.insert(0, str(_REPO))


def _seed(root: Path, pid: str) -> Path:
    from backend import uploaded_docs as u
    d = u._doc_dir(pid)
    d.mkdir(parents=True, exist_ok=True)
    (d / "record.json").write_text('{"policy_id": "%s"}' % pid)
    (d / "meta.json").write_text("{}")
    return d


def test_prune_exact_and_prefix(tmp_path, monkeypatch):
    from backend.config import settings
    from backend import uploaded_docs as u
    monkeypatch.setattr(settings, "UPLOADED_DOCS_DIR", tmp_path)

    a = _seed(tmp_path, "user-upload__e2e-verify-a__zzz")
    b = _seed(tmp_path, "user-upload__e2e-verify-b__zzz")
    keep = _seed(tmp_path, "user-upload__real-user__myplan")
    assert a.exists() and b.exists() and keep.exists()

    # exact id
    r1 = u.prune_persisted_upload("user-upload__e2e-verify-a__zzz")
    assert r1["removed"] == ["user-upload__e2e-verify-a__zzz"]
    assert not a.exists() and b.exists() and keep.exists()

    # prefix (bulk) β€” only e2e-verify-*, never the real user doc
    r2 = u.prune_persisted_upload(prefix="user-upload__e2e-verify")
    assert "user-upload__e2e-verify-b__zzz" in r2["removed"]
    assert not b.exists()
    assert keep.exists(), "prefix prune must NOT touch non-matching docs"

    # absent id β†’ skipped, not error, not silent
    r3 = u.prune_persisted_upload("user-upload__does-not-exist")
    assert r3["removed"] == [] and r3["skipped"] == ["user-upload__does-not-exist"]


def test_prune_path_traversal_raises(tmp_path, monkeypatch):
    """A traversal attempt MUST raise, never delete outside the root."""
    from backend.config import settings
    from backend import uploaded_docs as u
    monkeypatch.setattr(settings, "UPLOADED_DOCS_DIR", tmp_path)
    outside = tmp_path.parent / "DO_NOT_DELETE"
    outside.mkdir(exist_ok=True)
    (outside / "keep.txt").write_text("safe")
    # _doc_dir sanitises slashes/dots, so the dir resolves INSIDE root and
    # is simply "not present" β†’ skipped; the outside dir is untouched.
    r = u.prune_persisted_upload("../../DO_NOT_DELETE")
    assert r["removed"] == []
    assert outside.exists() and (outside / "keep.txt").exists()


def test_empty_prefix_rejected(tmp_path, monkeypatch):
    from backend.config import settings
    from backend import uploaded_docs as u
    monkeypatch.setattr(settings, "UPLOADED_DOCS_DIR", tmp_path)
    with pytest.raises(RuntimeError):
        u.prune_persisted_upload(prefix="///")


if __name__ == "__main__":
    raise SystemExit(pytest.main([__file__, "-v"]))