Merge main (roles and access revamp) into connectors

Main's access model (team editors and viewers, edit_credentials, owner-only
OAuth servers, per-user tool preferences, resource sponsors) now applies to
connection-backed tools and sources. Our migrations are renumbered to
0040_connections and 0041_connection_account_name, after main's
0038_resource_access_settings and 0039_resource_sponsors.

Where the two sides met: MCP tools save and load their connections as the
tool owner, editors may add a key (a new connection on the owner's account)
but never rewrite an existing connection's secret, fixed values stay
owner-only, and a member's own connection is used in member mode.
This commit is contained in:
arc53-machine committed 2026-09-29 14:02:26 +01:00
commit a1789d2ab4
167 files changed
+16909 -2126

No files matched your search

@@ -49,6 +49,12 @@ class TestCreate:
)
assert doc["legacy_mongo_id"] == "507f1f77bcf86cd799439011"
def test_create_with_resource_sponsors(self, pg_conn):
repo = _repo(pg_conn)
sponsors = {"tool:t1": "editor-1"}
doc = repo.create("u", "a", "draft", resource_sponsors=sponsors)
assert doc["resource_sponsors"] == sponsors
def test_create_normalizes_blank_key_to_null(self, pg_conn):
repo = _repo(pg_conn)
doc = repo.create("u", "a", "draft", key="")
@@ -1,4 +1,4 @@
"""Migration tests for 0038_connections: columns, backfill and round trip."""
"""Migration tests for 0040_connections: columns, backfill and round trip."""
from __future__ import annotations
@@ -14,7 +14,7 @@ from sqlalchemy import text
pytestmark = pytest.mark.integration
_0037 = "0037_request_traces"
_0037 = "0039_resource_sponsors" # the revision before 0040_connections
def _alembic_ini() -> Path:
@@ -38,7 +38,7 @@ def _columns(conn, table: str) -> set[str]:
def _seed_legacy(conn) -> dict:
"""Rows as a pre-0038 install left them."""
"""Rows as a pre-0040 install left them."""
ids = {}
ids["drive"] = conn.execute(
text(
@@ -87,7 +87,7 @@ def _seed_legacy(conn) -> dict:
return ids
class TestMigration0038:
class TestMigration0040:
def test_head_has_connection_columns(self, pg_engine):
with pg_engine.connect() as conn:
assert {"connector_key", "display_name", "account_label", "auth_kind", "updated_at"} <= _columns(
@@ -156,7 +156,7 @@ class TestMigration0038:
def _seed_secrets(conn) -> dict:
"""Plaintext tokens and v1 tool secrets, as a pre-0038 install stored them."""
"""Plaintext tokens and v1 tool secrets, as a pre-0040 install stored them."""
from docsgpt.security.encryption import encrypt_credentials
ids = {}
@@ -210,7 +210,7 @@ def _seed_secrets(conn) -> dict:
return ids
class TestMigration0038Credentials:
class TestMigration0040Credentials:
def _upgrade_with(self, pg_engine, seed):
url = pg_engine.url.render_as_string(hide_password=False)
_run_alembic(url, "downgrade", _0037)
@@ -1,4 +1,4 @@
"""Migration round-trip test for 0039_connection_account_name."""
"""Migration round-trip test for 0041_connection_account_name."""
from __future__ import annotations
@@ -13,8 +13,8 @@ from sqlalchemy import text
pytestmark = pytest.mark.integration
_0039 = "0039_connection_account_name"
_0038 = "0038_connections"
_0039 = "0041_connection_account_name"
_0038 = "0040_connections"
def _run_alembic(url: str, *args: str) -> None:
@@ -35,7 +35,7 @@ def _has_column(conn) -> bool:
).fetchone() is not None
class TestMigration0039RoundTrip:
class TestMigration0041RoundTrip:
def test_head_has_account_name(self, pg_engine):
with pg_engine.connect() as conn:
assert _has_column(conn)