
    ^	i                    j   d Z ddlmZ ddlmZmZ ddlmZmZm	Z	m
Z
 ddlmZmZ ddlmZmZ ddlmZ ddlmZ er*dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZ ddlm Z  ddl!m"Z"  ed          Z# ed          Z$ G d de          Z%d2dZ&d3dZ'd4dZ(d5dZ)d6d!Z*d7d#Z+d8d&Z,d9d)Z-d:d-Z.d;d0Z/d1S )<u  Shared FastAPI dependencies (DI) for request handlers.

公共依赖注入模块。
定义 JWT 认证、用户上下文解析，以及各基础设施客户端（ES、Neo4j、Redis、
Embedding、LLM）的依赖获取函数，供所有路由处理器通过 FastAPI Depends 使用。
    )annotations)	AnnotatedTYPE_CHECKING)DependsHTTPExceptionRequeststatus)HTTPAuthorizationCredentials
HTTPBearer)JWTErrorjwt)	BaseModel)settings)PermissionContext)EmbeddingClient)ESClient)	LLMClient)MySQLClient)Neo4jClient)RedisClientT)
auto_errorFc                  V    e Zd ZU dZded<   dZded<   dZded<   dZded<   g Zded	<   d
S )UserContextuv  User identity extracted from a JWT bearer token.

    JWT payload::

        {
            "sub": "<user_id>",
            "office_id": "O_17",
            "dept_id": "D_05",
            "area_id": "A_01",
            "role_ids": ["R_03"]
        }

    从 JWT 中提取的用户身份信息，贯穿整个请求生命周期，
    用于权限过滤和操作审计。
    struser_id 	office_iddept_idarea_idz	list[str]role_idsN)	__name__
__module____qualname____doc____annotations__r   r   r   r         &D:\work\zm-rag\backend\app\api\deps.pyr   r   $   sk            LLLIGGHr'   r   requestr   return
'ESClient'c                $    | j         j        j        S )u\   Yield the shared :class:`ESClient` instance.

    返回共享的 ES 客户端单例。
    )appstate	es_clientr)   s    r(   get_es_clientr1   A   s    
 ;&&r'   'Neo4jClient'c                $    | j         j        j        S )ub   Yield the shared :class:`Neo4jClient` instance.

    返回共享的 Neo4j 客户端单例。
    )r-   r.   neo4j_clientr0   s    r(   get_neo4j_clientr5   I       
 ;))r'   'RedisClient'c                $    | j         j        j        S )ub   Yield the shared :class:`RedisClient` instance.

    返回共享的 Redis 客户端单例。
    )r-   r.   redis_clientr0   s    r(   get_redis_clientr:   Q   r6   r'   'MySQLClient | None'c                8    t          | j        j        dd          S )u   Yield the shared MySQL client instance, if configured.

    返回共享的 MySQL 客户端单例；未配置时返回 None。
    mysql_clientN)getattrr-   r.   r0   s    r(   get_mysql_clientr?   Y   s    
 7;$nd;;;r'   'EmbeddingClient'c                $    | j         j        j        S )uj   Yield the shared :class:`EmbeddingClient` instance.

    返回共享的 Embedding 客户端单例。
    )r-   r.   embedding_clientr0   s    r(   get_embedding_clientrC   a   s    
 ;--r'   'LLMClient'c                $    | j         j        j        S )u^   Yield the shared :class:`LLMClient` instance.

    返回共享的 LLM 客户端单例。
    )r-   r.   
llm_clientr0   s    r(   get_llm_clientrG   i   s    
 ;''r'   credentials@Annotated[HTTPAuthorizationCredentials, Depends(_bearer_scheme)]c           
     
  K   | j         }	 t          j        |t          j        t          j        g          }n4# t          $ r'}t          t          j	        d| ddi          |d}~ww xY w|
                    d          }|st          t          j	        dddi          t          ||
                    d	d
          |
                    dd
          |
                    dd
          |
                    dg                     S )u   Decode and validate the JWT, returning a :class:`UserContext`.

    解码并验证 Bearer Token，提取用户身份信息。
    验证失败时返回 401 Unauthorized。
    
algorithmsInvalid or expired token: WWW-AuthenticateBearerstatus_codedetailheadersNsubToken missing 'sub' claimr   r   r   r   r    r   r   r   r   r    rH   r   decoder   
jwt_secretjwt_algorithmr   r   r	   HTTP_401_UNAUTHORIZEDgetr   rH   tokenpayloadexcr   s        r(   get_current_userra   t   s8      #E* ./
 
 

    4555'2
 
 
 		 "++e,,G 
4.'2
 
 
 	
 ++k2..Ir**Ir**Z,,   s   ,8 
A)"A$$A)PAnnotated[HTTPAuthorizationCredentials | None, Depends(_optional_bearer_scheme)]UserContext | Nonec           
       K   | dS | j         }	 t          j        |t          j        t          j        g          }n4# t          $ r'}t          t          j	        d| ddi          |d}~ww xY w|
                    d          }|st          t          j	        dddi          t          ||
                    d	d
          |
                    dd
          |
                    dd
          |
                    dg                     S )z:Decode JWT when present, otherwise allow anonymous access.NrK   rM   rN   rO   rP   rT   rU   r   r   r   r   r    rV   rW   r]   s        r(   get_optional_current_userre      sC      t#E* ./
 
 

    4555'2
 
 
 		 "++e,,G 
4.'2
 
 
 	
 ++k2..Ir**Ir**Z,,   s   ,< 
A-"A((A-user1Annotated[UserContext, Depends(get_current_user)]'PermissionContext'c                   K   ddl m} | j        j        j        } ||          }|                    |           d{V S )zEResolve the request user's permission context for ACL-aware handlers.r   PermissionServicer9   Napp.core.permissionrk   r-   r.   r9   resolver)   rf   rk   r9   services        r(   get_permission_contextrr      s^      
 655555;$1L\:::G&&&&&&&&&r'   AAnnotated[UserContext | None, Depends(get_optional_current_user)]'PermissionContext | None'c                   K   |dS ddl m} | j        j        j        } ||          }|                    |           d{V S )zFResolve permission context when JWT is present, otherwise return None.Nr   rj   rl   rm   rp   s        r(   get_optional_permission_contextrv      sh      
 |t555555;$1L\:::G&&&&&&&&&r'   N)r)   r   r*   r+   )r)   r   r*   r2   )r)   r   r*   r7   )r)   r   r*   r;   )r)   r   r*   r@   )r)   r   r*   rD   )rH   rI   r*   r   )rH   rb   r*   rc   )r)   r   rf   rg   r*   rh   )r)   r   rf   rs   r*   rt   )0r$   
__future__r   typingr   r   fastapir   r   r   r	   fastapi.securityr
   r   joser   r   pydanticr   
app.configr   rn   r   #app.infrastructure.embedding_clientr   app.infrastructure.es_clientr   app.infrastructure.llm_clientr   app.infrastructure.mysql_clientr   app.infrastructure.neo4j_clientr   app.infrastructure.redis_clientr   _bearer_scheme_optional_bearer_schemer   r1   r5   r:   r?   rC   rG   ra   re   rr   rv   r&   r'   r(   <module>r      s^    # " " " " " + + + + + + + + ; ; ; ; ; ; ; ; ; ; ; ; E E E E E E E E                     <555555CCCCCC555555777777;;;;;;;;;;;;;;;;;; t,,,$*666     )   :' ' ' '* * * ** * * *< < < <. . . .( ( ( ($ $ $ $N" " " "J	' 	' 	' 	'' ' ' ' ' 'r'   