fix: extend fetch_user error guard; escape HTML in login page

Move field-extraction inside the try/except in fetch_user so non-dict
responses from providers with empty profile_data_path (Gitea, GitHub)
raise OAuthError instead of an uncaught AttributeError. Apply
html.escape() to provider name, label, and logo URL in the login page.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-09 08:57:25 -04:00
parent 0e8250362e
commit a4a6c1e3d9
2 changed files with 10 additions and 10 deletions
+4 -3
View File
@@ -2,6 +2,7 @@
import asyncio import asyncio
import datetime import datetime
import html as _html
import json import json
import platform import platform
import socket import socket
@@ -630,10 +631,10 @@ async def start(
if _providers: if _providers:
buttons_html = "" buttons_html = ""
for _p in _providers: for _p in _providers:
_logo = f'<img src="{_p.logo}" alt="" class="oauth-logo">' if _p.logo else "" _logo = f'<img src="{_html.escape(_p.logo)}" alt="" class="oauth-logo">' if _p.logo else ""
buttons_html += f""" buttons_html += f"""
<a href="/login/oauth/{_p.name}" class="oauth-btn"> <a href="/login/oauth/{_html.escape(_p.name)}" class="oauth-btn">
{_logo}{_p.label} {_logo}{_html.escape(_p.label)}
</a>""" </a>"""
oauth_buttons = f""" oauth_buttons = f"""
<div class="divider">or</div>{buttons_html}""" <div class="divider">or</div>{buttons_html}"""
+6 -7
View File
@@ -244,12 +244,11 @@ async def fetch_user(provider: ResolvedProvider, token: str) -> dict:
try: try:
for key in provider.profile_data_path: for key in provider.profile_data_path:
data = data.get(key, {}) data = data.get(key, {})
avatar_field = provider.field_map.get("avatar")
return {
"login": data.get(provider.field_map["username"], ""),
"full_name": data.get(provider.field_map["full_name"], ""),
"avatar_url": data.get(avatar_field, "") if avatar_field else "",
}
except AttributeError: except AttributeError:
raise OAuthError(f"Unexpected profile response structure from {provider.type}") raise OAuthError(f"Unexpected profile response structure from {provider.type}")
avatar_field = provider.field_map.get("avatar")
return {
"login": data.get(provider.field_map["username"], ""),
"full_name": data.get(provider.field_map["full_name"], ""),
"avatar_url": data.get(avatar_field, "") if avatar_field else "",
}