Улучшен доступ к настройкам: заменён импорт USER_ID на settings, обновлены проверки прав доступа в командах и мидлваре.

This commit is contained in:
2026-04-21 00:37:39 +03:00
parent 94e34042a0
commit 6b0d5fedf3
3 changed files with 26 additions and 22 deletions
+17 -13
View File
@@ -1,34 +1,38 @@
from typing import Any
from pydantic import Field, ValidationError from pydantic import Field, ValidationError
from pydantic_settings import BaseSettings, SettingsConfigDict from pydantic_settings import BaseSettings, SettingsConfigDict
class Settings(BaseSettings): class Settings(BaseSettings):
"""App settings loaded from environment, но может быть переопределён через параметры.""" """App settings loaded from environment (или .env), но могут быть переопределены через параметры."""
TOKEN: str = Field(default='default_value', description='Токен Telegram-бота') TOKEN: str = Field(default='0', description='Токен Telegram-бота')
USER_ID: int = Field(default=0, description='ID пользователя для доступа') USER_ID: int = Field(default=0, description='ID пользователя для доступа')
model_config = SettingsConfigDict(env_file='.env', env_file_encoding='utf-8') model_config = SettingsConfigDict(env_file='.env', env_file_encoding='utf-8')
def get_settings(token: str = None, user_id: int = None) -> Settings: # Стартовая загрузка настроек — попытается взять переменные из среды или .env
"""Возвращает объект Settings, приоритет: параметры > env/.env"""
settings: Settings = Settings()
def get_settings(token: str | None = None, user_id: int | None = None) -> Settings:
"""Возвращает новый объект Settings. Приоритет: параметры > env > .env."""
try: try:
if token is not None or user_id is not None: data: dict[str, Any] = {}
# Переопределяем только если явно передано
data = {}
if token is not None: if token is not None:
data['TOKEN'] = token data['TOKEN'] = token
if user_id is not None: if user_id is not None:
data['USER_ID'] = user_id data['USER_ID'] = user_id
if data:
return Settings(**data) return Settings(**data)
return Settings() return Settings()
except ValidationError as exc: except ValidationError as exc:
msg = f'Ошибка валидации настроек: {exc}' raise RuntimeError(f'Ошибка валидации настроек: {exc}') from exc
raise RuntimeError(msg) from exc
# Для обратной совместимости: def set_settings(token: str | None = None, user_id: int | None = None) -> Settings:
settings = get_settings() """Возвращает новый объект settings с обновлёнными параметрами."""
TOKEN: str = settings.TOKEN return get_settings(token=token, user_id=user_id)
USER_ID: str = str(settings.USER_ID)
+3 -3
View File
@@ -7,7 +7,7 @@ from aiogram.enums import ParseMode
from aiogram.filters import Command from aiogram.filters import Command
from aiogram.types import Message from aiogram.types import Message
from src.config import USER_ID from src.config import settings
from src.utils.system import execute_command, get_cpu_temperature from src.utils.system import execute_command, get_cpu_temperature
router = Router() router = Router()
@@ -56,7 +56,7 @@ async def cmd_execute(message: Message) -> None:
"""Команда /c <команда> - выполняет указанную команду на сервере и возвращает результат.""" """Команда /c <команда> - выполняет указанную команду на сервере и возвращает результат."""
global current_directory global current_directory
user_id = message.from_user.id if message.from_user else 'Unknown' user_id = message.from_user.id if message.from_user else 'Unknown'
if str(user_id) != str(USER_ID): if str(user_id) != str(settings.USER_ID):
await message.answer('❌ У вас нет прав для использования этого бота.') await message.answer('❌ У вас нет прав для использования этого бота.')
return return
@@ -78,7 +78,7 @@ async def cmd_sysinfo(message: Message) -> None:
"""Sysinfo - Показать информацию о системе, включая имя хоста, ОС и количество ядер CPU.""" """Sysinfo - Показать информацию о системе, включая имя хоста, ОС и количество ядер CPU."""
"""Команда /sysinfo - выводит информацию о системе, включая имя хоста, ОС и количество ядер CPU.""" """Команда /sysinfo - выводит информацию о системе, включая имя хоста, ОС и количество ядер CPU."""
user_id = message.from_user.id if message.from_user else 'Unknown' user_id = message.from_user.id if message.from_user else 'Unknown'
if str(user_id) != str(USER_ID): if str(user_id) != str(settings.USER_ID):
await message.answer('❌ У вас нет прав для использования этого бота.') await message.answer('❌ У вас нет прав для использования этого бота.')
return return
logging.info(f'Пользователь {user_id} выполнил команду /sysinfo') logging.info(f'Пользователь {user_id} выполнил команду /sysinfo')
+2 -2
View File
@@ -4,7 +4,7 @@ from typing import Any
from aiogram.dispatcher.middlewares.base import BaseMiddleware from aiogram.dispatcher.middlewares.base import BaseMiddleware
from aiogram.types import Message, TelegramObject from aiogram.types import Message, TelegramObject
from src.config import USER_ID from src.config import settings
class AccessMiddleware(BaseMiddleware): class AccessMiddleware(BaseMiddleware):
@@ -21,7 +21,7 @@ class AccessMiddleware(BaseMiddleware):
if event.from_user is None: if event.from_user is None:
return None return None
if str(event.from_user.id) != USER_ID: if str(event.from_user.id) != str(settings.USER_ID):
await event.answer('❌ У вас нет прав для использования этого бота.') await event.answer('❌ У вас нет прав для использования этого бота.')
return None return None