-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Conversation
self.other_user_id = self.register_user("otheruser", "pass") | ||
self.other_access_token = self.login("otheruser", "pass") | ||
|
||
def test_invite(self): |
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.
Looks like these tests have failed once or twice intermittently? I have no idea why though. They're timing out.
(Originally mentioned this on #8034 (comment))
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 still need to look deeper into this.
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.
hrm, a few bits and bobs here.
I have a concern though. We are making up REST responses deep in the handler layer, where it is impossible to know which REST endpoint led to that path, and even where it is possible to figure it out, we'll forget about updating these codepaths when we decide to update the shape of the REST response.
We should be faking up the REST bodies close to where we are building the regular REST bodies. it may be appropriate to do so by catching ShadowBanError
s, in which case we should document each function that can raise a ShadowBanError
and trace them up the call stack.
Co-authored-by: Richard van der Hoff <[email protected]>
I agree that this will probably be clearer! I'll re-worker this. I think the current approach was chosen to avoid a bunch of try-excepts where the except essentially converts the |
Looking more deeply at this, I think it is still the proper thing to do, but it does bubble up through a lot of methods. |
I believe this fixes matrix-org/matrix-spec-proposals#789 (or at least makes most of it irrelevant) |
I believe this is ready for another review! Sorry that this grew quite a bit. Note that I wonder if we should add similar guards to |
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 suspect we need some logging when we do a "fake" response, partly so that we can see if we're seeing requests from shadow-banned users, but also because otherwise we're going to be confused when a user's requests unexpectedly do nothing.
@@ -1171,8 +1190,25 @@ async def shutdown_room( | |||
if not await self.store.get_room(room_id): | |||
raise NotFoundError("Unknown room id %s" % (room_id,)) | |||
|
|||
# Check if the user is shadow-banned before any mutations occur. |
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.
given this can only be called by an admin user, I think it might be a bit redundant to check the shadow-ban.
|
||
ShadowBanError: if the requester is shadow-banned. |
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.
is this coming from _update_canonical_alias
? should maybe just ignore the exception if so, as we do with AuthError.
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.
also: would be nice to stick the Raises
docstring on _update_canonical_alias
, even though it's internal.
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'm afraid I'm struggling to follow all of this, and I'm not convinced that all of the code flows have been considered. What happens, for example, if a shadow-banned account is deactivated?
It might be easier to break this up: first land the changes to get the shadow_banned
flag into Requester
in one PR. Then add a raise ShadowBanError
in one place and chase it up through the code, considering the correct behaviour on each path.
Sorry I know that's a load of work but I feel like this is currently a feature which will only work with one very specific set of configuration settings.
|
||
Raises: | ||
ShadowBanError if the requester is shadow-banned. |
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.
Again: what is the code path by which this happens? Is it just the final PL send? we should maybe ignore the exception there rather than allow it to propagate? or bail out sooner?
@@ -281,6 +288,31 @@ async def update_membership( | |||
content: Optional[dict] = None, | |||
require_consent: bool = True, | |||
) -> Tuple[str, int]: | |||
"""Update a user's membership in a room. |
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 note that this is used by auto-join rooms when registering. Does that mean that any server that has auto-join rooms will 500 on registration for a shadow-banned user?
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.
This change was already merged in #8095, which I think makes it clearer that this only affects invites, so it shouldn't cause an issue for auto-join rooms. (Unless I'm missing what the concern was here.)
# Since the requester can get overwritten below, check if the real | ||
# requester is shadow-banned. | ||
if requester.shadow_banned: | ||
# We randomly sleep a bit just to annoy the requester a bit. | ||
await self.clock.sleep(random.randint(1, 10)) | ||
raise ShadowBanError() | ||
|
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'm not sure if this is necessary. Shouldn't we let shadow-banned users change their displaynames if they want? It won't make it into any rooms thanks to the check in update_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.
Hm....I was under the impression it would still end up in the room, but I think you're right. I'll need to test this.
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.
So the changes to update_membership
won't catch this because those only apply to invite
requests.
This sounds like a tractable way to move forward with this. I suspect it would cleaner to start with a new pull request, but would be curious of your thoughts here! |
so do I... |
This has been split out into individual parts, so I'm going to close this. |
Shadow banned users are able to interact with the CS API (and receive "200 OK" responses), but the state changes aren't stored in the room.
It is worth noting that this PR doesn't give a way to mark users as shadow banned, it would need to be done manually in the database. There are follow-ups that will help here.
The majority of this PR is by @erikjohnston, I've fixed up some formatting and added tests.