-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Fix adding excluded users to the private room sharing tables when joining a room #11143
Changes from all commits
ed6bcec
60587bd
6b19eda
2a3c396
6238017
00c5d9e
56809e9
67f6373
02354e5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| Fix a long-standing bug where users excluded from the directory could still be added to the `users_who_share_private_rooms` table after a regular user joins a private room. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -646,22 +646,20 @@ def test_private_room(self) -> None: | |
| u2_token = self.login(u2, "pass") | ||
| u3 = self.register_user("user3", "pass") | ||
|
|
||
| # We do not add users to the directory until they join a room. | ||
| # u1 can't see u2 until they share a private room, or u1 is in a public room. | ||
| s = self.get_success(self.handler.search_users(u1, "user2", 10)) | ||
| self.assertEqual(len(s["results"]), 0) | ||
|
|
||
| # Get u1 and u2 into a private room. | ||
| room = self.helper.create_room_as(u1, is_public=False, tok=u1_token) | ||
| self.helper.invite(room, src=u1, targ=u2, tok=u1_token) | ||
| self.helper.join(room, user=u2, tok=u2_token) | ||
|
|
||
| # Check we have populated the database correctly. | ||
| shares_private = self.get_success( | ||
| self.user_dir_helper.get_users_who_share_private_rooms() | ||
| ) | ||
| public_users = self.get_success( | ||
| self.user_dir_helper.get_users_in_public_rooms() | ||
| users, public_users, shares_private = self.get_success( | ||
| self.user_dir_helper.get_tables() | ||
| ) | ||
|
|
||
| self.assertEqual(users, {u1, u2, u3}) | ||
| self.assertEqual(shares_private, {(u1, u2, room), (u2, u1, room)}) | ||
| self.assertEqual(public_users, set()) | ||
|
|
||
|
|
@@ -680,14 +678,11 @@ def test_private_room(self) -> None: | |
| # User 2 then leaves. | ||
| self.helper.leave(room, user=u2, tok=u2_token) | ||
|
|
||
| # Check we have removed the values. | ||
| shares_private = self.get_success( | ||
| self.user_dir_helper.get_users_who_share_private_rooms() | ||
| ) | ||
| public_users = self.get_success( | ||
| self.user_dir_helper.get_users_in_public_rooms() | ||
| # Check this is reflected in the DB. | ||
| users, public_users, shares_private = self.get_success( | ||
| self.user_dir_helper.get_tables() | ||
| ) | ||
|
|
||
| self.assertEqual(users, {u1, u2, u3}) | ||
| self.assertEqual(shares_private, set()) | ||
| self.assertEqual(public_users, set()) | ||
|
|
||
|
|
@@ -698,6 +693,50 @@ def test_private_room(self) -> None: | |
| s = self.get_success(self.handler.search_users(u1, "user3", 10)) | ||
| self.assertEqual(len(s["results"]), 0) | ||
|
|
||
| def test_joining_private_room_with_excluded_user(self) -> None: | ||
| """ | ||
| When a user excluded from the user directory, E say, joins a private | ||
| room, E will not appear in the `users_who_share_private_rooms` table. | ||
|
|
||
| When a normal user, U say, joins a private room containing E, then | ||
| U will appear in the `users_who_share_private_rooms` table, but E will | ||
| not. | ||
| """ | ||
| # Setup a support and two normal users. | ||
| alice = self.register_user("alice", "pass") | ||
| alice_token = self.login(alice, "pass") | ||
| bob = self.register_user("bob", "pass") | ||
| bob_token = self.login(bob, "pass") | ||
| support = "@support1:test" | ||
| self.get_success( | ||
| self.store.register_user( | ||
| user_id=support, password_hash=None, user_type=UserTypes.SUPPORT | ||
|
Comment on lines
+710
to
+713
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is it valid to register using a full user ID?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is cribbed from old tests, see e.g. here which I think is circa three years old. I still don't really know how support users get created in actual usage. (If it's "make a normal user, then mark them as support in the DB", they'll get added to the directory on registration and then not removed when made support.)
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah I see. I did not notice you were using I think (hope) that support users are born that way (e.g. using a CLI flag, or an admin GUI tool that will do shared-secret registration?): Maybe we should one day extend Happy for you to leave as-is if you like though |
||
| ) | ||
| ) | ||
|
|
||
| # Alice makes a room. Inject the support user into the room. | ||
| room = self.helper.create_room_as(alice, is_public=False, tok=alice_token) | ||
| self.get_success(inject_member_event(self.hs, room, support, "join")) | ||
|
Comment on lines
+718
to
+719
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In keeping with remark above, I would probably prefer to do the invite & join dance rather than injecting the event (as surely the support user is a local user?). Maybe I'm being a hypocrite and we already do this nearby? :P
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Not a hypocrite. I do this elsewhere, but only because I don't know how to do better (as in the other comment). I could use an appservice user instead. They're easy enough to register. (Though there is talk of not excluding AS users in the future..._
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Leaving it at a support user seems sensible. You can try (these helpers sometimes work without access tokens. I'm not sure what the conditions are for that (seems to be controlled by a flag
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I do this in a few places when trying to test room joins etc from support and deactivated users. But that's only because I didn't know how to do it better.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
No bueno I'm afraid: I think that hijack mechanism only kicks in for one nominated user on the test case class. So I think it might be best to (regrettably) leave this as it is for now.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fair enough! Thanks for entertaining it anyway :) |
||
| # Check the DB state. The support user should not be in the directory. | ||
| users, in_public, in_private = self.get_success( | ||
| self.user_dir_helper.get_tables() | ||
| ) | ||
| self.assertEqual(users, {alice, bob}) | ||
| self.assertEqual(in_public, set()) | ||
| self.assertEqual(in_private, set()) | ||
|
|
||
| # Then invite Bob, who accepts. | ||
| self.helper.invite(room, alice, bob, tok=alice_token) | ||
| self.helper.join(room, bob, tok=bob_token) | ||
|
|
||
| # Check the DB state. The support user should not be in the directory. | ||
| users, in_public, in_private = self.get_success( | ||
| self.user_dir_helper.get_tables() | ||
| ) | ||
| self.assertEqual(users, {alice, bob}) | ||
| self.assertEqual(in_public, set()) | ||
| self.assertEqual(in_private, {(alice, bob, room), (bob, alice, room)}) | ||
|
|
||
| def test_spam_checker(self) -> None: | ||
| """ | ||
| A user which fails the spam checks will not appear in search results. | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.