From c338bdc683522b00070d56530690e062f7a7d568 Mon Sep 17 00:00:00 2001 From: Untone Date: Sun, 28 Sep 2025 20:52:17 +0300 Subject: [PATCH] oauth-github --- auth/oauth.py | 59 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 37 insertions(+), 22 deletions(-) diff --git a/auth/oauth.py b/auth/oauth.py index e519ca61..413fab28 100644 --- a/auth/oauth.py +++ b/auth/oauth.py @@ -233,30 +233,45 @@ PROVIDER_HANDLERS = { async def _fetch_github_profile(client: Any, token: Any) -> dict: """Получает профиль из GitHub API""" try: - # Получаем основной профиль - profile = await client.get("user", token=token) - profile_data = profile.json() + # Извлекаем access_token из ответа + access_token = token.get("access_token") if isinstance(token, dict) else token - # Проверяем наличие ошибок в ответе GitHub - if "message" in profile_data: - logger.error(f"GitHub API error: {profile_data['message']}") + if not access_token: + logger.error("No access_token found in GitHub token response") return {} - # Получаем email адреса (требует scope user:email) - emails = await client.get("user/emails", token=token) - emails_data = emails.json() - - # Ищем основной email - primary_email = None - if isinstance(emails_data, list): - primary_email = next((email["email"] for email in emails_data if email.get("primary")), None) - - return { - "id": str(profile_data.get("id", "")), - "email": primary_email or profile_data.get("email"), - "name": profile_data.get("name") or profile_data.get("login", ""), - "picture": profile_data.get("avatar_url"), + # Используем прямой HTTP запрос к GitHub API + headers = { + "Authorization": f"Bearer {access_token}", + "Accept": "application/vnd.github.v3+json", + "User-Agent": "Discours-OAuth-Client", } + + async with httpx.AsyncClient() as http_client: + # Получаем основной профиль + profile_response = await http_client.get("https://api.github.com/user", headers=headers) + + if profile_response.status_code != 200: + logger.error(f"GitHub API error: {profile_response.status_code} - {profile_response.text}") + return {} + + profile_data = profile_response.json() + + # Получаем email адреса (требует scope user:email) + emails_response = await http_client.get("https://api.github.com/user/emails", headers=headers) + emails_data = emails_response.json() if emails_response.status_code == 200 else [] + + # Ищем основной email + primary_email = None + if isinstance(emails_data, list): + primary_email = next((email["email"] for email in emails_data if email.get("primary")), None) + + return { + "id": str(profile_data.get("id", "")), + "email": primary_email or profile_data.get("email"), + "name": profile_data.get("name") or profile_data.get("login", ""), + "picture": profile_data.get("avatar_url"), + } except Exception as e: logger.error(f"Error fetching GitHub profile: {e}") return {} @@ -694,7 +709,7 @@ async def oauth_callback_http(request: Request) -> JSONResponse | RedirectRespon "telegram": "https://oauth.telegram.org/auth/token", "facebook": "https://graph.facebook.com/v18.0/oauth/access_token", } - + token_endpoint = token_endpoints.get(provider) if not token_endpoint: logger.error(f"❌ Unknown token endpoint for provider: {provider}") @@ -739,7 +754,7 @@ async def oauth_callback_http(request: Request) -> JSONResponse | RedirectRespon "google": "https://oauth2.googleapis.com/token", "github": "https://github.com/login/oauth/access_token", } - + token_endpoint = token_endpoints.get(provider) if not token_endpoint: logger.error(f"❌ Unknown token endpoint for provider: {provider}")