Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

oauth.py 5.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  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 refresh_credentials(
  81. self,
  82. tenant_id: str,
  83. user_id: str,
  84. plugin_id: str,
  85. provider: str,
  86. redirect_uri: str,
  87. system_credentials: Mapping[str, Any],
  88. credentials: Mapping[str, Any],
  89. ) -> PluginOAuthCredentialsResponse:
  90. try:
  91. response = self._request_with_plugin_daemon_response_stream(
  92. "POST",
  93. f"plugin/{tenant_id}/dispatch/oauth/refresh_credentials",
  94. PluginOAuthCredentialsResponse,
  95. data={
  96. "user_id": user_id,
  97. "data": {
  98. "provider": provider,
  99. "redirect_uri": redirect_uri,
  100. "system_credentials": system_credentials,
  101. "credentials": credentials,
  102. },
  103. },
  104. headers={
  105. "X-Plugin-ID": plugin_id,
  106. "Content-Type": "application/json",
  107. },
  108. )
  109. for resp in response:
  110. return resp
  111. raise ValueError("No response received from plugin daemon for refresh credentials request.")
  112. except Exception as e:
  113. raise ValueError(f"Error refreshing credentials: {e}")
  114. def _convert_request_to_raw_data(self, request: Request) -> bytes:
  115. """
  116. Convert a Request object to raw HTTP data.
  117. Args:
  118. request: The Request object to convert.
  119. Returns:
  120. The raw HTTP data as bytes.
  121. """
  122. # Start with the request line
  123. method = request.method
  124. path = request.full_path
  125. protocol = request.headers.get("HTTP_VERSION", "HTTP/1.1")
  126. raw_data = f"{method} {path} {protocol}\r\n".encode()
  127. # Add headers
  128. for header_name, header_value in request.headers.items():
  129. raw_data += f"{header_name}: {header_value}\r\n".encode()
  130. # Add empty line to separate headers from body
  131. raw_data += b"\r\n"
  132. # Add body if exists
  133. body = request.get_data(as_text=False)
  134. if body:
  135. raw_data += body
  136. return raw_data