Files
ITWorx_MCP_Hub-Public/tests/test_machine_client_provisioning.py
T

226 lines
8.5 KiB
Python

from __future__ import annotations
from uuid import uuid4
import pytest
from packages.hub_clients import ClientKind, generate_config
from services.control_api.persistence.db import Base, create_engine_from_url, session_factory
from services.control_api.persistence.machine_client import provision_machine_client
from services.control_api.persistence.models import (
ClientBindingRow,
ClientRow,
EnvironmentRow,
ProjectRow,
VirtualServerRow,
WorkspaceRow,
)
from services.runtime.client_service import PersistentClientService
@pytest.fixture
def database(): # type: ignore[no-untyped-def]
engine = create_engine_from_url("sqlite:///:memory:")
Base.metadata.create_all(engine)
sessions = session_factory(engine)
workspace_id, project_id, environment_id = uuid4(), uuid4(), uuid4()
with sessions() as session, session.begin():
session.add(WorkspaceRow(id=workspace_id, slug="itworx", name="ITWorx"))
session.flush()
session.add(
ProjectRow(
id=project_id,
workspace_id=workspace_id,
slug="ludarium",
name="Ludarium",
)
)
session.flush()
session.add(
EnvironmentRow(
id=environment_id,
workspace_id=workspace_id,
project_id=project_id,
name="prod",
classification="production",
)
)
session.flush()
session.add(
VirtualServerRow(
workspace_id=workspace_id,
project_id=project_id,
environment_id=environment_id,
slug="ludarium-prod-readonly",
desired_hash="a" * 64,
enabled=True,
gateway_external_id="a" * 32,
)
)
yield sessions
engine.dispose()
def _provision(sessions): # type: ignore[no-untyped-def]
with sessions() as session, session.begin():
return provision_machine_client(
session,
issuer="https://auth.itworx.test/application/o/itworx-mcp-hub/",
subject="6f865098-6d67-4ee6-b0fe-b0173cc74e23",
oauth_username="svc-mcp-codex-ludarium",
name="Codex workstation",
project_slug="ludarium",
)
def test_real_machine_client_provisioning_is_idempotent_and_project_bound(database) -> None: # type: ignore[no-untyped-def]
first = _provision(database)
second = _provision(database)
assert first == second
assert first.endpoint == "https://mcp.example.com/mcp/ludarium/prod"
with database() as session:
client = session.get(ClientRow, first.client_id)
binding = session.get(ClientBindingRow, first.binding_id)
assert client is not None and binding is not None
assert client.status == "active"
assert client.record_metadata["identityProvisioned"] is True
assert binding.enabled is True
def test_real_machine_client_fails_closed_on_ambiguous_route(database) -> None: # type: ignore[no-untyped-def]
with database() as session, session.begin():
project = session.query(ProjectRow).filter_by(slug="ludarium").one()
environment = session.query(EnvironmentRow).filter_by(name="prod").one()
session.add(
VirtualServerRow(
workspace_id=project.workspace_id,
project_id=project.id,
environment_id=environment.id,
slug="ludarium-prod-other",
desired_hash="b" * 64,
enabled=True,
gateway_external_id="b" * 32,
)
)
with pytest.raises(ValueError, match="not uniquely determined"):
_provision(database)
def test_revoked_machine_client_cannot_be_silently_reactivated(database) -> None: # type: ignore[no-untyped-def]
result = _provision(database)
with database() as session, session.begin():
client = session.get(ClientRow, result.client_id)
assert client is not None
client.status = "revoked"
with pytest.raises(ValueError, match="cannot be reprovisioned"):
_provision(database)
@pytest.mark.parametrize("profile", [*ClientKind, None])
def test_pending_ui_client_is_activated_in_place_with_selected_profile(
database, profile: ClientKind | None
) -> None: # type: ignore[no-untyped-def]
pending_id = uuid4()
expected_profile = profile or ClientKind.STDIO_BRIDGE
metadata = {
"managedBy": "runtime-onboarding",
"project": "ludarium",
"environment": "prod",
}
if profile is not None:
metadata["kind"] = profile.value
with database() as session, session.begin():
workspace = session.query(WorkspaceRow).filter_by(slug="itworx").one()
project = session.query(ProjectRow).filter_by(slug="ludarium").one()
server = session.query(VirtualServerRow).filter_by(slug="ludarium-prod-readonly").one()
session.add(
ClientRow(
id=pending_id,
workspace_id=workspace.id,
subject=f"pending-{pending_id}",
issuer="https://auth.itworx.test/application/o/itworx-mcp-hub/",
status="pending",
record_metadata=metadata,
)
)
session.flush()
session.add(
ClientBindingRow(
workspace_id=workspace.id,
project_id=project.id,
client_id=pending_id,
virtual_server_id=server.id,
enabled=False,
)
)
with database() as session, session.begin():
result = provision_machine_client(
session,
issuer="https://auth.itworx.test/application/o/itworx-mcp-hub/",
subject="b7f5d1aa-f199-4334-b077-f6be0870115f",
oauth_username="svc-mcp-codex-ludarium",
name="Codex workstation",
project_slug="ludarium",
client_id=pending_id,
)
assert result.client_id == pending_id
with database() as session:
client = session.get(ClientRow, pending_id)
binding = session.get(ClientBindingRow, result.binding_id)
assert client is not None and binding is not None
assert client.status == "active"
assert client.subject == "b7f5d1aa-f199-4334-b077-f6be0870115f"
assert binding.enabled is True
assert client.record_metadata["kind"] == expected_profile.value
assert generate_config(PersistentClientService._record(client)).kind is expected_profile
def test_pending_ui_client_rejects_unknown_profile(database) -> None: # type: ignore[no-untyped-def]
pending_id = uuid4()
with database() as session, session.begin():
workspace = session.query(WorkspaceRow).filter_by(slug="itworx").one()
project = session.query(ProjectRow).filter_by(slug="ludarium").one()
server = session.query(VirtualServerRow).filter_by(slug="ludarium-prod-readonly").one()
session.add(
ClientRow(
id=pending_id,
workspace_id=workspace.id,
subject=f"pending-{pending_id}",
issuer="https://auth.itworx.test/application/o/itworx-mcp-hub/",
status="pending",
record_metadata={
"managedBy": "runtime-onboarding",
"project": "ludarium",
"environment": "prod",
"kind": "arbitrary-profile",
},
)
)
session.flush()
session.add(
ClientBindingRow(
workspace_id=workspace.id,
project_id=project.id,
client_id=pending_id,
virtual_server_id=server.id,
enabled=False,
)
)
with database() as session:
with pytest.raises(ValueError, match="invalid client kind"):
with session.begin():
provision_machine_client(
session,
issuer="https://auth.itworx.test/application/o/itworx-mcp-hub/",
subject="b7f5d1aa-f199-4334-b077-f6be0870115f",
oauth_username="svc-mcp-codex-ludarium",
name="Codex workstation",
project_slug="ludarium",
client_id=pending_id,
)
with database() as session:
client = session.get(ClientRow, pending_id)
assert client is not None
assert client.status == "pending"
assert client.record_metadata["kind"] == "arbitrary-profile"