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

+40 -2
View File
@@ -187,6 +187,23 @@ Index(
team_resource_grants_table.c.resource_id,
)
# Per-asset sharing switches set by the owner (migration 0038). A missing row
# means every switch is at its default; keys are validated in
# ``docsgpt/api/user/resource_access.py``.
resource_share_settings_table = Table(
"resource_share_settings",
metadata,
Column("resource_type", Text, primary_key=True),
Column("resource_id", UUID(as_uuid=True), primary_key=True),
Column("settings", JSONB, nullable=False, server_default="{}"),
Column("updated_by", Text),
Column("updated_at", DateTime(timezone=True), nullable=False, server_default=func.now()),
CheckConstraint(
"resource_type IN ('agent', 'source', 'prompt', 'tool')",
name="resource_share_settings_type_check",
),
)
prompts_table = Table(
"prompts",
@@ -223,6 +240,22 @@ user_tools_table = Table(
Column("credential_mode", Text, nullable=False, server_default="owner"),
)
# A grantee's personal "In my chats" switch for a tool shared with them
# (migration 0038). The owner's own switch stays ``user_tools.status``.
user_tool_preferences_table = Table(
"user_tool_preferences",
metadata,
Column("user_id", Text, primary_key=True),
Column(
"tool_id",
UUID(as_uuid=True),
ForeignKey("user_tools.id", ondelete="CASCADE"),
primary_key=True,
),
Column("in_chat", Boolean, nullable=False, server_default="false"),
Column("updated_at", DateTime(timezone=True), nullable=False, server_default=func.now()),
)
token_usage_table = Table(
"token_usage",
metadata,
@@ -377,6 +410,9 @@ agents_table = Table(
# Per-agent behavior contract (AgentConfig — guardrails today). Empty
# ``{}`` parses to guardrails-disabled.
Column("config", JSONB, nullable=False, server_default=text("'{}'::jsonb")),
# ``"<type>:<id>" -> user_id`` of the editor vouching for a referenced
# resource the owner can't use (migration 0039, see resource_access.py).
Column("resource_sponsors", JSONB, nullable=False, server_default=text("'{}'::jsonb")),
Column("default_model_id", Text),
Column("folder_id", UUID(as_uuid=True), ForeignKey("agent_folders.id", ondelete="SET NULL")),
Column("workflow_id", UUID(as_uuid=True), ForeignKey("workflows.id", ondelete="SET NULL")),
@@ -595,7 +631,7 @@ connector_sessions_table = Table(
Column("expires_at", DateTime(timezone=True)),
Column("created_at", DateTime(timezone=True), nullable=False, server_default=func.now()),
Column("legacy_mongo_id", Text),
# Added in ``0038_connections``: each row is a connection (one signed-in
# Added in ``0040_connections``: each row is a connection (one signed-in
# account, one MCP server or one set of API credentials).
Column("connector_key", Text),
Column("display_name", Text),
@@ -608,7 +644,7 @@ connector_sessions_table = Table(
Column("scopes", JSONB, nullable=False, server_default="[]"),
Column("last_error", Text),
Column("last_used_at", DateTime(timezone=True)),
# Added in ``0039_connection_account_name``: what the user calls the
# Added in ``0041_connection_account_name``: what the user calls the
# account; ``account_label`` stays its identity.
Column("account_name", Text),
)
@@ -963,6 +999,8 @@ workflows_table = Table(
Column("name", Text, nullable=False),
Column("description", Text),
Column("current_graph_version", Integer, nullable=False, server_default="1"),
# Same shape as ``agents.resource_sponsors``, for node tools and sources.
Column("resource_sponsors", JSONB, nullable=False, server_default=text("'{}'::jsonb")),
Column("created_at", DateTime(timezone=True), nullable=False, server_default=func.now()),
Column("updated_at", DateTime(timezone=True), nullable=False, server_default=func.now()),
Column("legacy_mongo_id", Text),