DispelEvilBot/common/repositories/admins_repo.py

107 lines
3.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Репозиторий администраторов веб-панели (Блок 4.2)."""
from __future__ import annotations
from typing import Any
from common.db.pool import get_pool
async def get_admin(telegram_id: int) -> dict[str, Any] | None:
"""Вернуть администратора по Telegram-ID (для проверки доступа)."""
async with get_pool().connection() as conn:
cur = await conn.execute(
"""
SELECT telegram_id, username, role, enabled, created_at, last_login_at
FROM bot.admin_users
WHERE telegram_id = %s
""",
(telegram_id,),
)
return await cur.fetchone()
async def ensure_admins(telegram_ids: list[int]) -> int:
"""Засеять администраторов из ADMIN_IDS (существующих не трогаем).
Возвращает количество вставленных строк.
"""
if not telegram_ids:
return 0
inserted = 0
async with get_pool().connection() as conn:
for telegram_id in dict.fromkeys(telegram_ids):
cur = await conn.execute(
"""
INSERT INTO bot.admin_users (telegram_id, role)
VALUES (%s, 'admin')
ON CONFLICT (telegram_id) DO NOTHING
""",
(telegram_id,),
)
inserted += cur.rowcount or 0
return inserted
async def touch_login(telegram_id: int) -> None:
"""Отметить успешный вход (не критично, ошибки не должны ломать логин)."""
async with get_pool().connection() as conn:
await conn.execute(
"UPDATE bot.admin_users SET last_login_at = now() WHERE telegram_id = %s",
(telegram_id,),
)
async def list_admins() -> list[dict[str, Any]]:
"""Все администраторы веб-панели (для раздела «Админы»)."""
async with get_pool().connection() as conn:
cur = await conn.execute(
"""
SELECT telegram_id, username, role, enabled, created_at, last_login_at
FROM bot.admin_users
ORDER BY role, username NULLS LAST, telegram_id
"""
)
return await cur.fetchall()
async def upsert_admin(telegram_id: int, username: str | None, role: str) -> None:
"""Добавить администратора или обновить имя/роль существующего."""
async with get_pool().connection() as conn:
await conn.execute(
"""
INSERT INTO bot.admin_users (telegram_id, username, role, enabled)
VALUES (%s, %s, %s, true)
ON CONFLICT (telegram_id) DO UPDATE
SET username = EXCLUDED.username,
role = EXCLUDED.role,
enabled = true
""",
(telegram_id, username, role),
)
async def set_admin_role(telegram_id: int, role: str) -> bool:
async with get_pool().connection() as conn:
cur = await conn.execute(
"UPDATE bot.admin_users SET role = %s WHERE telegram_id = %s",
(role, telegram_id),
)
return bool(cur.rowcount)
async def set_admin_enabled(telegram_id: int, enabled: bool) -> bool:
async with get_pool().connection() as conn:
cur = await conn.execute(
"UPDATE bot.admin_users SET enabled = %s WHERE telegram_id = %s",
(enabled, telegram_id),
)
return bool(cur.rowcount)
async def delete_admin(telegram_id: int) -> bool:
async with get_pool().connection() as conn:
cur = await conn.execute("DELETE FROM bot.admin_users WHERE telegram_id = %s", (telegram_id,))
return bool(cur.rowcount)