You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

oauth.py 3.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  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. system_credentials: Mapping[str, Any],
  15. ) -> PluginOAuthAuthorizationUrlResponse:
  16. response = self._request_with_plugin_daemon_response_stream(
  17. "POST",
  18. f"plugin/{tenant_id}/dispatch/oauth/get_authorization_url",
  19. PluginOAuthAuthorizationUrlResponse,
  20. data={
  21. "user_id": user_id,
  22. "data": {
  23. "provider": provider,
  24. "system_credentials": system_credentials,
  25. },
  26. },
  27. headers={
  28. "X-Plugin-ID": plugin_id,
  29. "Content-Type": "application/json",
  30. },
  31. )
  32. for resp in response:
  33. return resp
  34. raise ValueError("No response received from plugin daemon for authorization URL request.")
  35. def get_credentials(
  36. self,
  37. tenant_id: str,
  38. user_id: str,
  39. plugin_id: str,
  40. provider: str,
  41. system_credentials: Mapping[str, Any],
  42. request: Request,
  43. ) -> PluginOAuthCredentialsResponse:
  44. """
  45. Get credentials from the given request.
  46. """
  47. # encode request to raw http request
  48. raw_request_bytes = self._convert_request_to_raw_data(request)
  49. response = self._request_with_plugin_daemon_response_stream(
  50. "POST",
  51. f"plugin/{tenant_id}/dispatch/oauth/get_credentials",
  52. PluginOAuthCredentialsResponse,
  53. data={
  54. "user_id": user_id,
  55. "data": {
  56. "provider": provider,
  57. "system_credentials": system_credentials,
  58. # for json serialization
  59. "raw_http_request": binascii.hexlify(raw_request_bytes).decode(),
  60. },
  61. },
  62. headers={
  63. "X-Plugin-ID": plugin_id,
  64. "Content-Type": "application/json",
  65. },
  66. )
  67. for resp in response:
  68. return resp
  69. raise ValueError("No response received from plugin daemon for authorization URL request.")
  70. def _convert_request_to_raw_data(self, request: Request) -> bytes:
  71. """
  72. Convert a Request object to raw HTTP data.
  73. Args:
  74. request: The Request object to convert.
  75. Returns:
  76. The raw HTTP data as bytes.
  77. """
  78. # Start with the request line
  79. method = request.method
  80. path = request.full_path
  81. protocol = request.headers.get("HTTP_VERSION", "HTTP/1.1")
  82. raw_data = f"{method} {path} {protocol}\r\n".encode()
  83. # Add headers
  84. for header_name, header_value in request.headers.items():
  85. raw_data += f"{header_name}: {header_value}\r\n".encode()
  86. # Add empty line to separate headers from body
  87. raw_data += b"\r\n"
  88. # Add body if exists
  89. body = request.get_data(as_text=False)
  90. if body:
  91. raw_data += body
  92. return raw_data