summary refs log tree commit diff
path: root/synapse
diff options
context:
space:
mode:
Diffstat (limited to 'synapse')
-rw-r--r--synapse/api/filtering.py60
1 files changed, 52 insertions, 8 deletions
diff --git a/synapse/api/filtering.py b/synapse/api/filtering.py
index d7ba6510ee..21fe72d6c2 100644
--- a/synapse/api/filtering.py
+++ b/synapse/api/filtering.py
@@ -30,25 +30,69 @@ class Filtering(object):
         self._check_valid_filter(user_filter)
         return self.store.add_user_filter(user_localpart, user_filter)
 
+    def filter_public_user_data(self, events, user, filter_id):
+        return self._filter_on_key(
+            events, user, filter_id, ["public_user_data"]
+        )
+
+    def filter_private_user_data(self, events, user, filter_id):
+        return self._filter_on_key(
+            events, user, filter_id, ["private_user_data"]
+        )
+
+    def filter_room_state(self, events, user, filter_id):
+        return self._filter_on_key(
+            events, user, filter_id, ["room", "state"]
+        )
+
+    def filter_room_events(self, events, user, filter_id):
+        return self._filter_on_key(
+            events, user, filter_id, ["room", "events"]
+        )
+
+    def filter_room_ephemeral(self, events, user, filter_id):
+        return self._filter_on_key(
+            events, user, filter_id, ["room", "ephemeral"]
+        )
+
     # TODO(paul): surely we should probably add a delete_user_filter or
     #   replace_user_filter at some point? There's no REST API specified for
     #   them however
 
-    def passes_filter(self, filter_json, event):
-        """Check if the event passes through the filter.
+    def _filter_on_key(self, events, user, filter_id, keys):
+        filter_json = self.get_user_filter(user.localpart, filter_id)
+        if not filter_json:
+            return events
+
+        try:
+            # extract the right definition from the filter
+            definition = filter_json
+            for key in keys:
+                definition = definition[key]
+            return self._filter_with_definition(events, definition)
+        except KeyError:
+            return events  # return all events if definition isn't specified.
+
+    def _filter_with_definition(self, events, definition):
+        return [e for e in events if self._passes_definition(definition, e)]
+
+    def _passes_definition(self, definition, event):
+        """Check if the event passes through the given definition.
 
         Args:
-            filter_json(dict): The filter specification
-            event(Event): The event to check
+            definition(dict): The definition to check against.
+            event(Event): The event to check.
         Returns:
             True if the event passes through the filter.
         """
+        # Algorithm notes:
+        # For each key in the definition, check the event meets the criteria:
+        #   * For types: Literal match or prefix match (if ends with wildcard)
+        #   * For senders/rooms: Literal match only
+        #   * "not_" checks take presedence (e.g. if "m.*" is in both 'types'
+        #     and 'not_types' then it is treated as only being in 'not_types')
         return True
 
-    def filter_events(self, events, user, filter_id):
-        filter_json = self.get_user_filter(user, filter_id)
-        return [e for e in events if self.passes_filter(filter_json, e)]
-
     def _check_valid_filter(self, user_filter):
         """Check if the provided filter is valid.