
    h08                     x    d dl Z d dlmZmZ d dlmZmZmZ d dlm	Z	 d dl
mZmZmZmZmZ ddlmZ  G d d	      Zy)
    N)ListOptional)HTTPExceptionRequeststatus)verbose_proxy_logger)CommonProxyErrorsLiteLLM_UserTableLiteLLMRoutesLitellmUserRolesUserAPIKeyAuth   )_user_is_org_adminc                   r   e Zd Zededefd       Zedededefd       Zededefd       Z	ede
e   d	e
e   ded
ededefd       Zedefd       Zededefd       Zededefd       Zededefd       Zedededefd       Zedededefd       Zededee   defd       Zed
edefd       Zy)RouteChecksroutevalid_tokenc                     	 ddl m} |j                  |        t        j                  | |       y# t        $ r Y #w xY w)zK
        Check if management route is disabled and raise exception
        r   )EnterpriseRouteChecksr   )r   r   T)*litellm_enterprise.proxy.auth.route_checksr   should_call_route	Exceptionr   $is_virtual_key_allowed_to_call_route)r   r   r   s      [/var/www/Befach/backend/env/lib/python3.12/site-packages/litellm/proxy/auth/route_checks.pyr   zRouteChecks.should_call_route   sN    
	X!33%3@
 	88[ 	9 	
   		s   2 	>>returnc                    |j                   yt        |j                   t              syt        |j                         dk(  ry| |j                   v ryt	        d |j                   D              rX|j                   D ]I  }|t
        j                  v st        j                  | t
        j                  |   j                        sI y |j                   D ]  }t        j                  | |      s y t        d|j                    d|        )zR
        Raises Exception if Virtual Key is not allowed to call the route
        Tr   c              3   @   K   | ]  }|t         j                  v   y w)N)r   _member_names_).0allowed_routes     r   	<genexpr>zCRouteChecks.is_virtual_key_allowed_to_call_route.<locals>.<genexpr>:   s#      
 ]999
s   r   allowed_routesr   patternzLVirtual key is not allowed to call this route. Only allowed to call routes: z. Tried to call route: )r$   
isinstancelistlenanyr   r   r   check_route_access_member_map_value_route_matches_wildcard_patternr   )r   r   r!   s      r   r   z0RouteChecks.is_virtual_key_allowed_to_call_route%   s#    %%-+44d;{))*a/ K...  
!,!;!;
 
 "-!;!; M$@$@@"55#'4'A'A-'P'V'V 6   $ "< )77M::] ;  	 8 Z[f[u[uZv  wN  OT  NU  V
 	
    user_idc                 h    ddl m} | rt        |       dk  ry |ddd      }|j                  |       S )	z
        Mask user_id to prevent leaking sensitive information in error messages

        Args:
            user_id (str): The user_id to mask

        Returns:
            str: Masked user_id showing only first 2 and last 2 characters
        r   )SensitiveDataMasker   z***      *)visible_prefixvisible_suffix	mask_char)0litellm.litellm_core_utils.sensitive_data_maskerr2   r)   _mask_value)r0   r2   maskers      r   _mask_user_idzRouteChecks._mask_user_idQ   s;     	Y#g,!+ %AaSVW!!'**r/   user_obj
_user_rolerequestrequest_datac                 R   t         j                  |       t         j                  |      ry|t        j                  j
                  v r|dk(  ry|dk(  r|j                  }|j                  d      }t        j                  d| d|j                          |rR||j                  k7  rBt        t        j                  dj                  ||j                              |d	k(  ry|d
k(  ryyyy|t        j                  j
                  v rt!        |dd      dt!        |dg       v ry|t"        j$                  j
                  k(  rt         j                  |      rt        t        j                  d|       t         j'                  |t        j(                  j
                        ry|dk(  rS|t+        |t,              r|j/                         }|D ]+  }	|	dvst        t        j                  d| d| d|	 d       yt        t        j                  d| d|       t        t        j                  d| d|       yy|t"        j0                  j
                  k(  r0t         j'                  |t        j2                  j
                        ryt5        ||       r0t         j'                  |t        j6                  j
                        ry|t"        j8                  j
                  k(  r0t         j'                  |t        j:                  j
                        ryt         j'                  |t        j<                  j
                        ry|j?                  d      ryd}
d}|  | j@                  xs d}
| j                  xs d}t         jC                  |      }tE        d| d|
 d|       )zO
        Checks if Non Proxy Admin User is allowed to access the route
        r   z	/key/infoz
/user/infor0   z	user_id: z & valid_token.user_id: zHkey not allowed to access this user's info. user_id={}, key's user_id={}status_codedetailz/model/infoz
/team/infopermissionsNget_spend_routesz5user not allowed to access this OpenAI routes, role= r#   z/user/update)
user_emailpasswordz-user not allowed to access this route, role= z. Trying to access: z and updating invalid param: z-. only user_email and password can be updated)rA   user_objectz/v1/mcp/unknownz^Only proxy admin can be used to generate, delete, update info for new keys/users/teams. Route=z. Your role=z. Your user_id=)#r   custom_admin_only_route_checkis_llm_api_router   info_routesr-   query_paramsgetr   debugr0   r   r   HTTP_403_FORBIDDENformatglobal_spend_tracking_routesgetattrr   PROXY_ADMIN_VIEW_ONLYr+   management_routesr'   dictkeysINTERNAL_USERinternal_user_routesr   org_admin_allowed_routesINTERNAL_USER_VIEW_ONLYinternal_user_view_only_routesself_managed_routes
startswith	user_roler=   r   )r>   r?   r   r@   r   rA   rO   r0   _params_updatedparamra   masked_user_ids               r   $non_proxy_admin_allowed_routes_checkz0RouteChecks.non_proxy_admin_allowed_routes_checkf   s    	11 	2 	
 ''e'4]..444#,&&33&**95$**y(@ATAT@UV w+*=*=='$*$=$=ipp#[%8%8   -',& '  >7 ]??EEE]D9E"gk="&MM+AAGGG++%+8# & 9 9RS]R^_  --M,K,K,Q,Q . 
 N*#/J|T4R*6*;*;*=%4E$,FF&3060I0I-Z[eZffz  |A  {B  B_  `e  _f  fS  ,T'" !" &5 ($*$=$=!NzlZnotnuv 
 $ & 9 9J:,Vjkpjqr  5S/( *88>>>..M,N,N,T,T /  %8
,,(N(N(T(T - 
 *BBHHH..,KKQQ / 
 ++(I(I(O(O , 
 j)!IG#$..;)	"**7i(66w?Npqvpw  xD  EN  DO  O^  _m  ^n  o r/   c                     ddl m}m} d|v r[|dur1t        j                  dt
        j                  j                          y | |d   v rt        t        j                  d|  d      y )	Nr   )general_settingspremium_useradmin_only_routesTzFTrying to use 'admin_only_routes' this is an Enterprise only feature. z-user not allowed to access this route. Route=z is an admin only routerC   )litellm.proxy.proxy_serverrg   rh   r   errorr	   not_premium_userr-   r   r   rR   )r   rg   rh   s      r   rL   z)RouteChecks.custom_admin_only_route_check   s    M"224'$**\]n]]  ^F  ^F  ]G  H ()<==# & 9 9J5'Qhi  	r/   c                    | t         j                  j                  v ry| t         j                  j                  v ryt        j                  | t         j                  j                        ryt         j                  j                  D ]   }d|v st        j                  | |      s  y t        j                  |       ryt         j                  j                  D ]  }|| v s y y)z
        Helper to checks if provided route is an OpenAI route


        Returns:
            - True: if route is an OpenAI route
            - False: if route is not an OpenAI route
        Tr#   {r%   r   F)
r   openai_routesr-   anthropic_routesr   r+   
mcp_routes_route_matches_pattern_is_azure_openai_routemapped_pass_through_routes)r   openai_route_llm_passthrough_routes      r   rM   zRouteChecks.is_llm_api_route   s     M//555M22888))(@(@(F(F * 
  *77==L l"55 6    > --E-:&3&N&N&T&T"%. 'U r/   c                 :    | t         j                  j                  v S )z6
        Check if route is a management route
        )r   rW   r-   r   s    r   is_management_routezRouteChecks.is_management_route  s    
 77====r/   c                 f    d}d}t        j                  ||       st        j                  ||       ryy)z
        Check if route is a route from AzureOpenAI SDK client

        eg.
        route='/openai/deployments/vertex_ai/gemini-1.5-flash/chat/completions'
        z2^/openai/deployments/[^/]+/[^/]+/chat/completions$z!^/engines/[^/]+/chat/completions$TF)rematch)r   deployment_patternengine_patterns      r   rs   z"RouteChecks._is_azure_openai_route#  s2     S=88&."((>52Qr/   r&   c                 l    t        j                  dd|      }d| d}t        j                  ||       ryy)a  
        Check if route matches the pattern placed in proxy/_types.py

        Example:
        - pattern: "/threads/{thread_id}"
        - route: "/threads/thread_49EIN5QF32s4mH20M7GFKdlZ"
        - returns: True


        - pattern: "/key/{token_id}/regenerate"
        - route: "/key/regenerate/82akk800000000jjsk"
        - returns: False, pattern is "/key/{token_id}/regenerate"
        z	\{[^}]+\}z[^/]+^$TF)rz   subr{   r%   s     r   rr   z"RouteChecks._route_matches_pattern3  s7     &&x9gYa.88GU#r/   c                 Z    |j                  d      r|dd }| j                  |      S | |k(  S )aY  
        Check if route matches the wildcard pattern

        eg.

        pattern: "/scim/v2/*"
        route: "/scim/v2/Users"
        - returns: True

        pattern: "/scim/v2/*"
        route: "/chat/completions"
        - returns: False


        pattern: "/scim/v2/*"
        route: "/scim/v2/Users/123"
        - returns: True

        r6   N)endswithr`   )r   r&   prefixs      r   r.   z+RouteChecks._route_matches_wildcard_patternI  s;    * C Sb\F##F++ G##r/   r$   c                 8      |v xs t         fd|D              S )a%  
        Check if a route has access by checking both exact matches and patterns

        Args:
            route (str): The route to check
            allowed_routes (list): List of allowed routes/patterns

        Returns:
            bool: True if route is allowed, False otherwise
        c              3   L   K   | ]  }t         j                  |         yw)r%   N)r   rr   )r    r!   r   s     r   r"   z1RouteChecks.check_route_access.<locals>.<genexpr>r  s)      .
 ..UM.R.
s   !$)r*   r#   s   ` r   r+   zRouteChecks.check_route_accessf  s+     & 
# .
!/.
 +
 	
r/   c                 f    d| j                   j                  v sd| j                   j                  v ryy)z
        Returns True if `thread` or `assistant` is in the request path

        Args:
            request (Request): The request object

        Returns:
            bool: True if `thread` or `assistant` is in the request path, False otherwise
        thread	assistantTF)urlpath)r@   s    r   _is_assistants_api_requestz&RouteChecks._is_assistants_api_requestw  s-     w{{''';'++:J:J+Jr/   N)__name__
__module____qualname__staticmethodstrr   r   boolr   r=   r   r
   r   r   rX   re   rL   rM   rx   rs   rr   r.   r   r+   r    r/   r   r   r      s    >  " )
)
!/)
	)
 )
V +s +s + +( x,-x-.x x 	x
 $x x xt S    ' ' ' 'R >3 >4 > > c d   c C D  * $s $S $T $ $8 
# 
tCy 
T 
 
  G   r/   r   )rz   typingr   r   fastapir   r   r   litellm._loggingr   litellm.proxy._typesr	   r
   r   r   r   auth_checks_organizationr   r   r   r/   r   <module>r      s/    	 ! 2 2 1  9r rr/   