
    gw                        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
 ddlmZmZmZ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mZmZmZmZmZmZm Z m!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/m0Z0 ddl1m2Z2 ddl3m4Z4 ddl5m6Z6 erddl7m8Z8 nddlmZ8  e       Z9e9ju                  ddgd      defd       Z;de%fdZ<dede%de=de=de	e8   f
dZ>d  Z?d!ed"ee=   fd#Z@d$ ZAe9ju                  d%dgd      defd&       ZB	 d-d'e	e8   d(e	e   defd)ZCe9ju                  d*dgd ee'      g+      defd,       ZDy).z
Has all /sso/* routes

/sso/key/generate - handles user signing in with SSO and redirects to /sso/callback
/sso/callback - returns JWT Redirect Response that redirects to LiteLLM UI
    N)TYPE_CHECKINGAnyDictListOptionalcast)	APIRouterDependsHTTPExceptionRequeststatus)RedirectResponse)verbose_proxy_logger)MAX_SPENDLOG_ROWS_TO_QUERY)	LitellmUserRolesMemberNewUserRequestNewUserResponseProxyErrorTypesProxyExceptionSSOUserDefinedValuesTeamMemberAddRequestUserAPIKeyAuth)_has_user_setup_sso)
JWTHandler)user_api_key_auth)admin_ui_disabled	html_formshow_missing_vars_in_env)new_user)check_is_admin_only_accesshas_admin_ui_access)team_member_add)CustomOpenID)str_to_bool)OpenID)r   z/sso/key/generateexperimentalF)tagsinclude_in_schemarequestc                 :	  K   ddl m} t        j                  dd      }t        j                  dd      }t        j                  dd      }t        j                  d      }|t	        |      }|r
t               S |||/|d	ur+t        d
t        j                  dt        j                        t               }||S t        j                  dt        | j                              }t        j                  d      }	|j                  d      r|dz  }n|dz  }|ddlm}
 t        j                  dd      }|+t        dt        j                  dt        j"                         |
|||      }t%        j&                  d| d|        |5  |j)                          d{   cddd       S |ddlm} t        j                  dd      }t        j                  dd      }|+t        dt        j                  dt        j"                         |||||d	      }|5  |j)                          d{   cddd       S |ddlm} ddlm} t        j                  dd      }t        j                  d d!      j7                  d"      }t        j                  d#d      }t        j                  d$d      }t        j                  d%d      }|+t        d&t        j                  dt        j"                        |+t        d't        j                  d#t        j"                        |+t        d(t        j                  d$t        j"                        |+t        d)t        j                  d%t        j"                        t%        j8                  d*| d+| d,|        t%        j8                  d-| d.| d/        ||||0      } |d1|2      } ||||d	|3      }|5  i }t        j                  d4d      }|r||d5<   n%d6|v r!t;        j<                         j>                  |d5<    |j(                  d:i | d{   cddd       S |	dd7l m!}  |tD        d89      S dd7l m!}  |tD        d89      S 7 # 1 sw Y   yxY w7 N# 1 sw Y   yxY w7 U# 1 sw Y   yxY ww);z
    Create Proxy API Keys using Google Workspace SSO. Requires setting PROXY_BASE_URL in .env
    PROXY_BASE_URL should be the your deployed proxy endpoint, e.g. PROXY_BASE_URL="https://litellm-production-7002.up.railway.app/"
    Example:
    r   )premium_userMICROSOFT_CLIENT_IDNGOOGLE_CLIENT_IDGENERIC_CLIENT_IDDISABLE_ADMIN_UI)valueTa}  You must be a LiteLLM Enterprise user to use SSO. If you have a license please set `LITELLM_LICENSE` in your env. If you want to obtain a license meet with us here: https://calendly.com/d/4mp-gd3-k5k/litellm-1-1-onboarding-chat You are seeing this error message because You set one of `MICROSOFT_CLIENT_ID`, `GOOGLE_CLIENT_ID`, or `GENERIC_CLIENT_ID` in your env. Please unset thisr,   messagetypeparamcodePROXY_BASE_URLUI_USERNAME/sso/callback/sso/callback	GoogleSSOGOOGLE_CLIENT_SECRET1GOOGLE_CLIENT_SECRET not set. Set it in .env file)	client_idclient_secretredirect_uriz5In /google-login/key/generate, 
GOOGLE_REDIRECT_URI: z
GOOGLE_CLIENT_ID: MicrosoftSSOMICROSOFT_CLIENT_SECRETMICROSOFT_TENANT4MICROSOFT_CLIENT_SECRET not set. Set it in .env filer@   rA   tenantrB   allow_insecure_httpDiscoveryDocumentcreate_providerGENERIC_CLIENT_SECRETGENERIC_SCOPEopenid email profile GENERIC_AUTHORIZATION_ENDPOINTGENERIC_TOKEN_ENDPOINTGENERIC_USERINFO_ENDPOINT2GENERIC_CLIENT_SECRET not set. Set it in .env file;GENERIC_AUTHORIZATION_ENDPOINT not set. Set it in .env file3GENERIC_TOKEN_ENDPOINT not set. Set it in .env file6GENERIC_USERINFO_ENDPOINT not set. Set it in .env fileauthorization_endpoint: 
token_endpoint: 
userinfo_endpoint: GENERIC_REDIRECT_URI: 
GENERIC_CLIENT_ID: 
authorization_endpointtoken_endpointuserinfo_endpointoidc)namediscovery_documentr@   rA   rB   rJ   scopeGENERIC_CLIENT_STATEstateokta)HTMLResponse   )contentstatus_code )#litellm.proxy.proxy_serverr,   osgetenvr%   r   r   r   
auth_errorr   HTTP_403_FORBIDDENr   strbase_urlendswithfastapi_sso.sso.googler=   HTTP_500_INTERNAL_SERVER_ERRORr   infoget_login_redirectfastapi_sso.sso.microsoftrD   fastapi_sso.sso.baserL   fastapi_sso.sso.genericrN   splitdebuguuiduuid4hexfastapi.responsesrl   r   )r*   r,   microsoft_client_idgoogle_client_idgeneric_client_id_disable_ui_flagis_disabledmissing_env_varsredirect_urlui_usernamer=   google_client_secret
google_ssorD   microsoft_client_secretmicrosoft_tenantmicrosoft_ssorL   rN   generic_client_secretgeneric_scopegeneric_authorization_endpointgeneric_token_endpointgeneric_userinfo_endpoint	discoverySSOProvidergeneric_ssoredirect_paramsrj   rl   s                                 ^/var/www/openai/venv/lib/python3.12/site-packages/litellm/proxy/management_endpoints/ui_sso.pygoogle_loginr   7   s     8))$94@yy!3T:		"5t< yy!34#!(89$&& 	''(t#  X$//$..	  01# 99-s73C3C/DEL))M*KS!&'#4!yy)?F' K$//,::	  &.%


 	!!D\NRfgwfxy	
 #6688 Z 
	(:"$)),Et"L99%7>"* N$///::	  %)1#% $
 &99;; ]		&:; "		*A4 H		/3IJPPQTU)+,d*
& "$+CT!J$&II.I4$P! ( L$//-::	  *1 U$//6::	  ") M$//.::	  %, P$//1::	  	""&'E&FFXYoXp  qF  G`  Fa  b	
 	""$\N2GHYGZZ\]	
 &#A17
	
 &6iP!'/% $
 
 !OII4d;E+0(99JJL$$  ( 877J/JJ [ 
	  	3I3??2I3??S 9 Z. < ]T K [s   FR
Q2Q/Q2"A:RR0Q>1R4F(RAR7R8R;4R/Q22Q;7R>RR
RRRRjwt_handlerc                 R   t        j                  dd      }t        j                  dd      }t        j                  dd      }t        j                  dd      }t        j                  d	d
      }t        j                  dd      }t        j                  d| d|        t	        | j                  |      | j                  |      | j                  |      | j                  |      | j                  |      | j                  |      |j                  t        t        |                   S )NGENERIC_USER_ID_ATTRIBUTEpreferred_username#GENERIC_USER_DISPLAY_NAME_ATTRIBUTEsubGENERIC_USER_EMAIL_ATTRIBUTEemail!GENERIC_USER_FIRST_NAME_ATTRIBUTE
first_name GENERIC_USER_LAST_NAME_ATTRIBUTE	last_nameGENERIC_USER_PROVIDER_ATTRIBUTEproviderz! generic_user_id_attribute_name: z%
 generic_user_email_attribute_name: )iddisplay_namer   r   r   r   team_ids)	rr   rs   r   r   r$   getget_team_ids_from_jwtr   dict)responser   generic_user_id_attribute_name(generic_user_display_name_attribute_name!generic_user_email_attribute_name&generic_user_first_name_attribute_name%generic_user_last_name_attribute_namegeneric_provider_attribute_names           r   generic_response_convertorr      s'   %'YY#%9&" 02yy-u0, )+		&)% .0YY+\.* -/II*K-) ')ii):'# 
+,J+KKq  sT  rU  	V <<67\\"JKll<=<< FG,,DE=>224h3GH     r   r   returnc                 0  K   ddl m} ddlm} t	        j
                  dd       }t	        j
                  dd      j                  d      }t	        j
                  dd       }t	        j
                  d	d       }	t	        j
                  d
d       }
t	        j
                  dd      j                         dk(  }|+t        dt        j                  dt        j                        |+t        dt        j                  dt        j                        |	+t        dt        j                  d	t        j                        |
+t        dt        j                  d
t        j                        t        j                  d| d|	 d|
        t        j                  d| d| d        |||	|
      }fd} |d||      } ||||d|      }t        j                  d       |j                  | d |i!       d {   }t        j                  d"|       |S 7 w)#Nr   rK   rM   rO   rP   rQ   rR   rS   rT   rU   GENERIC_INCLUDE_CLIENT_IDfalsetruerV   r2   rW   rX   rY   rZ   r[   r\   r]   r^   r_   r`   c                     t        |       S )N)r   r   )r   )r   clientr   s     r   response_convertorz4get_generic_sso_response.<locals>.response_convertorF  s    )#
 	
r   rd   )re   rf   r   Trg   z&calling generic_sso.verify_and_processinclude_client_id)paramszgeneric result: %s)r~   rL   r   rN   rr   rs   r   lowerr   r   rt   r   rz   r   r   verify_and_process)r*   r   r   r   rL   rN   r   r   r   r   r   generic_include_client_idr   r   r   r   results    `               r   get_generic_sso_responser     sK     77II&=tDIIo/EFLLSQM%'YY/OQU%V"YY'?F "		*Et L
		-w7==?6I  $H ++)66	
 	
 &-Q ++266	
 	
 %I ++*66	
 	
 !(L ++-66	
 	
 
"#A"BBTUkTl  mB  C\  B]  	^ 
 .CDUCVVXY "=-3I
 "$-K
 #+! K GH11,.GH 2  F 3V<M	s   G4H7H8Hc           	      *  K   	 t        |j                  d      }t        ||       }t        |t	        t
        j                        t        ddd      	       d
{   S 7 # t        $ r"}t        j                  d|        Y d
}~y
d
}~ww xY ww)z,Create a task for adding a member to a team.user)user_idrole)memberteam_id)	user_rolehttpr;   )r4   path)rh   )datauser_api_key_dicthttp_requestN3[Non-Blocking] Error trying to add sso user to db: )r   r   r   r#   r   r   PROXY_ADMINr   	Exceptionr   r   )r   	user_infor   team_member_add_requestes        r   create_team_member_add_taskr   `  s     
	 1 1?"6#
 %(,7G7S7ST 'PQ
 
 	
 

  
""A!E	
 	

sA   BAA% A#A% "B#A% %	B.BBBBr   	sso_teamsc                 T  K   | j                   yt        |      t        | j                         z
  }t        |      }g }|D cg c]  }t        ||        }}	 t	        j
                  |  d{    yc c}w 7 
# t        $ r"}t        j                  d|        Y d}~yd}~ww xY ww)zq
    - Get missing teams (diff b/w user_info.team_ids and sso_teams)
    - Add missing user to missing teams
    Nr   )	teamssetlistr   asynciogatherr   r   r   )r   r   missing_teamsmissing_teams_listtasksr   r   s          r   add_missing_team_memberr   s  s     
 	NS%99Mm,E *)G 	$GY7) 
 

nne$$$ 	% 
""A!E	
 	

sN   A B(A3B(A: -A8.A: 2B(8A: :	B%B B( B%%B(c                      t         j                  } | y| j                  d      xs i }|j                  d      xs g }t        d|v       S )NFpersonal_key_generationallowed_user_rolesproxy_admin)litellmkey_generation_settingsr   bool)r   r   r   s      r   ,get_disabled_non_admin_personal_key_creationr     sZ    %==&##$=>D"  1445IJPb!3344r   r;   c                   K   ddl m} ddlm}m}m}m}m}m}m	} t        j                  dd      }	t        j                  dd      }
t        j                  dd      }|+t        dt        j                  d	t        j                   
      t        j                  dt#        | j$                              }|j'                  d      r|dz  }n|dz  }d}|
nddlm} t        j                  dd      }|+t        dt        j                  dt        j                   
       ||
||      }|j-                  |        d{   }n|	ddlm} t        j                  dd      }t        j                  dd      }|+t        dt        j                  dt        j                   
      |+t        dt        j                  dt        j                   
       ||	|||d      }|j-                  |        d{   }n|t3        | |||       d{   }t5        |dd      }|t5        |dd      nd}|pt        j                  d      [|j7                  d      d   }t        j                  d      j7                  d       }||vrt9        d!d"d#j;                  ||      i$      |?|=t        j                  d%d&      }t5        |dd      }t5        |dd      }t5        ||d      }|)|'t5        |d'd(      xs d(}t5        |d)d(      xs d(}||z   }||t=        |      dk(  r|}d}g }t>        j@                  }t>        jB                  } d*t>        jD                  i i dd+d,}!d}"|1tG        jH                  |      r ||       d{   }"ntK        d-      |tM        ||||d| .      }"|}#d}	 |X|jO                  |d/0       d{   }tQ        jR                  d1| d2t>        jT                          |0|jV                  jX                  j[                  d3|i4       d{   }||tM        t5        |d5|      |t5        |d3|      t5        |d6d      t5        |d7|      t5        |d8|       9      }"t5        |d6d      }|jV                  jX                  j]                  d3|id:|i;       d{    n3t_        ||"<       d{   }|j`                  xs tb        jd                  }t5        |d=g       }$tg        ||$>       d{    |"ti        d@      tQ        jj                  dA|"        |!jm                  |"       dB|!dC<    |dWi |!dDdBi d{   }&|&dE   }'|&d:   }||#k(  sJ dF}(|xs tb        jd                  jn                  }t        j                  dGd      0t        jp                  dG   |k(  rtb        jr                  jn                  }tQ        jR                  dH| dI|        tu        |      })|)r"tw        |      }*|*st9        d!dJdK| dL| i$      ty               }+ddl=},|,j}                  ||'||dM||j                  dNdO      |+dP|dQR      }-|t        |t"              r|(dS|z   z  }(t        |(dTU      }.|.j                  dE|-dV       |.S 7 O7 7 7 7 7 ~7 7 7 # th        $ r#}%tQ        jR                  d?|%        Y d}%~%d}%~%ww xY w7 w)XzVerify loginr   )generate_key_helper_fn)general_settingsr   
master_keyr,   prisma_clientui_access_modeuser_custom_ssor-   Nr.   r/   zMaster Key not set for Proxy. Please set Master Key to use Admin UI. Set `LITELLM_MASTER_KEY` in .env or set general_settings:master_key in config.yaml.  https://docs.litellm.ai/docs/proxy/virtual_keys. If set, use `--detailed_debug` to debug issue.r   r2   r7   r9   r:   r;   r<   r>   r?   )r@   rB   rA   rC   rE   rF   rG   z-MICROSOFT_TENANT not set. Set it in .env fileTrH   )r*   r   r   r   r   r   ALLOWED_EMAIL_DOMAINS@   ,i  r3   zZThe email domain={}, is not an allowed email domain={}. Contact your admin to change this.)ro   detailGENERIC_USER_ROLE_ATTRIBUTEr   r    r   24hrzlitellm-dashboard)durationkey_max_budgetaliasesconfigspendr   z,user_custom_sso must be a coroutine function)modelsr   
user_email
max_budgetr   budget_durationr   )r   
table_namezuser_info: z(; litellm.default_internal_user_params: r  )wherer  r   r  r  )r  r   r  r   r  r  r   )r	  r   )result_openiduser_defined_valuesr   )r   r   r   zUnable to map user identity to known values. 'user_defined_values' is None. File an issue - https://github.com/BerriAI/litellm/issuesz)user_defined_values for creating ui key: keyrequest_typer  tokenz/ui/PROXY_ADMIN_IDzuser_role: z; ui_access_mode: errorz,User not allowed to access proxy. User role=z, proxy mode=ssolitellm_key_header_nameAuthorization)r   r  r  r   login_methodr,   auth_header_name(disabled_non_admin_personal_key_creationHS256)	algorithmz?userID=i/  )urlro   )r  r1   securerp   )C;litellm.proxy.management_endpoints.key_management_endpointsr   rq   r   r   r   r,   r   r   r   rr   rs   r   r   rt   r   rz   rv   rw   rx   ry   r=   r   r}   rD   r   getattrr   r   formatlenr   max_internal_user_budgetinternal_user_budget_durationmax_ui_session_budgetr   iscoroutinefunction
ValueErrorr   get_datar   r   default_internal_user_paramsdblitellm_usertable
find_firstupdate_manyinsert_sso_userr   r   INTERNAL_USER_VIEW_ONLYr   r   r{   updater1   environr   r!   r"   r   jwtencoder   
isinstancer   
set_cookie)/r*   r   r   r   r   r,   r   r   r   r   r   r   r   r   r=   r   r   rD   r   r   r   r  r   email_domainallowed_domains generic_user_role_attribute_namer   _first_name
_last_namer   user_id_modelsr  r   default_ui_key_valuesr  _user_id_from_ssor   r   r   r  litellm_dashboard_uiis_admin_only_access
has_accessr  r.  	jwt_tokenredirect_responses/                                                  r   auth_callbackr?    s       ))$94@yy!3T:		"5t< P ++66	
 	
 99-s73C3C/DELS!&'F#4!yy)?F' K$//,::	  &%.


 "44W==		(:"$)),Et"L99%7>"* N$///::	  # G$//(::	  %)1#% $
 %77@@		&/#/%	
 
 !( >J<B<NWVT48TXG")),C"D"P!'',Q/))$;<BB3G.{   C   C$o   $);+-99)6,
( &$-VWd3
F$DdK	6-flB7=2V["5;

*7?c'la6GIN&??$+$I$I!
 !77&- ;?"&&7(7(?"?KLL		2!!/9
  I0
$+44WQW4XXI &&i[(PQXQuQuPvw  "/"2"2"D"D"O"O'4 #P # 	 $)<&:"9hG#&y,
K%idC&!<1I  %,!#46S%'# $I{DA	 $&&88DD'4Iw;O E   
 #2"((;# 	 ''S+;+S+S   
B7I)ISSS " T
 	
 
34G3HI   !45,1.)+ 
 H
 7
Cy!G ''''!K-EEKKI
		"D)5JJ'(G3 %0066	
i[ 2>2BC 6nE(3
KI;Vcdrcst  	56 - 

$"!( 0 4 4)?! 9a	
 	  I  z'37
W 44(-AsS  WId KC >6 A
v #@" Y*
 T 
""A!E	
 	

 s   D9[;Z
<B4[0Z1[
ZE3[>Z?'['Z%  ZAZ% ZBZ% 'Z(Z% =Z>?Z% =Z">Z% A
[[D>[[[[Z% Z% Z% Z% "Z% %	[.[[[[r
  r  c                 t  K   t        j                  d|        |t        d      t        j                  r|j                  t        j                         |j                  d      t        j                  j                  k(  rH|j                  d      t        j                  |d<   |j                  d      t        j                  |d<   |d   t        j                  |d<   t        |d   |d   |d   |d   |d   	      }| rd
| j                  i|_        t!        |t#                      d{   }|S 7 w)ar  
    Helper function to create a New User in LiteLLM DB after a successful SSO login

    Args:
        result_openid (OpenID): User information in OpenID format if the login was successful.
        user_defined_values (Optional[SSOUserDefinedValues], optional): LiteLLM SSOValues / fields that were read

    Returns:
        Tuple[str, str]: User ID and User Role
    z)Inserting SSO user into DB. User values: Nzuser_defined_values is Noner   r  r  r   r  )r   r  r   r  r  auth_provider)r   r   )r   r   r#  r   r%  r,  r   r   INTERNAL_USERr1   r  r   r+  r   r   metadatar    r   )r
  r  new_user_requestr   s       r   r*  r*    sF     
34G3HI "677++""7#G#GH {+/?/M/M/S/SS""<08070P0P-""#45=55   12 ;'/+;+S+SK(%#I.&|4%k2&|4+,=> %4m6L6L$M!#3~GWXXHO Ys   D-D8/D60D8z/sso/get/ui_settings)r(   r)   dependenciesc                 z  K   ddl m}m} t        j                  dd       }t        j                  dd       }t               }|j                  d      t        kD  }|j                  dd      }dt        j                  v r&t        j                  d   j                         d	k(  rd
}|||||j                  d      |dS w)Nr   )r   proxy_stater7   PROXY_LOGOUT_URLspend_logs_row_countdefault_team_disabledFPROXY_DEFAULT_TEAM_DISABLEDr   T)r7   rH  DEFAULT_TEAM_DISABLEDSSO_ENABLEDNUM_SPEND_LOGS_ROWSDISABLE_EXPENSIVE_DB_QUERIES)rq   r   rG  rr   rs   r   get_proxy_state_variabler   r   r-  r   )r*   r   rG  _proxy_base_url_logout_url_is_sso_enableddisable_expensive_db_queriesrJ  s           r   get_ui_settingsrU    s      Iii 0$7O)).5K)+O,,-CD
$	% ! -001H%P$

2::34::<F$(! *'!6&*CC" 
 )E	 	s   B9B;)N)E__doc__r   rr   r   typingr   r   r   r   r   r   fastapir	   r
   r   r   r   r   r   r   litellm._loggingr   litellm.constantsr   litellm.proxy._typesr   r   r   r   r   r   r   r   r   litellm.proxy.auth.auth_utilsr   litellm.proxy.auth.handle_jwtr   $litellm.proxy.auth.user_api_key_authr   )litellm.proxy.common_utils.admin_ui_utilsr   r   r   :litellm.proxy.management_endpoints.internal_user_endpointsr    3litellm.proxy.management_endpoints.sso_helper_utilsr!   r"   1litellm.proxy.management_endpoints.team_endpointsr#   (litellm.proxy.management_endpoints.typesr$   litellm.secret_managers.mainr%   r~   r&   routerr   r   r   rv   r   r   r   r   r?  r*  rU  rp   r   r   <module>rf     s    	  A A F F .  1 8
 
 
 > 4 B 
 P N A 4+$	 ~&6%Pk@ k@ Qk@\"j "JRRR R 	R
 fRj
&
_ 
c 
.5 O>"2eLR R MRn ;?1F#1!"671 1h 
	+,-	  7 r   