From d202700c3593efba4f32f5cae49edc356e1debc0 Mon Sep 17 00:00:00 2001 From: Louyijun <35680570+Louyijun@users.noreply.github.com> Date: Mon, 11 May 2026 10:12:32 +0800 Subject: [PATCH] Replace ban notice text with structured banned message --- server/exceptions.py | 12 ++++++++++++ server/lobbyconnection.py | 6 +----- tests/integration_tests/test_login.py | 24 ++++++------------------ tests/integration_tests/test_server.py | 12 +++--------- tests/unit_tests/test_lobbyconnection.py | 17 ++++++----------- 5 files changed, 28 insertions(+), 43 deletions(-) diff --git a/server/exceptions.py b/server/exceptions.py index ff7a7cc57..3a7f0aa1e 100644 --- a/server/exceptions.py +++ b/server/exceptions.py @@ -2,6 +2,8 @@ Common exception definitions """ +from datetime import timezone + import humanize from server.timing import datetime_now @@ -39,6 +41,16 @@ def message(self): "moderation@faforever.com" ) + def to_dict(self): + expires_at = self.ban_expiry + if expires_at.tzinfo is None: + expires_at = expires_at.replace(tzinfo=timezone.utc) + return { + "command": "banned", + "expires_at": expires_at.astimezone(timezone.utc).isoformat(), + "reason": self.ban_reason, + } + def _ban_duration_text(self): ban_duration = self.ban_expiry - datetime_now() if ban_duration.days > 365 * 100: diff --git a/server/lobbyconnection.py b/server/lobbyconnection.py index 5b5ec2e10..c1173c7c2 100644 --- a/server/lobbyconnection.py +++ b/server/lobbyconnection.py @@ -222,11 +222,7 @@ async def on_message_received(self, message): "text": e.message }) except BanError as e: - await self.send({ - "command": "notice", - "style": "error", - "text": e.message() - }) + await self.send(e.to_dict()) await self.abort(e.message()) except ClientError as e: self._logger.warning( diff --git a/tests/integration_tests/test_login.py b/tests/integration_tests/test_login.py index 0d7c5c843..2bf4cc942 100644 --- a/tests/integration_tests/test_login.py +++ b/tests/integration_tests/test_login.py @@ -38,15 +38,9 @@ async def test_server_ban(lobby_server, user): proto = await connect_client(lobby_server) await perform_login(proto, user) msg = await proto.read_message() - assert msg == { - "command": "notice", - "style": "error", - "text": ( - "You are banned from FAF forever.
Reason:
Test permanent ban" - "

If you would like to appeal this ban, please send an " - "email to: moderation@faforever.com" - ) - } + assert msg["command"] == "banned" + assert msg["reason"] == "Test permanent ban" + assert "expires_at" in msg @pytest.mark.parametrize("user", [ @@ -73,15 +67,9 @@ async def test_server_ban_token(lobby_server, user, jwk_priv_key, jwk_kid): "unique_id": "some_id" }) msg = await proto.read_message() - assert msg == { - "command": "notice", - "style": "error", - "text": ( - "You are banned from FAF forever.
Reason:
Test permanent ban" - "

If you would like to appeal this ban, please send an " - "email to: moderation@faforever.com" - ) - } + assert msg["command"] == "banned" + assert msg["reason"] == "Test permanent ban" + assert "expires_at" in msg @pytest.mark.parametrize("user", ["ban_revoked", "ban_expired"]) diff --git a/tests/integration_tests/test_server.py b/tests/integration_tests/test_server.py index ae00663bb..5f595e633 100644 --- a/tests/integration_tests/test_server.py +++ b/tests/integration_tests/test_server.py @@ -845,15 +845,9 @@ async def test_server_ban_prevents_hosting(lobby_server, database, command): await proto.send_message({"command": command}) msg = await proto.read_message() - assert msg == { - "command": "notice", - "style": "error", - "text": ( - "You are banned from FAF forever.
Reason:
Test live ban
" - "
If you would like to appeal this ban, please send an email " - "to: moderation@faforever.com" - ) - } + assert msg["command"] == "banned" + assert msg["reason"] == "Test live ban" + assert "expires_at" in msg @fast_forward(5) diff --git a/tests/unit_tests/test_lobbyconnection.py b/tests/unit_tests/test_lobbyconnection.py index ea764e84d..2e4cbf33c 100644 --- a/tests/unit_tests/test_lobbyconnection.py +++ b/tests/unit_tests/test_lobbyconnection.py @@ -1,4 +1,3 @@ -import re from hashlib import sha256 from unittest import mock @@ -1303,18 +1302,14 @@ async def test_abort_connection_if_banned( lobbyconnection.player.id = 203 with pytest.raises(BanError) as banned_error: await lobbyconnection.abort_connection_if_banned() - assert banned_error.value.message() == ( - "You are banned from FAF forever.
Reason:
Test permanent ban" - "

If you would like to appeal this ban, please send an email " - "to: moderation@faforever.com" - ) + assert banned_error.value.to_dict()["command"] == "banned" + assert banned_error.value.to_dict()["reason"] == "Test permanent ban" + assert "expires_at" in banned_error.value.to_dict() # test user who is banned for another 46 hours lobbyconnection.player.id = 204 with pytest.raises(BanError) as banned_error: await lobbyconnection.abort_connection_if_banned() - assert re.match( - r"You are banned from FAF for 1 day and 2[12]\.[0-9]+ hours.
" - "Reason:
Test ongoing ban with 46 hours left", - banned_error.value.message() - ) + assert banned_error.value.to_dict()["command"] == "banned" + assert banned_error.value.to_dict()["reason"] == "Test ongoing ban with 46 hours left" + assert "expires_at" in banned_error.value.to_dict()