From daee74ed07fbed402f92558082ec62aa27b97899 Mon Sep 17 00:00:00 2001 From: Valentin Lorentz Date: Fri, 26 May 2023 17:05:47 +0200 Subject: [PATCH 1/6] Add tests for draft/message-redaction --- irctest/controllers/ergo.py | 3 + irctest/server_tests/redaction.py | 132 ++++++++++++++++++++++++++++++ irctest/specifications.py | 1 + pytest.ini | 1 + 4 files changed, 137 insertions(+) create mode 100644 irctest/server_tests/redaction.py diff --git a/irctest/controllers/ergo.py b/irctest/controllers/ergo.py index 5655e824..df717878 100644 --- a/irctest/controllers/ergo.py +++ b/irctest/controllers/ergo.py @@ -77,6 +77,9 @@ "channel-length": 128, "client-length": 128, "chathistory-maxmessages": 100, + "retention": { + "allow-individual-delete": True, + }, "tagmsg-storage": { "default": False, "whitelist": ["+draft/persist", "+persist"], diff --git a/irctest/server_tests/redaction.py b/irctest/server_tests/redaction.py new file mode 100644 index 00000000..675c5efa --- /dev/null +++ b/irctest/server_tests/redaction.py @@ -0,0 +1,132 @@ +""" +`IRCv3 draft message redaction `_ +""" + +from irctest import cases +from irctest.patma import ANYDICT, ANYSTR, StrRe + +CAPABILITIES = [ + "message-tags", + "echo-message", + "labeled-response", + "draft/message-redaction", +] + + +@cases.mark_specifications("IRCv3") +@cases.mark_capabilities(*CAPABILITIES) +class RedactTestCase(cases.BaseServerTestCase): + def _setupRedactTest(self, redacteeId, redacteeNick): + self.connectClient("chanop", capabilities=CAPABILITIES, skip_if_cap_nak=True) + self.sendLine(1, "JOIN #chan") + self.connectClient("user", capabilities=CAPABILITIES, skip_if_cap_nak=True) + self.sendLine(2, "JOIN #chan") + self.getMessages(2) # synchronize + self.getMessages(1) + + self.sendLine(redacteeId, "@label=1234 PRIVMSG #chan :hello there") + echo = self.getMessage(redacteeId) + self.assertMessageMatch( + echo, + tags={"label": "1234", "msgid": StrRe("[^ ]+"), **ANYDICT}, + prefix=StrRe(redacteeNick + "!.*"), + command="PRIVMSG", + params=["#chan", "hello there"], + ) + msgid = echo.tags["msgid"] + + self.assertMessageMatch( + self.getMessage(3 - redacteeId), + tags={"msgid": msgid, **ANYDICT}, + prefix=StrRe(redacteeNick + "!.*"), + command="PRIVMSG", + params=["#chan", "hello there"], + ) + + return msgid + + def testRelayOpSelfRedact(self): + """Channel op writes a message and redacts it themselves.""" + msgid = self._setupRedactTest(redacteeId=1, redacteeNick="chanop") + + self.sendLine(1, f"REDACT #chan {msgid} :oops") + self.assertMessageMatch( + self.getMessage(1), + prefix=StrRe("chanop!.*"), + command="REDACT", + params=["#chan", msgid, "oops"], + ) + + self.assertMessageMatch( + self.getMessage(2), + prefix=StrRe("chanop!.*"), + command="REDACT", + params=["#chan", msgid, "oops"], + ) + + def testRelayOpRedact(self): + """User writes a message and channel op redacts it.""" + msgid = self._setupRedactTest( + redacteeId=2, + redacteeNick="user", + ) + + self.sendLine(1, f"REDACT #chan {msgid} :spam") + self.assertMessageMatch( + self.getMessage(1), + prefix=StrRe("chanop!.*"), + command="REDACT", + params=["#chan", msgid, "spam"], + ) + + self.assertMessageMatch( + self.getMessage(2), + prefix=StrRe("chanop!.*"), + command="REDACT", + params=["#chan", msgid, "spam"], + ) + + def testRelayUserSelfRedact(self): + """User writes a message and redacts it themselves. + + Servers may either accept or reject this.""" + msgid = self._setupRedactTest(redacteeId=2, redacteeNick="user") + + self.sendLine(2, f"REDACT #chan {msgid} :oops") + + msg = self.getMessage(2) + if msg.command == "REDACT": + self.assertMessageMatch( + msg, + prefix=StrRe("user!.*"), + command="REDACT", + params=["#chan", msgid, "oops"], + ) + + self.assertMessageMatch( + self.getMessage(1), + prefix=StrRe("user!.*"), + command="REDACT", + params=["#chan", msgid, "oops"], + ) + else: + self.assertMessageMatch( + msg, + command="FAIL", + params=["REDACT", "REDACT_FORBIDDEN", "#chan", msgid, ANYSTR], + ) + + self.assertEqual(self.getMessages(1), []) + + def testRejectRedactOtherUser(self): + """Channel op writes a message and a user attempts to redact it.""" + msgid = self._setupRedactTest(redacteeId=1, redacteeNick="chanop") + + self.sendLine(2, f"REDACT #chan {msgid} :oops") + self.assertMessageMatch( + self.getMessage(2), + command="FAIL", + params=["REDACT", "REDACT_FORBIDDEN", "#chan", msgid, ANYSTR], + ) + + self.assertEqual(self.getMessages(1), []) diff --git a/irctest/specifications.py b/irctest/specifications.py index 9c4617bc..e8533472 100644 --- a/irctest/specifications.py +++ b/irctest/specifications.py @@ -35,6 +35,7 @@ class Capabilities(enum.Enum): EXTENDED_JOIN = "extended-join" EXTENDED_MONITOR = "extended-monitor" LABELED_RESPONSE = "labeled-response" + MESSAGE_REDACTION = "draft/message-redaction" MESSAGE_TAGS = "message-tags" MULTILINE = "draft/multiline" MULTI_PREFIX = "multi-prefix" diff --git a/pytest.ini b/pytest.ini index 375f2bb3..4b3f5efb 100644 --- a/pytest.ini +++ b/pytest.ini @@ -26,6 +26,7 @@ markers = extended-join extended-monitor labeled-response + draft/message-redaction message-tags draft/multiline multi-prefix From f0969d1fe8f1c6163430bb798bee365257605031 Mon Sep 17 00:00:00 2001 From: Valentin Lorentz Date: Fri, 26 May 2023 18:11:24 +0200 Subject: [PATCH 2/6] Add test with chathistory --- irctest/server_tests/redaction.py | 64 +++++++++++++++++++++++++++++-- 1 file changed, 61 insertions(+), 3 deletions(-) diff --git a/irctest/server_tests/redaction.py b/irctest/server_tests/redaction.py index 675c5efa..be6407ec 100644 --- a/irctest/server_tests/redaction.py +++ b/irctest/server_tests/redaction.py @@ -16,10 +16,13 @@ @cases.mark_specifications("IRCv3") @cases.mark_capabilities(*CAPABILITIES) class RedactTestCase(cases.BaseServerTestCase): - def _setupRedactTest(self, redacteeId, redacteeNick): - self.connectClient("chanop", capabilities=CAPABILITIES, skip_if_cap_nak=True) + def _setupRedactTest(self, redacteeId, redacteeNick, chathistory=False): + capabilities = list(CAPABILITIES) + if chathistory: + capabilities.extend(["batch", "draft/chathistory"]) + self.connectClient("chanop", capabilities=capabilities, skip_if_cap_nak=True) self.sendLine(1, "JOIN #chan") - self.connectClient("user", capabilities=CAPABILITIES, skip_if_cap_nak=True) + self.connectClient("user", capabilities=capabilities, skip_if_cap_nak=True) self.sendLine(2, "JOIN #chan") self.getMessages(2) # synchronize self.getMessages(1) @@ -130,3 +133,58 @@ def testRejectRedactOtherUser(self): ) self.assertEqual(self.getMessages(1), []) + + def testRelayOpSelfRedactChathistory(self): + """Channel op writes a message and redacts it themselves; both the op + and a regular user check the chathistory afterward. + + https://github.com/progval/ircv3-specifications/blob/redaction/extensions/message-redaction.md#chat-history + """ + msgid = self._setupRedactTest( + redacteeId=1, redacteeNick="chanop", chathistory=True + ) + + self.sendLine(1, f"REDACT #chan {msgid} :oops") + self.assertMessageMatch( + self.getMessage(1), + prefix=StrRe("chanop!.*"), + command="REDACT", + params=["#chan", msgid, "oops"], + ) + + self.getMessages(1) + self.getMessages(2) + + for i in (1, 2): + self.sendLine(i, "CHATHISTORY LATEST #chan * 10") + + msg = self.getMessage(i) + self.assertMessageMatch( + msg, command="BATCH", params=[StrRe(r"\+.+"), "chathistory", "#chan"] + ) + batch_tag = msg.params[0][1:] + + msgs = self.getMessages(i) + + # remove Ergo's event-playback fallback + msgs = [msg for msg in msgs if not msg.prefix.startswith("HistServ!")] + + self.assertMessageMatch(msgs[-1], command="BATCH", params=["-" + batch_tag]) + + if len(msgs) >= 2: + # Server either replaced with or appended the REDACT + self.assertMessageMatch( + msgs[-2], command="REDACT", params=["#chan", msgid, "oops"] + ) + + if len(msgs) >= 3 and msgs[-3].command == "PRIVMSG": + # Server appended the react + self.assertMessageMatch( + msgs[-4], + tags={"msgid": msgid, **ANYDICT}, + command="PRIVMSG", + params=["#chan", msgid, "hello there"], + ) + else: + # Server removed the message entirely + pass From f538b4ae6a9ab898f91d2091b9937780cebeecc8 Mon Sep 17 00:00:00 2001 From: Valentin Lorentz Date: Fri, 26 May 2023 18:50:00 +0200 Subject: [PATCH 3/6] Add testOpRedactNonExistant --- irctest/server_tests/redaction.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/irctest/server_tests/redaction.py b/irctest/server_tests/redaction.py index be6407ec..e658bef6 100644 --- a/irctest/server_tests/redaction.py +++ b/irctest/server_tests/redaction.py @@ -2,6 +2,8 @@ `IRCv3 draft message redaction `_ """ +import uuid + from irctest import cases from irctest.patma import ANYDICT, ANYSTR, StrRe @@ -188,3 +190,18 @@ def testRelayOpSelfRedactChathistory(self): else: # Server removed the message entirely pass + + def testOpRedactNonExistant(self): + """Channel op writes a message and redacts a random non-existant id.""" + self._setupRedactTest(redacteeId=1, redacteeNick="chanop") + + nonexistent_msgid = str(uuid.uuid4()) + + self.sendLine(1, f"REDACT #chan {nonexistent_msgid} :oops") + self.assertMessageMatch( + self.getMessage(1), + command="FAIL", + params=["REDACT", "UNKNOWN_MSGID", "#chan", nonexistent_msgid, ANYSTR], + ) + + self.assertEqual(self.getMessages(2), []) From 34046d34ca369340439e92d7eb9a5fbc86efd844 Mon Sep 17 00:00:00 2001 From: Valentin Lorentz Date: Mon, 29 May 2023 18:31:54 +0200 Subject: [PATCH 4/6] Add tests for PMs --- irctest/cases.py | 2 +- irctest/server_tests/redaction.py | 340 +++++++++++++++++++++++++++--- 2 files changed, 310 insertions(+), 32 deletions(-) diff --git a/irctest/cases.py b/irctest/cases.py index 4ddf07fa..288c7d30 100644 --- a/irctest/cases.py +++ b/irctest/cases.py @@ -706,7 +706,7 @@ def connectClient( self.requestCapabilities(client, capabilities, skip_if_cap_nak) if password is not None: if "sasl" not in (capabilities or ()): - raise ValueError("Used 'password' option without sasl capbilitiy") + raise ValueError("Used 'password' option without sasl capbility") self.authenticateClient(client, account or nick, password) self.sendLine(client, "NICK {}".format(nick)) diff --git a/irctest/server_tests/redaction.py b/irctest/server_tests/redaction.py index e658bef6..2851f1c0 100644 --- a/irctest/server_tests/redaction.py +++ b/irctest/server_tests/redaction.py @@ -4,6 +4,8 @@ import uuid +import pytest + from irctest import cases from irctest.patma import ANYDICT, ANYSTR, StrRe @@ -17,7 +19,7 @@ @cases.mark_specifications("IRCv3") @cases.mark_capabilities(*CAPABILITIES) -class RedactTestCase(cases.BaseServerTestCase): +class ChannelRedactTestCase(cases.BaseServerTestCase): def _setupRedactTest(self, redacteeId, redacteeNick, chathistory=False): capabilities = list(CAPABILITIES) if chathistory: @@ -136,7 +138,14 @@ def testRejectRedactOtherUser(self): self.assertEqual(self.getMessages(1), []) - def testRelayOpSelfRedactChathistory(self): + @pytest.mark.parametrize( + "chathistory_requester", + [ + pytest.param(1, id="chathistory-to-chanop"), + pytest.param(2, id="chathistory-to-user"), + ], + ) + def testOpSelfRedactChathistory(self, chathistory_requester): """Channel op writes a message and redacts it themselves; both the op and a regular user check the chathistory afterward. @@ -157,39 +166,47 @@ def testRelayOpSelfRedactChathistory(self): self.getMessages(1) self.getMessages(2) - for i in (1, 2): - self.sendLine(i, "CHATHISTORY LATEST #chan * 10") - - msg = self.getMessage(i) - self.assertMessageMatch( - msg, command="BATCH", params=[StrRe(r"\+.+"), "chathistory", "#chan"] - ) - batch_tag = msg.params[0][1:] - - msgs = self.getMessages(i) + self.sendLine(chathistory_requester, "CHATHISTORY LATEST #chan * 10") - # remove Ergo's event-playback fallback - msgs = [msg for msg in msgs if not msg.prefix.startswith("HistServ!")] + (start_msg, *msgs, end_msg) = self.getMessages(chathistory_requester) + self.assertMessageMatch( + start_msg, + command="BATCH", + params=[StrRe(r"\+.+"), "chathistory", "#chan"], + ) + batch_tag = start_msg.params[0][1:] - self.assertMessageMatch(msgs[-1], command="BATCH", params=["-" + batch_tag]) + # remove Ergo's event-playback fallback + msgs = [msg for msg in msgs if not msg.prefix.startswith("HistServ!")] - if len(msgs) >= 2: - # Server either replaced with or appended the REDACT - self.assertMessageMatch( - msgs[-2], command="REDACT", params=["#chan", msgid, "oops"] - ) + self.assertMessageMatch(end_msg, command="BATCH", params=["-" + batch_tag]) - if len(msgs) >= 3 and msgs[-3].command == "PRIVMSG": - # Server appended the react - self.assertMessageMatch( - msgs[-4], - tags={"msgid": msgid, **ANYDICT}, - command="PRIVMSG", - params=["#chan", msgid, "hello there"], - ) - else: - # Server removed the message entirely - pass + if len(msgs) == 0: + pass # Server removed the message entirely + elif len(msgs) == 1: + # Server replaced with the REDACT + self.assertMessageMatch( + msgs[1], + prefix=StrRe("sender!.*"), + command="REDACT", + params=["#chan", msgid, "oops"], + ) + elif len(msgs) == 2: + # Server appended the REDACT + self.assertMessageMatch( + msgs[0], + tags={"msgid": msgid, **ANYDICT}, + command="PRIVMSG", + params=["#chan", msgid, "hello there"], + ) + self.assertMessageMatch( + msgs[1], + prefix=StrRe("sender!.*"), + command="REDACT", + params=["#chan", msgid, "oops"], + ) + else: + self.assertTrue(False, fail_msg=f"Unexpectedly many messages: {msgs}") def testOpRedactNonExistant(self): """Channel op writes a message and redacts a random non-existant id.""" @@ -205,3 +222,264 @@ def testOpRedactNonExistant(self): ) self.assertEqual(self.getMessages(2), []) + + def testOpRedactWrongChan(self): + """Channel op writes a message and redacts it, but uses the wrong channel + as target.""" + msgid = self._setupRedactTest(redacteeId=1, redacteeNick="chanop") + + self.sendLine(1, "JOIN #otherChan") + self.getMessages(1) + + self.sendLine(1, f"REDACT #otherChan {msgid} :oops") + self.assertMessageMatch( + self.getMessage(1), + command="FAIL", + params=["REDACT", "UNKNOWN_MSGID", "#otherChan", msgid, ANYSTR], + ) + + self.assertEqual(self.getMessages(2), []) + + +@cases.mark_specifications("IRCv3") +@cases.mark_capabilities(*CAPABILITIES) +@cases.mark_services +class PmRedactTestCase(cases.BaseServerTestCase): + """Tests REDACT command in private messages between authenticated accounts""" + + def _setupRedactTest(self, chathistory=False): + capabilities = [*CAPABILITIES, "sasl"] + if chathistory: + capabilities.extend(["batch", "draft/chathistory"]) + self.controller.registerUser(self, "sender", "senderpass") + self.controller.registerUser(self, "recipient", "recipientpass") + self.connectClient( + "sender", + password="senderpass", + capabilities=capabilities, + skip_if_cap_nak=True, + ) + self.connectClient( + "recipient", + password="recipientpass", + capabilities=capabilities, + skip_if_cap_nak=True, + ) + self.getMessages(2) # synchronize + self.getMessages(1) + + self.sendLine(1, "@label=1234 PRIVMSG recipient :hello there") + echo = self.getMessage(1) + self.assertMessageMatch( + echo, + tags={"label": "1234", "msgid": StrRe("[^ ]+"), **ANYDICT}, + prefix=StrRe("sender!.*"), + command="PRIVMSG", + params=["recipient", "hello there"], + ) + msgid = echo.tags["msgid"] + + self.assertMessageMatch( + self.getMessage(2), + tags={"msgid": msgid, **ANYDICT}, + prefix=StrRe("sender!.*"), + command="PRIVMSG", + params=["recipient", "hello there"], + ) + + return msgid + + def testRelaySenderRedact(self): + """Someone writes a message in private and redacts it themselves.""" + msgid = self._setupRedactTest() + + self.sendLine(1, f"REDACT recipient {msgid} :oops") + self.assertMessageMatch( + self.getMessage(1), + prefix=StrRe("sender!.*"), + command="REDACT", + params=["recipient", msgid, "oops"], + ) + + self.assertMessageMatch( + self.getMessage(2), + prefix=StrRe("sender!.*"), + command="REDACT", + params=["recipient", msgid, "oops"], + ) + + def testRelayRecipientRedact(self): + """Someone writes a message in private and their recipient redacts it. + + Servers may either accept or reject this.""" + msgid = self._setupRedactTest() + + self.sendLine(2, f"REDACT sender {msgid} :oops") + + msg = self.getMessage(2) + if msg.command == "REDACT": + self.assertMessageMatch( + msg, + prefix=StrRe("recipient!.*"), + command="REDACT", + params=["sender", msgid, "oops"], + ) + + self.assertMessageMatch( + self.getMessage(1), + prefix=StrRe("user!.*"), + command="REDACT", + params=["sender", msgid, "oops"], + ) + else: + self.assertMessageMatch( + msg, + command="FAIL", + params=[ + "REDACT", + StrRe("(REDACT_FORBIDDEN|UNKNOWN_MSGID)"), + "sender", + msgid, + ANYSTR, + ], + ) + + self.assertEqual(self.getMessages(1), []) + + @pytest.mark.parametrize("nick", ["sender", "recipient"]) + def testRejectRedactOtherUser(self, nick): + """Someone writes a message in private to someone else and an unrelated person + attempts to redact it.""" + msgid = self._setupRedactTest() + + self.controller.registerUser(self, "censor", "censorpass") + self.connectClient( + "censor", + password="censorpass", + capabilities=[*CAPABILITIES, "sasl"], + skip_if_cap_nak=True, + ) + self.getMessages(3) # synchronize + + self.sendLine(3, f"REDACT {nick} {msgid} :oops") + self.assertMessageMatch( + self.getMessage(3), + command="FAIL", + params=[ + "REDACT", + StrRe("(REDACT_FORBIDDEN|UNKNOWN_MSGID)"), + nick, + msgid, + ANYSTR, + ], + ) + + self.assertEqual(self.getMessages(1), []) + self.assertEqual(self.getMessages(2), []) + + @pytest.mark.parametrize( + "chathistory_requester", + [ + pytest.param(1, id="chathistory-to-sender"), + pytest.param(2, id="chathistory-to-recipient"), + ], + ) + @pytest.mark.private_chathistory + def testSenderRedactChathistory(self, chathistory_requester): + """Channel op writes a message and redacts it themselves; both the op + and a regular user check the chathistory afterward. + + https://github.com/progval/ircv3-specifications/blob/redaction/extensions/message-redaction.md#chat-history + """ + msgid = self._setupRedactTest(chathistory=True) + + self.sendLine(1, f"REDACT recipient {msgid} :oops") + self.assertMessageMatch( + self.getMessage(1), + prefix=StrRe("sender!.*"), + command="REDACT", + params=["recipient", msgid, "oops"], + ) + + self.getMessages(1) + self.getMessages(2) + + if chathistory_requester == 1: + others_nick = "recipient" + else: + others_nick = "sender" + + self.sendLine(chathistory_requester, f"CHATHISTORY LATEST {others_nick} * 10") + + (start_msg, *msgs, end_msg) = self.getMessages(chathistory_requester) + self.assertMessageMatch( + start_msg, + command="BATCH", + params=[StrRe(r"\+.+"), "chathistory", others_nick], + ) + batch_tag = start_msg.params[0][1:] + + # remove Ergo's event-playback fallback + msgs = [msg for msg in msgs if not msg.prefix.startswith("HistServ!")] + + self.assertMessageMatch(end_msg, command="BATCH", params=["-" + batch_tag]) + + if len(msgs) == 0: + pass # Server removed the message entirely + elif len(msgs) == 1: + # Server replaced with the REDACT + self.assertMessageMatch( + msgs[0], + prefix=StrRe("sender!.*"), + command="REDACT", + params=["recipient", msgid, "oops"], + ) + elif len(msgs) == 2: + # Server appended the REDACT + self.assertMessageMatch( + msgs[0], + tags={"msgid": msgid, **ANYDICT}, + command="PRIVMSG", + params=["recipient", msgid, "hello there"], + ) + self.assertMessageMatch( + msgs[1], + prefix=StrRe("sender!.*"), + command="REDACT", + params=["recipient", msgid, "oops"], + ) + else: + self.assertTrue(False, fail_msg=f"Unexpectedly many messages: {msgs}") + + def testRedactNonExistant(self): + """Someone writes a message in private to someone else and redacts a random + non-existant id.""" + self._setupRedactTest() + + nonexistent_msgid = str(uuid.uuid4()) + + self.sendLine(1, f"REDACT recipient {nonexistent_msgid} :oops") + self.assertMessageMatch( + self.getMessage(1), + command="FAIL", + params=["REDACT", "UNKNOWN_MSGID", "recipient", nonexistent_msgid, ANYSTR], + ) + + self.assertEqual(self.getMessages(2), []) + + def testOpRedactWrongChan(self): + """Channel op writes a message and redacts it, but uses the wrong channel + as target.""" + msgid = self._setupRedactTest() + + self.sendLine(1, "JOIN #otherChan") + self.getMessages(1) + + self.sendLine(1, f"REDACT #otherChan {msgid} :oops") + self.assertMessageMatch( + self.getMessage(1), + command="FAIL", + params=["REDACT", "UNKNOWN_MSGID", "#otherChan", msgid, ANYSTR], + ) + + self.assertEqual(self.getMessages(2), []) From 08a434851cc87fb4f09297078552d25b47711cb3 Mon Sep 17 00:00:00 2001 From: Valentin Lorentz Date: Sun, 9 Jul 2023 20:28:26 +0200 Subject: [PATCH 5/6] Unreal stuff? --- irctest/server_tests/redaction.py | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/irctest/server_tests/redaction.py b/irctest/server_tests/redaction.py index 2851f1c0..58223bba 100644 --- a/irctest/server_tests/redaction.py +++ b/irctest/server_tests/redaction.py @@ -12,6 +12,8 @@ CAPABILITIES = [ "message-tags", "echo-message", + "batch", + "server-time", "labeled-response", "draft/message-redaction", ] @@ -186,7 +188,7 @@ def testOpSelfRedactChathistory(self, chathistory_requester): elif len(msgs) == 1: # Server replaced with the REDACT self.assertMessageMatch( - msgs[1], + msgs[0], prefix=StrRe("sender!.*"), command="REDACT", params=["#chan", msgid, "oops"], @@ -232,11 +234,25 @@ def testOpRedactWrongChan(self): self.getMessages(1) self.sendLine(1, f"REDACT #otherChan {msgid} :oops") + + msg = self.getMessage(1) + self.assertMessageMatch( - self.getMessage(1), + msg, command="FAIL", - params=["REDACT", "UNKNOWN_MSGID", "#otherChan", msgid, ANYSTR], ) + if msg.params[1] == "UNKNOWN_MSGID": + self.assertMessageMatch( + msg, + command="FAIL", + params=["REDACT", "UNKNOWN_MSGID", "#otherChan", msgid, ANYSTR], + ) + else: + self.assertMessageMatch( + msg, + command="FAIL", + params=["REDACT", "REDACT_FORBIDDEN", "#otherChan", ANYSTR], + ) self.assertEqual(self.getMessages(2), []) @@ -244,6 +260,7 @@ def testOpRedactWrongChan(self): @cases.mark_specifications("IRCv3") @cases.mark_capabilities(*CAPABILITIES) @cases.mark_services +@pytest.mark.private_chathistory class PmRedactTestCase(cases.BaseServerTestCase): """Tests REDACT command in private messages between authenticated accounts""" From 0d93503ac7278528fbb95547090323354627eb8e Mon Sep 17 00:00:00 2001 From: Valentin Lorentz Date: Fri, 17 Nov 2023 13:07:16 +0100 Subject: [PATCH 6/6] Load third/redact on Unreal --- .github/workflows/test-devel.yml | 2 ++ .github/workflows/test-stable.yml | 2 ++ irctest/controllers/unrealircd.py | 6 ++++++ workflows.yml | 1 + 4 files changed, 11 insertions(+) diff --git a/.github/workflows/test-devel.yml b/.github/workflows/test-devel.yml index 7173c8c0..c4a42cee 100644 --- a/.github/workflows/test-devel.yml +++ b/.github/workflows/test-devel.yml @@ -324,6 +324,7 @@ jobs: CFLAGS="-O0 -march=x86-64" CXXFLAGS="$CFLAGS" ./Config -quick make -j 4 make install + ~/.local/unrealircd/unrealircd module install third/react # Prevent download of geoIP database on first startup sed -i 's/loadmodule "geoip_classic";//' ~/.local/unrealircd/conf/modules.default.conf - name: Make artefact tarball @@ -370,6 +371,7 @@ jobs: CFLAGS="-O0 -march=x86-64" CXXFLAGS="$CFLAGS" ./Config -quick make -j 4 make install + ~/.local/unrealircd/unrealircd module install third/react # Prevent download of geoIP database on first startup sed -i 's/loadmodule "geoip_classic";//' ~/.local/unrealircd/conf/modules.default.conf - name: Make artefact tarball diff --git a/.github/workflows/test-stable.yml b/.github/workflows/test-stable.yml index c3863ac0..084b48f2 100644 --- a/.github/workflows/test-stable.yml +++ b/.github/workflows/test-stable.yml @@ -364,6 +364,7 @@ jobs: CFLAGS="-O0 -march=x86-64" CXXFLAGS="$CFLAGS" ./Config -quick make -j 4 make install + ~/.local/unrealircd/unrealircd module install third/react # Prevent download of geoIP database on first startup sed -i 's/loadmodule "geoip_classic";//' ~/.local/unrealircd/conf/modules.default.conf - name: Make artefact tarball @@ -410,6 +411,7 @@ jobs: CFLAGS="-O0 -march=x86-64" CXXFLAGS="$CFLAGS" ./Config -quick make -j 4 make install + ~/.local/unrealircd/unrealircd module install third/react # Prevent download of geoIP database on first startup sed -i 's/loadmodule "geoip_classic";//' ~/.local/unrealircd/conf/modules.default.conf - name: Make artefact tarball diff --git a/irctest/controllers/unrealircd.py b/irctest/controllers/unrealircd.py index 8d7e643c..bad7be75 100644 --- a/irctest/controllers/unrealircd.py +++ b/irctest/controllers/unrealircd.py @@ -13,6 +13,7 @@ include "modules.default.conf"; include "operclass.default.conf"; {extras} +loadmodule "third/redact"; include "help/help.conf"; me {{ @@ -96,6 +97,11 @@ class servers; }} modes-on-join "+H 100:1d"; // Enables CHATHISTORY + redacters {{ + op; + sender; + }} + {set_v6only} }} diff --git a/workflows.yml b/workflows.yml index 65e27e23..0ac243b3 100644 --- a/workflows.yml +++ b/workflows.yml @@ -289,6 +289,7 @@ software: CFLAGS="-O0 -march=x86-64" CXXFLAGS="$CFLAGS" ./Config -quick make -j 4 make install + ~/.local/unrealircd/unrealircd module install third/react # Prevent download of geoIP database on first startup sed -i 's/loadmodule "geoip_classic";//' ~/.local/unrealircd/conf/modules.default.conf