Merge branch 'int' of ssh://git.poweron.swiss:2222/PowerOn/platform-core into int
This commit is contained in:
commit
f766219d4b
4 changed files with 45 additions and 9 deletions
|
|
@ -15,6 +15,15 @@ from modules.connectors.connectorProviderBase import ProviderConnector, ServiceA
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def _connection_uuid(connection: Any) -> str:
|
||||||
|
"""Resolve UserConnection primary key (tokens are stored by UUID, not reference string)."""
|
||||||
|
if connection is None:
|
||||||
|
return ""
|
||||||
|
if isinstance(connection, dict):
|
||||||
|
return str(connection.get("id") or "").strip()
|
||||||
|
return str(getattr(connection, "id", None) or "").strip()
|
||||||
|
|
||||||
|
|
||||||
class ConnectorResolver:
|
class ConnectorResolver:
|
||||||
"""Resolves connectionId → ProviderConnector (with fresh token) → ServiceAdapter."""
|
"""Resolves connectionId → ProviderConnector (with fresh token) → ServiceAdapter."""
|
||||||
|
|
||||||
|
|
@ -79,9 +88,16 @@ class ConnectorResolver:
|
||||||
if not providerClass:
|
if not providerClass:
|
||||||
raise ValueError(f"No ProviderConnector registered for authority: {authorityStr}")
|
raise ValueError(f"No ProviderConnector registered for authority: {authorityStr}")
|
||||||
|
|
||||||
token = self._security.getFreshToken(connectionId)
|
resolved_id = _connection_uuid(connection)
|
||||||
|
if not resolved_id:
|
||||||
|
raise ValueError(f"Connection {connectionId} has no id")
|
||||||
|
|
||||||
|
token = self._security.getFreshToken(resolved_id)
|
||||||
if not token or not token.tokenAccess:
|
if not token or not token.tokenAccess:
|
||||||
raise ValueError(f"No valid token for connection {connectionId}")
|
raise ValueError(
|
||||||
|
f"No valid token for connection {resolved_id}"
|
||||||
|
+ (f" (ref: {connectionId})" if connectionId != resolved_id else "")
|
||||||
|
)
|
||||||
|
|
||||||
return providerClass(connection, token.tokenAccess)
|
return providerClass(connection, token.tokenAccess)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -78,8 +78,8 @@ CLICKUP_NODES = [
|
||||||
{"name": "page", "type": "int", "required": False, "frontendType": "number",
|
{"name": "page", "type": "int", "required": False, "frontendType": "number",
|
||||||
"description": t("Seite"), "default": 0},
|
"description": t("Seite"), "default": 0},
|
||||||
{"name": "listId", "type": "str", "required": False, "frontendType": "clickupList",
|
{"name": "listId", "type": "str", "required": False, "frontendType": "clickupList",
|
||||||
"frontendOptions": {"dependsOn": "connectionReference"},
|
"frontendOptions": {"dependsOn": "connectionReference", "patchTeamId": True},
|
||||||
"description": t("In dieser Liste suchen")},
|
"description": t("Liste (optional — schränkt die Suche ein)")},
|
||||||
{"name": "includeClosed", "type": "bool", "required": False, "frontendType": "checkbox",
|
{"name": "includeClosed", "type": "bool", "required": False, "frontendType": "checkbox",
|
||||||
"description": t("Erledigte einbeziehen"), "default": False},
|
"description": t("Erledigte einbeziehen"), "default": False},
|
||||||
{"name": "fullTaskData", "type": "bool", "required": False, "frontendType": "checkbox",
|
{"name": "fullTaskData", "type": "bool", "required": False, "frontendType": "checkbox",
|
||||||
|
|
@ -106,7 +106,7 @@ CLICKUP_NODES = [
|
||||||
"description": t("ClickUp-Verbindung")},
|
"description": t("ClickUp-Verbindung")},
|
||||||
{"name": "pathQuery", "type": "str", "required": True, "frontendType": "clickupList",
|
{"name": "pathQuery", "type": "str", "required": True, "frontendType": "clickupList",
|
||||||
"frontendOptions": {"dependsOn": "connectionReference"},
|
"frontendOptions": {"dependsOn": "connectionReference"},
|
||||||
"description": t("Pfad zur Liste")},
|
"description": t("Liste")},
|
||||||
{"name": "page", "type": "int", "required": False, "frontendType": "number",
|
{"name": "page", "type": "int", "required": False, "frontendType": "number",
|
||||||
"description": t("Seite"), "default": 0},
|
"description": t("Seite"), "default": 0},
|
||||||
{"name": "includeClosed", "type": "bool", "required": False, "frontendType": "checkbox",
|
{"name": "includeClosed", "type": "bool", "required": False, "frontendType": "checkbox",
|
||||||
|
|
@ -151,11 +151,9 @@ CLICKUP_NODES = [
|
||||||
{"name": "connectionReference", "type": "str", "required": True, "frontendType": "userConnection",
|
{"name": "connectionReference", "type": "str", "required": True, "frontendType": "userConnection",
|
||||||
"frontendOptions": {"authority": "clickup"},
|
"frontendOptions": {"authority": "clickup"},
|
||||||
"description": t("ClickUp-Verbindung")},
|
"description": t("ClickUp-Verbindung")},
|
||||||
{"name": "pathQuery", "type": "str", "required": False, "frontendType": "clickupList",
|
{"name": "pathQuery", "type": "str", "required": True, "frontendType": "clickupList",
|
||||||
"frontendOptions": {"dependsOn": "connectionReference"},
|
"frontendOptions": {"dependsOn": "connectionReference"},
|
||||||
"description": t("Pfad zur Liste")},
|
"description": t("Liste")},
|
||||||
{"name": "listId", "type": "str", "required": False, "frontendType": "text",
|
|
||||||
"description": t("Listen-ID")},
|
|
||||||
{"name": "name", "type": "str", "required": True, "frontendType": "text",
|
{"name": "name", "type": "str", "required": True, "frontendType": "text",
|
||||||
"description": t("Name")},
|
"description": t("Name")},
|
||||||
{"name": "description", "type": "str", "required": False, "frontendType": "textarea",
|
{"name": "description", "type": "str", "required": False, "frontendType": "textarea",
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,12 @@ router = APIRouter(
|
||||||
|
|
||||||
|
|
||||||
def _getUserConnection(interface, connection_id: str, user_id: str) -> Optional[UserConnection]:
|
def _getUserConnection(interface, connection_id: str, user_id: str) -> Optional[UserConnection]:
|
||||||
|
"""Resolve by UUID or connection:authority:username (same as browse / workflow)."""
|
||||||
try:
|
try:
|
||||||
|
if hasattr(interface, "getUserConnectionById"):
|
||||||
|
conn = interface.getUserConnectionById(connection_id)
|
||||||
|
if conn is not None:
|
||||||
|
return conn
|
||||||
connections = interface.getUserConnections(user_id)
|
connections = interface.getUserConnections(user_id)
|
||||||
for conn in connections:
|
for conn in connections:
|
||||||
if conn.id == connection_id:
|
if conn.id == connection_id:
|
||||||
|
|
|
||||||
17
tests/unit/connectors/test_connectorResolver.py
Normal file
17
tests/unit/connectors/test_connectorResolver.py
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
# Copyright (c) 2025 Patrick Motsch
|
||||||
|
from types import SimpleNamespace
|
||||||
|
|
||||||
|
from modules.connectors.connectorResolver import _connection_uuid
|
||||||
|
|
||||||
|
|
||||||
|
def test_connection_uuid_from_model():
|
||||||
|
conn = SimpleNamespace(id="uuid-123")
|
||||||
|
assert _connection_uuid(conn) == "uuid-123"
|
||||||
|
|
||||||
|
|
||||||
|
def test_connection_uuid_from_dict():
|
||||||
|
assert _connection_uuid({"id": "uuid-456"}) == "uuid-456"
|
||||||
|
|
||||||
|
|
||||||
|
def test_connection_uuid_from_reference_string_returns_empty():
|
||||||
|
assert _connection_uuid("connection:clickup:Stephan Schellworth") == ""
|
||||||
Loading…
Reference in a new issue