You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

275 lines
12 KiB

  1. ===========
  2. Rooms Model
  3. ===========
  4. A description of the general data model used to implement Rooms, and the
  5. user-level visible effects and implications.
  6. Overview
  7. ========
  8. "Rooms" in Synapse are shared messaging channels over which all the participant
  9. users can exchange messages. Rooms have an opaque persistent identify, a
  10. globally-replicated set of state (consisting principly of a membership set of
  11. users, and other management and miscellaneous metadata), and a message history.
  12. Room Identity and Naming
  13. ========================
  14. Rooms can be arbitrarily created by any user on any home server; at which point
  15. the home server will sign the message that creates the channel, and the
  16. fingerprint of this signature becomes the strong persistent identify of the
  17. room. This now identifies the room to any home server in the network regardless
  18. of its original origin. This allows the identify of the room to outlive any
  19. particular server. Subject to appropriate permissions [to be discussed later],
  20. any current member of a room can invite others to join it, can post messages
  21. that become part of its history, and can change the persistent state of the room
  22. (including its current set of permissions).
  23. Home servers can provide a directory service, allowing a lookup from a
  24. convenient human-readable form of room label to a room ID. This mapping is
  25. scoped to the particular home server domain and so simply represents that server
  26. administrator's opinion of what room should take that label; it does not have to
  27. be globally replicated and does not form part of the stored state of that room.
  28. This room name takes the form
  29. #localname:some.domain.name
  30. for similarity and consistency with user names on directories.
  31. To join a room (and therefore to be allowed to inspect past history, post new
  32. messages to it, and read its state), a user must become aware of the room's
  33. fingerprint ID. There are two mechanisms to allow this:
  34. * An invite message from someone else in the room
  35. * A referral from a room directory service
  36. As room IDs are opaque and ephemeral, they can serve as a mechanism to create
  37. "ad-hoc" rooms deliberately unnamed, for small group-chats or even private
  38. one-to-one message exchange.
  39. Stored State and Permissions
  40. ============================
  41. Every room has a globally-replicated set of stored state. This state is a set of
  42. key/value or key/subkey/value pairs. The value of every (sub)key is a
  43. JSON-representable object. The main key of a piece of stored state establishes
  44. its meaning; some keys store sub-keys to allow a sub-structure within them [more
  45. detail below]. Some keys have special meaning to Synapse, as they relate to
  46. management details of the room itself, storing such details as user membership,
  47. and permissions of users to alter the state of the room itself. Other keys may
  48. store information to present to users, which the system does not directly rely
  49. on. The key space itself is namespaced, allowing 3rd party extensions, subject
  50. to suitable permission.
  51. Permission management is based on the concept of "power-levels". Every user
  52. within a room has an integer assigned, being their "power-level" within that
  53. room. Along with its actual data value, each key (or subkey) also stores the
  54. minimum power-level a user must have in order to write to that key, the
  55. power-level of the last user who actually did write to it, and the PDU ID of
  56. that state change.
  57. To be accepted as valid, a change must NOT:
  58. * Be made by a user having a power-level lower than required to write to the
  59. state key
  60. * Alter the required power-level for that state key to a value higher than the
  61. user has
  62. * Increase that user's own power-level
  63. * Grant any other user a power-level higher than the level of the user making
  64. the change
  65. [[TODO(paul): consider if relaxations should be allowed; e.g. is the current
  66. outright-winner allowed to raise their own level, to allow for "inflation"?]]
  67. Room State Keys
  68. ===============
  69. [[TODO(paul): if this list gets too big it might become necessary to move it
  70. into its own doc]]
  71. The following keys have special semantics or meaning to Synapse itself:
  72. m.member (has subkeys)
  73. Stores a sub-key for every Synapse User ID which is currently a member of
  74. this room. Its value gives the membership type ("knocked", "invited",
  75. "joined").
  76. m.power_levels
  77. Stores a mapping from Synapse User IDs to their power-level in the room. If
  78. they are not present in this mapping, the default applies.
  79. The reason to store this as a single value rather than a value with subkeys
  80. is that updates to it are atomic; allowing a number of colliding-edit
  81. problems to be avoided.
  82. m.default_level
  83. Gives the default power-level for members of the room that do not have one
  84. specified in their membership key.
  85. m.invite_level
  86. If set, gives the minimum power-level required for members to invite others
  87. to join, or to accept knock requests from non-members requesting access. If
  88. absent, then invites are not allowed. An invitation involves setting their
  89. membership type to "invited", in addition to sending the invite message.
  90. m.join_rules
  91. Encodes the rules on how non-members can join the room. Has the following
  92. possibilities:
  93. "public" - a non-member can join the room directly
  94. "knock" - a non-member cannot join the room, but can post a single "knock"
  95. message requesting access, which existing members may approve or deny
  96. "invite" - non-members cannot join the room without an invite from an
  97. existing member
  98. "private" - nobody who is not in the 'may_join' list or already a member
  99. may join by any mechanism
  100. In any of the first three modes, existing members with sufficient permission
  101. can send invites to non-members if allowed by the "m.invite_level" key. A
  102. "private" room is not allowed to have the "m.invite_level" set.
  103. A client may use the value of this key to hint at the user interface
  104. expectations to provide; in particular, a private chat with one other use
  105. might warrant specific handling in the client.
  106. m.may_join
  107. A list of User IDs that are always allowed to join the room, regardless of any
  108. of the prevailing join rules and invite levels. These apply even to private
  109. rooms. These are stored in a single list with normal update-powerlevel
  110. permissions applied; users cannot arbitrarily remove themselves from the list.
  111. m.add_state_level
  112. The power-level required for a user to be able to add new state keys.
  113. m.public_history
  114. If set and true, anyone can request the history of the room, without needing
  115. to be a member of the room.
  116. m.archive_servers
  117. For "public" rooms with public history, gives a list of home servers that
  118. should be included in message distribution to the room, even if no users on
  119. that server are present. These ensure that a public room can still persist
  120. even if no users are currently members of it. This list should be consulted by
  121. the dirctory servers as the candidate list they respond with.
  122. The following keys are provided by Synapse for user benefit, but their value is
  123. not otherwise used by Synapse.
  124. m.name
  125. Stores a short human-readable name for the room, such that clients can display
  126. to a user to assist in identifying which room is which.
  127. This name specifically is not the strong ID used by the message transport
  128. system to refer to the room, because it may be changed from time to time.
  129. m.topic
  130. Stores the current human-readable topic
  131. Room Creation Templates
  132. =======================
  133. A client (or maybe home server?) could offer a few templates for the creation of
  134. new rooms. For example, for a simple private one-to-one chat the channel could
  135. assign the creator a power-level of 1, requiring a level of 1 to invite, and
  136. needing an invite before members can join. An invite is then sent to the other
  137. party, and if accepted and the other user joins, the creator's power-level can
  138. now be reduced to 0. This now leaves a room with two participants in it being
  139. unable to add more.
  140. Rooms that Continue History
  141. ===========================
  142. An option that could be considered for room creation, is that when a new room is
  143. created the creator could specify a PDU ID into an existing room, as the history
  144. continuation point. This would be stored as an extra piece of meta-data on the
  145. initial PDU of the room's creation. (It does not appear in the normal previous
  146. PDU linkage).
  147. This would allow users in rooms to "fork" a room, if it is considered that the
  148. conversations in the room no longer fit its original purpose, and wish to
  149. diverge. Existing permissions on the original room would continue to apply of
  150. course, for viewing that history. If both rooms are considered "public" we might
  151. also want to define a message to post into the original room to represent this
  152. fork point, and give a reference to the new room.
  153. User Direct Message Rooms
  154. =========================
  155. There is no need to build a mechanism for directly sending messages between
  156. users, because a room can handle this ability. To allow direct user-to-user chat
  157. messaging we simply need to be able to create rooms with specific set of
  158. permissions to allow this direct messaging.
  159. Between any given pair of user IDs that wish to exchange private messages, there
  160. will exist a single shared Room, created lazily by either side. These rooms will
  161. need a certain amount of special handling in both home servers and display on
  162. clients, but as much as possible should be treated by the lower layers of code
  163. the same as other rooms.
  164. Specially, a client would likely offer a special menu choice associated with
  165. another user (in room member lists, presence list, etc..) as "direct chat". That
  166. would perform all the necessary steps to create the private chat room. Receiving
  167. clients should display these in a special way too as the room name is not
  168. important; instead it should distinguish them on the Display Name of the other
  169. party.
  170. Home Servers will need a client-API option to request setting up a new user-user
  171. chat room, which will then need special handling within the server. It will
  172. create a new room with the following
  173. m.member: the proposing user
  174. m.join_rules: "private"
  175. m.may_join: both users
  176. m.power_levels: empty
  177. m.default_level: 0
  178. m.add_state_level: 0
  179. m.public_history: False
  180. Having created the room, it can send an invite message to the other user in the
  181. normal way - the room permissions state that no users can be set to the invited
  182. state, but because they're in the may_join list then they'd be allowed to join
  183. anyway.
  184. In this arrangement there is now a room with both users may join but neither has
  185. the power to invite any others. Both users now have the confidence that (at
  186. least within the messaging system itself) their messages remain private and
  187. cannot later be provably leaked to a third party. They can freely set the topic
  188. or name if they choose and add or edit any other state of the room. The update
  189. powerlevel of each of these fixed properties should be 1, to lock out the users
  190. from being able to alter them.
  191. Anti-Glare
  192. ==========
  193. There exists the possibility of a race condition if two users who have no chat
  194. history with each other simultaneously create a room and invite the other to it.
  195. This is called a "glare" situation. There are two possible ideas for how to
  196. resolve this:
  197. * Each Home Server should persist the mapping of (user ID pair) to room ID, so
  198. that duplicate requests can be suppressed. On receipt of a room creation
  199. request that the HS thinks there already exists a room for, the invitation to
  200. join can be rejected if:
  201. a) the HS believes the sending user is already a member of the room (and
  202. maybe their HS has forgotten this fact), or
  203. b) the proposed room has a lexicographically-higher ID than the existing
  204. room (to resolve true race condition conflicts)
  205. * The room ID for a private 1:1 chat has a special form, determined by
  206. concatenting the User IDs of both members in a deterministic order, such that
  207. it doesn't matter which side creates it first; the HSes can just ignore
  208. (or merge?) received PDUs that create the room twice.