Document the event auth rules (#1027)

These are a necessary precursor to state resolution.
This commit is contained in:
Richard van der Hoff 2017-10-20 13:36:56 +01:00 committed by GitHub
parent 68b8192d86
commit 5fee8e54eb
2 changed files with 160 additions and 100 deletions

View file

@ -1,4 +1,5 @@
.. Copyright 2016 OpenMarket Ltd
.. Copyright 2017 New Vector Ltd
..
.. Licensed under the Apache License, Version 2.0 (the "License");
.. you may not use this file except in compliance with the License.
@ -442,24 +443,173 @@ keys exist to support this:
``state_key`` String Combined with the ``pdu_type`` this
identifies the which part of the room
state is updated
``required_power_level`` Integer The required power level needed to
replace this update.
``prev_state_id`` String The PDU id of the update this replaces.
``prev_state_origin`` String The homeserver of the update this
replaces.
``user_id`` String The user updating the state.
======================== ============ =========================================
.. code:: json
Authorization of PDUs
~~~~~~~~~~~~~~~~~~~~~
{...,
"is_state":true,
"state_key":TODO-doc
"required_power_level":TODO-doc
"prev_state_id":TODO-doc
"prev_state_origin":TODO-doc
}
Whenever a server receives an event from a remote server, the receiving server
must check that the event is allowed by the authorization rules. These rules
depend on the state of the room at that event.
Definitions
+++++++++++
Required Power Level
A given event type has an associated *required power level*. This is given by
the current ``m.room.power_levels`` event. The event type is either listed
explicitly in the ``events`` section or given by either ``state_default`` or
``events_default`` depending on if the event is a state event or not.
Invite Level, Kick Level, Ban Level, Redact Level
The levels given by the ``invite``, ``kick``, ``ban``, and ``redact``
properties in the current ``m.room.power_levels`` state. Each defaults to 50
if unspecified.
Target User
For an ``m.room.member`` state event, the user given by the ``state_key`` of
the event.
Rules
+++++
The rules governing whether an event is authorized depend solely on the
state of the room at the point in the room graph at which the new event is to
be inserted. The types of state events that affect authorization are:
- ``m.room.create``
- ``m.room.member``
- ``m.room.join_rules``
- ``m.room.power_levels``
Servers should not create new events that reference unauthorized events.
However, any event that does reference an unauthorized event is not itself
automatically considered unauthorized.
Unauthorized events that appear in the event graph do *not* have any effect on
the state of the room.
.. Note:: This is in contrast to redacted events which can still affect the
state of the room. For example, a redacted ``join`` event will still
result in the user being considered joined.
1. If type is ``m.room.create``, allow if and only if has depth 0 and it has no
previous events - *i.e.* it is the first event in the room.
#. If type is ``m.room.member``:
a. If ``membership`` is ``join``:
i. If the previous event in the room graph is an ``m.room.create``, the
depth is 1 and the ``state_key`` is the creator, allow.
#. If the ``sender`` does not match ``state_key``, reject.
#. If the user's current membership state is ``invite`` or ``join``,
allow.
#. If the ``join_rule`` is ``public``, allow.
#. Otherwise, reject.
#. If ``membership`` is ``invite``:
i. If the ``sender``'s current membership state is not ``joined``, reject.
#. If *target user*'s current membership state is ``join`` or ``ban``,
reject.
#. If the ``sender``'s power level is greater than or equal to the *invite
level*, allow.
#. Otherwise, reject.
#. If ``membership`` is ``leave``:
i. If the ``sender`` matches ``state_key``, allow if and only if that user's
current membership state is ``invite`` or ``join``.
#. If the ``sender``'s current membership state is not ``joined``, reject.
#. If the *target user*'s current membership state is ``ban``, and the
``sender``'s power level is less than the *ban level*, reject.
#. If the ``sender``'s power level is greater than or equal to the *kick
level*, and the *target user*'s power level is less than the
``sender``'s power level, allow.
#. Otherwise, reject.
#. If ``membership`` is ``ban``:
i. If the ``sender``'s current membership state is not ``joined``, reject.
#. If the ``sender``'s power level is greater than or equal to the *ban
level*, and the *target user*'s power level is less than the
``sender``'s power level, allow.
#. Otherwise, reject.
#. Otherwise, the membership is unknown. Reject.
#. If the ``sender``'s current membership state is not ``joined``, reject.
#. If the event type's *required power level* is greater than the ``sender``'s power
level, reject.
#. If type is ``m.room.power_levels``:
a. For each of the keys ``users_default``, ``events_default``,
``state_default``, ``ban``, ``redact``, ``kick``, ``invite``, as well as
each entry being changed under the ``events`` or ``users`` keys:
i. If the current value is higher than the ``sender``'s current power level,
reject.
#. If the new value is higher than the ``sender``'s current power level,
reject.
#. For each entry being changed under the ``users`` key, other than the
``sender``'s own entry:
i. If the current value is equal to the ``sender``'s current power level,
reject.
#. Otherwise, allow.
#. If type is ``m.room.redact``:
#. If the ``sender``'s power level is greater than or equal to the *redact
level*, allow.
#. If the ``sender`` of the event being redacted is the same as the
``sender`` of the ``m.room.redact``, allow.
#. Otherwise, reject.
#. Otherwise, allow.
.. NOTE::
Some consequences of these rules:
* Unless you are a member of the room, the only permitted operations (apart
from the intial create/join) are: joining a public room; accepting or
rejecting an invitation to a room.
* To unban somebody, you must have power level greater than or equal to both
the kick *and* ban levels, *and* greater than the target user's power
level.
.. TODO-spec
I think there is some magic about 3pid invites too.
EDUs
----