feat: skip action logs for dropped Telegram updates
This commit is contained in:
@@ -24,6 +24,9 @@ class ActionLoggerMiddleware(BaseMiddleware):
|
|||||||
|
|
||||||
result = await handler(event, data)
|
result = await handler(event, data)
|
||||||
|
|
||||||
|
if data.get("skip_action_log") or data.get("antiflood_dropped"):
|
||||||
|
return result
|
||||||
|
|
||||||
session: AsyncSession = data["session"]
|
session: AsyncSession = data["session"]
|
||||||
event_user: Optional[User] = data.get("event_from_user")
|
event_user: Optional[User] = data.get("event_from_user")
|
||||||
|
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ class UpdateAntiFloodMiddleware(BaseMiddleware):
|
|||||||
chat_type,
|
chat_type,
|
||||||
getattr(event, "event_type", "unknown"),
|
getattr(event, "event_type", "unknown"),
|
||||||
)
|
)
|
||||||
data["antiflood_dropped"] = True
|
_mark_dropped(data)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
if not bool(getattr(self.settings, "TELEGRAM_ANTIFLOOD_ENABLED", True)):
|
if not bool(getattr(self.settings, "TELEGRAM_ANTIFLOOD_ENABLED", True)):
|
||||||
@@ -112,7 +112,7 @@ class UpdateAntiFloodMiddleware(BaseMiddleware):
|
|||||||
actor_key,
|
actor_key,
|
||||||
cooldown[0],
|
cooldown[0],
|
||||||
)
|
)
|
||||||
data["antiflood_dropped"] = True
|
_mark_dropped(data)
|
||||||
await _quietly_answer_callback(event)
|
await _quietly_answer_callback(event)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@@ -126,7 +126,7 @@ class UpdateAntiFloodMiddleware(BaseMiddleware):
|
|||||||
actor_key,
|
actor_key,
|
||||||
action_key or getattr(event, "event_type", "unknown"),
|
action_key or getattr(event, "event_type", "unknown"),
|
||||||
)
|
)
|
||||||
data["antiflood_dropped"] = True
|
_mark_dropped(data)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
return await handler(event, data)
|
return await handler(event, data)
|
||||||
@@ -302,6 +302,11 @@ async def _quietly_answer_callback(update: Update) -> None:
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def _mark_dropped(data: Dict[str, Any]) -> None:
|
||||||
|
data["antiflood_dropped"] = True
|
||||||
|
data["skip_action_log"] = True
|
||||||
|
|
||||||
|
|
||||||
def _default_action_rules(settings: Settings) -> Dict[str, RateLimitRule]:
|
def _default_action_rules(settings: Settings) -> Dict[str, RateLimitRule]:
|
||||||
window_seconds = int(
|
window_seconds = int(
|
||||||
getattr(settings, "TELEGRAM_ANTIFLOOD_WINDOW_SECONDS", DEFAULT_WINDOW_SECONDS)
|
getattr(settings, "TELEGRAM_ANTIFLOOD_WINDOW_SECONDS", DEFAULT_WINDOW_SECONDS)
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
import unittest
|
||||||
|
from types import SimpleNamespace
|
||||||
|
from unittest.mock import AsyncMock, patch
|
||||||
|
|
||||||
|
from bot.middlewares.action_logger_middleware import ActionLoggerMiddleware
|
||||||
|
|
||||||
|
|
||||||
|
class ActionLoggerMiddlewareTests(unittest.IsolatedAsyncioTestCase):
|
||||||
|
async def test_skip_action_log_flag_suppresses_database_logging(self):
|
||||||
|
middleware = ActionLoggerMiddleware(
|
||||||
|
SimpleNamespace(ADMIN_IDS=[], LOG_ADMIN_ACTIONS=True)
|
||||||
|
)
|
||||||
|
event = SimpleNamespace(event_type="message")
|
||||||
|
data = {
|
||||||
|
"session": object(),
|
||||||
|
"event_from_user": SimpleNamespace(id=42, username="user", first_name="User"),
|
||||||
|
}
|
||||||
|
|
||||||
|
async def handler(_event, handler_data):
|
||||||
|
handler_data["skip_action_log"] = True
|
||||||
|
return "ok"
|
||||||
|
|
||||||
|
with (
|
||||||
|
patch(
|
||||||
|
"bot.middlewares.action_logger_middleware.user_dal.get_user_by_id",
|
||||||
|
AsyncMock(),
|
||||||
|
) as get_user,
|
||||||
|
patch(
|
||||||
|
"bot.middlewares.action_logger_middleware.message_log_dal.create_message_log_no_commit",
|
||||||
|
AsyncMock(),
|
||||||
|
) as create_log,
|
||||||
|
):
|
||||||
|
result = await middleware(handler, event, data)
|
||||||
|
|
||||||
|
self.assertEqual(result, "ok")
|
||||||
|
get_user.assert_not_awaited()
|
||||||
|
create_log.assert_not_awaited()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
unittest.main()
|
||||||
@@ -75,9 +75,12 @@ class UpdateAntiFloodMiddlewareTests(unittest.IsolatedAsyncioTestCase):
|
|||||||
with patch("bot.middlewares.update_antiflood.get_redis", AsyncMock(return_value=None)):
|
with patch("bot.middlewares.update_antiflood.get_redis", AsyncMock(return_value=None)):
|
||||||
self.assertEqual(await middleware(handler, event, {}), "ok")
|
self.assertEqual(await middleware(handler, event, {}), "ok")
|
||||||
self.assertEqual(await middleware(handler, event, {}), "ok")
|
self.assertEqual(await middleware(handler, event, {}), "ok")
|
||||||
self.assertIsNone(await middleware(handler, event, {}))
|
dropped_data = {}
|
||||||
|
self.assertIsNone(await middleware(handler, event, dropped_data))
|
||||||
|
|
||||||
self.assertEqual(handler.await_count, 2)
|
self.assertEqual(handler.await_count, 2)
|
||||||
|
self.assertTrue(dropped_data["antiflood_dropped"])
|
||||||
|
self.assertTrue(dropped_data["skip_action_log"])
|
||||||
|
|
||||||
async def test_antiflood_can_be_disabled(self):
|
async def test_antiflood_can_be_disabled(self):
|
||||||
middleware = UpdateAntiFloodMiddleware(
|
middleware = UpdateAntiFloodMiddleware(
|
||||||
|
|||||||
Reference in New Issue
Block a user