Ë
    tPêjo"  ã                   ó  — U d Z ddlmZmZ ddlmZ ddlmZ ddl­ de	de
dz  d	efd
„Zde
deee   e	eedz  f   f   fd„Z	 dde	de
dz  defd„Z edh«      Zeed<   dZeed<   	 dd	ede	deegeedz     f   dedz  de	f
d„Zy)z
Auth Checks for Organizations
é    )Ú	AwaitableÚCallable)ÚFinal)Ústatus)Ú*Úrequest_bodyÚuser_objectNÚroutec           
      ó¾  — |€y| j                  dd«      }|dk(  ri|j                  t        j                  j                  k7  rBt        d|j                  › �t        j                  j                  dt        j                  ¬«      ‚|j                  t        j                  j                  k(  ry|t        j                  j                  v �r5t        |«      \  }}|j                  €9t        d|› d�t        j                  j                  dt        j                  ¬«      ‚|€5t        d	t        j                  j                  dt        j                  ¬«      ‚|j                  |«      }|€9t        d
|› d�t        j                  j                  dt        j                  ¬«      ‚|t        j                  j                  k7  rAt        d|› d|› d|› d|› �t        j                  j                  dt        j                  ¬«      ‚y|dk(  rÛt        |«      \  }}|j                  �Àt        |j                  «      dkD  r§|€8t        d|› �t        j                  j                  dt        j                  ¬«      ‚|j                  |«      }|t        j                  j                  k7  r>t        d|› d|› d|› �t        j                  j                  dt        j                  ¬«      ‚yyyy)a^  
    Role based access control checks only run if a user is part of an Organization

    Organization Checks:
    ONLY RUN IF user_object.organization_memberships is not None

    1. Only Proxy Admins can access /organization/new
    2. IF route is a LiteLLMRoutes.org_admin_only_routes, then check if user is an Org Admin for that organization

    NÚorganization_idz/organization/newz8Only proxy admins can create new organizations. You are Ú	user_role)ÚmessageÚtypeÚparamÚcodezTried to access route=z` but you are not a member of any organization. Please contact the proxy admin to request access.zNPassed organization_id is None, please pass an organization_id in your requestzQYou do not have a role within the selected organization. Passed organization_id: z:. Please contact the organization admin to request access.z-You do not have the required role to perform z in Organization z. Your role is z	/team/newr   z|Passed organization_id is None, please specify the organization_id in your request. You are part of multiple organizations: z*You do not have the required role to call )Úgetr   ÚLitellmUserRolesÚPROXY_ADMINÚvalueÚProxyExceptionÚProxyErrorTypesÚ
auth_errorr   ÚHTTP_401_UNAUTHORIZEDÚLiteLLMRoutesÚorg_admin_only_routesÚget_user_organization_infoÚorganization_membershipsÚ	ORG_ADMINÚlen)r   r	   r
   Úpassed_organization_idÚ_user_organizationsÚ_user_organization_role_mappingr   Ú_user_role_in_passed_orgs           úp/home/oem/CyberBrain26-unified/.venv/lib/python3.12/site-packages/litellm/proxy/auth/auth_checks_organization.pyÚ$organization_role_based_access_checkr%      sB  € ð  ÐØà0<×0@Ñ0@ÐARÐTXÓ0YÐàÐ#Ò#Ø× Ñ Ô$4×$@Ñ$@×$FÑ$FÒFÜ ØRÐS^×ShÑShÐRiÐjÜ$×/Ñ/×5Ñ5Ø!Ü×1Ñ1ô	ð ð ×ÑÔ 0× <Ñ <× BÑ BÒBØð ”×3Ñ3×9Ñ9Ò9ô ' {Ó3ñ	
ØØ+ð ×/Ñ/Ð7Ü Ø0°°ð  8Xð  YÜ$×/Ñ/×5Ñ5Ø'Ü×1Ñ1ô	ð ð "Ð)Ü ØhÜ$×/Ñ/×5Ñ5Ø'Ü×1Ñ1ô	ð ð 5T×4WÑ4WÐXnÓ4oˆ	ØÐÜ Økð  mCð  lDð  D~ð  Ü$×/Ñ/×5Ñ5Ø'Ü×1Ñ1ô	ð ð Ô(×2Ñ2×8Ñ8Ò8Ü ØGÈÀwÐN_Ð`vÐ_wð  xGð  HQð  GRð  Rcð  dzð  c{ð  |Ü$×/Ñ/×5Ñ5Ø!Ü×1Ñ1ô	ð ð 9ð 
�+Ò	ô
 ' {Ó3ñ	
ØØ+à×/Ñ/Ð;ÄÀK×DhÑDhÓ@iÐlmÒ@mØ%Ð-Ü$ð [ð  \oð  [pð  qÜ(×3Ñ3×9Ñ9Ø+Ü×5Ñ5ô	ð ð /N×.QÑ.QÐRhÓ.iÐ$Ø'Ô+;×+EÑ+E×+KÑ+KÒKÜ$ØHÈÈÈÐ_wÐ^xð  yJð  Kað  Jbð  cÜ(×3Ñ3×9Ñ9Ø%Ü×5Ñ5ô	ð ð Lð AnÐ;ð 
ó    Úreturnc                 óÎ   — g }i }| j                   �R| j                   D ]C  }|j                  €Œ|j                  |j                  «       |j                  ||j                  <   ŒE ||fS )aŽ  
    Helper function to extract user organization information.

    Args:
        user_object (LiteLLM_UserTable): The user object containing organization memberships.

    Returns:
        Tuple[List[str], Dict[str, Optional[LitellmUserRoles]]]: A tuple containing:
            - List of organization IDs the user is a member of
            - Dictionary mapping organization IDs to user roles
    )r   r   Úappendr   )r	   r!   r"   Ú_memberships       r$   r   r   n   sx   € ð -/ÐØQSÐ#à×+Ñ+Ð7Ø&×?Ñ?ò 	eˆKØ×*Ñ*Ñ6Ø#×*Ñ*¨;×+FÑ+FÔGØOZ×OdÑOdÐ/°×0KÑ0KÒLð	eð
 Ð ?Ð?Ð?r&   Úrequest_datac                 ó¾  ‡— |€y|j                   €yg }| j                  dd«      }|�|j                  |«       | j                  dd«      }t        |t        «      r|j                  |«       |sy|j                   D �ch c]A  }|j                  t        j                  j                  k(  r|j                  �|j                  ’ŒC c}Št        ˆfd„|D «       «      S c c}w )uì   
    Helper function to check if user is an org admin for all of the passed organizations.

    Checks both:
    - `organization_id` (singular string) â€” legacy callers
    - `organizations` (list of strings) â€” used by /user/new
    NFr   Úorganizationsc              3   ó&   •K  — | ]  }|‰v –— Œ
 y ­w©N© )Ú.0Úorg_idÚadmin_org_idss     €r$   ú	<genexpr>z%_user_is_org_admin.<locals>.<genexpr>­   s   øè ø€ ÒG¨6ˆv˜Ô&ÑGùs   ƒ)r   r   r)   Ú
isinstanceÚlistÚextendr   r   r   r   r   Úall)r+   r	   Úcandidate_org_idsÚsingularÚ	orgs_listr*   r3   s         @r$   Ú_user_is_org_adminr<   ˆ   sá   ø€ ð ÐØà×+Ñ+Ð3Øð +-ÐØ"×&Ñ&Ð'8¸$Ó?€HØÐØ× Ñ  Ô*Ø#×'Ñ'¨¸Ó>€IÜ�)œTÔ"Ø× Ñ  Ô+áØð
 '×?Ñ?öàØ× Ñ Ô$4×$>Ñ$>×$DÑ$DÒDÈ×IdÑIdÐIpð 	×#Ó#ò€Mô ÓGÐ5FÔGÓGÐGùòs   Á=ACz/team/updateÚTEAM_ORG_CONTEXT_ROUTESz/team/{team_id}ÚPATCH_TEAM_ROUTE_TEMPLATEÚfetch_team_org_idÚroute_templatec              ƒ   ó
  K  — |j                  d«      r|S | t        v r|j                  d«      }n!|t        k(  r| j                  dd«      d   }n|S t	        |t
        «      r|s|S  ||«      ƒ d{  –—† }|s|S i |¥d|i¥S 7 Œ­w)a—  
    Return a copy of request_body with organization_id resolved from the target
    team when the route identifies the team by team_id and the caller did not
    pass organization_id. This lets an org admin of the team's own org reach the
    org-scoped branch of the route gate (which keys off organization_id) without
    the client having to send it. Returns request_body unchanged when it does
    not apply, so callers that already pass organization_id and non-team routes
    are untouched.

    The team_id is taken from the body for TEAM_ORG_CONTEXT_ROUTES, or from the
    last path segment when ``route_template`` is the ``/team/{team_id}`` route.
    r   Úteam_idú/é   éÿÿÿÿN)r   r=   r>   Úrsplitr5   Ústr)r
   r   r?   r@   rB   r2   s         r$   Ú$add_team_org_context_to_request_bodyrH   ·   sš   è ø€ ð$ ×ÑÐ)Ô*ØÐàÔ'Ñ'Ø*×.Ñ.¨yÓ9‰Ø	Ô4Ò	4Ø—,‘,˜s AÓ& rÑ*‰àÐä�gœsÔ#©7ØÐÙ+¨GÓ4×4€FÙØÐØ6ˆlÐ6Ð-¨vÑ6Ð6ð 5ús   ‚A.BÁ0BÁ1Br/   )Ú__doc__Úcollections.abcr   r   Útypingr   Úfastapir   Úlitellm.proxy._typesÚdictÚLiteLLM_UserTablerG   r%   Útupler6   r   r   Úboolr<   Ú	frozensetr=   Ú__annotations__r>   rH   r0   r&   r$   ú<module>rT      s  ðò÷ 0Ý å ä "ð^Øð^à" TÑ)ð^ð ó^ðB@Ø"ð@à
ˆ4�‰9�d˜3Ð 0°4Ñ 7Ð7Ñ8Ð8Ñ9ó@ð8 -1ñ%HØð%Hà" TÑ)ð%Hð 
ó%HñP "+¨NÐ+;Ó!<Ð ˜Ó <ð $5Ð ˜5Ó 4ð "&ñ	!7Øð!7àð!7ð     y°°t±Ñ'<Ð <Ñ=ð!7ð ˜$‘Jð	!7ð
 
ô!7r&   