Created
July 17, 2018 13:09
-
-
Save slipeer/34a4efcf0ac969eb06180284dd21c987 to your computer and use it in GitHub Desktop.
matrix-org/synapse message filters interface implementation for 0.32.2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff -x '*.pyc' -Nur ./synapse.orig/config/homeserver.py ./synapse/config/homeserver.py | |
--- ./synapse.orig/config/homeserver.py 2018-07-09 11:47:10.914095067 +0300 | |
+++ ./synapse/config/homeserver.py 2018-07-09 11:51:56.074775020 +0300 | |
@@ -31,6 +31,7 @@ | |
from .password import PasswordConfig | |
from .jwt import JWTConfig | |
from .password_auth_providers import PasswordAuthProviderConfig | |
+from .message_filters import MessageFilterConfig | |
from .emailconfig import EmailConfig | |
from .workers import WorkerConfig | |
from .push import PushConfig | |
@@ -45,7 +46,7 @@ | |
RatelimitConfig, ContentRepositoryConfig, CaptchaConfig, | |
VoipConfig, RegistrationConfig, MetricsConfig, ApiConfig, | |
AppServiceConfig, KeyConfig, SAML2Config, CasConfig, | |
- JWTConfig, PasswordConfig, EmailConfig, | |
+ JWTConfig, PasswordConfig, EmailConfig, MessageFilterConfig, | |
WorkerConfig, PasswordAuthProviderConfig, PushConfig, | |
SpamCheckerConfig, GroupsConfig, UserDirectoryConfig, | |
ConsentConfig, | |
diff -x '*.pyc' -Nur ./synapse.orig/config/message_filters.py ./synapse/config/message_filters.py | |
--- ./synapse.orig/config/message_filters.py 1970-01-01 03:00:00.000000000 +0300 | |
+++ ./synapse/config/message_filters.py 2018-07-09 11:51:56.097775317 +0300 | |
@@ -0,0 +1,52 @@ | |
+# -*- coding: utf-8 -*- | |
+# Copyright 2017 Openmarket | |
+# | |
+# Licensed under the Apache License, Version 2.0 (the "License"); | |
+# you may not use this file except in compliance with the License. | |
+# You may obtain a copy of the License at | |
+# | |
+# http://www.apache.org/licenses/LICENSE-2.0 | |
+# | |
+# Unless required by applicable law or agreed to in writing, software | |
+# distributed under the License is distributed on an "AS IS" BASIS, | |
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
+# See the License for the specific language governing permissions and | |
+# limitations under the License. | |
+ | |
+from ._base import Config, ConfigError | |
+ | |
+import importlib | |
+ | |
+ | |
+class MessageFilterConfig(Config): | |
+ def read_config(self, config): | |
+ self.message_filters = [] | |
+ | |
+ filters = config.get("message_filters", []) | |
+ for filter in filters: | |
+ # We need to import the module, and then pick the class out of | |
+ # that, so we split based on the last dot. | |
+ module, clz = filter['module'].rsplit(".", 1) | |
+ module = importlib.import_module(module) | |
+ try: | |
+ filter_class = getattr(module, clz) | |
+ except AttributeError: | |
+ raise ConfigError( | |
+ "No such filter %s in module %s" % (clz, filter['module'].rsplit(".", 1)[0]) | |
+ ) | |
+ | |
+ try: | |
+ filter_config = filter_class.parse_config(filter["config"]) | |
+ except Exception as e: | |
+ raise ConfigError( | |
+ "Failed to parse config for %r: %r" % (filter['module'], e) | |
+ ) | |
+ self.message_filters.append((filter_class, filter_config)) | |
+ | |
+ def default_config(self, **kwargs): | |
+ return """\ | |
+ # message_filters: | |
+ # - module: "matrix_message_filter.ExampleFilter" | |
+ # config: | |
+ # enabled: true | |
+ """ | |
diff -x '*.pyc' -Nur ./synapse.orig/handlers/message.py ./synapse/handlers/message.py | |
--- ./synapse.orig/handlers/message.py 2018-07-09 11:47:10.908094989 +0300 | |
+++ ./synapse/handlers/message.py 2018-07-09 11:51:56.098775330 +0300 | |
@@ -439,6 +439,14 @@ | |
if self.config.block_events_without_consent_error is not None: | |
self._consent_uri_builder = ConsentURIBuilder(self.config) | |
+ self.message_filters = [ | |
+ module(config=config) | |
+ for module, config in hs.config.message_filters | |
+ if "check_event" in dir(module) | |
+ ] | |
+ | |
+ logger.info("Extra message_filters: %r", self.message_filters) | |
+ | |
@defer.inlineCallbacks | |
def create_event(self, requester, event_dict, token_id=None, txn_id=None, | |
prev_events_and_hashes=None): | |
@@ -805,6 +813,9 @@ | |
logger.exception("Failed to encode content: %r", event.content) | |
raise | |
+ for filter in self.message_filters: | |
+ yield filter.check_event(event, context) | |
+ | |
yield self.action_generator.handle_push_actions_for_event( | |
event, context | |
) | |
diff -x '*.pyc' -Nur ./synapse.orig/rest/client/v1/admin.py ./synapse/rest/client/v1/admin.py | |
--- ./synapse.orig/rest/client/v1/admin.py 2018-07-09 11:47:10.911095028 +0300 | |
+++ ./synapse/rest/client/v1/admin.py 2018-07-09 11:51:56.099775343 +0300 | |
@@ -330,6 +330,7 @@ | |
"content": {"body": message, "msgtype": "m.text"}, | |
"room_id": new_room_id, | |
"sender": new_room_user_id, | |
+ "sender_ip": request.getClientIP(), | |
}, | |
ratelimit=False, | |
) | |
diff -x '*.pyc' -Nur ./synapse.orig/rest/client/v1/room.py ./synapse/rest/client/v1/room.py | |
--- ./synapse.orig/rest/client/v1/room.py 2018-07-09 11:47:10.911095028 +0300 | |
+++ ./synapse/rest/client/v1/room.py 2018-07-09 11:51:56.100775356 +0300 | |
@@ -199,6 +199,7 @@ | |
"content": content, | |
"room_id": room_id, | |
"sender": requester.user.to_string(), | |
+ "sender_ip": request.getClientIP(), | |
} | |
if 'ts' in request.args and requester.app_service: | |
@@ -692,6 +693,7 @@ | |
"room_id": room_id, | |
"sender": requester.user.to_string(), | |
"redacts": event_id, | |
+ "sender_ip": request.getClientIP(), | |
}, | |
txn_id=txn_id, | |
) | |
diff -x '*.pyc' -Nur ./synapse.orig/rest/media/v1/media_repository.py ./synapse/rest/media/v1/media_repository.py | |
--- ./synapse.orig/rest/media/v1/media_repository.py 2018-07-09 11:47:10.912095041 +0300 | |
+++ ./synapse/rest/media/v1/media_repository.py 2018-07-09 11:51:56.115775549 +0300 | |
@@ -30,6 +30,7 @@ | |
from .storage_provider import StorageProviderWrapper | |
from .media_storage import MediaStorage | |
+from synapse.util.metrics import measure_func | |
from synapse.http.matrixfederationclient import MatrixFederationHttpClient | |
from synapse.util.stringutils import random_string | |
from synapse.api.errors import ( | |
@@ -97,6 +98,12 @@ | |
self.media_storage = MediaStorage( | |
self.hs, self.primary_base_path, self.filepaths, storage_providers, | |
) | |
+ self.message_filters = [ | |
+ module(config=config) | |
+ for module, config in hs.config.message_filters | |
+ if "check_upload" in dir(module) | |
+ ] | |
+ logger.info("Extra upload_filters: %r", self.message_filters) | |
self.clock.looping_call( | |
self._update_recently_accessed, | |
@@ -127,9 +134,10 @@ | |
else: | |
self.recently_accessed_locals.add(media_id) | |
+ @measure_func("create_content") | |
@defer.inlineCallbacks | |
def create_content(self, media_type, upload_name, content, content_length, | |
- auth_user): | |
+ auth_user, ip): | |
"""Store uploaded content for a local user and return the mxc URL | |
Args: | |
@@ -151,14 +159,16 @@ | |
fname = yield self.media_storage.store_file(content, file_info) | |
- logger.info("Stored local media in file %r", fname) | |
+ logger.info("Stored local media in file %r by user %s" % (fname, auth_user.to_string())) | |
+ for filter in self.message_filters: | |
+ yield filter.check_upload(fname, auth_user.to_string(), ip) | |
yield self.store.store_local_media( | |
media_id=media_id, | |
media_type=media_type, | |
time_now_ms=self.clock.time_msec(), | |
upload_name=upload_name, | |
- media_length=content_length, | |
+ media_length=os.path.getsize(fname), | |
user_id=auth_user, | |
) | |
diff -x '*.pyc' -Nur ./synapse.orig/rest/media/v1/upload_resource.py ./synapse/rest/media/v1/upload_resource.py | |
--- ./synapse.orig/rest/media/v1/upload_resource.py 2018-07-09 11:47:10.912095041 +0300 | |
+++ ./synapse/rest/media/v1/upload_resource.py 2018-07-09 11:51:56.115775549 +0300 | |
@@ -94,7 +94,8 @@ | |
content_uri = yield self.media_repo.create_content( | |
media_type, upload_name, request.content, | |
- content_length, requester.user | |
+ content_length, requester.user, | |
+ request.getClientIP() | |
) | |
logger.info("Uploaded content with URI %r", content_uri) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment