@@ -1146,6 +1146,13 @@ func (m *membershipAllower) membershipAllowedSelf() error { // nolint: gocyclo
11461146 return nil
11471147 }
11481148
1149+ // If the sender is banned, reject, as they can not change their own ban status.
1150+ if m .oldMember .Membership == spec .Ban {
1151+ return m .membershipFailed (
1152+ "sender cannot set their own membership to %q" , m .newMember .Membership ,
1153+ )
1154+ }
1155+
11491156 switch m .newMember .Membership {
11501157 case spec .Knock :
11511158 if m .joinRule .JoinRule != spec .Knock && m .joinRule .JoinRule != spec .KnockRestricted {
@@ -1162,15 +1169,15 @@ func (m *membershipAllower) membershipAllowedSelf() error { // nolint: gocyclo
11621169 // Spec: https://github.com/matrix-org/matrix-spec-proposals/pull/3787
11631170 return m .roomVersionImpl .CheckKnockingAllowed (m )
11641171 case spec .Join :
1165- if m .oldMember . Membership == spec . Leave && ( m . joinRule .JoinRule == spec .Restricted || m .joinRule .JoinRule == spec .KnockRestricted ) {
1172+ if m .joinRule .JoinRule == spec .Restricted || m .joinRule .JoinRule == spec .KnockRestricted {
11661173 if err := m .membershipAllowedSelfForRestrictedJoin (); err != nil {
11671174 return err
11681175 }
1169- }
1170- // A user that is not in the room is allowed to join if the room
1171- // join rules are "public".
1172- if m . oldMember . Membership == spec . Leave && m . joinRule . JoinRule == spec . Public {
1173- return nil
1176+ // If, after validating restricted joins, the room is now "public", allow.
1177+ // This means that transitions from knock|invite|leave to join are allowed.
1178+ if m . joinRule . JoinRule == spec . Public {
1179+ return nil
1180+ }
11741181 }
11751182 // An invited user is always allowed to join, regardless of the join rule
11761183 if m .oldMember .Membership == spec .Invite {
@@ -1180,6 +1187,13 @@ func (m *membershipAllower) membershipAllowedSelf() error { // nolint: gocyclo
11801187 if m .oldMember .Membership == spec .Join {
11811188 return nil
11821189 }
1190+
1191+ // A user that is not in the room is allowed to join if the room
1192+ // join rules are "public".
1193+ if m .oldMember .Membership == spec .Leave && m .joinRule .JoinRule == spec .Public {
1194+ return nil
1195+ }
1196+
11831197 return m .membershipFailed (
11841198 "join rule %q forbids it" , m .joinRule .JoinRule ,
11851199 )
@@ -1231,7 +1245,7 @@ func disallowKnocking(m *membershipAllower) error {
12311245}
12321246
12331247func checkKnocking (m * membershipAllower ) error {
1234- supported := m .joinRule .JoinRule == spec .Restricted || m .joinRule .JoinRule == spec .KnockRestricted
1248+ supported := m .joinRule .JoinRule == spec .Knock || m . joinRule . JoinRule == spec . Restricted || m .joinRule .JoinRule == spec .KnockRestricted
12351249 if ! supported {
12361250 return m .membershipFailed (
12371251 "room version %q does not support knocking on rooms with join rule %q" ,
0 commit comments