Files
Click/auth/storage.py
T
Yuriy Yuriev 8bdd0c784e fix
2026-07-18 18:33:54 +07:00

73 lines
2.5 KiB
Python

"""
Хранилище зарегистрированных пользователей.
"""
import asyncio
import json
import logging
from datetime import datetime
from pathlib import Path
logger = logging.getLogger(__name__)
class AuthStorage:
"""Реестр пользователей бота в JSON-файле.
Паролей не хранит: личность подтверждает Telegram, идентификатором
служит user_id.
"""
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) -> bool:
async with self._lock:
data = await asyncio.to_thread(self._load_sync)
if str(user_id) in data:
return False
data[str(user_id)] = {"registered_at": datetime.now().isoformat()}
await asyncio.to_thread(self._save_sync, data)
logger.info(f"User {user_id} registered")
return True
async def delete_user(self, user_id: int) -> bool:
async with self._lock:
data = await asyncio.to_thread(self._load_sync)
user_str = str(user_id)
if user_str not in data:
return False
del data[user_str]
await asyncio.to_thread(self._save_sync, data)
logger.info(f"User {user_id} deleted")
return True
async def user_exists(self, user_id: int) -> bool:
async with self._lock:
data = await asyncio.to_thread(self._load_sync)
return str(user_id) in data
async def get_all_user_ids(self) -> list[int]:
async with self._lock:
data = await asyncio.to_thread(self._load_sync)
return [int(k) for k in data.keys()]
def _load_sync(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_sync(self, data: dict) -> None:
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}")