From 856169cba98f135d0eb2122a117e3c9c67e6a697 Mon Sep 17 00:00:00 2001 From: algizn97 Date: Fri, 14 Nov 2025 13:56:08 +0500 Subject: [PATCH] Added API key verification for permissions --- alembic.ini | 2 +- alembic/versions/f6e7eb3f25c0_initial.py | 32 +++++++++++++++++++ app/bybit/get_functions/get_positions.py | 10 ++++-- app/bybit/open_positions.py | 2 ++ app/bybit/profile_bybit.py | 2 +- .../main_settings/additional_settings.py | 23 ++++++++++--- app/telegram/handlers/start_trading.py | 21 ++++++++++-- 7 files changed, 81 insertions(+), 11 deletions(-) create mode 100644 alembic/versions/f6e7eb3f25c0_initial.py diff --git a/alembic.ini b/alembic.ini index 5d92823..4af3967 100644 --- a/alembic.ini +++ b/alembic.ini @@ -84,7 +84,7 @@ path_separator = os # database URL. This is consumed by the user-maintained env.py script only. # other means of configuring database URLs may be customized within the env.py # file. -sqlalchemy.url = sqlite+aiosqlite:///./database/dbs/stcs.db +sqlalchemy.url = sqlite+aiosqlite:///./database/stcs.db [post_write_hooks] diff --git a/alembic/versions/f6e7eb3f25c0_initial.py b/alembic/versions/f6e7eb3f25c0_initial.py new file mode 100644 index 0000000..da929ca --- /dev/null +++ b/alembic/versions/f6e7eb3f25c0_initial.py @@ -0,0 +1,32 @@ +"""initial + +Revision ID: f6e7eb3f25c0 +Revises: +Create Date: 2025-11-12 22:53:02.189445 + +""" +from typing import Sequence, Union + +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision: str = 'f6e7eb3f25c0' +down_revision: Union[str, Sequence[str], None] = None +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None + + +def upgrade() -> None: + """Upgrade schema.""" + # ### commands auto generated by Alembic - please adjust! ### + pass + # ### end Alembic commands ### + + +def downgrade() -> None: + """Downgrade schema.""" + # ### commands auto generated by Alembic - please adjust! ### + pass + # ### end Alembic commands ### diff --git a/app/bybit/get_functions/get_positions.py b/app/bybit/get_functions/get_positions.py index 1f6606a..986f3a7 100644 --- a/app/bybit/get_functions/get_positions.py +++ b/app/bybit/get_functions/get_positions.py @@ -38,7 +38,7 @@ async def get_active_positions(tg_id: int) -> list | None: return None -async def get_active_positions_by_symbol(tg_id: int, symbol: str) -> dict | None: +async def get_active_positions_by_symbol(tg_id: int, symbol: str): """ Get active positions for a user by symbol """ @@ -62,8 +62,12 @@ async def get_active_positions_by_symbol(tg_id: int, symbol: str) -> dict | None ) return None except Exception as e: - logger.error("Error getting active positions for user %s: %s", tg_id, e) - return None + errors = str(e) + if errors.startswith("Permission denied, please check your API key permissions"): + return "Invalid API key permissions" + else: + logger.error("Error getting active positions for user %s: %s", tg_id, e) + return None async def get_active_orders(tg_id: int) -> list | None: diff --git a/app/bybit/open_positions.py b/app/bybit/open_positions.py index 680a76f..d30d580 100644 --- a/app/bybit/open_positions.py +++ b/app/bybit/open_positions.py @@ -109,6 +109,7 @@ async def start_trading_cycle( "The number of contracts exceeds maximum limit allowed", "The number of contracts exceeds minimum limit allowed", "Order placement failed as your position may exceed the max", + "Permission denied, please check your API key permissions" } else None ) @@ -371,6 +372,7 @@ async def open_positions( "The number of contracts exceeds maximum limit allowed": "The number of contracts exceeds maximum limit allowed", "The number of contracts exceeds minimum limit allowed": "The number of contracts exceeds minimum limit allowed", "Order placement failed as your position may exceed the max": "Order placement failed as your position may exceed the max", + "Permission denied, please check your API key permissions": "Permission denied, please check your API key permissions" } for key, msg in known_errors.items(): if key in error_text: diff --git a/app/bybit/profile_bybit.py b/app/bybit/profile_bybit.py index b92f671..ac4f9f1 100644 --- a/app/bybit/profile_bybit.py +++ b/app/bybit/profile_bybit.py @@ -37,7 +37,7 @@ async def user_profile_bybit(tg_id: int, message: Message, state: FSMContext) -> ) else: await message.answer( - text="Ошибка при подключении к платформе. Проверьте ключи и повторите попытку.", + text="Ошибка при подключении к платформе. Проверьте корректность и разрешения API ключа и добавьте повторно.", reply_markup=kbi.connect_the_platform, ) logger.error("Error processing user profile for user %s", tg_id) diff --git a/app/telegram/handlers/main_settings/additional_settings.py b/app/telegram/handlers/main_settings/additional_settings.py index 262ed85..425029e 100644 --- a/app/telegram/handlers/main_settings/additional_settings.py +++ b/app/telegram/handlers/main_settings/additional_settings.py @@ -299,6 +299,12 @@ async def settings_for_margin_type( deals = await get_active_positions_by_symbol( tg_id=callback_query.from_user.id, symbol=symbol ) + if deals == "Invalid API key permissions": + await callback_query.answer( + text="API ключ не имеет достаточных прав для смены маржи", + ) + return + position = next((d for d in deals if d.get("symbol") == symbol), None) if position: @@ -676,10 +682,19 @@ async def set_leverage_handler(message: Message, state: FSMContext) -> None: await state.clear() except Exception as e: - await message.answer( - text="Произошла ошибка при установке кредитного плеча. Пожалуйста, попробуйте позже.", - reply_markup=kbi.back_to_additional_settings, - ) + errors_text = str(e) + known_errors = { + "Permission denied, please check your API key permissions": "API ключ не имеет достаточных прав для установки кредитного плеча" + + } + for key, msg in known_errors.items(): + if key in errors_text: + await message.answer(msg, reply_markup=kbi.back_to_additional_settings) + else: + await message.answer( + text="Произошла ошибка при установке кредитного плеча. Пожалуйста, попробуйте позже.", + reply_markup=kbi.back_to_additional_settings, + ) logger.error( "Error processing command leverage for user %s: %s", message.from_user.id, e ) diff --git a/app/telegram/handlers/start_trading.py b/app/telegram/handlers/start_trading.py index e410d61..9368e1a 100644 --- a/app/telegram/handlers/start_trading.py +++ b/app/telegram/handlers/start_trading.py @@ -38,6 +38,12 @@ async def start_trading(callback_query: CallbackQuery, state: FSMContext) -> Non deals = await get_active_positions_by_symbol( tg_id=callback_query.from_user.id, symbol=symbol ) + if deals == "Invalid API key permissions": + await callback_query.answer( + text="API ключ не имеет достаточных прав для запуска торговли", + ) + return + position = next((d for d in deals if d.get("symbol") == symbol), None) if position: @@ -109,7 +115,9 @@ async def start_trading(callback_query: CallbackQuery, state: FSMContext) -> Non "The number of contracts exceeds minimum limit allowed": "️️Лимит ставки меньше минимально допустимого", "Order placement failed as your position may exceed the max": "Не удалось разместить ордер, так как ваша позиция может превышать максимальный лимит." - "Пожалуйста, уменьшите кредитное плечо, чтобы увеличить максимальное значение" + "Пожалуйста, уменьшите кредитное плечо, чтобы увеличить максимальное значение", + "Permission denied, please check your API key permissions": "API ключ не имеет достаточных прав для запуска торговли" + } if res == "OK": @@ -131,7 +139,16 @@ async def start_trading(callback_query: CallbackQuery, state: FSMContext) -> Non await add_start_task_merged(user_id=callback_query.from_user.id, task=task) except Exception as e: - await callback_query.answer(text="Произошла ошибка при запуске торговли") + error_text = str(e) + known_errors = { + "Permission denied, please check your API key permissions": "API ключ не имеет достаточных прав для запуска торговли" + + } + for key, msg in known_errors.items(): + if key in error_text: + await callback_query.answer(msg) + else: + await callback_query.answer(text="Произошла ошибка при запуске торговли") logger.error( "Error processing command start_trading for user %s: %s", callback_query.from_user.id,