148 lines
6.2 KiB
Python
148 lines
6.2 KiB
Python
import httpx
|
|
import asyncio
|
|
from app.core import config
|
|
from app.core.database import add_session, logout, get_session
|
|
from app.core.localizer import localizer
|
|
from app.core.http_client import get_client, authorized_get
|
|
|
|
|
|
async def login(login, password):
|
|
"""
|
|
Логин пользователя по логину и паролю.
|
|
|
|
:param login: Логин пользователя
|
|
:param password: Пароль пользователя
|
|
:return: tuple (ok: bool, message: str)
|
|
"""
|
|
url = f"{config.BASE_URL}/v1/auth/login"
|
|
try:
|
|
response = await get_client().post(url, json={"login": login, "password": password})
|
|
|
|
if response.status_code == 200:
|
|
data = response.json()
|
|
if data.get("status") == "fine":
|
|
token_data = data["data"]
|
|
add_session(
|
|
login=login,
|
|
access_token=token_data["access_token"],
|
|
refresh_token=token_data["refresh_token"],
|
|
user_id=token_data.get("user_id"),
|
|
)
|
|
return True, localizer.translate("Вход выполнен успешно")
|
|
return False, data.get("detail", localizer.translate("Неизвестная ошибка"))
|
|
|
|
if response.status_code == 401:
|
|
return False, localizer.translate("Неверный логин или пароль")
|
|
return False, f"{localizer.translate('Ошибка сервера')}: {response.status_code}"
|
|
|
|
except httpx.RequestError as e:
|
|
return False, f"{localizer.translate('Сетевая ошибка')}: {e}"
|
|
except Exception as e:
|
|
return False, f"{localizer.translate('Произошла ошибка')}: {e}"
|
|
|
|
|
|
async def register(login, password, invite=None):
|
|
"""
|
|
Регистрация нового пользователя.
|
|
|
|
:param login: Логин
|
|
:param password: Пароль
|
|
:param invite: Инвайт-код (опционально)
|
|
:return: tuple (ok: bool, message: str)
|
|
"""
|
|
url = f"{config.BASE_URL}/v1/auth/register"
|
|
payload = {"login": login, "password": password}
|
|
if invite:
|
|
payload["invite"] = invite
|
|
|
|
try:
|
|
response = await get_client().post(url, json=payload)
|
|
|
|
if response.status_code == 201:
|
|
return True, localizer.translate("Регистрация прошла успешно!")
|
|
|
|
error_data = response.json()
|
|
error_message = error_data.get("detail", localizer.translate("Произошла ошибка"))
|
|
|
|
if response.status_code == 409:
|
|
return False, localizer.translate("Пользователь уже существует.")
|
|
if response.status_code == 400:
|
|
return False, localizer.translate("Некорректный запрос.")
|
|
if response.status_code == 403:
|
|
return False, localizer.translate("Регистрация по приглашению отключена.")
|
|
if response.status_code == 422:
|
|
return False, localizer.translate("Некорректные входные данные. Проверьте логин и пароль.")
|
|
|
|
return False, f"{localizer.translate('Ошибка сервера')} ({response.status_code}): {error_message}"
|
|
|
|
except httpx.RequestError as e:
|
|
return False, f"{localizer.translate('Сетевая ошибка')}: {e}"
|
|
except Exception as e:
|
|
return False, f"{localizer.translate('Произошла ошибка')}: {e}"
|
|
|
|
|
|
async def refresh_token(access_token: str, refresh_token: str):
|
|
"""
|
|
Обновление пары токенов по refresh_token.
|
|
|
|
:param access_token: Текущий access token
|
|
:param refresh_token: Refresh token
|
|
:return: tuple (ok: bool, data: dict | str)
|
|
"""
|
|
url = f"{config.BASE_URL}/v1/auth/token/refresh"
|
|
payload = {"access_token": access_token, "refresh_token": refresh_token}
|
|
print("payload", payload)
|
|
|
|
try:
|
|
response = await get_client().post(url, json=payload)
|
|
|
|
if response.status_code == 200:
|
|
data = response.json()
|
|
if data.get("status") == "fine":
|
|
token_data = data["data"]
|
|
add_session(
|
|
old_access_token=access_token,
|
|
old_refresh_token=refresh_token,
|
|
access_token=token_data["access_token"],
|
|
refresh_token=token_data["refresh_token"],
|
|
update_existing=True,
|
|
)
|
|
return True, token_data
|
|
return False, data.get("detail", localizer.translate("Неизвестная ошибка"))
|
|
|
|
if response.status_code == 401:
|
|
print("response.status_code", response.json())
|
|
return False, localizer.translate("Токен недействителен или истек")
|
|
return False, f"{localizer.translate('Ошибка сервера')}: {response.status_code}"
|
|
|
|
except httpx.RequestError as e:
|
|
return False, f"{localizer.translate('Сетевая ошибка')}: {e}"
|
|
except Exception as e:
|
|
return False, f"{localizer.translate('Произошла ошибка')}: {e}"
|
|
|
|
|
|
async def get_user_role(access_token: str, login: str):
|
|
"""
|
|
Получение роли пользователя. При 401 выполняется автообновление токена внутри authorized_get.
|
|
"""
|
|
url = f"{config.BASE_URL}/v1/user/role"
|
|
headers = {"Authorization": f"Bearer {access_token}"}
|
|
|
|
try:
|
|
response = await authorized_get(url, login=login, access_token=access_token, headers=headers)
|
|
|
|
if response.status_code == 200:
|
|
data = response.json()
|
|
return (True, data['data']) if data.get("status") == "fine" else (False, data.get("detail", localizer.translate("Неизвестная ошибка")))
|
|
|
|
if response.status_code == 401:
|
|
return False, localizer.translate("?? ???????????")
|
|
return False, f"{localizer.translate('Ошибка сервера')}: {response.status_code}"
|
|
|
|
except httpx.RequestError as e:
|
|
return False, f"{localizer.translate('Сетевая ошибка')}: {e}"
|
|
except Exception as e:
|
|
return False, f"{localizer.translate('Произошла ошибка')}: {e}"
|
|
|
|
|