Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Split up event validation between event and builder #4494

Merged
merged 5 commits into from
Jan 29, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/4494.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add infrastructure to support different event formats
60 changes: 37 additions & 23 deletions synapse/events/validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,22 @@


class EventValidator(object):
def validate_new(self, event):
"""Validates the event has roughly the right format

Args:
event (FrozenEvent)
"""
self.validate_builder(event)

def validate(self, event):
EventID.from_string(event.event_id)
RoomID.from_string(event.room_id)

required = [
# "auth_events",
"auth_events",
"content",
# "hashes",
"hashes",
"origin",
# "prev_events",
"prev_events",
"sender",
"type",
]
Expand All @@ -41,8 +46,25 @@ def validate(self, event):
raise SynapseError(400, "Event does not have key %s" % (k,))

# Check that the following keys have string values
strings = [
event_strings = [
"origin",
]

for s in event_strings:
if not isinstance(getattr(event, s), string_types):
raise SynapseError(400, "'%s' not a string type" % (s,))

def validate_builder(self, event):
"""Validates that the builder/event has roughly the right format. Only
checks values that we expect a proto event to have, rather than all the
fields an event would have

Args:
event (EventBuilder|FrozenEvent)
"""

strings = [
"room_id",
"sender",
"type",
]
Expand All @@ -54,22 +76,7 @@ def validate(self, event):
if not isinstance(getattr(event, s), string_types):
raise SynapseError(400, "Not '%s' a string type" % (s,))
erikjohnston marked this conversation as resolved.
Show resolved Hide resolved

if event.type == EventTypes.Member:
if "membership" not in event.content:
raise SynapseError(400, "Content has not membership key")

if event.content["membership"] not in Membership.LIST:
raise SynapseError(400, "Invalid membership key")

# Check that the following keys have dictionary values
# TODO

# Check that the following keys have the correct format for DAGs
# TODO

def validate_new(self, event):
self.validate(event)

RoomID.from_string(event.room_id)
UserID.from_string(event.sender)

if event.type == EventTypes.Message:
Expand All @@ -86,9 +93,16 @@ def validate_new(self, event):
elif event.type == EventTypes.Name:
self._ensure_strings(event.content, ["name"])

elif event.type == EventTypes.Member:
if "membership" not in event.content:
raise SynapseError(400, "Content has not membership key")

if event.content["membership"] not in Membership.LIST:
raise SynapseError(400, "Invalid membership key")

def _ensure_strings(self, d, keys):
for s in keys:
if s not in d:
raise SynapseError(400, "'%s' not in content" % (s,))
if not isinstance(d[s], string_types):
raise SynapseError(400, "Not '%s' a string type" % (s,))
raise SynapseError(400, "'%s' not a string type" % (s,))
7 changes: 5 additions & 2 deletions synapse/handlers/federation.py
Original file line number Diff line number Diff line change
Expand Up @@ -2278,7 +2278,7 @@ def exchange_third_party_invite(
room_version = yield self.store.get_room_version(room_id)
builder = self.event_builder_factory.new(room_version, event_dict)

EventValidator().validate_new(builder)
EventValidator().validate_builder(builder)
event, context = yield self.event_creation_handler.create_new_client_event(
builder=builder
)
Expand All @@ -2287,6 +2287,8 @@ def exchange_third_party_invite(
room_version, event_dict, event, context
)

EventValidator().validate_new(event)

try:
yield self.auth.check_from_context(event, context)
except AuthError as e:
Expand Down Expand Up @@ -2372,10 +2374,11 @@ def add_display_name_to_third_party_invite(self, room_version, event_dict,
# auth check code will explode appropriately.

builder = self.event_builder_factory.new(room_version, event_dict)
EventValidator().validate_new(builder)
EventValidator().validate_builder(builder)
event, context = yield self.event_creation_handler.create_new_client_event(
builder=builder,
)
EventValidator().validate_new(event)
defer.returnValue((event, context))

@defer.inlineCallbacks
Expand Down
4 changes: 3 additions & 1 deletion synapse/handlers/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ def create_event(self, requester, event_dict, token_id=None, txn_id=None,

builder = self.event_builder_factory.new(room_version, event_dict)

self.validator.validate_new(builder)
self.validator.validate_builder(builder)

if builder.type == EventTypes.Member:
membership = builder.content.get("membership", None)
Expand Down Expand Up @@ -326,6 +326,8 @@ def create_event(self, requester, event_dict, token_id=None, txn_id=None,
prev_events_and_hashes=prev_events_and_hashes,
)

self.validator.validate_new(event)

defer.returnValue((event, context))

def _is_exempt_from_privacy_policy(self, builder, requester):
Expand Down