refactor: split mcp auth catalog stores

This commit is contained in:
lda
2026-06-06 19:07:10 +07:00 Verified
parent 4b7088726b
commit 79a3ee4c7a
18 changed files with 303 additions and 61 deletions
+34 -2
View File
@@ -6,8 +6,8 @@ from wf_authoring import NodeSpec
from wf_core import RunStatus
from wf_mcp.broker import WfMcpService
from wf_mcp.broker.service.source_catalog import SourceCatalogService
from wf_mcp.models import ConnectionConfig
from wf_mcp.storage import FileStore
from wf_mcp.models import CatalogSnapshot, ConnectionConfig
from wf_mcp.storage import FileCatalogStore, FileStore
from wf_platform import (
CapabilityBuckets,
CapabilitySource,
@@ -500,3 +500,35 @@ def test_source_catalog_finds_local_documentation_resource_directly() -> None:
assert result is not None
assert result.uri == test_resource.uri
def test_source_catalog_uses_catalog_store_only(tmp_path) -> None:
catalog_store = FileCatalogStore(tmp_path / "catalog")
service = SourceCatalogService(
store=catalog_store,
connection_lookup=lambda connection_id: ConnectionConfig(
id=connection_id,
server="demo",
account="personal",
),
connection_list_enabled=lambda: [],
connection_list_all=lambda: [],
tool_executor_for=lambda connection: (_ for _ in ()).throw(
AssertionError("unexpected executor")
),
load_auth=lambda connection: None,
emit_event=lambda event: None,
)
snapshot = CatalogSnapshot(
connection_id="demo.personal",
fetched_at_epoch_ms=1,
max_age_seconds=300,
nodes=[],
resources=[],
prompts=[],
metadata={},
)
service.store.save_catalog(snapshot)
assert service.store.load_catalog("demo.personal") == snapshot
assert (tmp_path / "catalog" / "catalog" / "demo.personal.json").exists()
+2 -1
View File
@@ -30,7 +30,8 @@ def _make_content_access(
events = BrokerEventRecorder(EventBus())
connection_service = ConnectionService(events=events)
upstream = UpstreamTransportService(
store=store,
auth_store=store,
catalog_store=store,
event_sink=events.record_event,
)
source_catalog = SourceCatalogService(
+49 -10
View File
@@ -8,8 +8,8 @@ from wf_mcp.broker.service.source_catalog import SourceCatalogService
from wf_mcp.broker.service.upstream_transport import UpstreamTransportService
from wf_mcp.connections import ConnectionRegistry
from wf_mcp.events import McpEvent
from wf_mcp.models import AuthRecord, ConnectionConfig
from wf_mcp.storage import FileStore
from wf_mcp.models import AuthRecord, CatalogSnapshot, ConnectionConfig
from wf_mcp.storage import FileAuthStore, FileCatalogStore, FileStore
from wf_platform import CapabilityBuckets, CapabilitySource, SourcePermissions
from ..test_support import FakeAdapter, local_temp_root
@@ -19,7 +19,8 @@ from ..workflow_surface.conftest import echo_artifact
def _transport(root: Path) -> UpstreamTransportService:
events: list[McpEvent] = []
return UpstreamTransportService(
store=FileStore(root),
auth_store=FileStore(root),
catalog_store=FileStore(root),
event_sink=events.append,
)
@@ -27,7 +28,8 @@ def _transport(root: Path) -> UpstreamTransportService:
def test_upstream_transport_registers_adapter() -> None:
events: list[McpEvent] = []
transport = UpstreamTransportService(
store=FileStore(local_temp_root() / "upstream_adapter"),
auth_store=FileStore(local_temp_root() / "upstream_adapter"),
catalog_store=FileStore(local_temp_root() / "upstream_adapter"),
event_sink=events.append,
)
adapter = FakeAdapter()
@@ -40,7 +42,8 @@ def test_upstream_transport_registers_adapter() -> None:
def test_upstream_transport_saves_and_loads_auth_with_event() -> None:
events: list[McpEvent] = []
transport = UpstreamTransportService(
store=FileStore(local_temp_root() / "upstream_auth"),
auth_store=FileStore(local_temp_root() / "upstream_auth"),
catalog_store=FileStore(local_temp_root() / "upstream_auth"),
event_sink=events.append,
)
record = AuthRecord(connection_id="demo.personal", scheme="bearer")
@@ -74,7 +77,8 @@ async def test_upstream_transport_invokes_raw_method_and_records_events() -> Non
ConnectionConfig(id="demo.personal", server="demo", account="personal")
)
transport = UpstreamTransportService(
store=FileStore(local_temp_root() / "upstream_raw_method"),
auth_store=FileStore(local_temp_root() / "upstream_raw_method"),
catalog_store=FileStore(local_temp_root() / "upstream_raw_method"),
event_sink=events.append,
)
transport.register_adapter("demo", FakeAdapter())
@@ -98,7 +102,11 @@ async def test_upstream_transport_refreshes_catalog_directly() -> None:
connections = ConnectionRegistry()
connection = ConnectionConfig(id="demo.personal", server="demo", account="personal")
connections.register(connection)
transport = UpstreamTransportService(store=store, event_sink=events.append)
transport = UpstreamTransportService(
auth_store=store,
catalog_store=store,
event_sink=events.append,
)
transport.register_adapter("demo", FakeAdapter())
source_catalog = SourceCatalogService(
store=store,
@@ -126,7 +134,8 @@ async def test_upstream_transport_refreshes_catalog_directly() -> None:
async def test_upstream_transport_live_diagnostics_report_missing_connection() -> None:
transport = UpstreamTransportService(
store=FileStore(local_temp_root() / "upstream_live_missing"),
auth_store=FileStore(local_temp_root() / "upstream_live_missing"),
catalog_store=FileStore(local_temp_root() / "upstream_live_missing"),
event_sink=lambda event: None,
)
@@ -134,7 +143,7 @@ async def test_upstream_transport_live_diagnostics_report_missing_connection() -
raise KeyError(connection_id)
source_catalog = SourceCatalogService(
store=transport.store,
store=transport.catalog_store,
connection_lookup=_raise_missing_connection,
connection_list_enabled=lambda: [],
connection_list_all=lambda: [],
@@ -260,7 +269,11 @@ async def test_upstream_transport_live_diagnostics_report_missing_auth_ref(
metadata={"auth_ref": "github.creds"},
)
connections.register(connection)
transport = UpstreamTransportService(store=store, event_sink=events.append)
transport = UpstreamTransportService(
auth_store=store,
catalog_store=store,
event_sink=events.append,
)
transport.register_adapter("demo", FakeAdapter())
source_catalog = SourceCatalogService(
store=store,
@@ -296,3 +309,29 @@ async def test_upstream_transport_live_diagnostics_report_missing_auth_ref(
assert diagnostics[0].code == "auth_not_found"
assert diagnostics[0].bound_source == "github.work"
assert "github.creds" in diagnostics[0].message
def test_upstream_transport_uses_separate_auth_and_catalog_stores(tmp_path) -> None:
auth_store = FileAuthStore(tmp_path / "auth")
catalog_store = FileCatalogStore(tmp_path / "catalog")
events = []
transport = UpstreamTransportService(
auth_store=auth_store,
catalog_store=catalog_store,
event_sink=events.append,
)
record = AuthRecord(connection_id="demo.personal", scheme="bearer")
transport.save_auth(record)
snapshot = CatalogSnapshot(
connection_id="demo.personal",
fetched_at_epoch_ms=1,
max_age_seconds=300,
nodes=[],
resources=[],
prompts=[],
metadata={},
)
transport.catalog_store.save_catalog(snapshot)
assert (tmp_path / "auth" / "auth" / "demo.personal.json").exists()
assert (tmp_path / "catalog" / "catalog" / "demo.personal.json").exists()