-
Couldn't load subscription status.
- Fork 61
Fix flawed membership checks and align membership checking patterns #813
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
base: main
Are you sure you want to change the base?
Fix flawed membership checks and align membership checking patterns #813
Conversation
Same fix as applied in #808
| charlie.MustSyncUntil(t, client.SyncReq{}, client.SyncTimelineHas( | ||
| room, | ||
| func(ev gjson.Result) bool { | ||
| if ev.Get("type").Str != "m.room.member" || ev.Get("state_key").Str != bob.UserID { | ||
| return false | ||
| } | ||
| must.Equal(t, ev.Get("sender").Str, bob.UserID, "Bob should have joined by himself") | ||
| must.Equal(t, ev.Get("content").Get("membership").Str, "join", "Bob failed to join the room") | ||
|
|
||
| return true | ||
| }, | ||
| )) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Previous flawed check.
Our goal is to wait until bob is joined. Previously, this waited for any bob membership (which could have been the invite instead of the join which we're waiting for) and then asserted that it must be a join.
| bob.MustSyncUntil(t, client.SyncReq{}, client.SyncTimelineHas( | ||
| room, | ||
| func(ev gjson.Result) bool { | ||
| if ev.Get("type").Str != "m.room.member" || ev.Get("state_key").Str != charlie.UserID { | ||
| return false | ||
| } | ||
| must.MatchGJSON(t, ev, | ||
| match.JSONKeyEqual("content.membership", "join"), | ||
| match.JSONKeyEqual("content.join_authorised_via_users_server", alice.UserID), | ||
| ) | ||
| return true | ||
| }, | ||
| )) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Previous flawed check.
Our goal is to wait until charlie is joined. Previously, this waited for any charlie membership (which could have been the leave instead of the join which we're waiting for) and then asserted that it must be a join.
| // We assume the passively observing client user is joined to the room | ||
| roomTypeKey := "join" | ||
| // Otherwise, if the client is the user whose membership we are checking, we need to | ||
| // pick the correct room type JSON key based on the membership being checked. | ||
| if clientUserID == userID { | ||
| if membership == "join" { | ||
| roomTypeKey = "join" | ||
| } else if membership == "leave" || membership == "ban" { | ||
| roomTypeKey = "leave" | ||
| } else if membership == "invite" { | ||
| roomTypeKey = "invite" | ||
| } else if membership == "knock" { | ||
| roomTypeKey = "knock" | ||
| } else { | ||
| return fmt.Errorf("syncMembershipIn(%s, %s): unknown membership: %s", roomID, membership, membership) | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| if ev.Get("type").Str != "m.room.member" || ev.Get("state_key").Str != bob.UserID { | ||
| return false | ||
| } | ||
| must.Equal(t, ev.Get("sender").Str, bob.UserID, "Bob should have joined by himself") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've dropped this assertion as it doesn't matter to this test. You can only join yourself to a room (there is no other way).
| return true | ||
| }, | ||
| )) | ||
| bob.MustSyncUntil(t, client.SyncReq{}, client.SyncJoinedTo(bob.UserID, roomID)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've double-checked the translation is correct for all of these updates:
- The client syncing
- The user we're checking
- The membership being checked
| bob.MustSyncUntil(t, client.SyncReq{}, client.SyncTimelineHas( | ||
| roomID, | ||
| func(ev gjson.Result) bool { | ||
| if ev.Get("type").Str != "m.room.member" || ev.Get("state_key").Str != bob.UserID { | ||
| return false | ||
| } | ||
| must.Equal(t, ev.Get("content").Get("membership").Str, "join", "Bob failed to join the room") | ||
| return true | ||
| }, | ||
| )) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any of these client.SyncTimelineHas(...) checks where we check until we see a certain event type and then use an assert for the membership are bad form.
While, it works well in some tests like this specific one, that's only because the user doesn't have any other previous membership in the room to be confused with. If there was any other previous membership for this user, this is flawed (see #813 (comment) as an example).
Instead of leaving these around to be copy-pasted and cargo-culted around, I've updated all of them to use the more proper assertion check.
| bob.MustSyncUntil(t, client.SyncReq{}, client.SyncTimelineHas( | ||
| roomID, | ||
| func(ev gjson.Result) bool { | ||
| return ev.Get("type").Str == "m.room.member" && | ||
| ev.Get("content.membership").Str == "leave" && | ||
| ev.Get("state_key").Str == alice.UserID | ||
| }, | ||
| )) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For reference, this kind of check was just fine. We return false until we find a leave membership for the user. While fine, I've updated it to use the more proper utility we have for this.
(notice the difference to the above bad form assertion)
Spawning from #808 per my suggestion on #808 (comment),
We have other spots that have flawed membership checks that need to be fixed. For example, when our goal is to wait for the user's membership to be
leave, we should keep checking until it isleave. Currently, there are some spots that wait until any membership exists for the user and then assertsleaveon that which is flawed because that user may have previous membership events that may be picked up first instead of waiting for theleave.This PR fixes those flawed checks and aligns our membership checks so we don't cargo cult this bad pattern elsewhere.
client.SyncXXXhelpers to usesyncMembershipInutilitycheckson event (previously, only available withclient.SyncJoinedTo)client.SyncBannedFromso we can differentiate ban/leaveDev notes
30rooms/22profiletest #511Pull Request Checklist
Signed-off-by: Eric Eastwood [email protected]