|
30 | 30 | from twisted.internet.defer import Deferred |
31 | 31 |
|
32 | 32 | from synapse.logging.context import make_deferred_yieldable |
| 33 | +from synapse.rest import admin |
| 34 | +from synapse.rest.client.v1 import login |
33 | 35 | from synapse.rest.media.v1._base import FileInfo |
34 | 36 | from synapse.rest.media.v1.filepath import MediaFilePaths |
35 | 37 | from synapse.rest.media.v1.media_storage import MediaStorage |
36 | 38 | from synapse.rest.media.v1.storage_provider import FileStorageProviderBackend |
37 | 39 |
|
38 | 40 | from tests import unittest |
39 | 41 | from tests.server import FakeSite, make_request |
| 42 | +from tests.utils import default_config |
40 | 43 |
|
41 | 44 |
|
42 | 45 | class MediaStorageTests(unittest.HomeserverTestCase): |
@@ -398,3 +401,94 @@ def test_x_robots_tag_header(self): |
398 | 401 | headers.getRawHeaders(b"X-Robots-Tag"), |
399 | 402 | [b"noindex, nofollow, noarchive, noimageindex"], |
400 | 403 | ) |
| 404 | + |
| 405 | + |
| 406 | +class TestSpamChecker: |
| 407 | + """A spam checker module that rejects all media that includes the bytes |
| 408 | + `evil`. |
| 409 | + """ |
| 410 | + |
| 411 | + def __init__(self, config, api): |
| 412 | + self.config = config |
| 413 | + self.api = api |
| 414 | + |
| 415 | + def parse_config(config): |
| 416 | + return config |
| 417 | + |
| 418 | + async def check_event_for_spam(self, foo): |
| 419 | + return False # allow all events |
| 420 | + |
| 421 | + async def user_may_invite(self, inviter_userid, invitee_userid, room_id): |
| 422 | + return True # allow all invites |
| 423 | + |
| 424 | + async def user_may_create_room(self, userid): |
| 425 | + return True # allow all room creations |
| 426 | + |
| 427 | + async def user_may_create_room_alias(self, userid, room_alias): |
| 428 | + return True # allow all room aliases |
| 429 | + |
| 430 | + async def user_may_publish_room(self, userid, room_id): |
| 431 | + return True # allow publishing of all rooms |
| 432 | + |
| 433 | + async def check_media_file_for_spam(self, file_wrapper, file_info) -> bool: |
| 434 | + buf = BytesIO() |
| 435 | + await file_wrapper.write_chunks_to(buf.write) |
| 436 | + |
| 437 | + return b"evil" in buf.getvalue() |
| 438 | + |
| 439 | + |
| 440 | +class SpamCheckerTestCase(unittest.HomeserverTestCase): |
| 441 | + servlets = [ |
| 442 | + login.register_servlets, |
| 443 | + admin.register_servlets, |
| 444 | + ] |
| 445 | + |
| 446 | + def prepare(self, reactor, clock, hs): |
| 447 | + self.user = self.register_user("user", "pass") |
| 448 | + self.tok = self.login("user", "pass") |
| 449 | + |
| 450 | + # Allow for uploading and downloading to/from the media repo |
| 451 | + self.media_repo = hs.get_media_repository_resource() |
| 452 | + self.download_resource = self.media_repo.children[b"download"] |
| 453 | + self.upload_resource = self.media_repo.children[b"upload"] |
| 454 | + |
| 455 | + def default_config(self): |
| 456 | + config = default_config("test") |
| 457 | + |
| 458 | + config.update( |
| 459 | + { |
| 460 | + "spam_checker": [ |
| 461 | + { |
| 462 | + "module": TestSpamChecker.__module__ + ".TestSpamChecker", |
| 463 | + "config": {}, |
| 464 | + } |
| 465 | + ] |
| 466 | + } |
| 467 | + ) |
| 468 | + |
| 469 | + return config |
| 470 | + |
| 471 | + def test_upload_innocent(self): |
| 472 | + """Attempt to upload some innocent data that should be allowed. |
| 473 | + """ |
| 474 | + |
| 475 | + image_data = unhexlify( |
| 476 | + b"89504e470d0a1a0a0000000d4948445200000001000000010806" |
| 477 | + b"0000001f15c4890000000a49444154789c63000100000500010d" |
| 478 | + b"0a2db40000000049454e44ae426082" |
| 479 | + ) |
| 480 | + |
| 481 | + self.helper.upload_media( |
| 482 | + self.upload_resource, image_data, tok=self.tok, expect_code=200 |
| 483 | + ) |
| 484 | + |
| 485 | + def test_upload_ban(self): |
| 486 | + """Attempt to upload some data that includes bytes "evil", which should |
| 487 | + get rejected by the spam checker. |
| 488 | + """ |
| 489 | + |
| 490 | + data = b"Some evil data" |
| 491 | + |
| 492 | + self.helper.upload_media( |
| 493 | + self.upload_resource, data, tok=self.tok, expect_code=400 |
| 494 | + ) |
0 commit comments