From 146512b2abf2aed1ffc97969a119b16789b7f82b Mon Sep 17 00:00:00 2001 From: Vladless Date: Sun, 27 Oct 2024 06:15:34 +0300 Subject: [PATCH] =?UTF-8?q?=D0=90=D0=B4=D0=BC=D0=B8=D0=BD.=20=D0=A3=D1=81?= =?UTF-8?q?=D1=82=D0=B0=D0=BD=D0=BE=D0=B2=D0=BA=D0=B0=20=D0=B2=D1=80=D0=B5?= =?UTF-8?q?=D0=BC=D0=B5=D0=BD=D0=B8=20=D0=BA=D0=BB=D1=8E=D1=87=D0=B5=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bot.py | 2 +- client.py | 44 ++++++++++++++++++++++++++ database.py | 21 ++++++++++++- handlers/admin/admin.py | 68 +++++++++++++++++++++++++++++++++++++++-- 4 files changed, 130 insertions(+), 5 deletions(-) diff --git a/bot.py b/bot.py index 7dc9c5cf..b7c90090 100644 --- a/bot.py +++ b/bot.py @@ -13,6 +13,7 @@ from handlers.keys import key_management, keys from handlers import (notifications, pay, profile, start, commands) +dp.include_router(admin.router) dp.include_router(commands.router) dp.include_router(start.router) dp.include_router(profile.router) @@ -20,4 +21,3 @@ dp.include_router(keys.router) dp.include_router(key_management.router) dp.include_router(pay.router) dp.include_router(notifications.router) -dp.include_router(admin.router) \ No newline at end of file diff --git a/client.py b/client.py index ec2abc70..1f76bf5d 100644 --- a/client.py +++ b/client.py @@ -114,6 +114,50 @@ async def extend_client_key(session, server_id: str, tg_id, client_id, email: st print(f"Ошибка запроса: {e}") return False +async def extend_client_key_admin(session, server_id: str, tg_id, client_id: str, email: str, new_expiry_time: int) -> bool: + api_url = SERVERS[server_id]['API_URL'] + + # Формируем данные для POST-запроса + payload = { + "id": 1, + "settings": json.dumps({ + "clients": [ + { + "id": client_id, + "alterId": 0, + "email": email.lower(), + "limitIp": 2, + "totalGB": 429496729600000, # Убедитесь, что это значение корректно + "expiryTime": new_expiry_time, # Устанавливаем новое время + "enable": True, + "tgId": tg_id, + "subId": "", + "flow": "xtls-rprx-vision" + } + ] + }) + } + + headers = { + 'Content-Type': 'application/json', + 'Accept': 'application/json' + } + + try: + async with session.post(f"{api_url}/panel/api/inbounds/updateClient/{client_id}", json=payload, headers=headers) as response: + print(f"POST {response.url} Status: {response.status}") + print(f"POST Request Data: {json.dumps(payload, indent=2)}") + response_text = await response.text() + print(f"POST Response: {response_text}") + + if response.status == 200: + return True + else: + print(f"Ошибка при продлении ключа: {response.status} - {response_text}") + return False + except Exception as e: + print(f"Ошибка запроса: {e}") + return False async def delete_client(session, server_id: str, client_id: str) -> bool: api_url = SERVERS[server_id]['API_URL'] diff --git a/database.py b/database.py index cd5afa70..912358d2 100644 --- a/database.py +++ b/database.py @@ -225,4 +225,23 @@ async def add_balance_to_client(client_id: str, amount: float): SET balance = balance + $1 WHERE tg_id = $2 ''', amount, client_id) - await conn.close() \ No newline at end of file + await conn.close() + +async def get_client_id_by_email(email: str): + """ + Получение client_id по email. + """ + conn = await asyncpg.connect(DATABASE_URL) + client_id = await conn.fetchval(''' + SELECT client_id FROM keys WHERE email = $1 + ''', email) + await conn.close() + return client_id + +async def get_tg_id_by_client_id(client_id: str): + conn = await asyncpg.connect(DATABASE_URL) + try: + result = await conn.fetchrow('SELECT tg_id FROM keys WHERE client_id = $1', client_id) + return result['tg_id'] if result else None + finally: + await conn.close() \ No newline at end of file diff --git a/handlers/admin/admin.py b/handlers/admin/admin.py index 86bfa3f1..b8e4b7d8 100644 --- a/handlers/admin/admin.py +++ b/handlers/admin/admin.py @@ -1,7 +1,11 @@ from aiogram import Router, types from aiogram.filters import Command -from database import add_balance_to_client, get_balance, check_connection_exists -from config import ADMIN_ID +from database import add_balance_to_client, check_connection_exists, update_key_expiry, get_client_id_by_email, get_tg_id_by_client_id +from config import ADMIN_ID, DATABASE_URL, ADMIN_PASSWORD, ADMIN_USERNAME +from datetime import datetime +import asyncpg +from auth import login_with_credentials +from client import extend_client_key_admin router = Router() @@ -24,4 +28,62 @@ async def cmd_add_balance(message: types.Message): except ValueError: await message.reply("Пожалуйста, используйте формат: /add_balance ") except Exception as e: - await message.reply(f"Произошла ошибка: {e}") \ No newline at end of file + await message.reply(f"Произошла ошибка: {e}") + +@router.message(Command('update_key_expiry')) +async def cmd_update_key_expiry(message: types.Message): + if message.from_user.id != ADMIN_ID: + await message.reply("У вас нет доступа к этой команде.") + return + + try: + parts = message.text.split(maxsplit=2) + if len(parts) != 3: + await message.reply("Пожалуйста, используйте формат: /update_key_expiry ") + return + + _, email, expiry_time_str = parts + expiry_time = int(datetime.strptime(expiry_time_str, '%Y-%m-%d %H:%M:%S').timestamp() * 1000) + + # Получаем client_id по email + client_id = await get_client_id_by_email(email) + if client_id is None: + await message.reply(f"Клиент с email {email} не найден.") + return + + # Обновляем время истечения ключа в базе данных + await update_key_expiry(client_id, expiry_time) + + # Подключение для получения server_id и tg_id + conn = await asyncpg.connect(DATABASE_URL) + try: + record = await conn.fetchrow('SELECT server_id FROM keys WHERE client_id = $1', client_id) + if not record: + await message.reply("Клиент не найден в базе данных.") + return + + server_id = record['server_id'] + tg_id = await get_tg_id_by_client_id(client_id) + + # Авторизация на панели + session = await login_with_credentials(server_id, ADMIN_USERNAME, ADMIN_PASSWORD) + + # Вывод обновленных данных перед отправкой на панель + print(f"Попытка обновить панель для server_id: {server_id}, tg_id: {tg_id}, client_id: {client_id}, email: {email}, expiryTime: {expiry_time}") + + # Обновляем время истечения ключа на панели + success = await extend_client_key_admin(session, server_id, tg_id, client_id, email, expiry_time) + + # Проверка успеха и ответ пользователю + print(f"Статус обновления панели: {'Успешно' if success else 'Не удалось'}") + if success: + await message.reply(f"Время истечения ключа для клиента {client_id} ({email}) обновлено и синхронизировано с панелью.") + else: + await message.reply(f"Время истечения ключа для клиента {client_id} ({email}) обновлено, но не удалось синхронизировать с панелью.") + + finally: + await conn.close() + except ValueError: + await message.reply("Пожалуйста, используйте формат: /update_key_expiry ") + except Exception as e: + await message.reply(f"Произошла ошибка: {e}")