Files
dify/api/services/trigger/subscription_query_service.py
T

97 lines
3.8 KiB
Python

"""Read visible trigger subscriptions and mask their credentials outside the query transaction."""
from collections.abc import Mapping
from dataclasses import dataclass
from typing import Protocol
from core.entities.provider_entities import BasicProviderConfig
from core.helper.provider_encryption import create_provider_encrypter
from core.plugin.entities.plugin_daemon import CredentialType
from core.trigger.entities.api_entities import TriggerProviderSubscriptionApiEntity
from core.trigger.utils.encryption import TriggerProviderCredentialsCache, TriggerProviderPropertiesCache
from core.trigger.utils.endpoint import generate_plugin_trigger_endpoint_url
from models.provider_ids import TriggerProviderID
from services.credentials.query import CredentialQuery
@dataclass(frozen=True, slots=True)
class TriggerSubscriptionSchemas:
credentials: Mapping[CredentialType, list[BasicProviderConfig]]
properties: list[BasicProviderConfig]
class TriggerSubscriptionSchemaQuery(Protocol):
def get_subscription_schemas(
self,
*,
tenant_id: str,
provider_id: TriggerProviderID,
credential_types: frozenset[CredentialType],
) -> TriggerSubscriptionSchemas: ...
class TriggerSubscriptionQueryService:
"""Compose visible records with plugin schemas after the read session closes.
Credential decryption and caching remain with the shared encryption helpers.
"""
def __init__(self, *, credentials: CredentialQuery, schemas: TriggerSubscriptionSchemaQuery) -> None:
self._credentials = credentials
self._schemas = schemas
def list(
self, *, tenant_id: str, account_id: str, provider_id: TriggerProviderID
) -> list[TriggerProviderSubscriptionApiEntity]:
rows = self._credentials.list_trigger_subscriptions(
workspace_id=tenant_id,
provider=str(provider_id),
actor_id=account_id,
)
if not rows:
return []
schemas = self._schemas.get_subscription_schemas(
tenant_id=tenant_id,
provider_id=provider_id,
credential_types=frozenset(row.credential_type for row in rows),
)
subscriptions: list[TriggerProviderSubscriptionApiEntity] = []
for row in rows:
credential_encrypter, _ = create_provider_encrypter(
tenant_id=tenant_id,
config=schemas.credentials[row.credential_type],
cache=TriggerProviderCredentialsCache(
tenant_id=tenant_id,
provider_id=str(provider_id),
credential_id=row.id,
),
)
properties_encrypter, _ = create_provider_encrypter(
tenant_id=tenant_id,
config=schemas.properties,
cache=TriggerProviderPropertiesCache(
tenant_id=tenant_id,
provider_id=str(provider_id),
subscription_id=row.id,
),
)
subscriptions.append(
TriggerProviderSubscriptionApiEntity(
id=row.id,
name=row.name,
provider=row.provider,
credential_type=row.credential_type,
credentials=dict(
credential_encrypter.mask_credentials(credential_encrypter.decrypt(row.credentials))
),
endpoint=generate_plugin_trigger_endpoint_url(row.endpoint_id),
parameters=dict(row.parameters),
properties=dict(
properties_encrypter.mask_credentials(properties_encrypter.decrypt(row.properties))
),
workflows_in_use=row.workflows_in_use,
)
)
return subscriptions