|
|
|
@ -30,6 +30,8 @@ from twisted.internet import defer |
|
|
|
|
from twisted.internet.defer import Deferred |
|
|
|
|
|
|
|
|
|
from synapse.logging.context import make_deferred_yieldable |
|
|
|
|
from synapse.rest import admin |
|
|
|
|
from synapse.rest.client.v1 import login |
|
|
|
|
from synapse.rest.media.v1._base import FileInfo |
|
|
|
|
from synapse.rest.media.v1.filepath import MediaFilePaths |
|
|
|
|
from synapse.rest.media.v1.media_storage import MediaStorage |
|
|
|
@ -37,6 +39,7 @@ from synapse.rest.media.v1.storage_provider import FileStorageProviderBackend |
|
|
|
|
|
|
|
|
|
from tests import unittest |
|
|
|
|
from tests.server import FakeSite, make_request |
|
|
|
|
from tests.utils import default_config |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class MediaStorageTests(unittest.HomeserverTestCase): |
|
|
|
@ -398,3 +401,94 @@ class MediaRepoTests(unittest.HomeserverTestCase): |
|
|
|
|
headers.getRawHeaders(b"X-Robots-Tag"), |
|
|
|
|
[b"noindex, nofollow, noarchive, noimageindex"], |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class TestSpamChecker: |
|
|
|
|
"""A spam checker module that rejects all media that includes the bytes |
|
|
|
|
`evil`. |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
def __init__(self, config, api): |
|
|
|
|
self.config = config |
|
|
|
|
self.api = api |
|
|
|
|
|
|
|
|
|
def parse_config(config): |
|
|
|
|
return config |
|
|
|
|
|
|
|
|
|
async def check_event_for_spam(self, foo): |
|
|
|
|
return False # allow all events |
|
|
|
|
|
|
|
|
|
async def user_may_invite(self, inviter_userid, invitee_userid, room_id): |
|
|
|
|
return True # allow all invites |
|
|
|
|
|
|
|
|
|
async def user_may_create_room(self, userid): |
|
|
|
|
return True # allow all room creations |
|
|
|
|
|
|
|
|
|
async def user_may_create_room_alias(self, userid, room_alias): |
|
|
|
|
return True # allow all room aliases |
|
|
|
|
|
|
|
|
|
async def user_may_publish_room(self, userid, room_id): |
|
|
|
|
return True # allow publishing of all rooms |
|
|
|
|
|
|
|
|
|
async def check_media_file_for_spam(self, file_wrapper, file_info) -> bool: |
|
|
|
|
buf = BytesIO() |
|
|
|
|
await file_wrapper.write_chunks_to(buf.write) |
|
|
|
|
|
|
|
|
|
return b"evil" in buf.getvalue() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class SpamCheckerTestCase(unittest.HomeserverTestCase): |
|
|
|
|
servlets = [ |
|
|
|
|
login.register_servlets, |
|
|
|
|
admin.register_servlets, |
|
|
|
|
] |
|
|
|
|
|
|
|
|
|
def prepare(self, reactor, clock, hs): |
|
|
|
|
self.user = self.register_user("user", "pass") |
|
|
|
|
self.tok = self.login("user", "pass") |
|
|
|
|
|
|
|
|
|
# Allow for uploading and downloading to/from the media repo |
|
|
|
|
self.media_repo = hs.get_media_repository_resource() |
|
|
|
|
self.download_resource = self.media_repo.children[b"download"] |
|
|
|
|
self.upload_resource = self.media_repo.children[b"upload"] |
|
|
|
|
|
|
|
|
|
def default_config(self): |
|
|
|
|
config = default_config("test") |
|
|
|
|
|
|
|
|
|
config.update( |
|
|
|
|
{ |
|
|
|
|
"spam_checker": [ |
|
|
|
|
{ |
|
|
|
|
"module": TestSpamChecker.__module__ + ".TestSpamChecker", |
|
|
|
|
"config": {}, |
|
|
|
|
} |
|
|
|
|
] |
|
|
|
|
} |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
return config |
|
|
|
|
|
|
|
|
|
def test_upload_innocent(self): |
|
|
|
|
"""Attempt to upload some innocent data that should be allowed. |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
image_data = unhexlify( |
|
|
|
|
b"89504e470d0a1a0a0000000d4948445200000001000000010806" |
|
|
|
|
b"0000001f15c4890000000a49444154789c63000100000500010d" |
|
|
|
|
b"0a2db40000000049454e44ae426082" |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
self.helper.upload_media( |
|
|
|
|
self.upload_resource, image_data, tok=self.tok, expect_code=200 |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
def test_upload_ban(self): |
|
|
|
|
"""Attempt to upload some data that includes bytes "evil", which should |
|
|
|
|
get rejected by the spam checker. |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
data = b"Some evil data" |
|
|
|
|
|
|
|
|
|
self.helper.upload_media( |
|
|
|
|
self.upload_resource, data, tok=self.tok, expect_code=400 |
|
|
|
|
) |
|
|
|
|