Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion eventauth.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ const (
Leave = "leave"
// Invite is the string constant "invite"
Invite = "invite"
// Knock is the string constant "knock"
Knock = "knock"
// NOTSPEC: Peek is the string constant "peek" (MSC2753, used as the label in the sync block)
Peek = "peek"
// Public is the string constant "public"
Expand Down Expand Up @@ -1013,7 +1015,29 @@ func (m *membershipAllower) membershipAllowedSelf() error { // nolint: gocyclo
if m.oldMember.Membership == Leave && m.newMember.Membership == Leave {
return nil
}

if m.newMember.Membership == Knock {
// A user that is not in the room is allowed to knock if the join
// rules are "knock" and they are not already joined to, invited to
// or banned from the room.
// Spec: https://spec.matrix.org/unstable/rooms/v7/
if supported, err := m.create.RoomVersion.AllowKnockingInEventAuth(); err != nil {
return err
} else if !supported {
return m.membershipFailed()
}
if m.joinRule.JoinRule != Knock {
return m.membershipFailed()
}
switch m.oldMember.Membership {
case Join, Invite, Ban:
// The user is already joined, invited or banned, therefore they
// can't knock.
return m.membershipFailed()
default:
// A non-joined, non-invited, non-banned user is allowed to knock.
return nil
}
}
if m.newMember.Membership == Join {
// A user that is not in the room is allowed to join if the room
// join rules are "public".
Expand Down
17 changes: 17 additions & 0 deletions eventversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ var roomVersionMeta = map[RoomVersion]RoomVersionDescription{
enforceSignatureChecks: false,
enforceCanonicalJSON: false,
powerLevelsIncludeNotifications: false,
allowKnockingInEventAuth: false,
},
RoomVersionV2: {
Supported: true,
Expand All @@ -77,6 +78,7 @@ var roomVersionMeta = map[RoomVersion]RoomVersionDescription{
enforceSignatureChecks: false,
enforceCanonicalJSON: false,
powerLevelsIncludeNotifications: false,
allowKnockingInEventAuth: false,
},
RoomVersionV3: {
Supported: true,
Expand All @@ -88,6 +90,7 @@ var roomVersionMeta = map[RoomVersion]RoomVersionDescription{
enforceSignatureChecks: false,
enforceCanonicalJSON: false,
powerLevelsIncludeNotifications: false,
allowKnockingInEventAuth: false,
},
RoomVersionV4: {
Supported: true,
Expand All @@ -99,6 +102,7 @@ var roomVersionMeta = map[RoomVersion]RoomVersionDescription{
enforceSignatureChecks: false,
enforceCanonicalJSON: false,
powerLevelsIncludeNotifications: false,
allowKnockingInEventAuth: false,
},
RoomVersionV5: {
Supported: true,
Expand All @@ -110,6 +114,7 @@ var roomVersionMeta = map[RoomVersion]RoomVersionDescription{
enforceSignatureChecks: true,
enforceCanonicalJSON: false,
powerLevelsIncludeNotifications: false,
allowKnockingInEventAuth: false,
},
RoomVersionV6: {
Supported: true,
Expand All @@ -121,6 +126,7 @@ var roomVersionMeta = map[RoomVersion]RoomVersionDescription{
enforceSignatureChecks: true,
enforceCanonicalJSON: true,
powerLevelsIncludeNotifications: true,
allowKnockingInEventAuth: false,
},
RoomVersionV7: {
Supported: true,
Expand All @@ -132,6 +138,7 @@ var roomVersionMeta = map[RoomVersion]RoomVersionDescription{
enforceSignatureChecks: true,
enforceCanonicalJSON: true,
powerLevelsIncludeNotifications: true,
allowKnockingInEventAuth: true,
},
}

Expand Down Expand Up @@ -185,6 +192,7 @@ type RoomVersionDescription struct {
enforceSignatureChecks bool
enforceCanonicalJSON bool
powerLevelsIncludeNotifications bool
allowKnockingInEventAuth bool
Supported bool
Stable bool
}
Expand Down Expand Up @@ -239,6 +247,15 @@ func (v RoomVersion) PowerLevelsIncludeNotifications() (bool, error) {
return false, UnsupportedRoomVersionError{v}
}

// AllowKnockingInEventAuth returns true if the given room version allows for
// the `knock` membership state or false otherwise.
func (v RoomVersion) AllowKnockingInEventAuth() (bool, error) {
if r, ok := roomVersionMeta[v]; ok {
return r.allowKnockingInEventAuth, nil
}
return false, UnsupportedRoomVersionError{v}
}

// PowerLevelsIncludeNotifications returns true if the given room version calls
// for the power level checks to cover the `notifications` key or false otherwise.
func (v RoomVersion) EnforceCanonicalJSON() (bool, error) {
Expand Down