mirror of
https://github.com/andrewyng/openworker.git
synced 2026-11-04 13:27:11 +00:00
A machine joins with its own identity and holds a reverse channel to the controller. Provider keys and connector accounts deploy sealed to the machine's pinned key.
149 lines
7.6 KiB
Python
149 lines
7.6 KiB
Python
"""OPENWORKER_BASE_DIR (spec §Fly sandboxes, "Base directory"): a confined box
|
|
keeps state and scratch under the base and refuses folders outside it with a
|
|
plain error; an unconfined box behaves exactly as before."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from coworker.basedir import OutsideBaseDir, base_dir, ensure_under_base
|
|
from coworker.secrets import state_dir
|
|
from coworker.server.manager import SessionManager
|
|
|
|
|
|
def test_unconfined_is_a_no_op(tmp_path, monkeypatch):
|
|
monkeypatch.delenv("OPENWORKER_BASE_DIR", raising=False)
|
|
assert base_dir() is None
|
|
assert ensure_under_base(tmp_path / "anywhere") == (tmp_path / "anywhere").resolve()
|
|
|
|
|
|
def test_confined_paths_resolve_under_base_and_outsiders_are_refused(tmp_path, monkeypatch):
|
|
base = tmp_path / "data"
|
|
(base / "proj").mkdir(parents=True)
|
|
outside = tmp_path / "elsewhere"
|
|
outside.mkdir()
|
|
monkeypatch.setenv("OPENWORKER_BASE_DIR", str(base))
|
|
assert ensure_under_base(base) == base.resolve()
|
|
assert ensure_under_base(base / "proj") == (base / "proj").resolve()
|
|
with pytest.raises(OutsideBaseDir) as exc:
|
|
ensure_under_base(outside, "folder")
|
|
assert str(base.resolve()) in str(exc.value) and "folder" in str(exc.value)
|
|
# A symlink inside the base pointing out does not slip through.
|
|
link = base / "escape"
|
|
link.symlink_to(outside)
|
|
with pytest.raises(OutsideBaseDir):
|
|
ensure_under_base(link)
|
|
# `..` tricks neither.
|
|
with pytest.raises(OutsideBaseDir):
|
|
ensure_under_base(base / ".." / "elsewhere")
|
|
|
|
|
|
def test_state_dir_defaults_under_the_base(tmp_path, monkeypatch):
|
|
monkeypatch.delenv("COWORKER_STATE_DIR", raising=False)
|
|
monkeypatch.setenv("OPENWORKER_BASE_DIR", str(tmp_path / "data"))
|
|
assert state_dir() == tmp_path / "data" / "state"
|
|
# An explicit state dir still wins (the image sets both, consistently).
|
|
monkeypatch.setenv("COWORKER_STATE_DIR", str(tmp_path / "explicit"))
|
|
assert state_dir() == tmp_path / "explicit"
|
|
|
|
|
|
def test_manager_confines_workspaces_scratch_and_roots(tmp_path, monkeypatch):
|
|
base = tmp_path / "data"
|
|
inside = base / "repo"
|
|
inside.mkdir(parents=True)
|
|
outside = tmp_path / "home-project"
|
|
outside.mkdir()
|
|
monkeypatch.setenv("OPENWORKER_BASE_DIR", str(base))
|
|
monkeypatch.delenv("COWORKER_SCRATCH_BASE", raising=False)
|
|
manager = SessionManager(data_dir=tmp_path / "mgr")
|
|
|
|
assert manager.open_workspace(str(inside))["ok"] is True
|
|
refused = manager.open_workspace(str(outside))
|
|
assert refused["ok"] is False and "only works under" in refused["error"]
|
|
# Creating a new folder outside is refused before anything is made.
|
|
assert manager.open_workspace(str(tmp_path / "new-one"), create=True)["ok"] is False
|
|
assert not (tmp_path / "new-one").exists()
|
|
|
|
assert manager.resolve_workspace(str(inside)) == str(inside.resolve())
|
|
assert manager.resolve_workspace(str(outside)) is None
|
|
|
|
# Scratch lives under the base, and a stray pref cannot move it out.
|
|
assert manager.scratch_base() == (base / "workspaces").resolve()
|
|
manager._prefs["scratch_base"] = str(outside)
|
|
assert manager.scratch_base() == (base / "workspaces").resolve()
|
|
scratch = Path(manager._provision_scratch("s-confined"))
|
|
assert scratch.is_relative_to(base.resolve())
|
|
|
|
assert "only works under" in manager.add_root("s-confined", str(outside))["error"]
|
|
assert "only works under" in manager.promote_workspace("s-confined", str(outside))["error"]
|
|
assert "only works under" in manager.save_temp_as_project("s-confined", str(outside / "saved"))["error"]
|
|
|
|
|
|
def test_unconfined_manager_accepts_any_folder(tmp_path, monkeypatch):
|
|
monkeypatch.delenv("OPENWORKER_BASE_DIR", raising=False)
|
|
anywhere = tmp_path / "anywhere"
|
|
anywhere.mkdir()
|
|
manager = SessionManager(data_dir=tmp_path / "mgr")
|
|
assert manager.open_workspace(str(anywhere))["ok"] is True
|
|
|
|
|
|
def test_deployed_provider_key_adopts_a_runnable_default(tmp_path, monkeypatch):
|
|
"""A fresh box defaults to a model nobody can run; the first provider key
|
|
that arrives (by deploy, not just Settings) makes its recommended model
|
|
the default — a working default is never stolen."""
|
|
monkeypatch.delenv("OPENWORKER_BASE_DIR", raising=False)
|
|
monkeypatch.delenv("OPENAI_API_KEY", raising=False)
|
|
manager = SessionManager(data_dir=tmp_path / "mgr")
|
|
from coworker.secrets import SecretStore
|
|
|
|
manager.secrets = SecretStore(tmp_path / "secrets.json")
|
|
assert manager.get_settings()["model_ready"] is False
|
|
# The deploy path writes the profile then calls adopt — same as the joiner.
|
|
manager.secrets.put("provider:anthropic", {"api_key": "sk-ant-test"})
|
|
adopted = manager.adopt_provider_default("anthropic")
|
|
assert adopted and adopted.startswith("anthropic:")
|
|
s = manager.get_settings()
|
|
assert s["model"] == adopted and s["model_ready"] is True
|
|
# A second key does not steal a working default.
|
|
manager.secrets.put("provider:openai", {"api_key": "sk-test"})
|
|
assert manager.adopt_provider_default("openai") is None
|
|
assert manager.get_settings()["model"] == adopted
|
|
|
|
|
|
# -- store_managed_grant_bundle: the ONE staging routine (desktop + box) ------
|
|
|
|
|
|
def test_managed_grant_bundle_handles_every_family(tmp_path):
|
|
from coworker.connectors.setup import store_managed_grant_bundle
|
|
from coworker.secrets import SecretStore
|
|
|
|
grant = {"user_id": "usr_1", "machine_credential": "mc_1"}
|
|
# Generic (Notion-style, multi-account layer): stamps ride the profile.
|
|
s = SecretStore(tmp_path / "a.json")
|
|
out = store_managed_grant_bundle(s, "notion", {"provider": "notion", "connector": "notion", "connection_id": "conn_n", "access_token": "tok", "account": "Acme", "account_id": "ws_1"}, grant)
|
|
assert out.get("ok"), out
|
|
prof = s.get("notion:account:ws_1") or {}
|
|
assert prof["access_token"] == "tok" and prof["broker_user_id"] == "usr_1" and prof["machine_credential"] == "mc_1"
|
|
assert store_managed_grant_bundle(s, "notion", {"connector": "notion"}, grant)["ok"] is False
|
|
# GitHub: one profile per installation + pointer, all stamped, no tokens.
|
|
s = SecretStore(tmp_path / "b.json")
|
|
import json as _json
|
|
out = store_managed_grant_bundle(s, "github", {"connection_id": "conn_g", "installation_id": "1", "account_login": "a", "account_type": "User", "repo_selection": "all", "github_login": "me", "installations": _json.dumps([{"installation_id": "1", "account_login": "a", "account_type": "User", "repo_selection": "all"}, {"installation_id": "2", "account_login": "org", "account_type": "Organization", "repo_selection": "selected"}])}, grant)
|
|
assert out.get("ok"), out
|
|
for key in ("github:install:1", "github:install:2"):
|
|
p = s.get(key) or {}
|
|
assert p["connection_id"] == "conn_g" and p["broker_user_id"] == "usr_1" and p["machine_credential"] == "mc_1"
|
|
assert "access_token" not in p
|
|
assert (s.get("github:default") or {}).get("machine_credential") == "mc_1"
|
|
assert store_managed_grant_bundle(s, "github", {"connection_id": "x"}, grant)["ok"] is False
|
|
# Slack: per-workspace bot token + pointer, stamped.
|
|
s = SecretStore(tmp_path / "c.json")
|
|
out = store_managed_grant_bundle(s, "slack", {"connection_id": "conn_s", "access_token": "xoxb-1", "team_id": "T1", "team_domain": "acme", "bot_user_id": "B1", "slack_user_id": "U1", "account": "Acme"}, grant)
|
|
assert out.get("ok"), out
|
|
p = s.get("slack:team:T1") or {}
|
|
assert p.get("bot_token", p.get("access_token")) and p["machine_credential"] == "mc_1" and p["connection_id"] == "conn_s"
|
|
assert (s.get("slack:default") or {}).get("broker_user_id") == "usr_1"
|