
    g@                     
   d dl Z d dlZd dlZd dlmZmZmZmZ d dlm	Z	m
Z
mZ d dlmZmZ d dlmZ d dl d dlmZ 	 d,de
d	ee   d
ee   fdZ	 d,deee      de
d	ee   d
eeee   f   fdZded
efdZdeded
efdZdededed
efdZdedededee   d
ef
dZdededee   ded
ef
dZde
dedefdZdefdZde
d
efd Z de
d
efd!Z!d"ed
efd#Z"d$e#fd%Z$d&e%d
ee   fd'Z&d&e%d
ee   fd(Z'ded
efd)Z(ded
efd*Z)d+ Z*y)-    N)AnyListOptionalTuple)HTTPExceptionRequeststatus)Routerprovider_list)verbose_proxy_logger)*)#CONFIGURABLE_CLIENTSIDE_AUTH_PARAMSrequestuse_x_forwarded_forreturnc                     d }|du rd| j                   v r| j                   d   }|S | j                  | j                  j                  }|S d}|S )NTzx-forwarded-for )headersclienthost)r   r   	client_ips      R/var/www/openai/venv/lib/python3.12/site-packages/litellm/proxy/auth/auth_utils.py_get_request_ip_addressr      sd     Id"'8GOO'KOO$56	  
	#NN''	  	    allowed_ipsc                 :    | yt        ||      }|| vrd|fS d|fS )z)
    Returns if ip is allowed or not
    )TN)r   r   FT)r   )r   r   r   r   s       r   _check_valid_ipr      s>      (-@I
 #i?r   request_bodyc                 \    d}| j                  d      }|yd|v sd|v sd|v sd|v ryd| v ry	y)
zh
    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                 <    t        j                  ||       s|| k(  ryy)zP
    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	-.)?Q2Qr   param#configurable_clientside_auth_paramsc                     |y|D ]B  }t        |t              r| |k(  r yt        |t              s+| dk(  s1t        ||d         sB y y)zd
    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   sY     +23dC Ud]d#
"'?#5z*(  4 r   r    
llm_routerc                    |y|j                  |       }|@| j                  dd      d   t        v r%|j                  | j                  dd      d         }|y||j                  yt	        |||j                        S )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                     ddg}|D ]M  }|| v st        |       r|j                  d      du r yt        ||| |   |      du r yt        d| d       y)	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'3E':)	  $UG ,b b ' 2 r   request_dataroutec           	      &  K   ddl m}m}m} t	        |        d{    t        ||||j                  dd             t        |j                  dd      |j                  d	d
      |       \  }}|st        t        j                  d| d      d|v rx|d   }|dur0t        j                  dt        j                  j                          ||vr:t        j                  d| d|        t        t        j                  d| d      yy7 w)ax  
    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      sB    " 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C3Dcurrent_routec                     ddl m}m} 	 |dury|y|j                  dg       }| |v ryy# t        $ r+}t        j                  dt        |              Y d}~yd}~ww xY w)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      sn    , Jt##)--orBN* ""%GAx#PQs   * * * 	A!AAc                    	 t        | d      rr| j                  j                  j                  | j                  j                        r9| j                  j                  t        | j                  j                        dz
  d S | j                  j                  S # t        $ rX}t        j                  dt        |       d| j                  j                          | j                  j                  cY d}~S d}~ww xY w)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%   A=B  B 	C7AC2,C72C7c                   K   ddl m}m} |j                  dd      }|/|dur1t	        j
                  dt        j                  j                          y| j                  j                  d      }|rct        |      }t        |      }t	        j                  d	|        ||kD  r.t        d
| d| dt        j                  j                  dd      y| j!                          d{   }t#        |      }t        |      }	t	        j                  d|	        |	|kD  r.t        d
|	 d| dt        j                  j                  dd      y7 gw)a  
    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3$I.IYYjk~j  @C  D(::@@*	 .  !'DD	I)i@O &&2?2CD !44$I/IZZkl  lA  AD  E(::@@*	   (s   C&E(E)A(Eresponsec                   K   ddl m}m} |j                  dd      }||dur1t	        j
                  dt        j                  j                          yt        t        j                  |             }t	        j                  d|        ||kD  r.t        d	| d
| dt        j                  j                  dd      yw)a   
    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2 GHXGYYjk  kA  AD  E$66<<&	  s   B=B?ro   c                     | dz  S )z'
    Helper to convert bytes to MB
    i    rn   s    r   ry   ry     s     +&&r   user_api_key_dictc                     | j                   rd| j                   v r| j                   d   S y | j                  r9i }| j                  j                         D ]  \  }}d|v s|d   |d   ||<    |S y )Nmodel_rpm_limit	rpm_limit)metadatamodel_max_budgetitems)r   r   r    budgets       r   get_key_model_rpm_limitr     s    !! 1 : ::$--.?@@  
	+	+*,.??EEGME6f$)<)H)/)<& H r   c                     | j                   rd| j                   v r| j                   d   S y | j                  rd| j                  v r| j                  d   S y )Nmodel_tpm_limit	tpm_limit)r   r   )r   s    r   get_key_model_tpm_limitr     s_    !! 1 : ::$--.?@@
 	 
	+	++<<<$55kBBr   c                 $    dg}|D ]  }|| v s y y)Nz	vertex-aiTFr   )rJ   %PROVIDER_SPECIFIC_PASS_THROUGH_ROUTESprefixs      r   is_pass_through_provider_router     s(    -)
 8U? 8 r   c                 H    ddl m}m} |dury|j                  dd      du ryy)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                      t        j                  dd      } t        j                  dd      }t        j                  dd      }| duxs
 |duxs |du}|S )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   