-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Uniformize spam-checker API, part 5: expand other spam-checker callbacks to return Tuple[Codes, dict]
#13044
Conversation
…cks to return Tuple[Codes, dict]
c8affa5
to
e714f8d
Compare
As far as I can tell, the monolith test fails because of a network issue (cannot assign IP), unrelated to the PR. |
For some reason, |
…spam to return a Tuple[Codes, dict]?
Tuple[Codes, dict]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry about the round-trip time for this one!
tests/rest/client/test_rooms.py
Outdated
@@ -1312,6 +1354,71 @@ def test_rooms_messages_sent(self) -> None: | |||
channel = self.make_request("PUT", path, content) | |||
self.assertEqual(200, channel.code, msg=channel.result["body"]) | |||
|
|||
def test_spam_checker_check_event_for_spam(self) -> None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks to me like this test could be simplified a lot by using parameterized.expand
, see
synapse/tests/http/test_proxyagent.py
Lines 56 to 208 in 339c391
@parameterized.expand( | |
[ | |
# host | |
[b"localhost", b"http", b"localhost", 1080, None], | |
[b"localhost:9988", b"http", b"localhost", 9988, None], | |
# host+scheme | |
[b"https://localhost", b"https", b"localhost", 1080, None], | |
[b"https://localhost:1234", b"https", b"localhost", 1234, None], | |
# ipv4 | |
[b"1.2.3.4", b"http", b"1.2.3.4", 1080, None], | |
[b"1.2.3.4:9988", b"http", b"1.2.3.4", 9988, None], | |
# ipv4+scheme | |
[b"https://1.2.3.4", b"https", b"1.2.3.4", 1080, None], | |
[b"https://1.2.3.4:9988", b"https", b"1.2.3.4", 9988, None], | |
# ipv6 - without brackets is broken | |
# [ | |
# b"2001:0db8:85a3:0000:0000:8a2e:0370:effe", | |
# b"http", | |
# b"2001:0db8:85a3:0000:0000:8a2e:0370:effe", | |
# 1080, | |
# None, | |
# ], | |
# [ | |
# b"2001:0db8:85a3:0000:0000:8a2e:0370:1234", | |
# b"http", | |
# b"2001:0db8:85a3:0000:0000:8a2e:0370:1234", | |
# 1080, | |
# None, | |
# ], | |
# [b"::1", b"http", b"::1", 1080, None], | |
# [b"::ffff:0.0.0.0", b"http", b"::ffff:0.0.0.0", 1080, None], | |
# ipv6 - with brackets | |
[ | |
b"[2001:0db8:85a3:0000:0000:8a2e:0370:effe]", | |
b"http", | |
b"2001:0db8:85a3:0000:0000:8a2e:0370:effe", | |
1080, | |
None, | |
], | |
[ | |
b"[2001:0db8:85a3:0000:0000:8a2e:0370:1234]", | |
b"http", | |
b"2001:0db8:85a3:0000:0000:8a2e:0370:1234", | |
1080, | |
None, | |
], | |
[b"[::1]", b"http", b"::1", 1080, None], | |
[b"[::ffff:0.0.0.0]", b"http", b"::ffff:0.0.0.0", 1080, None], | |
# ipv6+port | |
[ | |
b"[2001:0db8:85a3:0000:0000:8a2e:0370:effe]:9988", | |
b"http", | |
b"2001:0db8:85a3:0000:0000:8a2e:0370:effe", | |
9988, | |
None, | |
], | |
[ | |
b"[2001:0db8:85a3:0000:0000:8a2e:0370:1234]:9988", | |
b"http", | |
b"2001:0db8:85a3:0000:0000:8a2e:0370:1234", | |
9988, | |
None, | |
], | |
[b"[::1]:9988", b"http", b"::1", 9988, None], | |
[b"[::ffff:0.0.0.0]:9988", b"http", b"::ffff:0.0.0.0", 9988, None], | |
# ipv6+scheme | |
[ | |
b"https://[2001:0db8:85a3:0000:0000:8a2e:0370:effe]", | |
b"https", | |
b"2001:0db8:85a3:0000:0000:8a2e:0370:effe", | |
1080, | |
None, | |
], | |
[ | |
b"https://[2001:0db8:85a3:0000:0000:8a2e:0370:1234]", | |
b"https", | |
b"2001:0db8:85a3:0000:0000:8a2e:0370:1234", | |
1080, | |
None, | |
], | |
[b"https://[::1]", b"https", b"::1", 1080, None], | |
[b"https://[::ffff:0.0.0.0]", b"https", b"::ffff:0.0.0.0", 1080, None], | |
# ipv6+scheme+port | |
[ | |
b"https://[2001:0db8:85a3:0000:0000:8a2e:0370:effe]:9988", | |
b"https", | |
b"2001:0db8:85a3:0000:0000:8a2e:0370:effe", | |
9988, | |
None, | |
], | |
[ | |
b"https://[2001:0db8:85a3:0000:0000:8a2e:0370:1234]:9988", | |
b"https", | |
b"2001:0db8:85a3:0000:0000:8a2e:0370:1234", | |
9988, | |
None, | |
], | |
[b"https://[::1]:9988", b"https", b"::1", 9988, None], | |
# with credentials | |
[ | |
b"https://user:pass@1.2.3.4:9988", | |
b"https", | |
b"1.2.3.4", | |
9988, | |
b"user:pass", | |
], | |
[b"user:pass@1.2.3.4:9988", b"http", b"1.2.3.4", 9988, b"user:pass"], | |
[ | |
b"https://user:pass@proxy.local:9988", | |
b"https", | |
b"proxy.local", | |
9988, | |
b"user:pass", | |
], | |
[ | |
b"user:pass@proxy.local:9988", | |
b"http", | |
b"proxy.local", | |
9988, | |
b"user:pass", | |
], | |
] | |
) | |
def test_parse_proxy( | |
self, | |
proxy_string: bytes, | |
expected_scheme: bytes, | |
expected_hostname: bytes, | |
expected_port: int, | |
expected_credentials: Optional[bytes], | |
): | |
""" | |
Tests that a given proxy URL will be broken into the components. | |
Args: | |
proxy_string: The proxy connection string. | |
expected_scheme: Expected value of proxy scheme. | |
expected_hostname: Expected value of proxy hostname. | |
expected_port: Expected value of proxy port. | |
expected_credentials: Expected value of credentials. | |
Must be in form '<username>:<password>' or None | |
""" | |
proxy_cred = None | |
if expected_credentials: | |
proxy_cred = ProxyCredentials(expected_credentials) | |
self.assertEqual( | |
( | |
expected_scheme, | |
expected_hostname, | |
expected_port, | |
proxy_cred, | |
), | |
parse_proxy(proxy_string), | |
) |
or
synapse/tests/app/test_openid_listener.py
Lines 42 to 79 in 5a15377
@parameterized.expand( | |
[ | |
(["federation"], "auth_fail"), | |
([], "no_resource"), | |
(["openid", "federation"], "auth_fail"), | |
(["openid"], "auth_fail"), | |
] | |
) | |
def test_openid_listener(self, names, expectation): | |
""" | |
Test different openid listener configurations. | |
401 is success here since it means we hit the handler and auth failed. | |
""" | |
config = { | |
"port": 8080, | |
"type": "http", | |
"bind_addresses": ["0.0.0.0"], | |
"resources": [{"names": names}], | |
} | |
# Listen with the config | |
self.hs._listen_http(parse_listener_def(config)) | |
# Grab the resource from the site that was told to listen | |
site = self.reactor.tcpServers[0][1] | |
try: | |
site.resource.children[b"_matrix"].children[b"federation"] | |
except KeyError: | |
if expectation == "no_resource": | |
return | |
raise | |
channel = make_request( | |
self.reactor, site, "GET", "/_matrix/federation/v1/openid/userinfo" | |
) | |
self.assertEqual(channel.code, 401) |
for examples.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, introduce a new framework to this test along with magic code generation to get rid of one loop?
I can do that if you insist, but my first impression is that this would actually increase cognitive load of reading that test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you mean by introducing a new framework? We already use it quite a bit in Synapse's tests suite. In my opinion it makes tests much easier to read as it reduces the complexity of the actual test code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean that reading this test doesn't require understanding that framework yet. If you wish me to introduce it, I can do that, of course.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, your wish is my command :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This plus I really think we should be using parameterized
in test_spam_checker_check_event_for_spam
.
The objective of this push is to progressively expand the spam-checker API into letting spam-checkers provide reasons for which an event/operation has been rejected. In particular, we wish to prototype account suspension (by opposition to account removal) through spam-checkers and let users know what they need to do to have the account unsuspended.
Specifically, letting a spam-checker return an additional
dict
gives us a way to point users towards an individual url on which they can read up all the details about their suspension.This is a followup to:
Code
enum. #12703, Uniformize spam-checker API, part 1: turningCodes
into anEnum
.check_event_for_spam
to let callbacks returnCodes
.check_event_for_spam
to let callbacks return additional fields.Union[Allow, Codes]
. #12857, Uniformize spam-checker API, part 4: convert other spam-checker callbacks to returnCodes
.Pull Request Checklist
EventStore
toEventWorkerStore
.".code blocks
.(run the linters)