Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Reject pending invites on deactivation #6125

Merged
merged 10 commits into from
Sep 27, 2019
Merged
Show file tree
Hide file tree
Changes from 6 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
1 change: 1 addition & 0 deletions changelog.d/6125.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Reject all pending invite for a user during deactivation.
babolivier marked this conversation as resolved.
Show resolved Hide resolved
37 changes: 37 additions & 0 deletions synapse/handlers/deactivate_account.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,10 @@ def deactivate_account(self, user_id, erase_data, id_server=None):
# parts users from rooms (if it isn't already running)
self._start_user_parting()

# Reject all pending invites for the user, so that it doesn't show up in the
babolivier marked this conversation as resolved.
Show resolved Hide resolved
# invitees list of rooms.
babolivier marked this conversation as resolved.
Show resolved Hide resolved
yield self._reject_pending_invites_for_user(user_id)

# Remove all information on the user from the account_validity table.
if self._account_validity_enabled:
yield self.store.delete_account_validity_for_user(user_id)
Expand All @@ -129,6 +133,39 @@ def deactivate_account(self, user_id, erase_data, id_server=None):

return identity_server_supports_unbinding

@defer.inlineCallbacks
def _reject_pending_invites_for_user(self, user_id):
"""Reject pending invites addressed to a given user ID.

Args:
user_id (str): The user ID to reject pending invites for.
"""
user = UserID.from_string(user_id)
pending_invites = yield self.store.get_invited_rooms_for_user(user_id)

logger.info(pending_invites)
babolivier marked this conversation as resolved.
Show resolved Hide resolved

for room in pending_invites:
try:
yield self._room_member_handler.update_membership(
create_requester(user),
user,
room.room_id,
"leave",
ratelimit=False,
require_consent=False,
)
logger.info(
"Rejected invite for user %r in room %r", user_id, room.room_id
babolivier marked this conversation as resolved.
Show resolved Hide resolved
)
except Exception:
logger.exception(
"Failed to reject invite for user %r in room %r:"
babolivier marked this conversation as resolved.
Show resolved Hide resolved
" ignoring and continuing",
babolivier marked this conversation as resolved.
Show resolved Hide resolved
user_id,
room.room_id,
)

def _start_user_parting(self):
"""
Start the process that goes through the table of users
Expand Down
68 changes: 54 additions & 14 deletions tests/rest/client/v2_alpha/test_account.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
import pkg_resources

import synapse.rest.admin
from synapse.api.constants import LoginType
from synapse.rest.client.v1 import login
from synapse.api.constants import LoginType, Membership
from synapse.rest.client.v1 import login, room
from synapse.rest.client.v2_alpha import account, register

from tests import unittest
Expand Down Expand Up @@ -244,16 +244,66 @@ class DeactivateTestCase(unittest.HomeserverTestCase):
synapse.rest.admin.register_servlets_for_client_rest_resource,
login.register_servlets,
account.register_servlets,
room.register_servlets,
]

def make_homeserver(self, reactor, clock):
hs = self.setup_test_homeserver()
return hs
self.hs = self.setup_test_homeserver()
return self.hs

def test_deactivate_account(self):
user_id = self.register_user("kermit", "test")
tok = self.login("kermit", "test")

self.deactivate(user_id, tok)

store = self.hs.get_datastore()

# Check that the user has been marked as deactivated.
self.assertTrue(self.get_success(store.get_user_deactivated_status(user_id)))

# Check that this access token has been invalidated.
request, channel = self.make_request("GET", "account/whoami")
self.render(request)
self.assertEqual(request.code, 401)

@unittest.INFO
def test_pending_invites(self):
"""Tests that deactivating a user rejects every pending invite for them."""
store = self.hs.get_datastore()

inviter_id = self.register_user("inviter", "test")
inviter_tok = self.login("inviter", "test")

invitee_id = self.register_user("invitee", "test")
invitee_tok = self.login("invitee", "test")

# Make @inviter:test invite @invitee:test in a new room.
room_id = self.helper.create_room_as(inviter_id, tok=inviter_tok)
self.helper.invite(
room=room_id, src=inviter_id, targ=invitee_id, tok=inviter_tok
)

# Make sure the invite is here.
pending_invites = self.get_success(store.get_invited_rooms_for_user(invitee_id))
self.assertEqual(len(pending_invites), 1, pending_invites)
self.assertEqual(pending_invites[0].room_id, room_id, pending_invites)

# Deactivate @invitee:test.
self.deactivate(invitee_id, invitee_tok)

# Check that the invite isn't there anymore.
pending_invites = self.get_success(store.get_invited_rooms_for_user(invitee_id))
self.assertEqual(len(pending_invites), 0, pending_invites)

# Check that the membership of @invitee:test in the room is now "leave".
memberships = self.get_success(
store.get_rooms_for_user_where_membership_is(invitee_id, [Membership.LEAVE])
)
self.assertEqual(len(memberships), 1, memberships)
self.assertEqual(memberships[0].room_id, room_id, memberships)

def deactivate(self, user_id, tok):
request_data = json.dumps(
{
"auth": {
Expand All @@ -269,13 +319,3 @@ def test_deactivate_account(self):
)
self.render(request)
self.assertEqual(request.code, 200)

store = self.hs.get_datastore()

# Check that the user has been marked as deactivated.
self.assertTrue(self.get_success(store.get_user_deactivated_status(user_id)))

# Check that this access token has been invalidated.
request, channel = self.make_request("GET", "account/whoami")
self.render(request)
self.assertEqual(request.code, 401)