rename users

This commit is contained in:
2026-03-31 18:10:12 +05:00
parent 59b3bcd0f4
commit 4e9b89fbe5
22 changed files with 1262 additions and 163 deletions

View File

@@ -1,60 +1,32 @@
import os
import secrets
import httpx
import flet as ft
API_URL = os.getenv("API_URL", "http://api:8000")
import api_client
_TOKEN_KEY = "auth_token"
class AuthService:
"""Сервис авторизации: логин, логаут, проверка токена."""
"""Сервис авторизации: логин, логаут, проверка токена.
HTTP-запросы делегируются в api_client.
"""
def __init__(self, page: ft.Page):
self._page = page
async def login(self, username: str, password: str) -> str | None:
"""
Отправляет запрос на POST /auth/login.
Возвращает None при успехе, строку с ошибкой при неудаче.
"""
try:
async with httpx.AsyncClient(base_url=API_URL, timeout=10) as client:
resp = await client.post(
"/auth/login",
data={"username": username, "password": password},
)
if resp.status_code == 200:
token = resp.json()["access_token"]
self._page.session.store.set(_TOKEN_KEY, token)
# Случайный ключ для URL профиля — хранится только в памяти сессии
self._page.session.store.set("session_key", secrets.token_hex(16))
# user_id Для фетчинга данных
me = await self._get_me(token)
if me:
self._page.session.store.set("user_id", me["id"])
return None
elif resp.status_code == 401:
return "Неверный логин или пароль"
else:
return f"Ошибка сервера: {resp.status_code}"
except httpx.ConnectError:
return "Не удалось подключиться к серверу"
except Exception as e:
return f"Ошибка: {e}"
async def _get_me(self, token: str) -> dict | None:
"""Внутренний метод: получает данные текущего пользователя по токену."""
try:
async with httpx.AsyncClient(base_url=API_URL, timeout=10) as client:
resp = await client.get(
"/users/me",
headers={"Authorization": f"Bearer {token}"},
)
if resp.status_code == 200:
return resp.json()
except Exception:
pass
"""POST /auth/login. Возвращает None при успехе, строку с ошибкой при неудаче."""
token, error = await api_client.login(username, password)
if error:
return error
self._page.session.store.set(_TOKEN_KEY, token)
self._page.session.store.set("url_key", secrets.token_hex(16)) # в адресную строку
self._page.session.store.set("session_key", secrets.token_hex(16)) # только в память
me = await api_client.get_me(token)
if me:
self._page.session.store.set("user_id", me["id"])
self._page.session.store.set("group_id", me.get("group_id") or "")
self._page.session.store.set("org_id", me.get("organization_id") or "")
return None
async def get_me(self) -> dict | None:
@@ -62,13 +34,16 @@ class AuthService:
token = self._page.session.store.get(_TOKEN_KEY)
if not token:
return None
return await self._get_me(token)
return await api_client.get_me(token)
async def logout(self):
"""Удаляет токен — пользователь разлогинен."""
self._page.session.store.remove(_TOKEN_KEY)
self._page.session.store.remove("user_id")
self._page.session.store.remove("url_key")
self._page.session.store.remove("session_key")
self._page.session.store.remove("group_id")
self._page.session.store.remove("org_id")
async def get_token(self) -> str | None:
"""Возвращает сохранённый токен или None если не авторизован."""
@@ -87,50 +62,13 @@ class AuthService:
group_id: str | None = None,
organization_id: str | None = None,
) -> str | None:
"""
Отправляет запрос на POST /auth/register.
Возвращает None при успехе, строку с ошибкой при неудаче.
"""
payload = {
"username": username,
"password": password,
"first_name": first_name,
"last_name": last_name,
}
if group_id:
payload["group_id"] = group_id
if organization_id:
payload["organization_id"] = organization_id
try:
async with httpx.AsyncClient(base_url=API_URL, timeout=10) as client:
resp = await client.post("/auth/register", json=payload)
if resp.status_code == 201:
return None
elif resp.status_code == 400:
return resp.json().get("detail", "Ошибка регистрации")
else:
return f"Ошибка сервера: {resp.status_code}"
except httpx.ConnectError:
return "Не удалось подключиться к серверу"
except Exception as e:
return f"Ошибка: {e}"
"""POST /auth/register. Возвращает None при успехе, строку с ошибкой при неудаче."""
return await api_client.register(
username, password, first_name, last_name, group_id, organization_id
)
async def get_organizations(self) -> list:
try:
async with httpx.AsyncClient(base_url=API_URL, timeout=10) as client:
resp = await client.get("/organizations/")
if resp.status_code == 200:
return resp.json()
except Exception:
pass
return []
return await api_client.get_organizations()
async def get_groups(self) -> list:
try:
async with httpx.AsyncClient(base_url=API_URL, timeout=10) as client:
resp = await client.get("/groups/")
if resp.status_code == 200:
return resp.json()
except Exception:
pass
return []
return await api_client.get_groups()