Skip to main content

ruma_common/
room_version_rules.rs

1//! Types for the rules applied to the different [room versions].
2//!
3//! [room versions]: https://spec.matrix.org/v1.19/rooms/
4
5#[allow(clippy::disallowed_types)]
6use std::collections::HashSet;
7
8use as_variant::as_variant;
9
10use crate::OwnedUserId;
11
12/// The rules applied to a [room version].
13///
14/// This type can be constructed from one of its constants (like [`RoomVersionRules::V1`]), or from
15/// [`RoomVersionId::rules()`].
16///
17/// [room version]: https://spec.matrix.org/v1.19/rooms/
18/// [`RoomVersionId::rules()`]: crate::RoomVersionId::rules
19#[derive(Debug, Clone)]
20#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
21pub struct RoomVersionRules {
22    /// The stability of the room version.
23    pub disposition: RoomVersionDisposition,
24
25    /// The format of event IDs.
26    pub event_id_format: EventIdFormatVersion,
27
28    /// The format of room IDs.
29    pub room_id_format: RoomIdFormatVersion,
30
31    /// The format of arrays referencing events in PDUs.
32    pub events_reference_format: EventsReferenceFormatVersion,
33
34    /// The state resolution algorithm used.
35    pub state_res: StateResolutionVersion,
36
37    /// Whether to enforce the key validity period when verifying signatures ([spec]), introduced
38    /// in room version 5.
39    ///
40    /// [spec]: https://spec.matrix.org/v1.19/rooms/v5/#signing-key-validity-period
41    pub enforce_key_validity: bool,
42
43    /// The tweaks in the authorization rules.
44    pub authorization: AuthorizationRules,
45
46    /// The tweaks in the redaction algorithm.
47    pub redaction: RedactionRules,
48
49    /// The tweaks for verifying signatures.
50    pub signatures: SignaturesRules,
51
52    /// The tweaks for verifying the event format.
53    pub event_format: EventFormatRules,
54}
55
56impl RoomVersionRules {
57    /// Rules for [room version 1].
58    ///
59    /// [room version 1]: https://spec.matrix.org/v1.19/rooms/v1/
60    pub const V1: Self = Self {
61        disposition: RoomVersionDisposition::Stable,
62        event_id_format: EventIdFormatVersion::V1,
63        room_id_format: RoomIdFormatVersion::V1,
64        events_reference_format: EventsReferenceFormatVersion::V1,
65        state_res: StateResolutionVersion::V1,
66        enforce_key_validity: false,
67        authorization: AuthorizationRules::V1,
68        redaction: RedactionRules::V1,
69        signatures: SignaturesRules::V1,
70        event_format: EventFormatRules::V1,
71    };
72
73    /// Rules for [room version 2].
74    ///
75    /// [room version 2]: https://spec.matrix.org/v1.19/rooms/v2/
76    pub const V2: Self =
77        Self { state_res: StateResolutionVersion::V2(StateResolutionV2Rules::V2_0), ..Self::V1 };
78
79    /// Rules for [room version 3].
80    ///
81    /// [room version 3]: https://spec.matrix.org/v1.19/rooms/v3/
82    pub const V3: Self = Self {
83        event_id_format: EventIdFormatVersion::V2,
84        events_reference_format: EventsReferenceFormatVersion::V2,
85        authorization: AuthorizationRules::V3,
86        signatures: SignaturesRules::V3,
87        event_format: EventFormatRules::V3,
88        ..Self::V2
89    };
90
91    /// Rules for [room version 4].
92    ///
93    /// [room version 4]: https://spec.matrix.org/v1.19/rooms/v4/
94    pub const V4: Self = Self { event_id_format: EventIdFormatVersion::V3, ..Self::V3 };
95
96    /// Rules for [room version 5].
97    ///
98    /// [room version 5]: https://spec.matrix.org/v1.19/rooms/v5/
99    pub const V5: Self = Self { enforce_key_validity: true, ..Self::V4 };
100
101    /// Rules for [room version 6].
102    ///
103    /// [room version 6]: https://spec.matrix.org/v1.19/rooms/v6/
104    pub const V6: Self =
105        Self { authorization: AuthorizationRules::V6, redaction: RedactionRules::V6, ..Self::V5 };
106
107    /// Rules for [room version 7].
108    ///
109    /// [room version 7]: https://spec.matrix.org/v1.19/rooms/v7/
110    pub const V7: Self = Self { authorization: AuthorizationRules::V7, ..Self::V6 };
111
112    /// Rules for [room version 8].
113    ///
114    /// [room version 8]: https://spec.matrix.org/v1.19/rooms/v8/
115    pub const V8: Self = Self {
116        authorization: AuthorizationRules::V8,
117        redaction: RedactionRules::V8,
118        signatures: SignaturesRules::V8,
119        ..Self::V7
120    };
121
122    /// Rules for [room version 9].
123    ///
124    /// [room version 9]: https://spec.matrix.org/v1.19/rooms/v9/
125    pub const V9: Self = Self { redaction: RedactionRules::V9, ..Self::V8 };
126
127    /// Rules for [room version 10].
128    ///
129    /// [room version 10]: https://spec.matrix.org/v1.19/rooms/v10/
130    pub const V10: Self = Self { authorization: AuthorizationRules::V10, ..Self::V9 };
131
132    /// Rules for [room version 11].
133    ///
134    /// [room version 11]: https://spec.matrix.org/v1.19/rooms/v11/
135    pub const V11: Self = Self {
136        authorization: AuthorizationRules::V11,
137        redaction: RedactionRules::V11,
138        ..Self::V10
139    };
140
141    /// Rules for [room version 12].
142    ///
143    /// [room version 12]: https://spec.matrix.org/v1.19/rooms/v12/
144    pub const V12: Self = Self {
145        room_id_format: RoomIdFormatVersion::V2,
146        authorization: AuthorizationRules::V12,
147        event_format: EventFormatRules::V12,
148        state_res: StateResolutionVersion::V2(StateResolutionV2Rules::V2_1),
149        ..Self::V11
150    };
151
152    /// Rules for room version `org.matrix.msc2870` ([MSC2870]).
153    ///
154    /// [MSC2870]: https://github.com/matrix-org/matrix-spec-proposals/pull/2870
155    #[cfg(feature = "unstable-msc2870")]
156    pub const MSC2870: Self = Self {
157        disposition: RoomVersionDisposition::Unstable,
158        redaction: RedactionRules::MSC2870,
159        ..Self::V11
160    };
161}
162
163/// The stability of a room version.
164#[derive(Debug, Clone, Copy, PartialEq, Eq)]
165#[allow(clippy::exhaustive_enums)]
166pub enum RoomVersionDisposition {
167    /// A room version that has a stable specification.
168    Stable,
169
170    /// A room version that is not yet fully specified.
171    Unstable,
172}
173
174/// The format of [event IDs] for a room version.
175///
176/// [event IDs]: https://spec.matrix.org/v1.19/appendices/#event-ids
177#[derive(Debug, Clone, Copy, PartialEq, Eq)]
178#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
179pub enum EventIdFormatVersion {
180    /// `$id:server` format ([spec]), introduced in room version 1.
181    ///
182    /// [spec]: https://spec.matrix.org/v1.19/rooms/v1/#event-ids
183    V1,
184
185    /// `$hash` format using standard unpadded base64 ([spec]), introduced in room version 3.
186    ///
187    /// [spec]: https://spec.matrix.org/v1.19/rooms/v3/#event-ids
188    V2,
189
190    /// `$hash` format using URL-safe unpadded base64 ([spec]), introduced in room version 4.
191    ///
192    /// [spec]: https://spec.matrix.org/v1.19/rooms/v4/#event-ids
193    V3,
194}
195
196/// The format of [room IDs] for a room version.
197///
198/// [room IDs]: https://spec.matrix.org/v1.19/appendices/#room-ids
199#[derive(Debug, Clone, Copy, PartialEq, Eq)]
200#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
201pub enum RoomIdFormatVersion {
202    /// `!id:server` format, introduced in room version 1.
203    V1,
204
205    /// `!hash` format using the reference hash of the `m.room.create` event of the room,
206    /// introduced in room version 12.
207    V2,
208}
209
210/// The format of [PDU] `auth_events` and `prev_events` for a room version.
211///
212/// [PDU]: https://spec.matrix.org/v1.19/server-server-api/#pdus
213#[derive(Debug, Clone, Copy, PartialEq, Eq)]
214#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
215pub enum EventsReferenceFormatVersion {
216    /// `[["$id:server", {"sha256": "hash"}]]` format ([spec]), introduced in room version 1.
217    ///
218    /// [spec]: https://spec.matrix.org/v1.19/rooms/v1/#event-format
219    V1,
220
221    /// `["$hash"]` format ([spec]), introduced in room version 3.
222    ///
223    /// [spec]: https://spec.matrix.org/v1.19/rooms/v3/#event-format
224    V2,
225}
226
227/// The version of [state resolution] for a room version.
228///
229/// [state resolution]: https://spec.matrix.org/v1.19/server-server-api/#room-state-resolution
230#[derive(Debug, Clone, Copy, PartialEq, Eq)]
231#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
232pub enum StateResolutionVersion {
233    /// First version of the state resolution algorithm ([spec]), introduced in room version 1.
234    ///
235    /// [spec]: https://spec.matrix.org/v1.19/rooms/v1/#state-resolution
236    V1,
237
238    /// Second version of the state resolution algorithm ([spec]), introduced in room version 2.
239    ///
240    /// [spec]: https://spec.matrix.org/v1.19/rooms/v2/#state-resolution
241    V2(StateResolutionV2Rules),
242}
243
244impl StateResolutionVersion {
245    /// Gets the `StateResolutionV2Rules` for the room version, if it uses the second version of
246    /// the state resolution algorithm.
247    pub fn v2_rules(&self) -> Option<&StateResolutionV2Rules> {
248        as_variant!(self, StateResolutionVersion::V2)
249    }
250}
251
252/// The tweaks in the [state resolution v2 algorithm] for a room version.
253///
254/// This type can be constructed from one of its constants (like [`StateResolutionV2Rules::V2_0`]),
255/// or by constructing a [`RoomVersionRules`] first and using the `state_res` field (if the room
256/// version uses version 2 of the state resolution algorithm).
257///
258/// [state resolution v2 algorithm]: https://spec.matrix.org/v1.19/rooms/v2/#state-resolution
259#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
260#[derive(Debug, Clone, Copy, PartialEq, Eq)]
261pub struct StateResolutionV2Rules {
262    /// Whether to begin the first phase of iterative auth checks with an empty state map, as
263    /// opposed to one containing the unconflicted state, enabled since room version 12.
264    pub begin_iterative_auth_checks_with_empty_state_map: bool,
265
266    /// Whether to include the conflicted state subgraph in the full conflicted state, enabled
267    /// since room version 12.
268    pub consider_conflicted_state_subgraph: bool,
269}
270
271impl StateResolutionV2Rules {
272    /// The first version of the second iteration of the state resolution algorithm, introduced in
273    /// room version 2.
274    pub const V2_0: Self = Self {
275        begin_iterative_auth_checks_with_empty_state_map: false,
276        consider_conflicted_state_subgraph: false,
277    };
278
279    /// The second version of the second iteration of the state resolution algorithm ([spec]),
280    /// introduced in room version 12.
281    ///
282    /// [spec]: https://spec.matrix.org/v1.19/rooms/v12/#state-resolution
283    pub const V2_1: Self = Self {
284        begin_iterative_auth_checks_with_empty_state_map: true,
285        consider_conflicted_state_subgraph: true,
286        ..Self::V2_0
287    };
288}
289
290/// The tweaks in the [authorization rules] for a room version.
291///
292/// This type can be constructed from one of its constants (like [`AuthorizationRules::V1`]), or by
293/// constructing a [`RoomVersionRules`] first and using the `authorization` field.
294///
295/// [authorization rules]: https://spec.matrix.org/v1.19/server-server-api/#authorisation-rules
296#[derive(Debug, Clone)]
297#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
298pub struct AuthorizationRules {
299    /// Whether to apply special authorization rules for `m.room.redaction` events ([spec]),
300    /// disabled since room version 3.
301    ///
302    /// [spec]: https://spec.matrix.org/v1.19/rooms/v3/#handling-redactions
303    pub special_case_room_redaction: bool,
304
305    /// Whether to apply special authorization rules for `m.room.aliases` events ([spec]), disabled
306    /// since room version 6.
307    ///
308    /// [spec]: https://spec.matrix.org/v1.19/rooms/v6/#authorisation-rules
309    pub special_case_room_aliases: bool,
310
311    /// Whether to strictly enforce [canonical JSON] ([spec]), introduced in room version 6.
312    ///
313    /// Numbers in Canonical JSON must be integers in the range [-2<sup>53</sup> + 1,
314    /// 2<sup>53</sup> - 1], represented without exponents or decimal places, and negative zero
315    /// (`-0`) MUST NOT appear.
316    ///
317    /// [canonical JSON]: https://spec.matrix.org/v1.19/appendices/#canonical-json
318    /// [spec]: https://spec.matrix.org/v1.19/rooms/v6/#canonical-json
319    pub strict_canonical_json: bool,
320
321    /// Whether to check the `notifications` field when checking `m.room.power_levels` events
322    /// ([spec]), introduced in room version 6.
323    ///
324    /// [spec]: https://spec.matrix.org/v1.19/rooms/v6/#authorisation-rules
325    pub limit_notifications_power_levels: bool,
326
327    /// Whether to allow the `knock` membership for `m.room.member` events and the `knock` join
328    /// rule for `m.room.join_rules` events ([spec]), introduced in room version 7.
329    ///
330    /// [spec]: https://spec.matrix.org/v1.19/rooms/v7/#authorisation-rules
331    pub knocking: bool,
332
333    /// Whether to allow the `restricted` join rule for `m.room.join_rules` events ([spec]),
334    /// introduced in room version 8.
335    ///
336    /// [spec]: https://spec.matrix.org/v1.19/rooms/v8/#authorisation-rules
337    pub restricted_join_rule: bool,
338
339    /// Whether to allow the `knock_restricted` join rule for `m.room.join_rules` events ([spec]),
340    /// introduced in room version 10.
341    ///
342    /// [spec]: https://spec.matrix.org/v1.19/rooms/v10/#authorisation-rules
343    pub knock_restricted_join_rule: bool,
344
345    /// Whether to enforce that power levels values in `m.room.power_levels` events be integers
346    /// ([spec]), introduced in room version 10.
347    ///
348    /// [spec]: https://spec.matrix.org/v1.19/rooms/v10/#values-in-mroompower_levels-events-must-be-integers
349    pub integer_power_levels: bool,
350
351    /// Whether the room creator should be determined using the `m.room.create` event's `sender`,
352    /// instead of the event content's `creator` field ([spec]), introduced in room version 11.
353    ///
354    /// [spec]: https://spec.matrix.org/v1.19/rooms/v11/#event-format
355    pub use_room_create_sender: bool,
356
357    /// Whether room creators should always be considered to have "infinite" power level ([spec]),
358    /// introduced in room version 12.
359    ///
360    /// [spec]: https://spec.matrix.org/v1.19/rooms/v12/#authorisation-rules
361    pub explicitly_privilege_room_creators: bool,
362
363    /// Whether additional room creators can be set with the `content.additional_creators` field of
364    /// an `m.room.create` event ([spec]), introduced in room version 12.
365    ///
366    /// [spec]: https://spec.matrix.org/v1.19/rooms/v12/#authorisation-rules
367    pub additional_room_creators: bool,
368
369    /// Whether to use the event ID of the `m.room.create` event of the room as the room ID
370    /// ([spec]), introduced in room version 12.
371    ///
372    /// [spec]: https://spec.matrix.org/v1.19/rooms/v12/#event-format-1
373    pub room_create_event_id_as_room_id: bool,
374}
375
376impl AuthorizationRules {
377    /// Authorization rules as introduced in room version 1 ([spec]).
378    ///
379    /// [spec]: https://spec.matrix.org/v1.19/rooms/v1/#authorisation-rules
380    pub const V1: Self = Self {
381        special_case_room_redaction: true,
382        special_case_room_aliases: true,
383        strict_canonical_json: false,
384        limit_notifications_power_levels: false,
385        knocking: false,
386        restricted_join_rule: false,
387        knock_restricted_join_rule: false,
388        integer_power_levels: false,
389        use_room_create_sender: false,
390        explicitly_privilege_room_creators: false,
391        additional_room_creators: false,
392        room_create_event_id_as_room_id: false,
393    };
394
395    /// Authorization rules with tweaks introduced in room version 3 ([spec]).
396    ///
397    /// [spec]: https://spec.matrix.org/v1.19/rooms/v3/#authorisation-rules
398    pub const V3: Self = Self { special_case_room_redaction: false, ..Self::V1 };
399
400    /// Authorization rules with tweaks introduced in room version 6 ([spec]).
401    ///
402    /// [spec]: https://spec.matrix.org/v1.19/rooms/v6/#authorisation-rules
403    pub const V6: Self = Self {
404        special_case_room_aliases: false,
405        strict_canonical_json: true,
406        limit_notifications_power_levels: true,
407        ..Self::V3
408    };
409
410    /// Authorization rules with tweaks introduced in room version 7 ([spec]).
411    ///
412    /// [spec]: https://spec.matrix.org/v1.19/rooms/v7/#authorisation-rules
413    pub const V7: Self = Self { knocking: true, ..Self::V6 };
414
415    /// Authorization rules with tweaks introduced in room version 8 ([spec]).
416    ///
417    /// [spec]: https://spec.matrix.org/v1.19/rooms/v8/#authorisation-rules
418    pub const V8: Self = Self { restricted_join_rule: true, ..Self::V7 };
419
420    /// Authorization rules with tweaks introduced in room version 10 ([spec]).
421    ///
422    /// [spec]: https://spec.matrix.org/v1.19/rooms/v10/#authorisation-rules
423    pub const V10: Self =
424        Self { knock_restricted_join_rule: true, integer_power_levels: true, ..Self::V8 };
425
426    /// Authorization rules with tweaks introduced in room version 11 ([spec]).
427    ///
428    /// [spec]: https://spec.matrix.org/v1.19/rooms/v11/#authorisation-rules
429    pub const V11: Self = Self { use_room_create_sender: true, ..Self::V10 };
430
431    /// Authorization rules with tweaks introduced in room version 12 ([spec]).
432    ///
433    /// [spec]: https://spec.matrix.org/v1.19/rooms/v12/#authorisation-rules
434    pub const V12: Self = Self {
435        explicitly_privilege_room_creators: true,
436        additional_room_creators: true,
437        room_create_event_id_as_room_id: true,
438        ..Self::V11
439    };
440}
441
442/// The tweaks in the [redaction] algorithm for a room version.
443///
444/// This type can be constructed from one of its constants (like [`RedactionRules::V1`]), or by
445/// constructing a [`RoomVersionRules`] first and using the `redaction` field.
446///
447/// [redaction]: https://spec.matrix.org/v1.19/client-server-api/#redactions
448#[derive(Debug, Clone)]
449#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
450pub struct RedactionRules {
451    /// Whether to keep the `aliases` field in the `content` of `m.room.aliases` events ([spec]),
452    /// disabled since room version 6.
453    ///
454    /// [spec]: https://spec.matrix.org/v1.19/rooms/v6/#redactions
455    pub keep_room_aliases_aliases: bool,
456
457    /// Whether to keep the `allow` field in the `content` of `m.room.join_rules` events ([spec]),
458    /// introduced in room version 8.
459    ///
460    /// [spec]: https://spec.matrix.org/v1.19/rooms/v8/#redactions
461    pub keep_room_join_rules_allow: bool,
462
463    /// Whether to keep the `join_authorised_via_users_server` field in the `content` of
464    /// `m.room.member` events ([spec]), introduced in room version 9.
465    ///
466    /// [spec]: https://spec.matrix.org/v1.19/rooms/v9/#redactions
467    pub keep_room_member_join_authorised_via_users_server: bool,
468
469    /// Whether to keep the `origin`, `membership` and `prev_state` fields a the top-level of all
470    /// events ([spec]), disabled since room version 11.
471    ///
472    /// [spec]: https://spec.matrix.org/v1.19/rooms/v11/#redactions
473    pub keep_origin_membership_prev_state: bool,
474
475    /// Whether to keep the entire `content` of `m.room.create` events ([spec]), introduced in room
476    /// version 11.
477    ///
478    /// [spec]: https://spec.matrix.org/v1.19/rooms/v11/#redactions
479    pub keep_room_create_content: bool,
480
481    /// Whether to keep the `redacts` field in the `content` of `m.room.redaction` events ([spec]),
482    /// introduced in room version 11.
483    ///
484    /// [spec]: https://spec.matrix.org/v1.19/rooms/v11/#redactions
485    pub keep_room_redaction_redacts: bool,
486
487    /// Whether to keep the `invite` field in the `content` of `m.room.power_levels` events
488    /// ([spec]), introduced in room version 11.
489    ///
490    /// [spec]: https://spec.matrix.org/v1.19/rooms/v11/#redactions
491    pub keep_room_power_levels_invite: bool,
492
493    /// Whether to keep the `signed` field in `third_party_invite` of the `content` of
494    /// `m.room.member` events ([spec]), introduced in room version 11.
495    ///
496    /// [spec]: https://spec.matrix.org/v1.19/rooms/v11/#redactions
497    pub keep_room_member_third_party_invite_signed: bool,
498
499    /// Whether the `content.redacts` field should be used to determine the event an event
500    /// redacts, as opposed to the top-level `redacts` field ([spec]), introduced in room version
501    /// 11.
502    ///
503    /// [spec]: https://spec.matrix.org/v1.19/rooms/v11/#redactions
504    pub content_field_redacts: bool,
505
506    /// Whether to keep the `allow`, `deny` and `allow_ip_literals` in the `content` of
507    /// `m.room.server_acl` events ([MSC2870]).
508    ///
509    /// [MSC2870]: https://github.com/matrix-org/matrix-spec-proposals/pull/2870
510    #[cfg(feature = "unstable-msc2870")]
511    pub keep_room_server_acl_allow_deny_allow_ip_literals: bool,
512}
513
514impl RedactionRules {
515    /// Redaction rules as introduced in room version 1 ([spec]).
516    ///
517    /// [spec]: https://spec.matrix.org/v1.19/rooms/v1/#redactions
518    pub const V1: Self = Self {
519        keep_room_aliases_aliases: true,
520        keep_room_join_rules_allow: false,
521        keep_room_member_join_authorised_via_users_server: false,
522        keep_origin_membership_prev_state: true,
523        keep_room_create_content: false,
524        keep_room_redaction_redacts: false,
525        keep_room_power_levels_invite: false,
526        keep_room_member_third_party_invite_signed: false,
527        content_field_redacts: false,
528        #[cfg(feature = "unstable-msc2870")]
529        keep_room_server_acl_allow_deny_allow_ip_literals: false,
530    };
531
532    /// Redaction rules with tweaks introduced in room version 6 ([spec]).
533    ///
534    /// [spec]: https://spec.matrix.org/v1.19/rooms/v6/#redactions
535    pub const V6: Self = Self { keep_room_aliases_aliases: false, ..Self::V1 };
536
537    /// Redaction rules with tweaks introduced in room version 8 ([spec]).
538    ///
539    /// [spec]: https://spec.matrix.org/v1.19/rooms/v8/#redactions
540    pub const V8: Self = Self { keep_room_join_rules_allow: true, ..Self::V6 };
541
542    /// Redaction rules with tweaks introduced in room version 9 ([spec]).
543    ///
544    /// [spec]: https://spec.matrix.org/v1.19/rooms/v9/#redactions
545    pub const V9: Self =
546        Self { keep_room_member_join_authorised_via_users_server: true, ..Self::V8 };
547
548    /// Redaction rules with tweaks introduced in room version 11 ([spec]).
549    ///
550    /// [spec]: https://spec.matrix.org/v1.19/rooms/v11/#redactions
551    pub const V11: Self = Self {
552        keep_origin_membership_prev_state: false,
553        keep_room_create_content: true,
554        keep_room_redaction_redacts: true,
555        keep_room_power_levels_invite: true,
556        keep_room_member_third_party_invite_signed: true,
557        content_field_redacts: true,
558        ..Self::V9
559    };
560
561    /// Redaction rules with tweaks introduced in [MSC2870].
562    ///
563    /// [MSC2870]: https://github.com/matrix-org/matrix-spec-proposals/pull/2870
564    #[cfg(feature = "unstable-msc2870")]
565    pub const MSC2870: Self =
566        Self { keep_room_server_acl_allow_deny_allow_ip_literals: true, ..Self::V11 };
567}
568
569/// The tweaks for [verifying the signatures] for a room version.
570///
571/// This type can be constructed from one of its constants (like [`SignaturesRules::V1`]), or by
572/// constructing a [`RoomVersionRules`] first and using the `signatures` field.
573///
574/// [verifying the signatures]: https://spec.matrix.org/v1.19/server-server-api/#validating-hashes-and-signatures-on-received-events
575#[derive(Debug, Clone)]
576#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
577pub struct SignaturesRules {
578    /// Whether to check the server of the event ID, disabled since room version 3.
579    pub check_event_id_server: bool,
580
581    /// Whether to check the server of the `join_authorised_via_users_server` field in the
582    /// `content` of `m.room.member` events ([spec]), introduced in room version 8.
583    ///
584    /// [spec]: https://spec.matrix.org/v1.19/rooms/v8/#authorisation-rules
585    pub check_join_authorised_via_users_server: bool,
586}
587
588impl SignaturesRules {
589    /// Signatures verification rules as introduced in room version 1.
590    pub const V1: Self =
591        Self { check_event_id_server: true, check_join_authorised_via_users_server: false };
592
593    /// Signatures verification rules with tweaks introduced in room version 3.
594    pub const V3: Self = Self { check_event_id_server: false, ..Self::V1 };
595
596    /// Signatures verification rules with tweaks introduced in room version 8.
597    pub const V8: Self = Self { check_join_authorised_via_users_server: true, ..Self::V3 };
598}
599
600/// The tweaks for verifying the event format for a room version.
601///
602/// This type can be constructed from one of its constants (like [`EventFormatRules::V1`]), or by
603/// constructing a [`RoomVersionRules`] first and using the `event_format` field.
604#[derive(Debug, Clone)]
605#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
606pub struct EventFormatRules {
607    /// Whether the `event_id` field is required, disabled since room version 3.
608    pub require_event_id: bool,
609
610    /// Whether the `room_id` field is required on the `m.room.create` event ([spec]), disabled
611    /// since room version 12.
612    ///
613    /// [spec]: https://spec.matrix.org/v1.19/rooms/v12/#event-format-1
614    pub require_room_create_room_id: bool,
615
616    /// Whether the `m.room.create` event is allowed to be in the `auth_events` ([spec]), disabled
617    /// since room version 12.
618    ///
619    /// [spec]: https://spec.matrix.org/v1.19/rooms/v12/#event-format-1
620    pub allow_room_create_in_auth_events: bool,
621}
622
623impl EventFormatRules {
624    /// Event format rules as introduced in room version 1.
625    pub const V1: Self = Self {
626        require_event_id: true,
627        require_room_create_room_id: true,
628        allow_room_create_in_auth_events: true,
629    };
630
631    /// Event format rules with tweaks introduced in room version 3.
632    pub const V3: Self = Self { require_event_id: false, ..Self::V1 };
633
634    /// Event format rules with tweaks introduced in room version 12 ([spec]).
635    ///
636    /// [spec]: https://spec.matrix.org/v1.19/rooms/v12/#event-format-1
637    pub const V12: Self = Self {
638        require_room_create_room_id: false,
639        allow_room_create_in_auth_events: false,
640        ..Self::V3
641    };
642}
643
644/// The tweaks for determining the power level of a user.
645#[derive(Clone, Debug)]
646#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
647pub struct RoomPowerLevelsRules {
648    /// The creator(s) of the room which are considered to have "infinite" power level, introduced
649    /// in room version 12.
650    #[allow(clippy::disallowed_types)]
651    pub privileged_creators: Option<HashSet<OwnedUserId>>,
652}
653
654impl RoomPowerLevelsRules {
655    /// Creates a new `RoomPowerLevelsRules` from the given parameters, using the `creators` if
656    /// the rule `explicitly_privilege_room_creators` is `true`.
657    pub fn new(
658        rules: &AuthorizationRules,
659        creators: impl IntoIterator<Item = OwnedUserId>,
660    ) -> Self {
661        Self {
662            privileged_creators: rules
663                .explicitly_privilege_room_creators
664                .then(|| creators.into_iter().collect()),
665        }
666    }
667}