about summary refs log tree commit diff
path: root/.venv/lib/python3.12/site-packages/litellm/proxy/auth/auth_checks_organization.py
diff options
context:
space:
mode:
authorS. Solomon Darnell2025-03-28 21:52:21 -0500
committerS. Solomon Darnell2025-03-28 21:52:21 -0500
commit4a52a71956a8d46fcb7294ac71734504bb09bcc2 (patch)
treeee3dc5af3b6313e921cd920906356f5d4febc4ed /.venv/lib/python3.12/site-packages/litellm/proxy/auth/auth_checks_organization.py
parentcc961e04ba734dd72309fb548a2f97d67d578813 (diff)
downloadgn-ai-master.tar.gz
two version of R2R are here HEAD master
Diffstat (limited to '.venv/lib/python3.12/site-packages/litellm/proxy/auth/auth_checks_organization.py')
-rw-r--r--.venv/lib/python3.12/site-packages/litellm/proxy/auth/auth_checks_organization.py161
1 files changed, 161 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/litellm/proxy/auth/auth_checks_organization.py b/.venv/lib/python3.12/site-packages/litellm/proxy/auth/auth_checks_organization.py
new file mode 100644
index 00000000..3da3d8dd
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/litellm/proxy/auth/auth_checks_organization.py
@@ -0,0 +1,161 @@
+"""
+Auth Checks for Organizations
+"""
+
+from typing import Dict, List, Optional, Tuple
+
+from fastapi import status
+
+from litellm.proxy._types import *
+
+
+def organization_role_based_access_check(
+    request_body: dict,
+    user_object: Optional[LiteLLM_UserTable],
+    route: str,
+):
+    """
+    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
+
+    """
+
+    if user_object is None:
+        return
+
+    passed_organization_id: Optional[str] = request_body.get("organization_id", None)
+
+    if route == "/organization/new":
+        if user_object.user_role != LitellmUserRoles.PROXY_ADMIN.value:
+            raise ProxyException(
+                message=f"Only proxy admins can create new organizations. You are {user_object.user_role}",
+                type=ProxyErrorTypes.auth_error.value,
+                param="user_role",
+                code=status.HTTP_401_UNAUTHORIZED,
+            )
+
+    if user_object.user_role == LitellmUserRoles.PROXY_ADMIN.value:
+        return
+
+    # Checks if route is an Org Admin Only Route
+    if route in LiteLLMRoutes.org_admin_only_routes.value:
+        _user_organizations, _user_organization_role_mapping = (
+            get_user_organization_info(user_object)
+        )
+
+        if user_object.organization_memberships is None:
+            raise ProxyException(
+                message=f"Tried to access route={route} but you are not a member of any organization. Please contact the proxy admin to request access.",
+                type=ProxyErrorTypes.auth_error.value,
+                param="organization_id",
+                code=status.HTTP_401_UNAUTHORIZED,
+            )
+
+        if passed_organization_id is None:
+            raise ProxyException(
+                message="Passed organization_id is None, please pass an organization_id in your request",
+                type=ProxyErrorTypes.auth_error.value,
+                param="organization_id",
+                code=status.HTTP_401_UNAUTHORIZED,
+            )
+
+        user_role: Optional[LitellmUserRoles] = _user_organization_role_mapping.get(
+            passed_organization_id
+        )
+        if user_role is None:
+            raise ProxyException(
+                message=f"You do not have a role within the selected organization. Passed organization_id: {passed_organization_id}. Please contact the organization admin to request access.",
+                type=ProxyErrorTypes.auth_error.value,
+                param="organization_id",
+                code=status.HTTP_401_UNAUTHORIZED,
+            )
+
+        if user_role != LitellmUserRoles.ORG_ADMIN.value:
+            raise ProxyException(
+                message=f"You do not have the required role to perform {route} in Organization {passed_organization_id}. Your role is {user_role} in Organization {passed_organization_id}",
+                type=ProxyErrorTypes.auth_error.value,
+                param="user_role",
+                code=status.HTTP_401_UNAUTHORIZED,
+            )
+    elif route == "/team/new":
+        # if user is part of multiple teams, then they need to specify the organization_id
+        _user_organizations, _user_organization_role_mapping = (
+            get_user_organization_info(user_object)
+        )
+        if (
+            user_object.organization_memberships is not None
+            and len(user_object.organization_memberships) > 0
+        ):
+            if passed_organization_id is None:
+                raise ProxyException(
+                    message=f"Passed organization_id is None, please specify the organization_id in your request. You are part of multiple organizations: {_user_organizations}",
+                    type=ProxyErrorTypes.auth_error.value,
+                    param="organization_id",
+                    code=status.HTTP_401_UNAUTHORIZED,
+                )
+
+            _user_role_in_passed_org = _user_organization_role_mapping.get(
+                passed_organization_id
+            )
+            if _user_role_in_passed_org != LitellmUserRoles.ORG_ADMIN.value:
+                raise ProxyException(
+                    message=f"You do not have the required role to call {route}. Your role is {_user_role_in_passed_org} in Organization {passed_organization_id}",
+                    type=ProxyErrorTypes.auth_error.value,
+                    param="user_role",
+                    code=status.HTTP_401_UNAUTHORIZED,
+                )
+
+
+def get_user_organization_info(
+    user_object: LiteLLM_UserTable,
+) -> Tuple[List[str], Dict[str, Optional[LitellmUserRoles]]]:
+    """
+    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
+    """
+    _user_organizations: List[str] = []
+    _user_organization_role_mapping: Dict[str, Optional[LitellmUserRoles]] = {}
+
+    if user_object.organization_memberships is not None:
+        for _membership in user_object.organization_memberships:
+            if _membership.organization_id is not None:
+                _user_organizations.append(_membership.organization_id)
+                _user_organization_role_mapping[_membership.organization_id] = _membership.user_role  # type: ignore
+
+    return _user_organizations, _user_organization_role_mapping
+
+
+def _user_is_org_admin(
+    request_data: dict,
+    user_object: Optional[LiteLLM_UserTable] = None,
+) -> bool:
+    """
+    Helper function to check if user is an org admin for the passed organization_id
+    """
+    if request_data.get("organization_id", None) is None:
+        return False
+
+    if user_object is None:
+        return False
+
+    if user_object.organization_memberships is None:
+        return False
+
+    for _membership in user_object.organization_memberships:
+        if _membership.organization_id == request_data.get("organization_id", None):
+            if _membership.user_role == LitellmUserRoles.ORG_ADMIN.value:
+                return True
+
+    return False