diff --git a/Pipfile.lock b/Pipfile.lock index 615d5a42b..91020093f 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "67adacda446396d91de50fe41c426c738226113aa0b3e3f16a00f2141ff7bc8a" + "sha256": "a187fb4a62ec0cc2dab78542af7c21eb559388bac49e0f84f35f656aa1e19200" }, "pipfile-spec": 6, "requires": { diff --git a/server/exceptions.py b/server/exceptions.py index ff7a7cc57..ad536fbff 100644 --- a/server/exceptions.py +++ b/server/exceptions.py @@ -2,10 +2,6 @@ Common exception definitions """ -import humanize - -from server.timing import datetime_now - class ClientError(Exception): """ @@ -33,21 +29,15 @@ def __init__(self, ban_expiry, ban_reason, *args, **kwargs): def message(self): return ( - f"You are banned from FAF {self._ban_duration_text()}.
" - f"Reason:
{self.ban_reason}

" - "If you would like to appeal this ban, please send an email to: " - "moderation@faforever.com" + "User is banned until " + f"{self.ban_expiry.isoformat()} for reason: {self.ban_reason}" ) - def _ban_duration_text(self): - ban_duration = self.ban_expiry - datetime_now() - if ban_duration.days > 365 * 100: - return "forever" - humanized_ban_duration = humanize.precisedelta( - ban_duration, - minimum_unit="hours" - ) - return f"for {humanized_ban_duration}" + def response(self): + return { + "command": "banned", + "expires_at": self.ban_expiry.isoformat(), + } class AuthenticationError(Exception): diff --git a/server/lobbyconnection.py b/server/lobbyconnection.py index 5b5ec2e10..2791c2e5a 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.response()) await self.abort(e.message()) except ClientError as e: self._logger.warning( diff --git a/server/protocol/qdatastream.py b/server/protocol/qdatastream.py index 999d2313c..6adea3227 100644 --- a/server/protocol/qdatastream.py +++ b/server/protocol/qdatastream.py @@ -92,7 +92,7 @@ def pack_message(*args: str) -> bytes: raise NotImplementedError("Only string serialization is supported") msg += QDataStreamProtocol.pack_qstring(arg) - return QDataStreamProtocol.pack_block(msg) + return QDataStreamProtocol.pack_block(bytes(msg)) @staticmethod def encode_message(message: dict) -> bytes: diff --git a/tests/integration_tests/test_login.py b/tests/integration_tests/test_login.py index 0d7c5c843..ae22bec16 100644 --- a/tests/integration_tests/test_login.py +++ b/tests/integration_tests/test_login.py @@ -1,3 +1,4 @@ +from datetime import datetime from time import time import jwt @@ -38,15 +39,8 @@ 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" + datetime.fromisoformat(msg["expires_at"]) @pytest.mark.parametrize("user", [ @@ -73,15 +67,8 @@ 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" + datetime.fromisoformat(msg["expires_at"]) @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..9a00b92e8 100644 --- a/tests/integration_tests/test_server.py +++ b/tests/integration_tests/test_server.py @@ -1,6 +1,7 @@ import asyncio import contextlib import re +from datetime import datetime import pytest from sqlalchemy import and_, select @@ -845,15 +846,8 @@ 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" + datetime.fromisoformat(msg["expires_at"]) @fast_forward(5) diff --git a/tests/unit_tests/test_lobbyconnection.py b/tests/unit_tests/test_lobbyconnection.py index ea764e84d..a77726f22 100644 --- a/tests/unit_tests/test_lobbyconnection.py +++ b/tests/unit_tests/test_lobbyconnection.py @@ -1,4 +1,4 @@ -import re +from datetime import datetime from hashlib import sha256 from unittest import mock @@ -1303,18 +1303,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" - ) + response = banned_error.value.response() + assert response["command"] == "banned" + datetime.fromisoformat(response["expires_at"]) # 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() - ) + response = banned_error.value.response() + assert response["command"] == "banned" + datetime.fromisoformat(response["expires_at"])