| 
                        1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253 | 
                        - import json
 - import uuid
 - 
 - from core.plugin.impl.base import BasePluginClient
 - from extensions.ext_redis import redis_client
 - 
 - 
 - class OAuthProxyService(BasePluginClient):
 -     # Default max age for proxy context parameter in seconds
 -     __MAX_AGE__ = 5 * 60  # 5 minutes
 -     __KEY_PREFIX__ = "oauth_proxy_context:"
 - 
 -     @staticmethod
 -     def create_proxy_context(user_id: str, tenant_id: str, plugin_id: str, provider: str):
 -         """
 -         Create a proxy context for an OAuth 2.0 authorization request.
 - 
 -         This parameter is a crucial security measure to prevent Cross-Site Request
 -         Forgery (CSRF) attacks. It works by generating a unique nonce and storing it
 -         in a distributed cache (Redis) along with the user's session context.
 - 
 -         The returned nonce should be included as the 'proxy_context' parameter in the
 -         authorization URL. Upon callback, the `use_proxy_context` method
 -         is used to verify the state, ensuring the request's integrity and authenticity,
 -         and mitigating replay attacks.
 -         """
 -         context_id = str(uuid.uuid4())
 -         data = {
 -             "user_id": user_id,
 -             "plugin_id": plugin_id,
 -             "tenant_id": tenant_id,
 -             "provider": provider,
 -         }
 -         redis_client.setex(
 -             f"{OAuthProxyService.__KEY_PREFIX__}{context_id}",
 -             OAuthProxyService.__MAX_AGE__,
 -             json.dumps(data),
 -         )
 -         return context_id
 - 
 -     @staticmethod
 -     def use_proxy_context(context_id: str):
 -         """
 -         Validate the proxy context parameter.
 -         This checks if the context_id is valid and not expired.
 -         """
 -         if not context_id:
 -             raise ValueError("context_id is required")
 -         # get data from redis
 -         data = redis_client.getdel(f"{OAuthProxyService.__KEY_PREFIX__}{context_id}")
 -         if not data:
 -             raise ValueError("context_id is invalid")
 -         return json.loads(data)
 
 
  |