Merge pull request #3952 from BerriAI/litellm_ui_invite_for_spend_viewer

[Feat] Admin UI - invite users to view spend
This commit is contained in:
Ishaan Jaff 2024-05-31 18:36:14 -07:00 committed by GitHub
commit 7bda701b5d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 54 additions and 14 deletions

View file

@ -97,6 +97,7 @@ from litellm.proxy.utils import (
_read_request_body,
_is_valid_team_configs,
_is_user_proxy_admin,
_get_user_role,
_is_projected_spend_over_limit,
_get_projected_spend_over_limit,
update_spend,
@ -1108,7 +1109,7 @@ async def user_api_key_auth(
user_email: Optional[str] = None
# Check if the token has any user id information
if user_id_information is not None:
if user_id_information is not None and len(user_id_information) > 0:
specific_user_id_information = user_id_information[0]
_user_email = specific_user_id_information.get("user_email", None)
if _user_email is not None:
@ -1273,6 +1274,8 @@ async def user_api_key_auth(
if _end_user_object is not None:
valid_token_dict.update(end_user_params)
_user_role = _get_user_role(user_id_information=user_id_information)
if not _is_user_proxy_admin(user_id_information): # if non-admin
if route in LiteLLMRoutes.openai_routes.value:
pass
@ -1326,11 +1329,37 @@ async def user_api_key_auth(
):
pass
elif _user_role == LitellmUserRoles.PROXY_ADMIN_VIEW_ONLY:
if route in LiteLLMRoutes.openai_routes.value:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail=f"user not allowed to access this OpenAI routes, role= {_user_role}",
)
if route in LiteLLMRoutes.management_routes.value:
# the Admin Viewer is only allowed to call /user/update for their own user_id and can only update
if route == "/user/update":
# Check the Request params are valid for PROXY_ADMIN_VIEW_ONLY
if request_data is not None and isinstance(
request_data, dict
):
_params_updated = request_data.keys()
for param in _params_updated:
if param not in ["user_email", "password"]:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail=f"user not allowed to access this route, role= {_user_role}. Trying to access: {route} and updating invalid param: {param}. only user_email and password can be updated",
)
else:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail=f"user not allowed to access this route, role= {_user_role}. Trying to access: {route}",
)
else:
user_role = "unknown"
user_id = "unknown"
if user_id_information is not None and isinstance(
user_id_information, list
user_id_information, list and len(user_id_information) > 0
):
_user = user_id_information[0]
user_role = _user.get("user_role", "unknown")
@ -1365,6 +1394,7 @@ async def user_api_key_auth(
"/global/spend/keys",
"/global/spend/models",
"/global/predict/spend/logs",
"/global/activity",
"/health/services",
]
# check if the current route startswith any of the allowed routes
@ -11869,8 +11899,7 @@ async def onboarding(invite_link: str):
response = await generate_key_helper_fn(
**{
"user_role": LitellmUserRoles.PROXY_ADMIN,
request_type="key",
"user_role": user_obj.user_role,
"duration": "2hr",
"key_max_budget": 5,
"models": [],
@ -11895,7 +11924,7 @@ async def onboarding(invite_link: str):
"user_id": user_obj.user_id,
"key": key,
"user_email": user_obj.user_email,
"user_role": "app_owner",
"user_role": user_obj.user_role,
"login_method": "username_password",
"premium_user": premium_user,
},

View file

@ -2658,6 +2658,17 @@ def _is_user_proxy_admin(user_id_information: Optional[list]):
return False
def _get_user_role(user_id_information: Optional[list]):
if user_id_information is None:
return None
if len(user_id_information) == 0 or user_id_information[0] is None:
return None
_user = user_id_information[0]
return _user.get("user_role")
def encrypt_value(value: str, master_key: str):
import hashlib
import nacl.secret

View file

@ -338,6 +338,15 @@ const AdminPanel: React.FC<AdminPanelProps> = ({
);
console.log(`response for team create call: ${response}`);
// Checking if the team exists in the list and updating or adding accordingly
// Give admin an invite link for inviting user to proxy
const user_id = response.data?.user_id || response.user_id;
invitationCreateCall(accessToken, user_id).then((data) => {
setInvitationLinkData(data);
setIsInvitationLinkModalVisible(true);
});
const foundIndex = admins.findIndex((user) => {
console.log(
`user.user_id=${user.user_id}; response.user_id=${response.user_id}`

View file

@ -28,15 +28,6 @@ const Sidebar: React.FC<SidebarProps> = ({
}
style={{ height: "100%", borderRight: 0 }}
>
<Menu.Item key="4" onClick={() => setPage("api-keys")}>
API Keys
</Menu.Item>
<Menu.Item key="2" onClick={() => setPage("models")}>
Models
</Menu.Item>
<Menu.Item key="3" onClick={() => setPage("llm-playground")}>
Chat UI
</Menu.Item>
<Menu.Item key="1" onClick={() => setPage("usage")}>
Usage
</Menu.Item>