[Bug Fix] Fix Server root path regression on UI when using "Login" (#13267)

* bug fix serve_login_page

* test_serve_login_page_server_root_path
This commit is contained in:
Ishaan Jaff 2025-08-04 15:58:28 -07:00
parent ccbc81af8d
commit 6310eeffa4
2 changed files with 55 additions and 8 deletions

View file

@ -116,6 +116,14 @@ async def serve_login_page(
missing_env_vars = show_missing_vars_in_env()
if missing_env_vars is not None:
return missing_env_vars
#########################################################
# Construct Redirect URL
base_url_to_redirect_to: Optional[str] = None
base_url_to_redirect_to = os.getenv("PROXY_BASE_URL", "")
server_root_path = os.getenv("SERVER_ROOT_PATH", "")
if server_root_path != "":
base_url_to_redirect_to += server_root_path
#########################################################
# Build the unified login page HTML
error_message = ""
@ -137,7 +145,7 @@ async def serve_login_page(
sso_button = ""
if sso_available:
sso_button = """
sso_button = f"""
<div style="
margin-top: 20px;
padding-top: 20px;
@ -149,7 +157,7 @@ async def serve_login_page(
font-size: 14px;
margin-bottom: 16px;
">or</p>
<a href="/sso/login" style="
<a href="{base_url_to_redirect_to}/sso/login" style="
display: inline-block;
background-color: #f8fafc;
border: 1px solid #e2e8f0;
@ -168,12 +176,7 @@ async def serve_login_page(
"""
# Get the base URL for form action using proper URL construction
url_to_redirect_to = os.getenv("PROXY_BASE_URL", "")
server_root_path = os.getenv("SERVER_ROOT_PATH", "")
if server_root_path != "":
url_to_redirect_to += server_root_path
url_to_redirect_to += "/login"
url_to_redirect_to = f"{base_url_to_redirect_to}/login"
unified_login_html = f"""
<!DOCTYPE html>
<html lang="en">

View file

@ -1245,3 +1245,47 @@ class TestCustomUISSO:
# Verify the result is the redirect response
assert result == mock_redirect_response
assert result.status_code == 303
@pytest.mark.asyncio
async def test_serve_login_page_server_root_path():
"""
Test that serve_login_page includes SERVER_ROOT_PATH in the SSO login URL
when SERVER_ROOT_PATH is set.
"""
# Arrange
mock_request = MagicMock(spec=Request)
captured_html = ""
# Mock environment variables
env_vars = {
"PROXY_BASE_URL": "https://example.com",
"SERVER_ROOT_PATH": "/api/v1",
"GOOGLE_CLIENT_ID": "mock_google_client_id", # Enable SSO
"DATABASE_URL": "mock_db_url", # Satisfy show_missing_vars_in_env
"LITELLM_MASTER_KEY": "mock_master_key", # Satisfy show_missing_vars_in_env
}
# Patch HTMLResponse to capture the content
def mock_html_response(content, status_code=200):
nonlocal captured_html
captured_html = content
return MagicMock()
with patch.dict(os.environ, env_vars):
with patch("litellm.proxy.proxy_server.premium_user", True):
with patch("litellm.proxy.proxy_server.prisma_client", MagicMock()):
with patch("litellm.proxy.proxy_server.master_key", "mock_master_key"):
with patch("fastapi.responses.HTMLResponse", side_effect=mock_html_response):
# Import the function to test
from litellm.proxy.management_endpoints.ui_sso import (
serve_login_page,
)
# Act
result = await serve_login_page(request=mock_request)
# Assert
assert result is not None
expected_url = "https://example.com/api/v1/sso/login"
assert expected_url in captured_html, f"Expected URL '{expected_url}' not found in HTML content"