Implement updated auth rules from MSC2260
parent
a8ce7aeb43
commit
49d3bca37b
|
@ -57,6 +57,9 @@ class RoomVersion(object):
|
||||||
state_res = attr.ib() # int; one of the StateResolutionVersions
|
state_res = attr.ib() # int; one of the StateResolutionVersions
|
||||||
enforce_key_validity = attr.ib() # bool
|
enforce_key_validity = attr.ib() # bool
|
||||||
|
|
||||||
|
# bool: before MSC2260, anyone was allowed to send an aliases event
|
||||||
|
special_case_aliases_auth = attr.ib(type=bool, default=False)
|
||||||
|
|
||||||
|
|
||||||
class RoomVersions(object):
|
class RoomVersions(object):
|
||||||
V1 = RoomVersion(
|
V1 = RoomVersion(
|
||||||
|
@ -65,6 +68,7 @@ class RoomVersions(object):
|
||||||
EventFormatVersions.V1,
|
EventFormatVersions.V1,
|
||||||
StateResolutionVersions.V1,
|
StateResolutionVersions.V1,
|
||||||
enforce_key_validity=False,
|
enforce_key_validity=False,
|
||||||
|
special_case_aliases_auth=True,
|
||||||
)
|
)
|
||||||
V2 = RoomVersion(
|
V2 = RoomVersion(
|
||||||
"2",
|
"2",
|
||||||
|
@ -72,6 +76,7 @@ class RoomVersions(object):
|
||||||
EventFormatVersions.V1,
|
EventFormatVersions.V1,
|
||||||
StateResolutionVersions.V2,
|
StateResolutionVersions.V2,
|
||||||
enforce_key_validity=False,
|
enforce_key_validity=False,
|
||||||
|
special_case_aliases_auth=True,
|
||||||
)
|
)
|
||||||
V3 = RoomVersion(
|
V3 = RoomVersion(
|
||||||
"3",
|
"3",
|
||||||
|
@ -79,6 +84,7 @@ class RoomVersions(object):
|
||||||
EventFormatVersions.V2,
|
EventFormatVersions.V2,
|
||||||
StateResolutionVersions.V2,
|
StateResolutionVersions.V2,
|
||||||
enforce_key_validity=False,
|
enforce_key_validity=False,
|
||||||
|
special_case_aliases_auth=True,
|
||||||
)
|
)
|
||||||
V4 = RoomVersion(
|
V4 = RoomVersion(
|
||||||
"4",
|
"4",
|
||||||
|
@ -86,6 +92,7 @@ class RoomVersions(object):
|
||||||
EventFormatVersions.V3,
|
EventFormatVersions.V3,
|
||||||
StateResolutionVersions.V2,
|
StateResolutionVersions.V2,
|
||||||
enforce_key_validity=False,
|
enforce_key_validity=False,
|
||||||
|
special_case_aliases_auth=True,
|
||||||
)
|
)
|
||||||
V5 = RoomVersion(
|
V5 = RoomVersion(
|
||||||
"5",
|
"5",
|
||||||
|
@ -93,6 +100,14 @@ class RoomVersions(object):
|
||||||
EventFormatVersions.V3,
|
EventFormatVersions.V3,
|
||||||
StateResolutionVersions.V2,
|
StateResolutionVersions.V2,
|
||||||
enforce_key_validity=True,
|
enforce_key_validity=True,
|
||||||
|
special_case_aliases_auth=True,
|
||||||
|
)
|
||||||
|
MSC2260_DEV = RoomVersion(
|
||||||
|
"org.matrix.msc2260",
|
||||||
|
RoomDisposition.UNSTABLE,
|
||||||
|
EventFormatVersions.V3,
|
||||||
|
StateResolutionVersions.V2,
|
||||||
|
enforce_key_validity=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -104,5 +119,6 @@ KNOWN_ROOM_VERSIONS = {
|
||||||
RoomVersions.V3,
|
RoomVersions.V3,
|
||||||
RoomVersions.V4,
|
RoomVersions.V4,
|
||||||
RoomVersions.V5,
|
RoomVersions.V5,
|
||||||
|
RoomVersions.MSC2260_DEV,
|
||||||
)
|
)
|
||||||
} # type: Dict[str, RoomVersion]
|
} # type: Dict[str, RoomVersion]
|
||||||
|
|
|
@ -100,7 +100,12 @@ def check(
|
||||||
if not event.signatures.get(event_id_domain):
|
if not event.signatures.get(event_id_domain):
|
||||||
raise AuthError(403, "Event not signed by sending server")
|
raise AuthError(403, "Event not signed by sending server")
|
||||||
|
|
||||||
|
# Implementation of https://matrix.org/docs/spec/rooms/v1#authorization-rules
|
||||||
|
#
|
||||||
|
# 1. If type is m.room.create:
|
||||||
if event.type == EventTypes.Create:
|
if event.type == EventTypes.Create:
|
||||||
|
# 1b. If the domain of the room_id does not match the domain of the sender,
|
||||||
|
# reject.
|
||||||
sender_domain = get_domain_from_id(event.sender)
|
sender_domain = get_domain_from_id(event.sender)
|
||||||
room_id_domain = get_domain_from_id(event.room_id)
|
room_id_domain = get_domain_from_id(event.room_id)
|
||||||
if room_id_domain != sender_domain:
|
if room_id_domain != sender_domain:
|
||||||
|
@ -108,40 +113,49 @@ def check(
|
||||||
403, "Creation event's room_id domain does not match sender's"
|
403, "Creation event's room_id domain does not match sender's"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# 1c. If content.room_version is present and is not a recognised version, reject
|
||||||
room_version_prop = event.content.get("room_version", "1")
|
room_version_prop = event.content.get("room_version", "1")
|
||||||
if room_version_prop not in KNOWN_ROOM_VERSIONS:
|
if room_version_prop not in KNOWN_ROOM_VERSIONS:
|
||||||
raise AuthError(
|
raise AuthError(
|
||||||
403,
|
403,
|
||||||
"room appears to have unsupported version %s" % (room_version_prop,),
|
"room appears to have unsupported version %s" % (room_version_prop,),
|
||||||
)
|
)
|
||||||
# FIXME
|
|
||||||
logger.debug("Allowing! %s", event)
|
logger.debug("Allowing! %s", event)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# 3. If event does not have a m.room.create in its auth_events, reject.
|
||||||
creation_event = auth_events.get((EventTypes.Create, ""), None)
|
creation_event = auth_events.get((EventTypes.Create, ""), None)
|
||||||
|
|
||||||
if not creation_event:
|
if not creation_event:
|
||||||
raise AuthError(403, "No create event in auth events")
|
raise AuthError(403, "No create event in auth events")
|
||||||
|
|
||||||
|
# additional check for m.federate
|
||||||
creating_domain = get_domain_from_id(event.room_id)
|
creating_domain = get_domain_from_id(event.room_id)
|
||||||
originating_domain = get_domain_from_id(event.sender)
|
originating_domain = get_domain_from_id(event.sender)
|
||||||
if creating_domain != originating_domain:
|
if creating_domain != originating_domain:
|
||||||
if not _can_federate(event, auth_events):
|
if not _can_federate(event, auth_events):
|
||||||
raise AuthError(403, "This room has been marked as unfederatable.")
|
raise AuthError(403, "This room has been marked as unfederatable.")
|
||||||
|
|
||||||
# FIXME: Temp hack
|
# 4. If type is m.room.aliases
|
||||||
if event.type == EventTypes.Aliases:
|
if event.type == EventTypes.Aliases:
|
||||||
|
# 4a. If event has no state_key, reject
|
||||||
if not event.is_state():
|
if not event.is_state():
|
||||||
raise AuthError(403, "Alias event must be a state event")
|
raise AuthError(403, "Alias event must be a state event")
|
||||||
if not event.state_key:
|
if not event.state_key:
|
||||||
raise AuthError(403, "Alias event must have non-empty state_key")
|
raise AuthError(403, "Alias event must have non-empty state_key")
|
||||||
|
|
||||||
|
# 4b. If sender's domain doesn't matches [sic] state_key, reject
|
||||||
sender_domain = get_domain_from_id(event.sender)
|
sender_domain = get_domain_from_id(event.sender)
|
||||||
if event.state_key != sender_domain:
|
if event.state_key != sender_domain:
|
||||||
raise AuthError(
|
raise AuthError(
|
||||||
403, "Alias event's state_key does not match sender's domain"
|
403, "Alias event's state_key does not match sender's domain"
|
||||||
)
|
)
|
||||||
logger.debug("Allowing! %s", event)
|
|
||||||
return
|
# 4c. Otherwise, allow.
|
||||||
|
# This is removed by https://github.com/matrix-org/matrix-doc/pull/2260
|
||||||
|
if room_version.special_case_aliases_auth:
|
||||||
|
logger.debug("Allowing! %s", event)
|
||||||
|
return
|
||||||
|
|
||||||
if logger.isEnabledFor(logging.DEBUG):
|
if logger.isEnabledFor(logging.DEBUG):
|
||||||
logger.debug("Auth events: %s", [a.event_id for a in auth_events.values()])
|
logger.debug("Auth events: %s", [a.event_id for a in auth_events.values()])
|
||||||
|
|
Loading…
Reference in New Issue