
    ^h>                     0   S SK r S SKrS SKrS SKJrJrJrJr  S SKJ	r	J
r
Jr  S SKJrJr  S SKJr  S SK7  S SKJr   S,S\
S	\\   S
\\   4S jjr S,S\\\      S\
S	\\   S
\\\\   4   4S jjrS\S
\4S jrS\S\S
\4S jrS\S\S\S
\4S jrS\S\S\S\\   S
\4
S jrS\S\S\\   S\S
\4
S jrS\
S\S\4S jrS\4S jrS\
S
\4S  jr S\
S
\4S! jr!S"\S
\4S# jr"S$\#4S% jr$S&\%S
\\   4S' jr&S&\%S
\\   4S( jr'S\S
\4S) jr(S\S
\4S* jr)S+ r*g)-    N)AnyListOptionalTuple)HTTPExceptionRequeststatus)Routerprovider_list)verbose_proxy_logger)*)#CONFIGURABLE_CLIENTSIDE_AUTH_PARAMSrequestuse_x_forwarded_forreturnc                     S nUSL a!  SU R                   ;   a  U R                   S   nU$ U R                  b  U R                  R                  nU$ SnU$ )NTzx-forwarded-for )headersclienthost)r   r   	client_ips      W/home/james-whalen/.local/lib/python3.13/site-packages/litellm/proxy/auth/auth_utils.py_get_request_ip_addressr      sd     Id"'8GOO'KOO$56	  
	#NN''	  	    allowed_ipsc                 6    U c  g[        XS9nX0;  a  SU4$ SU4$ )z!
Returns if ip is allowed or not
)TN)r   r   FT)r   )r   r   r   r   s       r   _check_valid_ipr      s9      (I
 #i?r   request_bodyc                 r    SnU R                  S5      nUc  gSU;   d  SU;   d  SU;   d  SU;   a  gSU ;   a  g	g)
z`
if 'api_base' in request body. Check if complete credentials given. Prevent malicious attacks.
NmodelF	sagemakerbedrock	vertex_aivertex_ai_betaapi_keyT)get)r   given_models     r   check_complete_credentialsr(   4   sW     "&K""7+K 	{"#+%{* L r   request_body_value	regex_strc                 F    [         R                  " X5      (       d  X:X  a  gg)zH
Check if request_body_value matches the regex_str or is equal to param
TF)rematchr)   r*   s     r   check_regex_or_str_matchr/   M   s     
xx	..)2Qr   param#configurable_clientside_auth_paramsc                     Uc  gU HR  n[        U[        5      (       a  X:X  a    g[        U[        5      (       d  M6  U S:X  d  M>  [        UUS   S9(       d  MR    g   g)z\
Check if param is a str or dict and if request_body_value is in the list of allowed values
FTapi_baser.   )
isinstancestrDictr/   )r0   r)   r1   items       r   _is_param_allowedr8   V   sb     +23dC  U]d##
"'?#5z*( (  4 r   r    
llm_routerc                     Uc  gUR                  U S9nUc?  U R                  SS5      S   [        ;   a"  UR                  U R                  SS5      S   S9nUc  gUb  UR                  c  g[	        UUUR                  S9$ )z
Check if model is allowed to use configurable client-side params
- get matching model
- check if 'clientside_configurable_parameters' is set for model
-
F)model_group/   r   )r0   r)   r1   )get_model_group_infosplitr   r1   r8   )r    r0   r)   r9   
model_infos        r   5_allow_model_level_clientside_configurable_parametersrA   n   s     00U0CJ;;sAq!]2#88!KKQ/2 9 J ZKKS-,6,Z,Z r   general_settingsc                     SS/nU HP  nXP;   d  M
  [        U S9(       a  M  UR                  S5      SL a    g[        UUX   US9SL a    g[        SU S35      e   g)	u   
Check if the request body is safe.

A malicious user can set the ﻿api_base to their own domain and invoke POST /chat/completions to intercept and steal the OpenAI API key.
Relevant issue: https://huntr.com/bounties/4001e1a2-7b7a-4776-a3ae-e6692ec3d997
r3   base_url)r   allow_client_side_credentialsT)r    r0   r)   r9   zRejected Request: z is not allowed in request body. Enable with `general_settings::allow_client_side_credentials` on proxy config.yaml. Relevant Issue: https://huntr.com/bounties/4001e1a2-7b7a-4776-a3ae-e6692ec3d997)r(   r&   rA   
ValueError)r   rB   r9   r    banned_paramsr0   s         r   is_request_body_saferH      s      ,M!.)   ##$CDLE'3':)	  $UG ,b b ' 2 r   request_dataroutec           	        #    SSK JnJnJn  [	        U S9I Sh  vN   [        UUUUR                  SS5      S9  [        UR                  SS5      UR                  S	S
5      U S9u  pgU(       d  [        [        R                  SU S3S9eSU;   ay  US   nUSLa1  [        R                  " S[        R                  R                   35        X(;  a8  [        R                  " SU SU 35        [        [        R                  SU S3S9egg N7f)aT  
1. Checks if request size is under max_request_size_mb (if set)
2. Check if request body is safe (example user has not set api_base in request body)
3. Check if IP address is allowed (if set)
4. Check if request route is an allowed route on the proxy (if set)

Returns:
- True

Raises:
- HTTPException if request fails initial auth checks
r   )rB   r9   premium_user)r   Nr    r   )r   rB   r9   r    r   r   F)r   r   r   zAccess forbidden: IP address z not allowed.)status_codedetailallowed_routesTz=Trying to set allowed_routes. This is an Enterprise feature. zRoute z not in allowed_routes=zAccess forbidden: Route z not allowed)litellm.proxy.proxy_serverrB   r9   rL   check_if_request_size_is_saferH   r&   r   r   r	   HTTP_403_FORBIDDENr   errorCommonProxyErrorsnot_premium_uservalue)	r   rI   rJ   rB   r9   rL   is_valid_ippassed_in_ip_allowed_routess	            r   pre_db_read_auth_checksrZ      s=    " VU (
888 !)R
	 !0$((=,001FN!K 112<.N
 	
 ++*+;<t# &&OPaPrPrPxPxOyz ' &&66GH  "551%E 	 ( ,5 9s   DD
C1Dcurrent_routec                     SSK JnJn   USLa  gUc  gUR                  S/ 5      nX;   a  gg! [         a,  n[
        R                  " S[        U5       35         SnAgSnAff = f)a  
Helper to check if the user defined public_routes on config.yaml

Parameters:
- current_route: str - the route the user is trying to call

Returns:
- bool - True if the route is defined in public_routes
- bool - False if the route is not defined in public_routes


In order to use this the litellm config.yaml should have the following in general_settings:

```yaml
general_settings:
    master_key: sk-1234
    public_routes: ["LiteLLMRoutes.public_routes", "/spend/calculate"]
```
r   rB   rL   TFNpublic_routesz"route_in_additonal_public_routes: )rP   rB   rL   r&   	Exceptionr   rS   r5   )r[   rB   rL   routes_definedes        r    route_in_additonal_public_routesrb      sl    , Jt##)--orB* ""%GAx#PQs   - - - 
A#"AA#c                     [        U S5      (       aw  U R                  R                  R                  U R                  R                  5      (       a9  U R                  R                  [        U R                  R                  5      S-
  S $ U R                  R                  $ ! [         aY  n[        R                  " S[        U5       SU R                  R                   35        U R                  R                  s SnA$ SnAff = f)z
Helper to get the route from the request

remove base url from path if set e.g. `/genai/chat/completions` -> `/chat/completions
rD   r=   Nzerror on get_request_route: z!, defaulting to request.url.path=)
hasattrurlpath
startswithrD   lenr_   r   debugr5   )r   ra   s     r   get_request_routerj     s     7J''GKK,<,<,G,G!!-
 -
 ;;##C(8(8(=(=$>$B$DEE;;###  ""*3q6(2ST[T_T_TdTdSef	
 {{	 s%   BB  
B   
D*AC>8D>Dc                   #    SSK JnJn  UR                  SS5      nUGb-  USLa2  [        R
                  " S[        R                  R                   35        gU R                  R                  S5      nU(       a_  [        U5      n[        US9n[        R                  " S	U 35        Xc:  a+  [        S
U SU S3[        R                  R                  SSS9e gU R!                  5       I Sh  vN n[#        U5      n[        US9n	[        R                  " SU	 35        X:  a+  [        S
U	 SU S3[        R                  R                  SSS9eg Nb7f)z
Enterprise Only:
    - Checks if the request size is within the limit

Args:
    request (Request): The incoming request.

Returns:
    bool: True if the request size is within the limit

Raises:
    ProxyException: If the request size is too large

r   r]   max_request_size_mbNTzPusing max_request_size_mb - not checking -  this is an enterprise only feature. content-lengthbytes_valuez"content_length request size in MB=z+Request size is too large. Request size is  MB. Max size is  MB  messagetypecoder0   z request body request size in MB=)rP   rB   rL   r&   r   warningrT   rU   rV   r   intbytes_to_mbri   ProxyExceptionProxyErrorTypesbad_request_errorbodyrh   )
r   rB   rL   rl   content_lengthheader_sizeheader_size_mbr}   	body_sizerequest_size_mbs
             r   rQ   rQ   2  s     J*../DdK&t# ((bct  dF  dF  dL  dL  cM  N  !,,-=>n-K([AN &&4^4DE 3$I.IYYjk~j  @C  D(::@@*	  40  !'DD	I)i@O &&2?2CD 4$I/IZZkl  lA  AD  E(::@@*	   (s   C*E,E-A#Eresponsec                   #    SSK JnJn  UR                  SS5      nUb  USLa2  [        R
                  " S[        R                  R                   35        g[        [        R                  " U 5      S9n[        R                  " SU 35        XC:  a+  [        S	U S
U S3[        R                  R                  SSS9eg7f)z
Enterprise Only:
    - Checks if the response size is within the limit

Args:
    response (Any): The response to check.

Returns:
    bool: True if the response size is within the limit

Raises:
    ProxyException: If the response size is too large

r   r]   max_response_size_mbNTzQusing max_response_size_mb - not checking -  this is an enterprise only feature. rn   zresponse size in MB=z-Response size is too large. Response size is rp   rq   rr   rm   rs   )rP   rB   rL   r&   r   rw   rT   rU   rV   ry   sys	getsizeofri   rz   r{   r|   )r   rB   rL   r   response_size_mbs        r   check_response_size_is_safer   q  s       J+//0FM't# ((cdu  eG  eG  eM  eM  dN  O &3==3JK""%9:J9K#LM2 GHXGYYjk  kA  AD  E$66<<&	  s   B<B>ro   c                     U S-  $ )z
Helper to convert bytes to MB
i    rn   s    r   ry   ry     s     +&&r   user_api_key_dictc                 d    U R                   (       a  SU R                   ;   a  U R                   S   $ g )Nmodel_rpm_limitmetadatar   s    r   get_key_model_rpm_limitr     /    !! 1 : ::$--.?@@r   c                 d    U R                   (       a  SU R                   ;   a  U R                   S   $ g )Nmodel_tpm_limitr   r   s    r   get_key_model_tpm_limitr     r   r   c                 *    S/nU H
  nX ;   d  M
    g   g)Nz	vertex-aiTFr   )rJ   %PROVIDER_SPECIFIC_PASS_THROUGH_ROUTESprefixs      r   is_pass_through_provider_router     s&    -)
 8? 8 r   c                 L    SSK JnJn  USLa  gUR                  SS5      SL a  gg)a  
Use this to decide if the rest of the LiteLLM Virtual Key auth checks should run on /vertex-ai/{endpoint} routes
Use this to decide if the rest of the LiteLLM Virtual Key auth checks should run on provider pass through routes
ex /vertex-ai/{endpoint} routes
Run virtual key auth if the following is try:
- User is premium_user
- User has enabled litellm_setting.use_client_credentials_pass_through_routes
r   r]   TF*use_client_credentials_pass_through_routes)rP   rB   rL   r&   )rJ   rB   rL   s      r   .should_run_auth_on_pass_through_provider_router     s8     J4 	I5Q	  r   c                      [         R                  " SS5      n [         R                  " SS5      n[         R                  " SS5      nU SL=(       d    USL=(       d    USLnU$ )z
Check if the user has set up single sign-on (SSO) by verifying the presence of Microsoft client ID, Google client ID or generic client ID and UI username environment variables.
Returns a boolean indicating whether SSO has been set up.
MICROSOFT_CLIENT_IDNGOOGLE_CLIENT_IDGENERIC_CLIENT_ID)osgetenv)microsoft_client_idgoogle_client_idgeneric_client_id	sso_setups       r   _has_user_setup_ssor     sk    
 ))$94@yy!3T:		"5t< 
D	( 	+D(	+T)  r   )F)+r   r,   r   typingr   r   r   r   fastapir   r   r	   litellmr
   r   litellm._loggingr   litellm.proxy._typeslitellm.types.routerr   boolr5   r   r   dictr(   r/   r8   rA   rH   rZ   rb   rj   rQ   r   rx   ry   UserAPIKeyAuthr   r   r   r   r   r   r   r   <module>r      s$   	 	 
 - - 2 2 ) 1 " D =B+3D>c]$ +0$s)$ "$ 4#	.T d 2    *M 
	003AI&AQ	B$$*.$<DV<L$UX$	$N;;; ;|&C &R w  3  *< <T <~% % %P'S '~ (4. ~ (4. 
# 
$ 
# $ 2r   