summary refs log tree commit diff
path: root/synapse/api/events
diff options
context:
space:
mode:
authorMark Haines <mjark@negativecurvature.net>2014-12-16 13:53:43 +0000
committerMark Haines <mjark@negativecurvature.net>2014-12-16 13:53:43 +0000
commit2af40cfa14ba579c156349ae3457a55bc93f8548 (patch)
tree2b94b53c72d51fc170549213ed8cb88556c2b501 /synapse/api/events
parentAdd a script for talking matrix federation adding X-Matrix Authorization (diff)
parentFix pyflakes (diff)
downloadsynapse-2af40cfa14ba579c156349ae3457a55bc93f8548.tar.xz
Merge pull request #25 from matrix-org/events_refactor
Event refactor
Diffstat (limited to 'synapse/api/events')
-rw-r--r--synapse/api/events/__init__.py148
-rw-r--r--synapse/api/events/factory.py90
-rw-r--r--synapse/api/events/room.py170
-rw-r--r--synapse/api/events/utils.py85
-rw-r--r--synapse/api/events/validator.py87
5 files changed, 0 insertions, 580 deletions
diff --git a/synapse/api/events/__init__.py b/synapse/api/events/__init__.py
deleted file mode 100644
index 22939d011a..0000000000
--- a/synapse/api/events/__init__.py
+++ /dev/null
@@ -1,148 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright 2014 OpenMarket Ltd
-#
-# 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 synapse.util.jsonobject import JsonEncodedObject
-
-
-def serialize_event(hs, e):
-    # FIXME(erikj): To handle the case of presence events and the like
-    if not isinstance(e, SynapseEvent):
-        return e
-
-    # Should this strip out None's?
-    d = {k: v for k, v in e.get_dict().items()}
-    if "age_ts" in d:
-        d["age"] = int(hs.get_clock().time_msec()) - d["age_ts"]
-        del d["age_ts"]
-
-    return d
-
-
-class SynapseEvent(JsonEncodedObject):
-
-    """Base class for Synapse events. These are JSON objects which must abide
-    by a certain well-defined structure.
-    """
-
-    # Attributes that are currently assumed by the federation side:
-    # Mandatory:
-    # - event_id
-    # - room_id
-    # - type
-    # - is_state
-    #
-    # Optional:
-    # - state_key (mandatory when is_state is True)
-    # - prev_events (these can be filled out by the federation layer itself.)
-    # - prev_state
-
-    valid_keys = [
-        "event_id",
-        "type",
-        "room_id",
-        "user_id",  # sender/initiator
-        "content",  # HTTP body, JSON
-        "state_key",
-        "age_ts",
-        "prev_content",
-        "replaces_state",
-        "redacted_because",
-        "origin_server_ts",
-    ]
-
-    internal_keys = [
-        "is_state",
-        "depth",
-        "destinations",
-        "origin",
-        "outlier",
-        "redacted",
-        "prev_events",
-        "hashes",
-        "signatures",
-        "prev_state",
-        "auth_events",
-        "state_hash",
-    ]
-
-    required_keys = [
-        "event_id",
-        "room_id",
-        "content",
-    ]
-
-    outlier = False
-
-    def __init__(self, raises=True, **kwargs):
-        super(SynapseEvent, self).__init__(**kwargs)
-        # if "content" in kwargs:
-        #     self.check_json(self.content, raises=raises)
-
-    def get_content_template(self):
-        """ Retrieve the JSON template for this event as a dict.
-
-        The template must be a dict representing the JSON to match. Only
-        required keys should be present. The values of the keys in the template
-        are checked via type() to the values of the same keys in the actual
-        event JSON.
-
-        NB: If loading content via json.loads, you MUST define strings as
-        unicode.
-
-        For example:
-            Content:
-                {
-                    "name": u"bob",
-                    "age": 18,
-                    "friends": [u"mike", u"jill"]
-                }
-            Template:
-                {
-                    "name": u"string",
-                    "age": 0,
-                    "friends": [u"string"]
-                }
-            The values "string" and 0 could be anything, so long as the types
-            are the same as the content.
-        """
-        raise NotImplementedError("get_content_template not implemented.")
-
-    def get_pdu_json(self, time_now=None):
-        pdu_json = self.get_full_dict()
-        pdu_json.pop("destinations", None)
-        pdu_json.pop("outlier", None)
-        pdu_json.pop("replaces_state", None)
-        pdu_json.pop("redacted", None)
-        pdu_json.pop("prev_content", None)
-        state_hash = pdu_json.pop("state_hash", None)
-        if state_hash is not None:
-            pdu_json.setdefault("unsigned", {})["state_hash"] = state_hash
-        content = pdu_json.get("content", {})
-        content.pop("prev", None)
-        if time_now is not None and "age_ts" in pdu_json:
-            age = time_now - pdu_json["age_ts"]
-            pdu_json.setdefault("unsigned", {})["age"] = int(age)
-            del pdu_json["age_ts"]
-        user_id = pdu_json.pop("user_id")
-        pdu_json["sender"] = user_id
-        return pdu_json
-
-
-class SynapseStateEvent(SynapseEvent):
-
-    def __init__(self, **kwargs):
-        if "state_key" not in kwargs:
-            kwargs["state_key"] = ""
-        super(SynapseStateEvent, self).__init__(**kwargs)
diff --git a/synapse/api/events/factory.py b/synapse/api/events/factory.py
deleted file mode 100644
index a1ec708a81..0000000000
--- a/synapse/api/events/factory.py
+++ /dev/null
@@ -1,90 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright 2014 OpenMarket Ltd
-#
-# 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 synapse.api.events.room import (
-    RoomTopicEvent, MessageEvent, RoomMemberEvent, FeedbackEvent,
-    InviteJoinEvent, RoomConfigEvent, RoomNameEvent, GenericEvent,
-    RoomPowerLevelsEvent, RoomJoinRulesEvent,
-    RoomCreateEvent,
-    RoomRedactionEvent,
-)
-
-from synapse.types import EventID
-
-from synapse.util.stringutils import random_string
-
-
-class EventFactory(object):
-
-    _event_classes = [
-        RoomTopicEvent,
-        RoomNameEvent,
-        MessageEvent,
-        RoomMemberEvent,
-        FeedbackEvent,
-        InviteJoinEvent,
-        RoomConfigEvent,
-        RoomPowerLevelsEvent,
-        RoomJoinRulesEvent,
-        RoomCreateEvent,
-        RoomRedactionEvent,
-    ]
-
-    def __init__(self, hs):
-        self._event_list = {}  # dict of TYPE to event class
-        for event_class in EventFactory._event_classes:
-            self._event_list[event_class.TYPE] = event_class
-
-        self.clock = hs.get_clock()
-        self.hs = hs
-
-        self.event_id_count = 0
-
-    def create_event_id(self):
-        i = str(self.event_id_count)
-        self.event_id_count += 1
-
-        local_part = str(int(self.clock.time())) + i + random_string(5)
-
-        e_id = EventID.create_local(local_part, self.hs)
-
-        return e_id.to_string()
-
-    def create_event(self, etype=None, **kwargs):
-        kwargs["type"] = etype
-        if "event_id" not in kwargs:
-            kwargs["event_id"] = self.create_event_id()
-            kwargs["origin"] = self.hs.hostname
-        else:
-            ev_id = self.hs.parse_eventid(kwargs["event_id"])
-            kwargs["origin"] = ev_id.domain
-
-        if "origin_server_ts" not in kwargs:
-            kwargs["origin_server_ts"] = int(self.clock.time_msec())
-
-        # The "age" key is a delta timestamp that should be converted into an
-        # absolute timestamp the minute we see it.
-        if "age" in kwargs:
-            kwargs["age_ts"] = int(self.clock.time_msec()) - int(kwargs["age"])
-            del kwargs["age"]
-        elif "age_ts" not in kwargs:
-            kwargs["age_ts"] = int(self.clock.time_msec())
-
-        if etype in self._event_list:
-            handler = self._event_list[etype]
-        else:
-            handler = GenericEvent
-
-        return handler(**kwargs)
diff --git a/synapse/api/events/room.py b/synapse/api/events/room.py
deleted file mode 100644
index 8c4ac45d02..0000000000
--- a/synapse/api/events/room.py
+++ /dev/null
@@ -1,170 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright 2014 OpenMarket Ltd
-#
-# 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 synapse.api.constants import Feedback, Membership
-from synapse.api.errors import SynapseError
-from . import SynapseEvent, SynapseStateEvent
-
-
-class GenericEvent(SynapseEvent):
-    def get_content_template(self):
-        return {}
-
-
-class RoomTopicEvent(SynapseEvent):
-    TYPE = "m.room.topic"
-
-    internal_keys = SynapseEvent.internal_keys + [
-        "topic",
-    ]
-
-    def __init__(self, **kwargs):
-        kwargs["state_key"] = ""
-        if "topic" in kwargs["content"]:
-            kwargs["topic"] = kwargs["content"]["topic"]
-        super(RoomTopicEvent, self).__init__(**kwargs)
-
-    def get_content_template(self):
-        return {"topic": u"string"}
-
-
-class RoomNameEvent(SynapseEvent):
-    TYPE = "m.room.name"
-
-    internal_keys = SynapseEvent.internal_keys + [
-        "name",
-    ]
-
-    def __init__(self, **kwargs):
-        kwargs["state_key"] = ""
-        if "name" in kwargs["content"]:
-            kwargs["name"] = kwargs["content"]["name"]
-        super(RoomNameEvent, self).__init__(**kwargs)
-
-    def get_content_template(self):
-        return {"name": u"string"}
-
-
-class RoomMemberEvent(SynapseEvent):
-    TYPE = "m.room.member"
-
-    valid_keys = SynapseEvent.valid_keys + [
-        # target is the state_key
-        "membership",  # action
-    ]
-
-    def __init__(self, **kwargs):
-        if "membership" not in kwargs:
-            kwargs["membership"] = kwargs.get("content", {}).get("membership")
-        if not kwargs["membership"] in Membership.LIST:
-            raise SynapseError(400, "Bad membership value.")
-        super(RoomMemberEvent, self).__init__(**kwargs)
-
-    def get_content_template(self):
-        return {"membership": u"string"}
-
-
-class MessageEvent(SynapseEvent):
-    TYPE = "m.room.message"
-
-    valid_keys = SynapseEvent.valid_keys + [
-        "msg_id",  # unique per room + user combo
-    ]
-
-    def __init__(self, **kwargs):
-        super(MessageEvent, self).__init__(**kwargs)
-
-    def get_content_template(self):
-        return {"msgtype": u"string"}
-
-
-class FeedbackEvent(SynapseEvent):
-    TYPE = "m.room.message.feedback"
-
-    valid_keys = SynapseEvent.valid_keys
-
-    def __init__(self, **kwargs):
-        super(FeedbackEvent, self).__init__(**kwargs)
-        if not kwargs["content"]["type"] in Feedback.LIST:
-            raise SynapseError(400, "Bad feedback value.")
-
-    def get_content_template(self):
-        return {
-            "type": u"string",
-            "target_event_id": u"string"
-        }
-
-
-class InviteJoinEvent(SynapseEvent):
-    TYPE = "m.room.invite_join"
-
-    valid_keys = SynapseEvent.valid_keys + [
-        # target_user_id is the state_key
-        "target_host",
-    ]
-
-    def __init__(self, **kwargs):
-        super(InviteJoinEvent, self).__init__(**kwargs)
-
-    def get_content_template(self):
-        return {}
-
-
-class RoomConfigEvent(SynapseEvent):
-    TYPE = "m.room.config"
-
-    def __init__(self, **kwargs):
-        kwargs["state_key"] = ""
-        super(RoomConfigEvent, self).__init__(**kwargs)
-
-    def get_content_template(self):
-        return {}
-
-
-class RoomCreateEvent(SynapseStateEvent):
-    TYPE = "m.room.create"
-
-    def get_content_template(self):
-        return {}
-
-
-class RoomJoinRulesEvent(SynapseStateEvent):
-    TYPE = "m.room.join_rules"
-
-    def get_content_template(self):
-        return {}
-
-
-class RoomPowerLevelsEvent(SynapseStateEvent):
-    TYPE = "m.room.power_levels"
-
-    def get_content_template(self):
-        return {}
-
-
-class RoomAliasesEvent(SynapseStateEvent):
-    TYPE = "m.room.aliases"
-
-    def get_content_template(self):
-        return {}
-
-
-class RoomRedactionEvent(SynapseEvent):
-    TYPE = "m.room.redaction"
-
-    valid_keys = SynapseEvent.valid_keys + ["redacts"]
-
-    def get_content_template(self):
-        return {}
diff --git a/synapse/api/events/utils.py b/synapse/api/events/utils.py
deleted file mode 100644
index d6019d56eb..0000000000
--- a/synapse/api/events/utils.py
+++ /dev/null
@@ -1,85 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright 2014 OpenMarket Ltd
-#
-# 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 .room import (
-    RoomMemberEvent, RoomJoinRulesEvent, RoomPowerLevelsEvent,
-    RoomAliasesEvent, RoomCreateEvent,
-)
-
-
-def prune_event(event):
-    """ Returns a pruned version of the given event, which removes all keys we
-    don't know about or think could potentially be dodgy.
-
-    This is used when we "redact" an event. We want to remove all fields that
-    the user has specified, but we do want to keep necessary information like
-    type, state_key etc.
-    """
-    event_type = event.type
-
-    allowed_keys = [
-        "event_id",
-        "user_id",
-        "room_id",
-        "hashes",
-        "signatures",
-        "content",
-        "type",
-        "state_key",
-        "depth",
-        "prev_events",
-        "prev_state",
-        "auth_events",
-        "origin",
-        "origin_server_ts",
-    ]
-
-    new_content = {}
-
-    def add_fields(*fields):
-        for field in fields:
-            if field in event.content:
-                new_content[field] = event.content[field]
-
-    if event_type == RoomMemberEvent.TYPE:
-        add_fields("membership")
-    elif event_type == RoomCreateEvent.TYPE:
-        add_fields("creator")
-    elif event_type == RoomJoinRulesEvent.TYPE:
-        add_fields("join_rule")
-    elif event_type == RoomPowerLevelsEvent.TYPE:
-        add_fields(
-            "users",
-            "users_default",
-            "events",
-            "events_default",
-            "events_default",
-            "state_default",
-            "ban",
-            "kick",
-            "redact",
-        )
-    elif event_type == RoomAliasesEvent.TYPE:
-        add_fields("aliases")
-
-    allowed_fields = {
-        k: v
-        for k, v in event.get_full_dict().items()
-        if k in allowed_keys
-    }
-
-    allowed_fields["content"] = new_content
-
-    return type(event)(**allowed_fields)
diff --git a/synapse/api/events/validator.py b/synapse/api/events/validator.py
deleted file mode 100644
index 067215f6ef..0000000000
--- a/synapse/api/events/validator.py
+++ /dev/null
@@ -1,87 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright 2014 OpenMarket Ltd
-#
-# 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 synapse.api.errors import SynapseError, Codes
-
-
-class EventValidator(object):
-    def __init__(self, hs):
-        pass
-
-    def validate(self, event):
-        """Checks the given JSON content abides by the rules of the template.
-
-        Args:
-            content : A JSON object to check.
-            raises: True to raise a SynapseError if the check fails.
-        Returns:
-            True if the content passes the template. Returns False if the check
-            fails and raises=False.
-        Raises:
-            SynapseError if the check fails and raises=True.
-        """
-        # recursively call to inspect each layer
-        err_msg = self._check_json_template(
-            event.content,
-            event.get_content_template()
-        )
-        if err_msg:
-            raise SynapseError(400, err_msg, Codes.BAD_JSON)
-        else:
-            return True
-
-    def _check_json_template(self, content, template):
-        """Check content and template matches.
-
-        If the template is a dict, each key in the dict will be validated with
-        the content, else it will just compare the types of content and
-        template. This basic type check is required because this function will
-        be recursively called and could be called with just strs or ints.
-
-        Args:
-            content: The content to validate.
-            template: The validation template.
-        Returns:
-            str: An error message if the validation fails, else None.
-        """
-        if type(content) != type(template):
-            return "Mismatched types: %s" % template
-
-        if type(template) == dict:
-            for key in template:
-                if key not in content:
-                    return "Missing %s key" % key
-
-                if type(content[key]) != type(template[key]):
-                    return "Key %s is of the wrong type (got %s, want %s)" % (
-                        key, type(content[key]), type(template[key]))
-
-                if type(content[key]) == dict:
-                    # we must go deeper
-                    msg = self._check_json_template(
-                        content[key],
-                        template[key]
-                    )
-                    if msg:
-                        return msg
-                elif type(content[key]) == list:
-                    # make sure each item type in content matches the template
-                    for entry in content[key]:
-                        msg = self._check_json_template(
-                            entry,
-                            template[key][0]
-                        )
-                        if msg:
-                            return msg