""" Хранилище учётных данных пользователей. """ import json import asyncio import logging from pathlib import Path from typing import Optional, Dict logger = logging.getLogger(__name__) class AuthStorage: """Хранилище паролей пользователей в JSON-файле.""" def __init__(self, file_path: str = "data/users.json"): self.file_path = Path(file_path) self.file_path.parent.mkdir(parents=True, exist_ok=True) self._lock = asyncio.Lock() async def register(self, user_id: int, password_hash: str, salt: str) -> bool: """Регистрирует нового пользователя. Возвращает True если успешно.""" async with self._lock: data = self._load() if str(user_id) in data: return False data[str(user_id)] = { "password_hash": password_hash, "salt": salt, } self._save(data) logger.info(f"User {user_id} registered") return True async def get_user(self, user_id: int) -> Optional[Dict]: """Получает данные пользователя по ID.""" async with self._lock: data = self._load() return data.get(str(user_id)) async def change_password(self, user_id: int, new_hash: str, new_salt: str) -> bool: """Сменить пароль пользователя.""" async with self._lock: data = self._load() user_str = str(user_id) if user_str not in data: return False data[user_str]["password_hash"] = new_hash data[user_str]["salt"] = new_salt self._save(data) logger.info(f"User {user_id} changed password") return True async def delete_user(self, user_id: int) -> bool: """Удалить учётную запись пользователя.""" async with self._lock: data = self._load() user_str = str(user_id) if user_str not in data: return False del data[user_str] self._save(data) logger.info(f"User {user_id} deleted") return True async def user_exists(self, user_id: int) -> bool: """Проверяет, существует ли пользователь.""" async with self._lock: data = self._load() return str(user_id) in data def _load(self) -> dict: if not self.file_path.exists(): return {} try: with open(self.file_path, "r", encoding="utf-8") as f: return json.load(f) except (json.JSONDecodeError, IOError) as e: logger.warning(f"Failed to load auth storage: {e}") return {} def _save(self, data: dict): try: with open(self.file_path, "w", encoding="utf-8") as f: json.dump(data, f, ensure_ascii=False, indent=2) except IOError as e: logger.error(f"Failed to save auth storage: {e}")