fix(webui): respect full access in file preview
This commit is contained in:
@@ -28,7 +28,7 @@ def file_preview_payload(
|
||||
scope: WorkspaceScope,
|
||||
max_bytes: int = MAX_FILE_PREVIEW_BYTES,
|
||||
) -> dict[str, Any]:
|
||||
"""Return a text preview for a file inside the session workspace."""
|
||||
"""Return a text preview for a file allowed by the session workspace scope."""
|
||||
|
||||
path = _clean_preview_path(raw_path)
|
||||
if not path:
|
||||
@@ -40,7 +40,7 @@ def file_preview_payload(
|
||||
resolved = resolve_allowed_path(
|
||||
path,
|
||||
workspace=scope.project_path,
|
||||
allowed_root=scope.project_path,
|
||||
allowed_root=scope.project_path if scope.restrict_to_workspace else None,
|
||||
strict=True,
|
||||
)
|
||||
except FileNotFoundError as e:
|
||||
|
||||
@@ -2914,7 +2914,11 @@ def test_handle_file_preview_rejects_paths_outside_workspace(tmp_path) -> None:
|
||||
outside = tmp_path / "secret.py"
|
||||
outside.write_text("secret = True\n", encoding="utf-8")
|
||||
|
||||
gateway = _basic_handler(MagicMock(), workspace_path=workspace)
|
||||
gateway = _basic_handler(
|
||||
MagicMock(),
|
||||
workspace_path=workspace,
|
||||
default_restrict_to_workspace=True,
|
||||
)
|
||||
gateway.tokens.api_tokens["tok"] = time.monotonic() + 300.0
|
||||
key = "websocket:file-preview"
|
||||
enc = quote(key, safe="")
|
||||
@@ -2928,6 +2932,39 @@ def test_handle_file_preview_rejects_paths_outside_workspace(tmp_path) -> None:
|
||||
assert resp.status_code == 403
|
||||
|
||||
|
||||
def test_handle_file_preview_allows_paths_outside_workspace_in_full_access(tmp_path) -> None:
|
||||
from urllib.parse import quote
|
||||
|
||||
from websockets.datastructures import Headers
|
||||
from websockets.http11 import Request
|
||||
|
||||
workspace = tmp_path / "workspace"
|
||||
workspace.mkdir()
|
||||
outside = tmp_path / "notes.py"
|
||||
outside.write_text("value = 42\n", encoding="utf-8")
|
||||
|
||||
gateway = _basic_handler(
|
||||
MagicMock(),
|
||||
workspace_path=workspace,
|
||||
default_restrict_to_workspace=False,
|
||||
)
|
||||
gateway.tokens.api_tokens["tok"] = time.monotonic() + 300.0
|
||||
key = "websocket:file-preview"
|
||||
enc = quote(key, safe="")
|
||||
req = Request(
|
||||
f"/api/sessions/{enc}/file-preview?path={quote(str(outside), safe='')}",
|
||||
Headers([("Authorization", "Bearer tok")]),
|
||||
)
|
||||
|
||||
resp = gateway.http._handle_file_preview(req, enc)
|
||||
|
||||
assert resp.status_code == 200
|
||||
body = json.loads(resp.body.decode())
|
||||
assert body["path"] == str(outside.resolve())
|
||||
assert body["display_path"] == outside.resolve().as_posix()
|
||||
assert body["content"].splitlines() == ["value = 42"]
|
||||
|
||||
|
||||
def test_handle_webui_thread_get_backfills_legacy_missing_user_rows(
|
||||
tmp_path,
|
||||
monkeypatch,
|
||||
|
||||
Reference in New Issue
Block a user