money/vendor/maunium.net/go/mautrix/id/roomversion.go

266 lines
10 KiB
Go

// Copyright (c) 2025 Tulir Asokan
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package id
import (
"errors"
"fmt"
"slices"
)
type RoomVersion string
const (
RoomV0 RoomVersion = "" // No room version, used for rooms created before room versions were introduced, equivalent to v1
RoomV1 RoomVersion = "1"
RoomV2 RoomVersion = "2"
RoomV3 RoomVersion = "3"
RoomV4 RoomVersion = "4"
RoomV5 RoomVersion = "5"
RoomV6 RoomVersion = "6"
RoomV7 RoomVersion = "7"
RoomV8 RoomVersion = "8"
RoomV9 RoomVersion = "9"
RoomV10 RoomVersion = "10"
RoomV11 RoomVersion = "11"
RoomV12 RoomVersion = "12"
)
func (rv RoomVersion) Equals(versions ...RoomVersion) bool {
return slices.Contains(versions, rv)
}
func (rv RoomVersion) NotEquals(versions ...RoomVersion) bool {
return !rv.Equals(versions...)
}
var ErrUnknownRoomVersion = errors.New("unknown room version")
func (rv RoomVersion) unknownVersionError() error {
return fmt.Errorf("%w %s", ErrUnknownRoomVersion, rv)
}
func (rv RoomVersion) IsKnown() bool {
switch rv {
case RoomV0, RoomV1, RoomV2, RoomV3, RoomV4, RoomV5, RoomV6, RoomV7, RoomV8, RoomV9, RoomV10, RoomV11, RoomV12:
return true
default:
return false
}
}
type StateResVersion int
const (
// StateResV1 is the original state resolution algorithm.
StateResV1 StateResVersion = 0
// StateResV2 is state resolution v2 introduced by https://github.com/matrix-org/matrix-spec-proposals/pull/1759
StateResV2 StateResVersion = 1
// StateResV2_1 is state resolution v2.1 introduced by https://github.com/matrix-org/matrix-spec-proposals/pull/4297
StateResV2_1 StateResVersion = 2
)
// StateResVersion returns the version of the state resolution algorithm used by this room version.
func (rv RoomVersion) StateResVersion() StateResVersion {
switch rv {
case RoomV0, RoomV1:
return StateResV1
case RoomV2, RoomV3, RoomV4, RoomV5, RoomV6, RoomV7, RoomV8, RoomV9, RoomV10, RoomV11:
return StateResV2
case RoomV12:
return StateResV2_1
default:
panic(rv.unknownVersionError())
}
}
type EventIDFormat int
const (
// EventIDFormatCustom is the original format used by room v1 and v2.
// Event IDs in this format are an arbitrary string followed by a colon and the server name.
EventIDFormatCustom EventIDFormat = 0
// EventIDFormatBase64 is the format used by room v3 introduced by https://github.com/matrix-org/matrix-spec-proposals/pull/1659.
// Event IDs in this format are the standard unpadded base64-encoded SHA256 reference hash of the event.
EventIDFormatBase64 EventIDFormat = 1
// EventIDFormatURLSafeBase64 is the format used by room v4 and later introduced by https://github.com/matrix-org/matrix-spec-proposals/pull/2002.
// Event IDs in this format are the url-safe unpadded base64-encoded SHA256 reference hash of the event.
EventIDFormatURLSafeBase64 EventIDFormat = 2
)
// EventIDFormat returns the format of event IDs used by this room version.
func (rv RoomVersion) EventIDFormat() EventIDFormat {
switch rv {
case RoomV0, RoomV1, RoomV2:
return EventIDFormatCustom
case RoomV3:
return EventIDFormatBase64
default:
return EventIDFormatURLSafeBase64
}
}
/////////////////////
// Room v5 changes //
/////////////////////
// https://github.com/matrix-org/matrix-spec-proposals/pull/2077
// EnforceSigningKeyValidity returns true if the `valid_until_ts` field of federation signing keys
// must be enforced on received events.
//
// See https://github.com/matrix-org/matrix-spec-proposals/pull/2076
func (rv RoomVersion) EnforceSigningKeyValidity() bool {
return rv.NotEquals(RoomV0, RoomV1, RoomV2, RoomV3, RoomV4)
}
/////////////////////
// Room v6 changes //
/////////////////////
// https://github.com/matrix-org/matrix-spec-proposals/pull/2240
// SpecialCasedAliasesAuth returns true if the `m.room.aliases` event authorization is special cased
// to only always allow servers to modify the state event with their own server name as state key.
// This also implies that the `aliases` field is protected from redactions.
//
// See https://github.com/matrix-org/matrix-spec-proposals/pull/2432
func (rv RoomVersion) SpecialCasedAliasesAuth() bool {
return rv.Equals(RoomV0, RoomV1, RoomV2, RoomV3, RoomV4, RoomV5)
}
// ForbidFloatsAndBigInts returns true if floats and integers greater than 2^53-1 or lower than -2^53+1 are forbidden everywhere.
//
// See https://github.com/matrix-org/matrix-spec-proposals/pull/2540
func (rv RoomVersion) ForbidFloatsAndBigInts() bool {
return rv.NotEquals(RoomV0, RoomV1, RoomV2, RoomV3, RoomV4, RoomV5)
}
// NotificationsPowerLevels returns true if the `notifications` field in `m.room.power_levels` is validated in event auth.
// However, the field is not protected from redactions.
//
// See https://github.com/matrix-org/matrix-spec-proposals/pull/2209
func (rv RoomVersion) NotificationsPowerLevels() bool {
return rv.NotEquals(RoomV0, RoomV1, RoomV2, RoomV3, RoomV4, RoomV5)
}
/////////////////////
// Room v7 changes //
/////////////////////
// https://github.com/matrix-org/matrix-spec-proposals/pull/2998
// Knocks returns true if the `knock` join rule is supported.
//
// See https://github.com/matrix-org/matrix-spec-proposals/pull/2403
func (rv RoomVersion) Knocks() bool {
return rv.NotEquals(RoomV0, RoomV1, RoomV2, RoomV3, RoomV4, RoomV5, RoomV6)
}
/////////////////////
// Room v8 changes //
/////////////////////
// https://github.com/matrix-org/matrix-spec-proposals/pull/3289
// RestrictedJoins returns true if the `restricted` join rule is supported.
// This also implies that the `allow` field in the `m.room.join_rules` event is supported and protected from redactions.
//
// See https://github.com/matrix-org/matrix-spec-proposals/pull/3083
func (rv RoomVersion) RestrictedJoins() bool {
return rv.NotEquals(RoomV0, RoomV1, RoomV2, RoomV3, RoomV4, RoomV5, RoomV6, RoomV7)
}
/////////////////////
// Room v9 changes //
/////////////////////
// https://github.com/matrix-org/matrix-spec-proposals/pull/3375
// RestrictedJoinsFix returns true if the `join_authorised_via_users_server` field in `m.room.member` events is protected from redactions.
//
// See https://github.com/matrix-org/matrix-spec-proposals/pull/3375
func (rv RoomVersion) RestrictedJoinsFix() bool {
return rv.RestrictedJoins() && rv != RoomV8
}
//////////////////////
// Room v10 changes //
//////////////////////
// https://github.com/matrix-org/matrix-spec-proposals/pull/3604
// ValidatePowerLevelInts returns true if the known values in `m.room.power_levels` must be integers (and not strings).
//
// See https://github.com/matrix-org/matrix-spec-proposals/pull/3667
func (rv RoomVersion) ValidatePowerLevelInts() bool {
return rv.NotEquals(RoomV0, RoomV1, RoomV2, RoomV3, RoomV4, RoomV5, RoomV6, RoomV7, RoomV8, RoomV9)
}
// KnockRestricted returns true if the `knock_restricted` join rule is supported.
//
// See https://github.com/matrix-org/matrix-spec-proposals/pull/3787
func (rv RoomVersion) KnockRestricted() bool {
return rv.NotEquals(RoomV0, RoomV1, RoomV2, RoomV3, RoomV4, RoomV5, RoomV6, RoomV7, RoomV8, RoomV9)
}
//////////////////////
// Room v11 changes //
//////////////////////
// https://github.com/matrix-org/matrix-spec-proposals/pull/3820
// CreatorInContent returns true if the `m.room.create` event has a `creator` field in content.
//
// See https://github.com/matrix-org/matrix-spec-proposals/pull/2175
func (rv RoomVersion) CreatorInContent() bool {
return rv.Equals(RoomV0, RoomV1, RoomV2, RoomV3, RoomV4, RoomV5, RoomV6, RoomV7, RoomV8, RoomV9, RoomV10)
}
// RedactsInContent returns true if the `m.room.redaction` event has the `redacts` field in content instead of at the top level.
// The redaction protection is also moved from the top level to the content field.
//
// See https://github.com/matrix-org/matrix-spec-proposals/pull/2174
// (and https://github.com/matrix-org/matrix-spec-proposals/pull/2176 for the redaction protection).
func (rv RoomVersion) RedactsInContent() bool {
return rv.NotEquals(RoomV0, RoomV1, RoomV2, RoomV3, RoomV4, RoomV5, RoomV6, RoomV7, RoomV8, RoomV9, RoomV10)
}
// UpdatedRedactionRules returns true if various updates to the redaction algorithm are applied.
//
// Specifically:
//
// * the `membership`, `origin`, and `prev_state` fields at the top level of all events are no longer protected.
// * the entire content of `m.room.create` is protected.
// * the `redacts` field in `m.room.redaction` content is protected instead of the top-level field.
// * the `m.room.power_levels` event protects the `invite` field in content.
// * the `signed` field inside the `third_party_invite` field in content of `m.room.member` events is protected.
//
// See https://github.com/matrix-org/matrix-spec-proposals/pull/2176,
// https://github.com/matrix-org/matrix-spec-proposals/pull/3821, and
// https://github.com/matrix-org/matrix-spec-proposals/pull/3989
func (rv RoomVersion) UpdatedRedactionRules() bool {
return rv.NotEquals(RoomV0, RoomV1, RoomV2, RoomV3, RoomV4, RoomV5, RoomV6, RoomV7, RoomV8, RoomV9, RoomV10)
}
//////////////////////
// Room v12 changes //
//////////////////////
// https://github.com/matrix-org/matrix-spec-proposals/pull/4304
// Return value of StateResVersion was changed to StateResV2_1
// PrivilegedRoomCreators returns true if the creator(s) of a room always have infinite power level.
// This also implies that the `m.room.create` event has an `additional_creators` field,
// and that the creators can't be present in the `m.room.power_levels` event.
//
// See https://github.com/matrix-org/matrix-spec-proposals/pull/4289
func (rv RoomVersion) PrivilegedRoomCreators() bool {
return rv.NotEquals(RoomV0, RoomV1, RoomV2, RoomV3, RoomV4, RoomV5, RoomV6, RoomV7, RoomV8, RoomV9, RoomV10, RoomV11)
}
// RoomIDIsCreateEventID returns true if the ID of rooms is the same as the ID of the `m.room.create` event.
// This also implies that `m.room.create` events do not have a `room_id` field.
//
// See https://github.com/matrix-org/matrix-spec-proposals/pull/4291
func (rv RoomVersion) RoomIDIsCreateEventID() bool {
return rv.NotEquals(RoomV0, RoomV1, RoomV2, RoomV3, RoomV4, RoomV5, RoomV6, RoomV7, RoomV8, RoomV9, RoomV10, RoomV11)
}