您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. import binascii
  2. from collections.abc import Mapping
  3. from typing import Any
  4. from werkzeug import Request
  5. from core.plugin.entities.plugin_daemon import PluginOAuthAuthorizationUrlResponse, PluginOAuthCredentialsResponse
  6. from core.plugin.impl.base import BasePluginClient
  7. class OAuthHandler(BasePluginClient):
  8. def get_authorization_url(
  9. self,
  10. tenant_id: str,
  11. user_id: str,
  12. plugin_id: str,
  13. provider: str,
  14. redirect_uri: str,
  15. system_credentials: Mapping[str, Any],
  16. ) -> PluginOAuthAuthorizationUrlResponse:
  17. try:
  18. response = self._request_with_plugin_daemon_response_stream(
  19. "POST",
  20. f"plugin/{tenant_id}/dispatch/oauth/get_authorization_url",
  21. PluginOAuthAuthorizationUrlResponse,
  22. data={
  23. "user_id": user_id,
  24. "data": {
  25. "provider": provider,
  26. "redirect_uri": redirect_uri,
  27. "system_credentials": system_credentials,
  28. },
  29. },
  30. headers={
  31. "X-Plugin-ID": plugin_id,
  32. "Content-Type": "application/json",
  33. },
  34. )
  35. for resp in response:
  36. return resp
  37. raise ValueError("No response received from plugin daemon for authorization URL request.")
  38. except Exception as e:
  39. raise ValueError(f"Error getting authorization URL: {e}")
  40. def get_credentials(
  41. self,
  42. tenant_id: str,
  43. user_id: str,
  44. plugin_id: str,
  45. provider: str,
  46. redirect_uri: str,
  47. system_credentials: Mapping[str, Any],
  48. request: Request,
  49. ) -> PluginOAuthCredentialsResponse:
  50. """
  51. Get credentials from the given request.
  52. """
  53. try:
  54. # encode request to raw http request
  55. raw_request_bytes = self._convert_request_to_raw_data(request)
  56. response = self._request_with_plugin_daemon_response_stream(
  57. "POST",
  58. f"plugin/{tenant_id}/dispatch/oauth/get_credentials",
  59. PluginOAuthCredentialsResponse,
  60. data={
  61. "user_id": user_id,
  62. "data": {
  63. "provider": provider,
  64. "redirect_uri": redirect_uri,
  65. "system_credentials": system_credentials,
  66. # for json serialization
  67. "raw_http_request": binascii.hexlify(raw_request_bytes).decode(),
  68. },
  69. },
  70. headers={
  71. "X-Plugin-ID": plugin_id,
  72. "Content-Type": "application/json",
  73. },
  74. )
  75. for resp in response:
  76. return resp
  77. raise ValueError("No response received from plugin daemon for authorization URL request.")
  78. except Exception as e:
  79. raise ValueError(f"Error getting credentials: {e}")
  80. def _convert_request_to_raw_data(self, request: Request) -> bytes:
  81. """
  82. Convert a Request object to raw HTTP data.
  83. Args:
  84. request: The Request object to convert.
  85. Returns:
  86. The raw HTTP data as bytes.
  87. """
  88. # Start with the request line
  89. method = request.method
  90. path = request.full_path
  91. protocol = request.headers.get("HTTP_VERSION", "HTTP/1.1")
  92. raw_data = f"{method} {path} {protocol}\r\n".encode()
  93. # Add headers
  94. for header_name, header_value in request.headers.items():
  95. raw_data += f"{header_name}: {header_value}\r\n".encode()
  96. # Add empty line to separate headers from body
  97. raw_data += b"\r\n"
  98. # Add body if exists
  99. body = request.get_data(as_text=False)
  100. if body:
  101. raw_data += body
  102. return raw_data