
    h                     ,
   d Z ddlZddlZddlZddlmZmZmZmZm	Z	m
Z
mZmZ ddlmZmZ ddlmZ ddlZddlm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m Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1 ddl2m3Z3 ddl4m5Z5 ddl6m7Z7m8Z8m9Z9 ddl:m;Z; ddl<m=Z= ddl>m?Z? ddl@mAZA erddlBmCZD eeDef   ZCneZC ed      ZEeZFe+j                  j                  e+j                  j                  z   ZJdeKde
e(   de
e*   de
e"   de
eL   deKdeMde
e;   de8d e
e1   d!ed"eNfd#ZO	 ddeMd$e
e*   d"eNfd%ZPd$e
e*   d"e
e,   fd&ZQ	 ddeMd!ed'eKd e
e1   d$e
e*   d"eNfd(ZRd$e
e*   fd)ZS	 ddeMd*e	d+   d!ed'eKd e
e1   d$e
e*   d"eNfd,ZTd-eMd.eUd"eNfd/ZVd0e	e,j                  e,j                  e,j                  f   d-eMd1e$d"eNfd2ZZd3e1d4e
eM   d"eNfd5Z[d.eUd"eUfd6Z\e9	 	 dd7e
eM   d8e
e7   d9ed:e
eC   de
e8   d"e
e"   fd;       Z]d<eMd=e
eeM      de
e;   d"eNfd>Z^d?eMd@edAe_d"eNfdBZ`d?eMdCe
e   d@efdDZadEe deKd?e	dF   d"e
eeM      fdGZbdEe deKd"e
eeM      fdHZcdEe deKd"e
eeM      fdIZd	 	 dd8e7dJe
eM   dKe
eM   d"e
e*   fdLZee9	 	 	 	 	 ddMe
eM   d8e
e7   d9edNeNd:e
eC   de
e8   dJe
eM   dKe
eM   dOe
eN   d"e
e*   fdP       Zfd?eMdCed9ede
e8   fdQZgdReMdSe)d9ede
e8   fdTZhdUeMdVe1d9ede
e8   fdWZidUeMd9ede
e8   fdXZje9	 ddReMd8e7dYe
eN   fdZ       ZkdReMd8e7fd[Zl	 ddReMd8e7d9ed@edAe_de
e8   d?eMdYe
eN   d"e)fd\Zmd?eMde
e8   d9ed:e
eC   d"e
e)   f
d]Zn	 	 	 	 	 ddReMd8e
e7   d9ed:e
eC   de
e8   d^e
eN   dOe
eN   dYe
eN   d"e)fd_Zo G d` da      Zpe9	 	 	 ddUeMd8e
e7   d9ed:e
eC   de
e8   d^e
eN   d"e1fdb       Zqe9	 	 ddceMd8e
e7   d9ed:e
eC   de
e8   d"e
e'   fdd       Zr	 	 	 dd<eeMeeM   f   de
e;   deeeM   dfe
eeMeMf      dge	dh   die_d"e	dj   fdkZs	 dd<eMdfe
eeMeMf      d"eNfdlZtd<eeMeeM   f   dme
eU   d e1de
ejv                     d"e	dj   f
dnZu	 dd<eMdoe
e'   de
e;   dfe
eeMeMf      d"e	dj   f
dpZv	 dd<eeMeeM   f   de
e(   de
e;   dfe
eeMeMf      d"e	dj   f
dqZwd<eeMeeM   f   de
e;   de
e*   d"e	dj   fdrZxd<eMde
e;   dse
eM   d"e	dj   fdtZy	 dd e1de8d$e
e*   fduZzd e1de8fdvZ{de
e(   d e
e1   de8fdwZ|d<eMdxeMd"eNfdyZ}d<eMdzeUd"eNfd{Z~d<eMdxeMd"eNfd|ZdxeMd"eNfd}ZdeKde
e(   d e
e1   fd~Zdge	d   deeM   de
e%   fdZy)z
Got Valid Token from Cache, DB
Run checks for:

1. If user can call model
2. If user is in budget
3. If end_user ('user' passed to /chat/completions, /embeddings endpoint) is in budget
    N)TYPE_CHECKINGAnyDictListLiteralOptionalUnioncast)Requeststatus)	BaseModel)verbose_proxy_logger)	DualCache)LimitedSizeOrderedDict)DEFAULT_IN_MEMORY_TTL-DEFAULT_MANAGEMENT_OBJECT_IN_MEMORY_CACHE_TTLDEFAULT_MAX_RECURSE_DEPTH)get_llm_provider)
RBAC_ROLESCallInfoLiteLLM_EndUserTableLitellm_EntityTypeLiteLLM_JWTAuthLiteLLM_ObjectPermissionTable#LiteLLM_OrganizationMembershipTableLiteLLM_OrganizationTableLiteLLM_TeamTableLiteLLM_TeamTableCachedObjLiteLLM_UserTableLiteLLMRoutesLitellmUserRolesProxyErrorTypesProxyExceptionRoleBasedPermissionsSpecialModelNamesUserAPIKeyAuth)RouteChecksroute_request)PrismaClientProxyLogginglog_db_metrics)Router)get_utc_datetime   )$organization_role_based_access_check)get_model_from_request)Spand   )max_sizerequest_bodyteam_objectuser_objectend_user_objectglobal_proxy_spendgeneral_settingsroute
llm_routerproxy_logging_objvalid_tokenrequestreturnc           
      "  K   t        | |      }|'|j                  du rt        d|j                   d      |rg|ret	        ||||	r|	j
                  nd      sHt        d|j                   d| d|j                   t        j                  d	t        j                  
      |r||t        |||       d{    t        |||	       d{    ||j                  h|f|j                  Z|j                  }||j                  k  r?t!        j"                  |j                  |d|j$                   d|j                   d|       |r|j&                  f|j&                  j                  }|N|j                  |kD  r?t!        j"                  |j                  |d|j$                   d|j                   d|       |j)                  dd      2|d   du r+t+        j,                  |      rd| vrt        d|d          t         j                  dkD  rZ|Xt+        j,                  |      rB|dk7  r=|dk7  r8|t         j                  kD  r%t!        j"                  |t         j                        | j)                  di       xs i }|j)                  d      r$ddlm}  ||      }|du rddlm}  |dd d!i"      t7        ||| #       t9        |	d$d      }||d%k(  rd&nd'}t;        ||||
| |	(      }t=        | ||	)       d{    y7 O7 <7 w)*a  
    Common checks across jwt + key-based auth.

    1. If team is blocked
    2. If team can call model
    3. If team is in budget
    4. If user passed in (JWT or key.user_id) - is in budget
    5. If end_user (either via JWT or 'user' passed to /chat/completions, /embeddings endpoint) is in budget
    6. [OPTIONAL] If 'enforce_end_user' enabled - did developer pass in 'user' param for openai endpoints
    7. [OPTIONAL] If 'litellm.max_budget' is set (>0), is proxy under budget
    8. [OPTIONAL] If guardrails modified - is request allowed to change this
    9. Check if request body is safe
    10. [OPTIONAL] Organization checks - is user_object.organization_id is set, run these checks
    11. [OPTIONAL] Vector store checks - is the object allowed to access the vector store
    NTzTeam=z6 is blocked. Update via `/team/unblock` if your admin.modelr6   r<   team_model_aliasesz'Team not allowed to access model. Team=z, Model=z. Allowed team models = rC   messagetypeparamcoderC   r<   r7   )r6   r=   r>   zExceededBudget: User=z over budget. Spend=z	, Budget=current_cost
max_budgetrF   zExceededBudget: End User=enforce_user_param)r;   userz1'user' param not passed in. 'enforce_user_param'=r   z
/v1/modelsz/modelsrL   rM   metadata
guardrails)can_modify_guardrailsF)HTTPExceptioni  errorz8Your team does not have permission to modify guardrails.)status_codedetail)r7   r;   r5   team_idlitellm-dashboarduiapi)r;   
token_typeuser_objr?   request_datar>   )r5   r6   r>   )r1   blocked	ExceptionrX   can_team_access_modelrD   r#   modelsr"   team_model_access_deniedr   HTTP_401_UNAUTHORIZEDcan_user_call_model_team_max_budget_checkrM   spendlitellmBudgetExceededErroruser_idlitellm_budget_tablegetr'   is_llm_api_route*litellm.proxy.guardrails.guardrail_helpersrS   fastapirT   r0   getattr_is_allowed_routevector_store_access_check)r5   r6   r7   r8   r9   r:   r;   r<   r=   r>   r?   _modeluser_budgetend_user_budget_request_metadatarS   
can_modifyrT   
token_teamr\   _is_route_alloweds                        Z/var/www/Befach/backend/env/lib/python3.12/site-packages/litellm/proxy/auth/auth_checks.pycommon_checksr{   H   s    8 /Ee/F
 ;#6#6$#>K''((^_
 	

 +$#!AL{==RV	
 !A+BUBUAVV^_e^ff~  @K  @R  @R  S  T$==11	  +%+*A!!#
 	
 	
 !+   
	 3 3 ;#"".!,,***--(..&/0C0C/DDXYdYjYjXkkt  vA  uB  C  "'K'K'W)>>II&?+@+@?+R--,22*3O4K4K3LL`apavav`w  xA  BQ  AR  S  	148D12d:''e4|9SCDTUiDjCkl 
 	Q* ((u5\!Y 2 22--/G<N<N  +..z2>D"\*T0=
-W  )u< i6J&:9L+LRW  *! $!   Q	
vs7   B6L8L9LL
H2LLL
LLr]   c                      t         j                  j                  } %t         t              rt         fd|D              ryt         fd|D              ryy)z1
    - Check if the route is a UI used route
    c              3   @   K   | ]  }j                  |        y wN)
startswith.0allowed_router;   s     rz   	<genexpr>z_is_ui_route.<locals>.<genexpr>   s     TM  /Ts   Tc              3   L   K   | ]  }t        j                  |         yw))r;   patternN)r'   _route_matches_patternr   s     rz   r   z_is_ui_route.<locals>.<genexpr>   s)       	**NNs   !$F)r    	ui_routesvalue
isinstancestrany)r;   r]   allowed_routess   `  rz   _is_ui_router      sX     #,,22N 	uc"T^TT 	 + 
     c                 ~    | y | }|j                   }	 t        |      }|S # t        $ r t        j                  cY S w xY wr~   )	user_roler!   
ValueErrorINTERNAL_USER)r]   _user
_user_roleroles       rz   _get_user_roler     sN     EJ.
+ K  .---.s     <<r^   c                     t        |      }|t        d      t        j                  | |       t	        |      st        j
                  ||| |||       y)z<
    - Route b/w api token check and normal token check
    r]   z4Invalid proxy server token passed. valid_token=None.)r;   r>   )r]   r   r;   r?   r^   r>   T)r   r`   r'   should_call_route_is_user_proxy_admin$non_proxy_admin_allowed_routes_check)r;   r?   r^   r>   r]   r   s         rz   _is_api_route_allowedr     s_      2JNOO !!;G288!%#	
 r   c                     | y| j                   (| j                   t        j                  j                  k(  ry| j                   (| j                   t        j                  j                  k(  ryy)NFT)r   r!   PROXY_ADMINr   r   s    rz   r   r   2  sf     	&"2">">"D"DD 	&"2">">"D"DDr   r\   )rZ   r[   c                 H    |dk(  rt        | |      ryt        | ||||      S )z;
    - Route b/w ui token check and normal token check
    rZ   )r;   r]   T)r;   r?   r^   r>   r]   )r   r   )r;   r\   r?   r^   r>   r]   s         rz   rq   rq   E  s4     TlJ$%#
 	
r   
user_router   c                 r    |D ]2  }|t         j                  v r| t         |   j                  v r y|| k(  s2 y y)a	  
    Return if a user is allowed to access route. Helper function for `allowed_routes_check`.

    Parameters:
    - user_route: str - the route the user is trying to call
    - allowed_routes: List[str|LiteLLMRoutes] - the list of allowed routes for the user.
    TF)r    __members__r   )r   r   r   s      rz   _allowed_routes_checkr   ]  sB     (]666mM:@@@j( ( r   r   litellm_proxy_rolesc                    | t         j                  k(  rt        ||j                        }|S | t         j                  k(  rC|j
                  	 t        |ddg      }|S |j
                  t        ||j
                        }|S y)zE
    Check if user -> not admin - allowed to access these routes
    )r   r   openai_routesinfo_routesF)r!   r   r   admin_allowed_routesTEAMteam_allowed_routes)r   r   r   
is_alloweds       rz   allowed_routes_checkr   q  s     $000*!.CC

 	&++	+22: /%6VJ  44@.%2FFJ r   user_api_key_dictrequested_user_idc                     d}| j                   t        j                  k7  r| j                   t        j                  k7  rd}|| j                  | j                  |k(  rd}|S )NTF)r   r!   r   PROXY_ADMIN_VIEW_ONLYrj   )r   r   ret_vals      rz    allowed_route_check_inside_router     sc     G##'7'C'CC''+;+Q+QQ$):)B)B)N$$(99GNr   c                     g }| D ]R  }	 t         |   j                  }t        |t              r|j	                  t        |             n|j	                  |       T |S # t        $ r |j                  |       Y sw xY wr~   )r    r   r   setextendlistKeyErrorappend)r   actual_routes
route_nameroute_values       rz   get_actual_routesr     sy    M$
	-'
399K+s+$$T+%67$$[1 %   	-  ,	-s   AAA98A9end_user_idprisma_clientuser_api_key_cacheparent_otel_spanc                   K   |t        d      | ydj                  |       }dt        fd}|j                  |       d{   }|Ct	        |t
              rt        di |} ||       |S t	        |t              r|} ||       |S 	 |j                  j                  j                  d| id	d
i       d{   }	|	t         |j                  dj                  |       |	       d{    t        di |	j                         }
 ||
       |
S 7 7 \7 ,# t         $ r&}t	        |t        j                        r|Y d}~yd}~ww xY ww)af  
    Returns end user object, if in db.

    Do a isolated check for end user in table vs. doing a combined key + team + user + end-user check, as key might come in frequently for different end-users. Larger call will slowdown query time. This way we get to cache the constant (key/team/user info) and only update based on the changing value (end-user).
    NNo db connectedzend_user_id:{}end_user_objc                     | j                   y | j                   j                  }|1| j                  |kD  r!t        j                  | j                  |      y y )NrP   )rk   rM   rg   rh   ri   )r   ru   s     rz   check_in_budgetz,get_end_user_object.<locals>.check_in_budget  s\    ,,4&;;FF&<+=+=+O--)//O  ,P&r   key)r   rj   rk   Twhereinclude)r   r    )r`   formatr   async_get_cacher   dictdblitellm_endusertablefind_uniqueasync_set_cacherh   ri   )r   r   r   r   r=   _keyr   cached_user_obj
return_objresponse	_responsees               rz   get_end_user_objectr     sw     )**"";/D&:  />>4>HHO"ot,-@@J4)=>(J4&))>>JJk*+T2 K 
 

 O !00 ''4H 1 
 	
 	
 );8==?;	Y/; I
	
  a445Gsa   AEDA	E.D <D=1D .D/'D ED D 	E&EEEErC   team_modelsc                     ddl m} |y| |v ry |t              }|r|j                  |       }t	        |      dkD  rt        |      D ]  \  }}||v s y |D cg c]	  }||vs| }}| |v ryyc c}w )Nr   defaultdictT
model_nameF)collectionsr   r   get_model_access_groupslen	enumerate)rC   r   r<   r   access_groupsidxmfiltered_modelss           rz   model_in_access_groupr     s     (*5d*;M"::e:L
=A
FC M!	
 #.HQ-1GqHOH Is   	A0$A0r   last_db_access_timedb_cache_expiryc                 p    t        j                          }| |vry||    d   y||    d   |||    z
  |k\  ryy)zM
    Prevent calling db repeatedly for items that don't exist in the db.
    Tr   Ftime)r   r   r   current_times       rz   _should_check_dbr     sW     99;L
%%C #/	S	!!	$	,-c22oEr   r   c                 6    |t        j                          f|| <   y r~   r   r   r   r   s      rz   _update_last_db_access_timer   *  s     !&tyy{3r   	rbac_role)rb   routesc                     t        t        t        t              |j	                  dg             }|y|D ]  }|j
                  | k(  st        ||      c S  y)zC
    Get the role based permissions from the general settings.
    role_permissionsN)r
   r   r   r$   rl   r   rp   )r   r:   r   role_based_permissionsrole_based_permissions        rz   _get_role_based_permissionsr   0  se     "*+,/4 %!7 %%20#66 "8 r   c                     t        | |d      S )zH
    Get the models allowed for a user role.

    Used by JWT Auth.
    rb   r   r:   r   r   r   r:   s     rz   get_role_based_modelsr   F  s     ') r   c                     t        | |d      S )z1
    Get the routes allowed for a user role.
    r   r   r   r   s     rz   get_role_based_routesr   W  s     ') r   sso_user_id
user_emailc                   K   d}|3| j                   j                  j                  d|iddi       d{   }||| j                   j                  j                  d|iddi       d{   }|J|Ht	        j
                  | j                   j                  j                  d|j                  id|i             |S 7 7 Tw)	a<  
    Checks if sso user is in db.

    Called when user id match is not found in db.

    - Check if sso_user_id is user_id in db
    - Check if sso_user_id is sso_user_id in db
    - Check if user_email is user_email in db
    - If not, create new user with user_email and sso_user_id and user_id = sso_user_id
    Nr  organization_membershipsTr   r  rj   )r   data)r   litellm_usertabler   
find_firstasynciocreate_taskupdaterj   )r   r  r  r   s       rz   _get_fuzzy_user_objectr  f  s       H&));;GG +./6 H 
 

 J2&));;FF,/6 G 
 

 K$;  2299$h&6&67'5 :  O'

s"   3CB?6C,C-ACCrj   user_id_upsertcheck_db_onlyc	           	      `  K   | y|sI|j                  |        d{   }	|	-t        |	t              rt        di |	S t        |	t              r|	S |t	        d      	 dj                  |       }
t        |
t        t              }|rL|j                  j                  j                  d| iddi	       d{   }|t        |||
       d{   }nd}|m|red| i}t        j                  |j                  t        j                         |j                  j                  j!                  |ddi       d{   }nt        |j"                  Qt%        |j"                        dkD  r9|j"                  D cg c]  }|t'        di |j)                          }}||_        t        di t        |      }|j)                         }|j+                  | |t,               d{    t/        |
|t               |S 7 7 G7 27 c c}w 7 (# t        $ r}t1        d|  d|       d}~ww xY ww)z
    - Check if user id in proxy User Table
    - if valid, return LiteLLM_UserTable object with defined limits
    - if not, then raise an error
    Nr   r   z
user_id:{}r   r   r   rj   r  Tr   )r   r  r  )r  r   r   r   r   ttlr   z$User doesn't exist in db. 'user_id'=z0. Create user via `/user/new` call. Got error - r   )r   r   r   r   r`   r   r   r   r   r   r  r   r  rh   default_internal_user_paramsr
  creater  r   r   
model_dumpr   r   r   r   )rj   r   r   r  r   r=   r  r  r  r   db_access_time_keyshould_check_dbr   new_user_params
membership_dumped_membershipsr   response_dictr   s                      rz   get_user_objectr    s    $   2 B Bw B OO&/40(;?;;O->?&&)**G
)009*" 3+
 *--??KK '*5OQU4V L  H !7"/ +)"  Hw3 77C#**7+O+OP!.!1!1!C!C!J!J(7> "K " 
   --9H556:
 #+"C"C#) 4Nj6K6K6MN# #
 1DH-%7X7	!,,. !00= 1 
 	
 	
 	$" 3	
 Y P$
"#	
  
27);klmkno
 	

s   H.G:A H.AH 6G=7H H A*H 9H:=H 7"HAH !H
"H 9H.=H  H H H 	H+H&&H++H.c                 P   K   |j                  | |t               d {    y 7 w)Nr  )r   r   r   r   r   r=   s       rz   _cache_management_objectr    s-      
,
,u"O -   s   &$&rX   
team_tablec                    K   dj                  |       }t        j                         |_        t        ||||       d {    y 7 w)N
team_id:{}r  )r   r   last_refreshed_atr  )rX   r  r   r=   r   s        rz   _cache_team_objectr#    sF      

g
&C $(99;J 
"-+	  s   =AA Ahashed_tokenuser_api_key_objc                 t   K   | }t        j                          |_        t        ||||       d {    y 7 w)Nr  )r   r"  r  )r$  r%  r   r=   r   s        rz   _cache_key_objectr'    s<      C *.&
"-+	  s   .868c                    K   | }|j                  |       |/|j                  j                  j                  |       d {    y y 7 w)Nr   )delete_cacheinternal_usage_cache
dual_cacheasync_delete_cache)r$  r   r=   r   s       rz   _delete_cache_key_objectr-  )  s]     
 C###, $44??RR S 
 	
 	
 %	
s   A AA	Ateam_id_upsertc                    K   |j                   j                  j                  d| i       d {   }|2|r0|j                   j                  j                  d| i       d {   }|S 7 :7 w)NrX   r   )r  )r   litellm_teamtabler   r  )rX   r   r.  r   s       rz   _get_team_db_checkr2  9  s      #%%77CC'" D  H N&));;BBW% C 
 
 O

s!   ,A-A)3A-"A+#A-+A-c                 n   K   |j                   j                  j                  d| i       d {   S 7 w)NrX   r0  )r   r1  r   )rX   r   s     rz   _get_team_object_from_dbr4  I  s=     !!33??'" @    s   ,535c                    K   |}t        |||      }	|	rt        | ||       d {   }
nd }
|
t        t        di |
j	                         }t        | |||       d {    t        |||       |S 7 O7 w)Nr  )rX   r   r.  )rX   r  r   r=   r   r   )r   r2  r`   r   r   r#  r   )rX   r   r   r   r   r=   r   r.  r  r  r   r   s               rz   (_get_team_object_from_user_api_key_cacher6  O  s      &/'O
 +=
 
 *=X]]_=I
-+	    / 3
s!   $A:A6:A:!A8"A:8A:c                 <  K   d }|E|j                   j                  r/|j                   j                  j                  | |       d {   }||j                  |        d {   }|-t        |t              rt        di |S t        |t
              r|S y 7 P7 6w)N)r   r   r   r   )r*  r+  r   r   r   r   )r   r=   r   r   cached_team_objs        rz   _get_team_object_from_cacher9  |  s      =AO 	%22== $88CCSS*: T   	  2 B Bs B KK"ot,-@@@)CD"" Ls$   ABBB#B$5BBcheck_cache_onlyc           
      *  K   |t        d      dj                  |       }|s,t        ||||       d{   }	|	|	S |rt        d|  d      	 t        | |||t        t
        ||       d{   S 7 =7 # t         $ r t        d|  d	      w xY ww)
z
    - Check if team id in proxy Team Table
    - if valid, return LiteLLM_TeamTable object with defined limits
    - if not, then raise an error

    Raises:
        - Exception: If team doesn't exist in db or cache
    NFNo DB Connected. See - https://docs.litellm.ai/docs/proxy/virtual_keysr!  )r   r=   r   r   z:Team doesn't exist in cache + check_cache_only=True. Team=.)rX   r   r   r=   r   r   r   r.  zTeam doesn't exist in db. Team=z#. Create team via `/team/new` call.)r`   r   r9  r6  r   r   )
rX   r   r   r   r=   r:  r  r.  r   r8  s
             rz   get_team_objectr>    s     $ T
 	

 

g
&C ;/1-	!
 
 &""LWIUVW 

='1/ 3+)	
 	
 		
#
"	
  
-gY6YZ
 	

s9   3BA3BA7 .A5/A7 2B5A7 7BBc                   F    e Zd Zededefd       Zededee   fd       Z	y)ExperimentalUIJWTToken	user_infor@   c                 d   ddl m} ddlm} | j                  t        d      t                |d      z   }|j                  d      d d d	z   }t        d
d
d
t        j                  d|| j                  d| j                  d t        | j                              } ||j                  d            S )Nr   )	timedelta)encrypt_value_helperz/User role is required for experimental UI login
   )minutesz%Y-%m-%dT%H:%M:%S.%fz+00:00zui-tokenr3   rY   )tokenkey_name	key_aliasrM   	rpm_limitexpiresrj   rX   rb   max_parallel_requestsr   Texclude_none)datetimerC  0litellm.proxy.common_utils.encrypt_decrypt_utilsrD  r   r`   r.   strftimer&   rh   max_ui_session_budgetrj   rb   r!   model_dump_json)rA  rC  rD  expiration_timerL  r>   s         rz   (get_experimental_ui_login_jwt_auth_tokenz?ExperimentalUIJWTToken.get_experimental_ui_login_jwt_auth_token  s    &	
 &MNN +,y/DD "**+AB3BG(R$ 44%%'##"&&y':':;
 $K$?$?T$?$RSSr   r$  c           	          dd l }ddlm} ddlm}  || dd      }|y 	  |d
i |j                  |      S # t        $ r}t        d|  d| d	|       d }~ww xY w)Nr   )r&   )decrypt_value_helperui_hash_keydebug)r   exception_typezInvalid hash key. Hash key=z. Decrypted token=z	. Error: r   )json$litellm.proxy.auth.user_api_key_authr&   rQ  rX  loadsr`   )r$  r\  r&   rX  decrypted_tokenr   s         rz   get_key_object_from_ui_hash_keyz6ExperimentalUIJWTToken.get_key_object_from_ui_hash_key  s     	G	
 /mG
 "	!@DJJ$?@@ 	-l^;MoM^^ghigjk 	s   7 	A AAN)
__name__
__module____qualname__staticmethodr   r   rV  r   r&   r`  r   r   rz   r@  r@    sR    T<M TRU T T@ 	.	! r   r@  c                   K   |t        d      | }|j                  |       d{   }|-t        |t              rt	        di |S t        |t              r|S |rt        d| d      |j                  | d||       d{   }|:t        dj                  |       t        j                  d	t        j                  
      t	        di |j                  d      }	t        | |	||       d{    |	S 7 7 v7 
w)z
    - Check if team id in proxy Team Table
    - if valid, return LiteLLM_TeamTable object with defined limits
    - if not, then raise an error
    Nr<  r   z8Key doesn't exist in cache + check_cache_only=True. key=r=  combined_view)rH  
table_namer   r=   zvAuthentication Error, Invalid proxy server token passed. key={}, not found in db. Create key via `/key/generate` call.r   rE   TrN  )r$  r%  r   r=   r   )r`   r   r   r   r&   get_datar#   r   r"   token_not_found_in_dbr   rd   r  r'  )
r$  r   r   r   r=   r:  r   cached_key_obj_valid_tokenr   s
             rz   get_key_objectrl    sU     T
 	

 C5G5W5W 6X 6 0N !nd+!3N337!!Fse1M
 	

 /<.D.D")+	 /E / )L  M  T  T !66--
 	
 L!8!8d!8!KLI !"-+	   W0 )(s5   %C?C9AC?C;A-C?2C=3C?;C?=C?org_idc                 v  K   |t        d      |j                  dj                  |             }|-t        |t              rt        d	i |S t        |t
              r|S 	 |j                  j                  j                  d| i       d{   }|t         |S 7 # t         $ r t        d|  d      w xY ww)
z
    - Check if org id in proxy Org Table
    - if valid, return LiteLLM_OrganizationTable object
    - if not, then raise an error
    Nr<  z	org_id:{}r   organization_idr0  z/Organization doesn't exist in db. Organization=z3. Create organization via `/organization/new` call.r   )	r`   r   r   r   r   r   r   litellm_organizationtabler   )rm  r   r   r   r=   cached_org_objr   s          rz   get_org_objectrr  U  s      T
 	

 (77K<N<Nv<V7WN!nd+,>~>>(AB!!
&))CCOO$f- P 
 
 O
  
=fXExy
 	

s0   AB9!+B BB B9B B66B9rb   rD   object_type)rO   teamr   orgfallback_depthTc           
         |t         k\  rt        dj                  |             t        | t              r| D ]  }t        ||||||dz           y| t        j                  v rt        j                  |    } n%|r#| |j                  v r|j                  |       }|r|} ddl
m}  |t              }	|r|j                  |       }	t        |	      dkD  r|t        |      D ]  \  }
}||	v s y |D cg c]	  }||	vs| }}t        | |      ryt!        | |	      ryd
}t        |      dk(  rt        |      dk(  sd|v rd}t"        j$                  j&                  |v rd}| D| |vr@|d
u r<t)        | d| d| d|  t+        j,                  |      dt.        j0                        t3        j4                  d| d|        yc c}w )a  
    Checks if token can call a given model

    Args:
        - model: str
        - llm_router: Optional[Router]
        - models: List[str]
        - team_model_aliases: Optional[Dict[str, str]]
        - object_type: Literal["user", "team", "key", "org"]. We use the object type to raise the correct exception type

    Returns:
        - True: if token allowed to call model

    Raises:
        - Exception: If token not allowed to call model
    zGUnable to parse model, max fallback depth exceeded - received model: {}r/   )rC   r<   rb   rD   rs  rv  Tr   r   r   rC   rD   rC   allowed_model_listF*z# not allowed to access model. This z can only access models=z. Tried to access )rs  rC   rE   zfiltered allowed_models: z
; models: )r   r`   r   r   r   _can_object_call_modelrh   model_alias_mapmodel_group_alias_get_model_from_aliasr   r   r   r   r   _model_in_team_aliases+_model_matches_any_wildcard_pattern_in_listr%   all_proxy_modelsr   r#   r"   &get_model_access_error_type_for_objectr   rd   r   rZ  )rC   r<   rb   rD   rs  rv  r   rs   r   r   r   r   all_model_accesss                rz   r|  r|  ~  s&   0 22U\\
 	

 %A"%#5'-1  '''''.	!=!==11%8E (*5d*;M"::e:L 	MQ:#9
FC M!	
 #)CQA],BqCOCE>PQ2 "O!c&kQ&63/;Q))//?BU/9>NRW>W"m#F{mSklrks  tF  GL  FM  N GG' --
 	
 
#O#4JvhG ? Ds   .	F>8F>c                     |r| |v ryy)a  
    Returns True if `model` being accessed is an alias of a team model

    - `model=gpt-4o`
    - `team_model_aliases={"gpt-4o": "gpt-4o-team-1"}`
        - returns True

    - `model=gp-4o`
    - `team_model_aliases={"o-3": "o3-preview"}`
        - returns False
    TFr   rx  s     rz   r  r    s     &&r   llm_model_listc                 R   K   t        | ||j                  |j                  d      S w)z
    Checks if token can call a given model

    Returns:
        - True: if token allowed to call model

    Raises:
        - Exception: If token not allowed to call model
    r   rC   r<   rb   rD   rs  )r|  rb   rD   )rC   r  r>   r<   s       rz   can_key_call_modelr    s0      "!!&99 s   %'
org_objectc                 >    t        | ||r|j                  ng |d      S )@
    Returns True if the team can access a specific model.

    ru  r  r|  rb   )rC   r  r<   rD   s       rz   can_org_access_modelr    s*     "$.z  B- r   c                 >    t        | ||r|j                  ng |d      S )r  rt  r  r  rB   s       rz   ra   ra   "  s*     "%0{!!b- r   c                    K   |yt         j                  j                  |j                  v r.t	        d|  t
        j                  dt        j                        t        | ||j                  d      S w)NTzeUser not allowed to access model. No default model access, only team models allowed. Tried to access rC   rE   rO   )rC   r<   rb   rs  )
r%   no_default_modelsr   rb   r#   r"   key_model_access_deniedr   rd   r|  rJ   s      rz   re   re   5  s     
 **00K4F4FF{  }B  |C  D 88--	
 	
 "!!	 s   A1A3
user_modelc                 L   K   t        | dddgd||d       d{    y7 w)	z
    Try to route the fallback model request.

    Validate if it can't be routed.

    Help catch invalid fallback models.
    rO   zWho was Alexander?)r   content)rC   messagesacompletion)r  r<   r  
route_typeNTr(   )rC   r<   r  s      rz   is_valid_fallback_modelr  M  sC      "(5IJK
     s   $"$c           
        K   | j                   | j                  d}||j                  }t        | j                  | j                   | j                  | j
                  | j                  || j                  t        j                        }t        j                  |j                  d|             | j                   | j                  k\  r+t        j                  | j                   | j                        yyyw)z
    Raises:
        BudgetExceededError if the token is over it's max budget.
        Triggers a budget alert if the token is over it's max budget.

    N)rH  rg   rM   rj   rX   r  rJ  event_grouptoken_budgetrG   rA  rP   )rg   rM   r  r   rH  rj   rX   rJ  r   KEYr  r	  budget_alertsrh   ri   )r>   r=   r]   r  	call_infos        rz   _virtual_key_max_budget_checkr  f  s      $)?)?)K
 
!,,J####"--''''!!++*..	
	 	++## , 	
  6 66--(..&11  7? *L$s   C3C5c                   K   | j                   r| j                  | j                   k\  rt        j                  d| j                  | j                  | j                          t        | j                  | j                  | j                  | j                   | j                  | j                  | j                  d| j                  t        j                  
      }t        j                  |j                  d|             yyyw)zI
    Triggers a budget alert if the token is over it's soft budget.

    z:Crossed Soft Budget for token %s, spend %s, soft_budget %sN)
rH  rg   rM   soft_budgetrj   rX   
team_aliasr  rJ  r  r  r  )r  rg   r   rZ  rH  r   rM   rj   rX   r  rJ  r   r  r  r	  r  )r>   r=   r  s      rz   _virtual_key_soft_budget_checkr    s      ;#4#48O8O#O""H##		
 ####"--#//''''"--!++*..
	 	++"# , 	
' $Ps   C8C:c           
      (  K   | | j                   | j                  | j                  | j                   kD  r|rt        |j                  | j                  | j                   |j                  |j
                  |j                  t        j                        }t        j                  |j                  d|             t        j                  | j                  | j                   d| j
                   d| j                   d| j                          yyyyw)	z
    Check if the team is over it's max budget.

    Raises:
        BudgetExceededError if the team is over it's max budget.
        Triggers a budget alert if the team is over it's max budget.
    N)rH  rg   rM   rj   rX   r  r  team_budgetr  zBudget has been exceeded! Team=z Current cost: z, Max budget: rK   )rM   rg   r   rH  rj   rX   r  r   r   r  r	  r  rh   ri   )r6   r>   r=   r  s       rz   rf   rf     s+     	"".) 6 66 !''!''&11#++#++&11.33I !//&' 0  ))$**"--5k6I6I5J/ZeZkZkYllz  |G  |R  |R  {S  T
 	
' 7 * / 	 s   DDallowed_model_patternc                 v    d|v r5d|j                  dd       d}t        t        j                  ||             S y)a~  
    Check if a model matches an allowed pattern.
    Handles exact matches and wildcard patterns.

    Args:
        model (str): The model to check (e.g., "bedrock/anthropic.claude-3-5-sonnet-20240620")
        allowed_model_pattern (str): The allowed pattern (e.g., "bedrock/*", "*", "openai/*")

    Returns:
        bool: True if model matches the pattern, False otherwise
    r{  ^z.*$F)replaceboolrematch)rC   r  r   s      rz   is_model_allowed_by_patternr    sC     ##+33C>?qABHHWe,--r   rz  c                 Z     t         fd|D              ryt         fd|D              ryy)ae  
    Returns True if a model matches any wildcard pattern in a list.

    eg.
    - model=`bedrock/us.amazon.nova-micro-v1:0`, allowed_models=`bedrock/*` returns True
    - model=`bedrock/us.amazon.nova-micro-v1:0`, allowed_models=`bedrock/us.*` returns True
    - model=`bedrockzzzz/us.amazon.nova-micro-v1:0`, allowed_models=`bedrock/*` returns False
    c              3   R   K   | ]  }t        |      xr t        |          ywrC   r  N)_is_wildcard_patternr  r   r  rC   s     rz   r   z>_model_matches_any_wildcard_pattern_in_list.<locals>.<genexpr>  s9      
 "	 	23 	
'/D
	
   $'Tc              3   R   K   | ]  }t        |      xr t        |          ywr  )r  3_model_custom_llm_provider_matches_wildcard_patternr  s     rz   r   z>_model_matches_any_wildcard_pattern_in_list.<locals>.<genexpr>  s9      
 "	 	23 	
?/D
	
r  F)r   ry  s   ` rz   r  r    s@      
 &8  
 
 &8  r   c                 h    	 t        |       \  } }}}t        | d|  |      S # t        $ r Y yw xY w)z
    Returns True for this scenario:
    - `model=gpt-4o`
    - `allowed_model_pattern=openai/*`

    or
    - `model=claude-3-5-sonnet-20240620`
    - `allowed_model_pattern=anthropic/*`
    )rC   F/r  )r   r`   r  )rC   r  custom_llm_provider_s       rz   r  r    sP    +;%+H("Aq '$%Qug.3   s   % 	11c                 
    d| v S )zb
    Returns True if the pattern is a wildcard pattern.

    Checks if `*` is in the pattern.
    r{  r   )r  s    rz   r  r  0  s     '''r   c                   K   ddl m} |t        j                  d       yt        j
                  t        j                  d       yt        j
                  j                  | | j                  dd            }|t        j                  d	       y|V|j                  J|j                  j                  j                  d
|j                  i       d{   }|t        d||       |V|j                  J|j                  j                  j                  d
|j                  i       d{   }|t        d||       y7 m7 w)z
    Checks if the object (key, team, org) has access to the vector store.

    Raises ProxyException if the object (key, team, org) cannot access the specific vector store.
    r   )r   Nz;Prisma client not found, skipping vector store access checkTzCVector store registry not found, skipping vector store access checktools)non_default_paramsr  zAVector store to run not found, skipping vector store access checkobject_permission_idr0  r   )rs  vector_store_ids_to_runobject_permissionsrt  )litellm.proxy.proxy_serverr   r   rZ  rh   vector_store_registryget_vector_store_ids_to_runrl   r  r   litellm_objectpermissiontabler   _can_object_call_vector_stores)r5   r6   r>   r   r  key_object_permissionteam_object_permissions          rz   rr   rr   9  sp     9
 ""I	
 $$,""Q	
 %;;WW'|/?/?/N X  &""O	
  ;#C#C#O""@@LL-{/O/OP M   	
 !,*!(?#8 ;#C#C#O""@@LL-{/O/OP M   	
 "-*"(?#9
 1s%   CEEAE+E,EE)r   rt  ru  r  r  c                     |y|j                   yt        |j                         dk(  ry|D ]P  }||j                   vst        d| d|j                    t        j                  |       dt
        j                         y)zg
    Raises ProxyException if the object (key, team, org) cannot access the specific vector store.
    Tr   z9User not allowed to access vector store. Tried to access z. Only allowed to access vector_storerE   )vector_storesr   r#   r"   -get_vector_store_access_error_type_for_objectr   rd   )rs  r  r  vector_store_ids       rz   r  r  ~  s     !''/ ++,12"4"B"BB STcSdd}  Q  _  _  ~`  a$RR %11  3 r   r~   )NN)NNNNN)NNN)NrO   r   )__doc__r  r  r   typingr   r   r   r   r   r   r	   r
   ro   r   r   pydanticr   rh   litellm._loggingr   litellm.caching.cachingr   litellm.caching.dual_cacher   litellm.constantsr   r   r   1litellm.litellm_core_utils.get_llm_provider_logicr   litellm.proxy._typesr   r   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   litellm.proxy.auth.route_checksr'   litellm.proxy.route_llm_requestr)   litellm.proxy.utilsr*   r+   r,   litellm.routerr-   litellm.utilsr.   auth_checks_organizationr0   
auth_utilsr1   opentelemetry.tracer2   _Spanr   r   r   r   management_routes
all_routesr   floatr   r  r{   r   r   r   r   rq   r   r   r   r   r   r   r   r   r   r   intr   r   r   r   r   r  r  r  r#  r'  r-  r2  r4  r6  r9  r>  r@  rl  rr  r|  r  r  r  ra   re   r  r  r  rf   r  r  r  r  rr   r  r   r   rz   <module>r     s    	  Q Q Q #   1 - = 
 O    ( 8 9 J J ! * J .1DD -c: '((..1P1P1V1VV
__+,_ +,_ 23	_
 !_ _ _  _ $_ .)_ _ 
_H -1() 
2(), -1  .)	
 () 
<8,=#> 2 -1

$
 
 	

 .)
 ()
 

0c 4 D (#$$&&	(# # )# 
#L%} 
 d t  
 (,04>#>L)> "> tn	>
  -> "#> >B%d3i0>Fv>N	<	#9LO	(4	4c]49O4 
#	$ d3i	, d3i" d3i" "& $%%#% %  	%P  (,04!% $$(f
c]f
L)f
 "f
 	f

 tnf
  -f
 #f
 f
 D>f
  f
 f
R	 "  -	* "  -	&$ "  -	&

!
  -
  PT!-?G~ C   &**** "* 0	*
 *  -* 
* TN*  *Z	- " tn	
 ()F (,04'+$(%)9
9
L)9
 "9
 tn	9

  -9
 tn9
 D>9
 TN9
  9
x7 7t 
 (,04'+@@L)@ "@ tn	@
  -@ tn@ @ @F 
 (,04%
%
L)%
 "%
 tn	%

  -%
 '(%
 %
X 489?bd3i b b Ib !c3h0	b
 56b b T]bL @D$,T#s(^$<	(d3i TN   (	
 T]8 48	23   !c3h0	
 T]. 48	d3i +,   !c3h0	
 T]&d3i   +, T]	0   T]	8 -1..#. ().b!
!
#!
H'
+,'
.)'
 $'
Ts 3 4 &$(	B'*	.( ( (BB+,B .)BJ-.!#Y !!>?r   