Files
tracer-cloud--opensre/platform/scheduler/credentials.py
T
wehub-resource-sync 4b6817381b
CI (OpenClaw E2E) / openclaw test (push) Has been cancelled
CI / coverage-report (push) Has been cancelled
CI / test-kubernetes (push) Has been cancelled
CI / should-run-thorough (push) Has been cancelled
CI / test-thorough (cloudwatch-demo) (push) Has been cancelled
CI / test-thorough (flink-ecs) (push) Has been cancelled
CI / test-thorough (upstream-lambda) (push) Has been cancelled
CI / test-thorough (prefect-ecs-fargate) (push) Has been cancelled
Release / build-binaries (zip, opensre.exe, onefile, windows-latest, windows-x64) (push) Has been cancelled
Benchmark image — build + push to ECR (any adapter) / build + push (push) Has been cancelled
CI / quality (ubuntu-latest) (push) Has been cancelled
CI / test (tools-runtime) (push) Has been cancelled
CI / test (e2e-general) (push) Has been cancelled
CI / test (cli-runtime) (push) Has been cancelled
CI / test (e2e-provider-and-openclaw) (push) Has been cancelled
CI / test (integrations-and-misc) (push) Has been cancelled
Release / verify (push) Has been cancelled
Release / build-python-dist (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, macos-15-intel, darwin-x64) (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, macos-latest, darwin-arm64) (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04, linux-x64) (push) Has been cancelled
Release / publish-release (push) Has been cancelled
Release / publish-main-release (push) Has been cancelled
Interactive Shell Live (PR + post-merge) / turn-checks (no-LLM) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Interactive Shell Live (PR + post-merge) / turn-live shard ${{ matrix.shard_index }} (push) Has been cancelled
Release / prepare (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04-arm, linux-arm64) (push) Has been cancelled
Synthetic Deterministic Tests / Synthetic offline (deterministic) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:10:45 +08:00

139 lines
4.0 KiB
Python

"""Credential resolution for scheduled task delivery.
Resolves provider credentials from the integration store and environment
rather than requiring them to be stored in task params.
"""
from __future__ import annotations
import logging
import os
from typing import Any
logger = logging.getLogger(__name__)
try:
from keyring.errors import KeyringError as _KeyringError
except ImportError:
class _KeyringError(Exception): # type: ignore[no-redef]
"""Fallback when keyring is not installed."""
def resolve_telegram_credentials(task_params: dict[str, str]) -> dict[str, str]:
"""Resolve Telegram bot_token from task params, integration store, env, or keyring.
Priority: task.params > integration store > environment variable > system keyring.
"""
token = task_params.get("bot_token", "").strip()
if token:
return {"bot_token": token}
token = _get_integration_credential("telegram", "bot_token")
if token:
return {"bot_token": token}
try:
from config.llm_credentials import resolve_env_credential
token = resolve_env_credential("TELEGRAM_BOT_TOKEN").strip()
except (ImportError, _KeyringError) as exc:
logger.debug("Failed to resolve Telegram credentials from keyring: %s", exc)
token = os.getenv("TELEGRAM_BOT_TOKEN", "").strip()
return {"bot_token": token} if token else {}
def resolve_slack_credentials(task_params: dict[str, str]) -> dict[str, str]:
"""Resolve Slack credentials from task params, integration store, or env.
Priority: task.params > integration store > environment variable.
"""
webhook_url = task_params.get("webhook_url", "")
if webhook_url:
return {"webhook_url": webhook_url}
access_token = task_params.get("access_token", "")
if access_token:
return {"access_token": access_token}
webhook = _resolve_credentials(
{},
service="slack",
credential_key="webhook_url",
env_vars=("SLACK_WEBHOOK_URL",),
)
if webhook:
return webhook
return _resolve_credentials(
{},
service="slack",
credential_key="access_token",
env_vars=("SLACK_BOT_TOKEN", "SLACK_ACCESS_TOKEN"),
)
def resolve_discord_credentials(task_params: dict[str, str]) -> dict[str, str]:
"""Resolve Discord bot_token from task params, integration store, or env.
Priority: task.params > integration store > environment variable.
"""
return _resolve_credentials(
task_params,
service="discord",
credential_key="bot_token",
env_vars=("DISCORD_BOT_TOKEN",),
)
def _resolve_credentials(
task_params: dict[str, str],
*,
service: str,
credential_key: str,
env_vars: tuple[str, ...],
) -> dict[str, str]:
"""Resolve a single credential from task params, integration store, or env."""
value = task_params.get(credential_key, "")
if value:
return {credential_key: value}
value = _get_integration_credential(service, credential_key)
if value:
return {credential_key: value}
for env_var in env_vars:
value = os.getenv(env_var, "")
if value:
return {credential_key: value}
return {}
def _get_integration_credential(service: str, key: str) -> str:
"""Look up a credential from the integration store."""
try:
from integrations.catalog import resolve_effective_integrations
integrations = resolve_effective_integrations()
integration: dict[str, Any] = integrations.get(service, {})
if not isinstance(integration, dict):
return ""
config = integration.get("config", {})
if not isinstance(config, dict):
return ""
value = config.get(key, "")
return str(value) if value else ""
except Exception:
logger.debug("Failed to resolve %s credential from integration store", service)
return ""
__all__ = [
"resolve_discord_credentials",
"resolve_slack_credentials",
"resolve_telegram_credentials",
]