Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix event auth for knocking #431

Merged
merged 3 commits into from
Jan 16, 2024
Merged
Show file tree
Hide file tree
Changes from 2 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
30 changes: 14 additions & 16 deletions eventauth.go
Original file line number Diff line number Diff line change
Expand Up @@ -1155,18 +1155,7 @@ func (m *membershipAllower) membershipAllowedSelf() error { // nolint: gocyclo

switch m.newMember.Membership {
case spec.Knock:
if m.joinRule.JoinRule != spec.Knock && m.joinRule.JoinRule != spec.KnockRestricted {
return m.membershipFailed(
"join rule %q does not allow knocking", m.joinRule.JoinRule,
)
}
// 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/
// MSC3787 extends this: the behaviour above is also permitted if the
// join rules are "knock_restricted"
// Spec: https://github.com/matrix-org/matrix-spec-proposals/pull/3787
// Check if the given roomVersionImpl allows knocking.
return m.roomVersionImpl.CheckKnockingAllowed(m)
case spec.Join:
if m.joinRule.JoinRule == spec.Restricted || m.joinRule.JoinRule == spec.KnockRestricted {
Expand Down Expand Up @@ -1244,8 +1233,16 @@ func disallowKnocking(m *membershipAllower) error {
)
}

// 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
// or banned from the room.
// Spec: https://spec.matrix.org/unstable/rooms/v7/
// MSC3787 extends this: the behaviour above is also permitted if the
// join rules are "knock_restricted"
// Spec: https://github.com/matrix-org/matrix-spec-proposals/pull/3787
func checkKnocking(m *membershipAllower) error {
supported := m.joinRule.JoinRule == spec.Knock || m.joinRule.JoinRule == spec.Restricted || m.joinRule.JoinRule == spec.KnockRestricted
// If the join_rule is anything other than knock or knock_restricted, reject.
supported := m.joinRule.JoinRule == spec.Knock || m.joinRule.JoinRule == spec.KnockRestricted
if !supported {
return m.membershipFailed(
"room version %q does not support knocking on rooms with join rule %q",
Expand All @@ -1255,11 +1252,12 @@ func checkKnocking(m *membershipAllower) error {
}
switch m.oldMember.Membership {

case spec.Join, spec.Invite, spec.Ban:
// The user is already joined, invited or banned, therefore they
// If the sender’s current membership is not ban or join, allow.
case spec.Join, spec.Ban:
// The user is already joined or banned, therefore they
// can't knock.
return m.membershipFailed(
"sender is already joined/invited/banned",
"sender is already joined/banned",
)
}
// A non-joined, non-invited, non-banned user is allowed to knock.
Expand Down
37 changes: 37 additions & 0 deletions eventauth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1834,6 +1834,14 @@ func TestJoinRuleKnock(t *testing.T) {
"state_key": "@u4:a",
"event_id": "$e2:a",
"content": {"membership": "knock"}
},
"@u5:a": {
"type": "m.room.member",
"sender": "@u5:a",
"room_id": "!r1:a",
"state_key": "@u5:a",
"event_id": "$e2:a",
"content": {"membership": "ban"}
}
}
},
Expand All @@ -1851,6 +1859,13 @@ func TestJoinRuleKnock(t *testing.T) {
"state_key": "@u3:a",
"event_id": "$e2:a",
"content": {"membership": "join"}
}, {
"type": "m.room.member",
"sender": "@u2:a",
"room_id": "!r1:a",
"state_key": "@u2:a",
"event_id": "$e2:a",
"content": {"membership": "knock"}
}],
"not_allowed": [{
"type": "m.room.member",
Expand All @@ -1873,6 +1888,28 @@ func TestJoinRuleKnock(t *testing.T) {
"unsigned": {
"not_allowed": "Sender not invited or joined"
}
},
{
"type": "m.room.member",
"sender": "@u3:a",
"room_id": "!r1:a",
"state_key": "@u3:a",
"event_id": "$e2:a",
"content": {"membership": "knock"},
"unsigned": {
"not_allowed": "Sender is already joined"
}
},
{
"type": "m.room.member",
"sender": "@u5:a",
"room_id": "!r1:a",
"state_key": "@u5:a",
"event_id": "$e2:a",
"content": {"membership": "knock"},
"unsigned": {
"not_allowed": "Sender is banned"
}
}]
}`, RoomVersionV10)
}
Expand Down