Scope workspace roots per account

This commit is contained in:
Hamza Ayed
2026-10-03 01:44:00 +03:00
parent 1b56f70aa6
commit 4345e43e29
10 changed files with 250 additions and 54 deletions
+47
View File
@@ -1,6 +1,9 @@
import json
import os
import tempfile
import unittest
from pathlib import Path
from unittest.mock import patch
from uuid import uuid4
_PROJECT_ROOT = Path(__file__).resolve().parents[1]
@@ -199,6 +202,50 @@ class AuthenticationTests(unittest.TestCase):
)
auth.clear_login_failures(email, client_host)
def test_workspace_files_are_isolated_by_account_assignment(self) -> None:
first_email = f"{uuid4().hex}@example.test"
second_email = f"{uuid4().hex}@example.test"
_, first_token = self._register(first_email)
_, second_token = self._register(second_email)
with tempfile.TemporaryDirectory() as directory:
parent = Path(directory)
first_root = parent / "first"
second_root = parent / "second"
first_root.mkdir()
second_root.mkdir()
(first_root / "one.md").write_text("first", encoding="utf-8")
(second_root / "two.md").write_text("second", encoding="utf-8")
environment = {
"SOVEREIGNAI_ALLOWED_WORKSPACES": str(parent),
"SOVEREIGNAI_USER_WORKSPACES": json.dumps(
{
first_email: [str(first_root)],
second_email: [str(second_root)],
}
),
}
with patch.dict(os.environ, environment, clear=False):
first_own = self.client.post(
"/v1/agent/workspace/files",
headers={"Authorization": f"Bearer {first_token}"},
json={"workspace_path": str(first_root)},
)
first_other = self.client.post(
"/v1/agent/workspace/files",
headers={"Authorization": f"Bearer {first_token}"},
json={"workspace_path": str(second_root)},
)
second_own = self.client.post(
"/v1/agent/workspace/files",
headers={"Authorization": f"Bearer {second_token}"},
json={"workspace_path": str(second_root)},
)
self.assertEqual(first_own.status_code, 200, first_own.text)
self.assertEqual(first_own.json()["files"], ["one.md"])
self.assertEqual(first_other.status_code, 403, first_other.text)
self.assertEqual(second_own.status_code, 200, second_own.text)
self.assertEqual(second_own.json()["files"], ["two.md"])
def test_local_bootstrap_is_restricted_to_loopback_clients(self) -> None:
remote = self.client.post("/v1/auth/local-session", json={})
self.assertEqual(remote.status_code, 403, remote.text)