upgrade schema, resolvers, panel added
This commit is contained in:
122
auth/__init__.py
Normal file
122
auth/__init__.py
Normal file
@@ -0,0 +1,122 @@
|
||||
from starlette.requests import Request
|
||||
from starlette.responses import JSONResponse, RedirectResponse
|
||||
from starlette.routing import Route
|
||||
|
||||
from auth.sessions import SessionManager
|
||||
from auth.internal import verify_internal_auth
|
||||
from auth.orm import Author
|
||||
from services.db import local_session
|
||||
from utils.logger import root_logger as logger
|
||||
from settings import (
|
||||
SESSION_COOKIE_NAME,
|
||||
SESSION_COOKIE_HTTPONLY,
|
||||
SESSION_COOKIE_SECURE,
|
||||
SESSION_COOKIE_SAMESITE,
|
||||
SESSION_COOKIE_MAX_AGE,
|
||||
)
|
||||
|
||||
|
||||
async def logout(request: Request):
|
||||
"""
|
||||
Выход из системы с удалением сессии и cookie.
|
||||
"""
|
||||
# Получаем токен из cookie или заголовка
|
||||
token = request.cookies.get(SESSION_COOKIE_NAME)
|
||||
if not token:
|
||||
# Проверяем заголовок авторизации
|
||||
auth_header = request.headers.get("Authorization")
|
||||
if auth_header and auth_header.startswith("Bearer "):
|
||||
token = auth_header[7:] # Отрезаем "Bearer "
|
||||
|
||||
# Если токен найден, отзываем его
|
||||
if token:
|
||||
try:
|
||||
# Декодируем токен для получения user_id
|
||||
user_id, _ = await verify_internal_auth(token)
|
||||
if user_id:
|
||||
# Отзываем сессию
|
||||
await SessionManager.revoke_session(user_id, token)
|
||||
logger.info(f"[auth] logout: Токен успешно отозван для пользователя {user_id}")
|
||||
else:
|
||||
logger.warning("[auth] logout: Не удалось получить user_id из токена")
|
||||
except Exception as e:
|
||||
logger.error(f"[auth] logout: Ошибка при отзыве токена: {e}")
|
||||
|
||||
# Создаем ответ с редиректом на страницу входа
|
||||
response = RedirectResponse(url="/login")
|
||||
|
||||
# Удаляем cookie с токеном
|
||||
response.delete_cookie(SESSION_COOKIE_NAME)
|
||||
logger.info("[auth] logout: Cookie успешно удалена")
|
||||
|
||||
return response
|
||||
|
||||
|
||||
async def refresh_token(request: Request):
|
||||
"""
|
||||
Обновление токена аутентификации.
|
||||
"""
|
||||
# Получаем текущий токен из cookie или заголовка
|
||||
token = request.cookies.get(SESSION_COOKIE_NAME)
|
||||
if not token:
|
||||
auth_header = request.headers.get("Authorization")
|
||||
if auth_header and auth_header.startswith("Bearer "):
|
||||
token = auth_header[7:] # Отрезаем "Bearer "
|
||||
|
||||
if not token:
|
||||
return JSONResponse({"success": False, "error": "Токен не найден"}, status_code=401)
|
||||
|
||||
try:
|
||||
# Получаем информацию о пользователе из токена
|
||||
user_id, _ = await verify_internal_auth(token)
|
||||
if not user_id:
|
||||
return JSONResponse({"success": False, "error": "Недействительный токен"}, status_code=401)
|
||||
|
||||
# Получаем пользователя из базы данных
|
||||
with local_session() as session:
|
||||
author = session.query(Author).filter(Author.id == user_id).first()
|
||||
|
||||
if not author:
|
||||
return JSONResponse({"success": False, "error": "Пользователь не найден"}, status_code=404)
|
||||
|
||||
# Обновляем сессию (создаем новую и отзываем старую)
|
||||
device_info = {"ip": request.client.host, "user_agent": request.headers.get("user-agent")}
|
||||
new_token = await SessionManager.refresh_session(user_id, token, device_info)
|
||||
|
||||
if not new_token:
|
||||
return JSONResponse(
|
||||
{"success": False, "error": "Не удалось обновить токен"}, status_code=500
|
||||
)
|
||||
|
||||
# Создаем ответ
|
||||
response = JSONResponse(
|
||||
{
|
||||
"success": True,
|
||||
"token": new_token,
|
||||
"author": {"id": author.id, "email": author.email, "name": author.name},
|
||||
}
|
||||
)
|
||||
|
||||
# Устанавливаем cookie с новым токеном
|
||||
response.set_cookie(
|
||||
key=SESSION_COOKIE_NAME,
|
||||
value=new_token,
|
||||
httponly=SESSION_COOKIE_HTTPONLY,
|
||||
secure=SESSION_COOKIE_SECURE,
|
||||
samesite=SESSION_COOKIE_SAMESITE,
|
||||
max_age=SESSION_COOKIE_MAX_AGE,
|
||||
)
|
||||
|
||||
logger.info(f"[auth] refresh_token: Токен успешно обновлен для пользователя {user_id}")
|
||||
return response
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"[auth] refresh_token: Ошибка при обновлении токена: {e}")
|
||||
return JSONResponse({"success": False, "error": str(e)}, status_code=401)
|
||||
|
||||
|
||||
# Маршруты для авторизации
|
||||
routes = [
|
||||
Route("/auth/logout", logout, methods=["GET", "POST"]),
|
||||
Route("/auth/refresh", refresh_token, methods=["POST"]),
|
||||
]
|
Reference in New Issue
Block a user