mypyfix
Some checks failed
Deploy on push / deploy (push) Failing after 36s

This commit is contained in:
2025-09-27 12:31:53 +03:00
parent ee799120f6
commit 0f6cc61286
2 changed files with 109 additions and 2 deletions

View File

@@ -680,6 +680,14 @@ async def oauth_callback_http(request: Request) -> JSONResponse | RedirectRespon
client = oauth.create_client(provider)
if not client:
logger.warning(f"🚨 OAuth provider {provider} not configured - returning graceful error")
# Проверяем конфигурацию провайдера
from settings import OAUTH_CLIENTS
provider_config = OAUTH_CLIENTS.get(provider.upper(), {})
logger.error(
f"🚨 OAuth config for {provider}: client_id={'***' if provider_config.get('id') else 'MISSING'}, client_secret={'***' if provider_config.get('key') else 'MISSING'}"
)
# Graceful fallback: редиректим на фронтенд с информативной ошибкой
redirect_uri = oauth_data.get("redirect_uri", FRONTEND_URL)
error_url = f"{redirect_uri}?error=provider_not_configured&provider={provider}&message=OAuth+provider+credentials+missing"
@@ -692,6 +700,9 @@ async def oauth_callback_http(request: Request) -> JSONResponse | RedirectRespon
# 🔍 Обмениваем code на токен - с PKCE или без в зависимости от провайдера
logger.info("🔄 Step 1: Exchanging authorization code for access token...")
logger.info(f"🔧 Authorization response URL: {request.url}")
logger.info(f"🔧 Code parameter: {code[:20]}..." if code and len(code) > 20 else f"🔧 Code parameter: {code}")
try:
if provider in ["vk", "yandex", "telegram", "facebook"]:
# Провайдеры без PKCE поддержки (Facebook может иметь проблемы с PKCE)
@@ -707,12 +718,15 @@ async def oauth_callback_http(request: Request) -> JSONResponse | RedirectRespon
return JSONResponse({"error": "Missing code verifier in OAuth state"}, status_code=400)
logger.info(f"🔧 Using OAuth with PKCE for {provider}")
logger.info(f"🔧 Code verifier length: {len(code_verifier) if code_verifier else 0}")
token = await client.fetch_access_token(
authorization_response=str(request.url),
code_verifier=code_verifier,
)
except Exception as e:
logger.error(f"❌ Failed to fetch access token for {provider}: {e}", exc_info=True)
logger.error(f"❌ Request URL: {request.url}")
logger.error(f"❌ OAuth data: {oauth_data}")
raise # Re-raise для обработки в основном except блоке
if not token:
logger.error(f"❌ Failed to get access token for {provider}")
@@ -848,9 +862,30 @@ async def oauth_callback_http(request: Request) -> JSONResponse | RedirectRespon
logger.error(f"OAuth callback error for {provider}: {e!s}", exc_info=True)
logger.error(f"OAuth callback request URL: {request.url}")
logger.error(f"OAuth callback query params: {dict(request.query_params)}")
# В случае ошибки редиректим на фронтенд с ошибкой
fallback_redirect = request.query_params.get("redirect_uri", FRONTEND_URL)
return RedirectResponse(url=f"{fallback_redirect}?error=auth_failed&provider={provider}")
# Используем сохраненный redirect_uri из OAuth state или fallback
try:
state = request.query_params.get("state")
oauth_data = await get_oauth_state(state) if state else None
fallback_redirect = oauth_data.get("redirect_uri") if oauth_data else FRONTEND_URL
except Exception:
fallback_redirect = FRONTEND_URL
# Обеспечиваем что fallback_redirect это строка
if not isinstance(fallback_redirect, str):
fallback_redirect = FRONTEND_URL
# Для testing.discours.io используем специальный формат
if "testing.discours.io" in fallback_redirect:
from urllib.parse import quote
error_url = f"https://testing.discours.io/oauth?error=auth_failed&provider={provider}&redirect_url={quote(fallback_redirect)}"
else:
error_url = f"{fallback_redirect}?error=auth_failed&provider={provider}"
logger.error(f"🚨 Redirecting to error URL: {error_url}")
return RedirectResponse(url=error_url)
async def _create_or_update_user(provider: str, profile: dict) -> Author:

View File

@@ -0,0 +1,72 @@
# 🔍 OAuth Debug Checklist
## 🚨 Проблема: Google callback получает параметры, но фронтенд получает auth_failed
### ✅ Диагностика выполнена:
1. **✅ OAuth Endpoint существует**: `/oauth/google/callback` - роут настроен в `main.py`
2. **⚠️ OAuth провайдеры**: Настроены на продакшн сервере (Dokku), локально отсутствуют
3. **✅ Логирование добавлено**: Детальные логи на каждом этапе OAuth flow
### 🎯 Правильный подход к диагностике продакшн проблем:
### 🔧 Исправления внесены:
1. **Улучшена обработка ошибок**: Правильный redirect на testing.discours.io с error параметрами
2. **Добавлена диагностика**: Проверка конфигурации OAuth провайдеров
3. **Создан скрипт проверки**: `scripts/check_oauth_config.py`
### 🎯 Диагностика продакшн OAuth проблем:
#### 1. Анализ продакшн логов (приоритет):
```bash
# Смотрим логи OAuth callback на продакшн сервере
dokku logs discours --tail 100 | grep -E "(OAuth|callback|google)"
# Ищем конкретные ошибки в логах
dokku logs discours --tail 500 | grep -E "(❌|ERROR|Exception)"
```
#### 2. Проверка переменных окружения на сервере:
```bash
# Проверяем настройки OAuth на продакшн
dokku config:show discours | grep -E "(GOOGLE|GITHUB|OAUTH)"
```
#### 3. Проверка redirect URI в Google Console:
- Должен быть: `https://v3.dscrs.site/oauth/google/callback`
- Проверить точное совпадение URL
- Убедиться что HTTPS включен
#### 4. Тестирование с детальными логами:
- Логи уже добавлены в код
- Смотреть продакшн логи во время OAuth попытки
- Анализировать каждый этап: token exchange, profile fetch, user creation
### 🔍 Логи для мониторинга:
После настройки OAuth провайдеров, логи должны показывать:
```
✅ Got access token for google: True
✅ Got user profile for google: id=..., email=..., name=...
✅ User created/updated for google: user_id=..., email=...
✅ Session token created for google: token_length=...
🔗 OAuth redirect URL: https://testing.discours.io/oauth?redirect_url=...
OAuth успешно завершен для google, user_id=...
```
### 🚨 Критические проверки:
1. **Redirect URI в Google Console** должен точно совпадать с `https://v3.dscrs.site/oauth/google/callback`
2. **HTTPS обязателен** для продакшена
3. **Переменные окружения** должны быть установлены на сервере
4. **Перезапуск сервера** после установки переменных окружения
### 📊 Ожидаемый результат:
После настройки OAuth:
- ✅ Google callback обрабатывается успешно
- ✅ Пользователь создается/обновляется
- ✅ Session token устанавливается в httpOnly cookie
- ✅ Редирект на `https://testing.discours.io/oauth?redirect_url=...`
- ✅ Фронтенд получает успешную аутентификацию