o
    "i5                     @   s   U d Z ddlmZ ddlmZ ddlmZmZmZ ddl	m
Z
 ddlZddlZeeZedddZeee  ed	< G d
d de
Zddedee fddZdee fddZdee fddZdee fddZdd Zdd ZdS )zM
Tenant Context Middleware
Manages tenant context for multi-tenant isolation
    )
ContextVar)Optional)RequestHTTPExceptionstatus)BaseHTTPMiddlewareNtenant_context)default_tenant_contextc                   @   s   e Zd ZdZdefddZdS )TenantContextMiddlewarez
    Middleware to extract and set tenant context from JWT token

    Extracts tenant_id and user_id from JWT token and sets them in context.
    This enables automatic tenant isolation in database queries.
    requestc              
      s  g d}|j j|v s|j jdr||I d H S |jd}|r|dr|dd}zxddlm} tj	||j
dgd	d
id}|dpI|d}|d}	|rddlm}
 ddlm} |
 }z=|||jt|k|jdk }|std|  ntt||	rt|	nd d td| d|	  W |  n|  w W n4 tjy } ztd|  W Y d }~nd }~w ty } ztd|  W Y d }~nd }~ww z||I d H }|W t  S t  w )N)/z/healthz/docsz/openapi.jsonz/redocz/api/v1/auth/loginz/api/v1/auth/registerz/staticAuthorizationzBearer  r   )settingsHS256
verify_expT)
algorithmsoptions	tenant_idsub)SessionLocal)TenantFz%Invalid or deleted tenant_id in JWT: r   user_idz'Tenant context set from JWT: tenant_id=
, user_id=zInvalid JWT token: z*Error extracting tenant context from JWT: )urlpath
startswithheadersgetreplace
app.configr   jwtdecode
SECRET_KEYapp.db.sessionr   app.models.tenantr   queryfilteridint
is_deletedfirstloggerwarningset_tenant_contextdebugcloseInvalidTokenError	Exceptionerrorclear_tenant_context)selfr   	call_nextpublic_pathsauth_headertokenr   payloadr   r   r   r   dbtenanteresponse rA   ?/lsinfo/ai/hellotax_ai/base_platform/app/core/tenant_context.pydispatch   sb   

z TenantContextMiddleware.dispatchN)__name__
__module____qualname____doc__r   rC   rA   rA   rA   rB   r      s    r   r   r   c                 K   s2   | |d|}t | td|  d|  dS )z
    Set the current tenant context

    Args:
        tenant_id: Tenant ID
        user_id: Optional user ID
        **kwargs: Additional context data
    r   zTenant context set: tenant_id=r   Nr
   setr.   r1   )r   r   kwargscontextrA   rA   rB   r0   a   s   

r0   returnc                   C   s   t  S )zZ
    Get the current tenant context

    Returns:
        Tenant context dict or None
    r
   r    rA   rA   rA   rB   get_tenant_contexts   s   rN   c                  C      t  } | r| dS dS )zX
    Get the current tenant ID from context

    Returns:
        Tenant ID or None
    r   NrM   rK   rA   rA   rB   get_current_tenant_id}      rQ   c                  C   rO   )zT
    Get the current user ID from context

    Returns:
        User ID or None
    r   NrM   rP   rA   rA   rB   get_current_user_id   rR   rS   c                   C   s   t d td dS )z*
    Clear the current tenant context
    NzTenant context clearedrH   rA   rA   rA   rB   r6      s   
r6   c                  C   s(   t  } | r| dsttjdd| S )z
    Require tenant context to be set, raise exception if not

    Raises:
        HTTPException: If tenant context is not set
    r   z,Tenant context not set. Please authenticate.)status_codedetail)r
   r    r   r   HTTP_401_UNAUTHORIZEDrP   rA   rA   rB   require_tenant_context   s   rW   )N)rG   contextvarsr   typingr   fastapir   r   r   starlette.middleware.baser   loggingr#   	getLoggerrD   r.   r
   dict__annotations__r   r+   r0   rN   rQ   rS   r6   rW   rA   rA   rA   rB   <module>   s     
O
