Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

auth_provider.py 3.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. from typing import Optional
  2. from configs import dify_config
  3. from core.mcp.types import (
  4. OAuthClientInformation,
  5. OAuthClientInformationFull,
  6. OAuthClientMetadata,
  7. OAuthTokens,
  8. )
  9. from models.tools import MCPToolProvider
  10. from services.tools.mcp_tools_mange_service import MCPToolManageService
  11. LATEST_PROTOCOL_VERSION = "1.0"
  12. class OAuthClientProvider:
  13. mcp_provider: MCPToolProvider
  14. def __init__(self, provider_id: str, tenant_id: str, for_list: bool = False):
  15. if for_list:
  16. self.mcp_provider = MCPToolManageService.get_mcp_provider_by_provider_id(provider_id, tenant_id)
  17. else:
  18. self.mcp_provider = MCPToolManageService.get_mcp_provider_by_server_identifier(provider_id, tenant_id)
  19. @property
  20. def redirect_url(self) -> str:
  21. """The URL to redirect the user agent to after authorization."""
  22. return dify_config.CONSOLE_API_URL + "/console/api/mcp/oauth/callback"
  23. @property
  24. def client_metadata(self) -> OAuthClientMetadata:
  25. """Metadata about this OAuth client."""
  26. return OAuthClientMetadata(
  27. redirect_uris=[self.redirect_url],
  28. token_endpoint_auth_method="none",
  29. grant_types=["authorization_code", "refresh_token"],
  30. response_types=["code"],
  31. client_name="Dify",
  32. client_uri="https://github.com/langgenius/dify",
  33. )
  34. def client_information(self) -> Optional[OAuthClientInformation]:
  35. """Loads information about this OAuth client."""
  36. client_information = self.mcp_provider.decrypted_credentials.get("client_information", {})
  37. if not client_information:
  38. return None
  39. return OAuthClientInformation.model_validate(client_information)
  40. def save_client_information(self, client_information: OAuthClientInformationFull) -> None:
  41. """Saves client information after dynamic registration."""
  42. MCPToolManageService.update_mcp_provider_credentials(
  43. self.mcp_provider,
  44. {"client_information": client_information.model_dump()},
  45. )
  46. def tokens(self) -> Optional[OAuthTokens]:
  47. """Loads any existing OAuth tokens for the current session."""
  48. credentials = self.mcp_provider.decrypted_credentials
  49. if not credentials:
  50. return None
  51. return OAuthTokens(
  52. access_token=credentials.get("access_token", ""),
  53. token_type=credentials.get("token_type", "Bearer"),
  54. expires_in=int(credentials.get("expires_in", "3600") or 3600),
  55. refresh_token=credentials.get("refresh_token", ""),
  56. )
  57. def save_tokens(self, tokens: OAuthTokens) -> None:
  58. """Stores new OAuth tokens for the current session."""
  59. # update mcp provider credentials
  60. token_dict = tokens.model_dump()
  61. MCPToolManageService.update_mcp_provider_credentials(self.mcp_provider, token_dict, authed=True)
  62. def save_code_verifier(self, code_verifier: str) -> None:
  63. """Saves a PKCE code verifier for the current session."""
  64. MCPToolManageService.update_mcp_provider_credentials(self.mcp_provider, {"code_verifier": code_verifier})
  65. def code_verifier(self) -> str:
  66. """Loads the PKCE code verifier for the current session."""
  67. # get code verifier from mcp provider credentials
  68. return str(self.mcp_provider.decrypted_credentials.get("code_verifier", ""))