Publish curated ITWorx_MCP_Hub source from 6c7434368ce2a594005983c5a6601a31a639e7f1
This commit is contained in:
1 parent
77946d62c4
commit
6d40ab975c
86 files changed
+6784
-1478
No files matched your search
@@ -0,0 +1,194 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
from uuid import uuid4
|
||||
|
||||
from services.control_api.persistence import create_engine_from_url, session_factory
|
||||
from services.control_api.persistence.models import (
|
||||
AuditEventRow,
|
||||
EnvironmentRow,
|
||||
ProjectRow,
|
||||
WorkspaceRow,
|
||||
)
|
||||
from tests.test_wp230_rbac import ManagementRole, RoleSession
|
||||
|
||||
pytest_plugins = ("tests.test_wp230_rbac",)
|
||||
|
||||
|
||||
def test_resource_search_matches_connector_slug(
|
||||
role_sessions: dict[ManagementRole, RoleSession],
|
||||
) -> None:
|
||||
response = role_sessions[ManagementRole.VIEWER].get(
|
||||
"/api/connectors", params={"q": "knowledge-default"}
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
body = response.json()
|
||||
assert [row["id"] for row in body["rows"]] == ["knowledge-default"]
|
||||
|
||||
|
||||
def test_project_scoped_connector_search_uses_bindings_and_environment(
|
||||
role_sessions: dict[ManagementRole, RoleSession],
|
||||
) -> None:
|
||||
viewer = role_sessions[ManagementRole.VIEWER]
|
||||
response = viewer.get(
|
||||
"/api/connectors",
|
||||
params={
|
||||
"project": "ludarium",
|
||||
"environment": "prod",
|
||||
"q": "knowledge-default",
|
||||
},
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
rows = response.json()["rows"]
|
||||
assert len(rows) == 1
|
||||
assert rows[0]["id"] == "knowledge-default"
|
||||
assert rows[0]["project"] == "ludarium"
|
||||
assert rows[0]["environment"] == "prod"
|
||||
assert not any("url" in key.casefold() for key in rows[0])
|
||||
|
||||
unbound_project = viewer.get(
|
||||
"/api/connectors",
|
||||
params={
|
||||
"project": "mobilityops",
|
||||
"environment": "prod",
|
||||
"q": "knowledge-default",
|
||||
},
|
||||
)
|
||||
assert unbound_project.status_code == 200
|
||||
assert unbound_project.json()["rows"] == []
|
||||
|
||||
|
||||
def test_resource_search_matches_tool_canonical_name(
|
||||
role_sessions: dict[ManagementRole, RoleSession],
|
||||
) -> None:
|
||||
response = role_sessions[ManagementRole.VIEWER].get(
|
||||
"/api/tools", params={"q": "deployment.project.status"}
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
body = response.json()
|
||||
assert [row["canonicalName"] for row in body["rows"]] == ["deployment.project.status"]
|
||||
|
||||
|
||||
def test_project_scoped_tool_search_uses_bindings_and_capability_packs(
|
||||
role_sessions: dict[ManagementRole, RoleSession],
|
||||
) -> None:
|
||||
viewer = role_sessions[ManagementRole.VIEWER]
|
||||
|
||||
ludarium_tools = viewer.get(
|
||||
"/api/tools",
|
||||
params={"project": "ludarium", "limit": 100},
|
||||
)
|
||||
assert ludarium_tools.status_code == 200
|
||||
ludarium_body = ludarium_tools.json()
|
||||
ludarium_rows = ludarium_body["rows"]
|
||||
assert ludarium_body["page"]["total"] == len(ludarium_rows)
|
||||
ludarium_names = {row["canonicalName"] for row in ludarium_rows}
|
||||
assert "deployment.project.status" in ludarium_names
|
||||
assert "gitea.branch.delete" not in ludarium_names
|
||||
assert all(row["project"] == "ludarium" for row in ludarium_rows)
|
||||
assert all(row["environment"] == "prod" for row in ludarium_rows)
|
||||
|
||||
unbound_connector = viewer.get(
|
||||
"/api/tools",
|
||||
params={
|
||||
"project": "mobilityops",
|
||||
"environment": "prod",
|
||||
"q": "deployment.project.status",
|
||||
},
|
||||
)
|
||||
assert unbound_connector.status_code == 200
|
||||
assert unbound_connector.json()["rows"] == []
|
||||
|
||||
environment_without_server = viewer.get(
|
||||
"/api/tools",
|
||||
params={
|
||||
"project": "forgeflow",
|
||||
"environment": "dev",
|
||||
"q": "deployment.project.status",
|
||||
},
|
||||
)
|
||||
assert environment_without_server.status_code == 200
|
||||
assert environment_without_server.json()["rows"] == []
|
||||
|
||||
|
||||
def test_audit_search_matches_trace_id_without_exposing_search_to_viewers(
|
||||
role_sessions: dict[ManagementRole, RoleSession], db_path: Path
|
||||
) -> None:
|
||||
trace_id = f"operator-search-{uuid4()}"
|
||||
engine = create_engine_from_url(f"sqlite:///{db_path}")
|
||||
sessions = session_factory(engine)
|
||||
with sessions() as session, session.begin():
|
||||
workspace = session.query(WorkspaceRow).filter_by(slug="itworx").one()
|
||||
project = session.query(ProjectRow).filter_by(slug="ludarium").one()
|
||||
environment = (
|
||||
session.query(EnvironmentRow).filter_by(project_id=project.id, name="prod").one()
|
||||
)
|
||||
session.add(
|
||||
AuditEventRow(
|
||||
trace_id=trace_id,
|
||||
workspace_id=workspace.id,
|
||||
project_id=project.id,
|
||||
environment_id=environment.id,
|
||||
event_type="operator.search.fixture",
|
||||
tool_name="operator.search.fixture",
|
||||
policy_decision="must-not-be-a-search-field",
|
||||
outcome="success",
|
||||
)
|
||||
)
|
||||
engine.dispose()
|
||||
|
||||
auditor = role_sessions[ManagementRole.AUDITOR]
|
||||
matching = auditor.get("/api/audit", params={"q": trace_id})
|
||||
assert matching.status_code == 200
|
||||
assert [row["traceId"] for row in matching.json()["rows"]] == [trace_id]
|
||||
|
||||
excluded_field = auditor.get("/api/audit", params={"q": "must-not-be-a-search-field"})
|
||||
assert excluded_field.status_code == 200
|
||||
assert excluded_field.json()["rows"] == []
|
||||
|
||||
denied = role_sessions[ManagementRole.VIEWER].get("/api/audit", params={"q": trace_id})
|
||||
assert denied.status_code == 403
|
||||
|
||||
|
||||
def test_servers_list_virtual_server_identities_and_apply_project_environment_scope(
|
||||
role_sessions: dict[ManagementRole, RoleSession],
|
||||
) -> None:
|
||||
viewer = role_sessions[ManagementRole.VIEWER]
|
||||
|
||||
scoped = viewer.get(
|
||||
"/api/servers",
|
||||
params={"project": "forgeflow", "environment": "prod", "limit": 1},
|
||||
)
|
||||
assert scoped.status_code == 200
|
||||
scoped_body = scoped.json()
|
||||
assert scoped_body["page"]["total"] == 1
|
||||
assert scoped_body["rows"] == [
|
||||
{
|
||||
"id": "forgeflow-prod-readonly",
|
||||
"name": "forgeflow-prod-readonly",
|
||||
"status": "unknown",
|
||||
"summary": "Catalog registered; live runtime health has not been observed.",
|
||||
"project": "forgeflow",
|
||||
"environment": "prod",
|
||||
"risk": None,
|
||||
"canonicalName": None,
|
||||
}
|
||||
]
|
||||
|
||||
wrong_environment = viewer.get(
|
||||
"/api/servers", params={"project": "forgeflow", "environment": "dev"}
|
||||
)
|
||||
assert wrong_environment.status_code == 200
|
||||
assert wrong_environment.json()["page"]["total"] == 0
|
||||
assert wrong_environment.json()["rows"] == []
|
||||
|
||||
wrong_project = viewer.get(
|
||||
"/api/servers",
|
||||
params={"project": "mobilityops", "environment": "prod", "q": "forgeflow-prod-readonly"},
|
||||
)
|
||||
assert wrong_project.status_code == 200
|
||||
assert wrong_project.json()["page"]["total"] == 0
|
||||
assert wrong_project.json()["rows"] == []
|
||||
Reference in new issue
Block a user