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

Part user from rooms on account deactivate #3201

Merged
merged 8 commits into from
May 14, 2018
Merged
Show file tree
Hide file tree
Changes from 5 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
51 changes: 49 additions & 2 deletions synapse/handlers/deactivate_account.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# Copyright 2017 New Vector Ltd
# Copyright 2017, 2018 New Vector Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand All @@ -12,9 +12,11 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from twisted.internet import defer
from twisted.internet import defer, reactor

from ._base import BaseHandler
from synapse.types import UserID, create_requester
from synapse.util.logcontext import run_in_background

import logging

Expand All @@ -27,6 +29,11 @@ def __init__(self, hs):
super(DeactivateAccountHandler, self).__init__(hs)
self._auth_handler = hs.get_auth_handler()
self._device_handler = hs.get_device_handler()
self._room_member_handler = hs.get_room_member_handler()

self._user_parter_running = False

reactor.callWhenRunning(self._start_user_parting)

@defer.inlineCallbacks
def deactivate_account(self, user_id):
Expand All @@ -50,3 +57,43 @@ def deactivate_account(self, user_id):

yield self.store.user_delete_threepids(user_id)
yield self.store.user_set_password_hash(user_id, None)

yield self.store.add_user_pending_deactivation(user_id)

self._start_user_parting()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we comment about what this is and why we're doing it?


def _start_user_parting(self):
if not self._user_parter_running:
run_in_background(self._user_parter_loop())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be run_in_background(self._user_parter_loop)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oops, good spot


@defer.inlineCallbacks
def _user_parter_loop(self):
self._user_parter_running = True
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Short docstring pls

logger.info("Starting user parter")
try:
while True:
user_id = yield self.store.get_user_pending_deactivation()
if user_id is None:
break
logger.info("User parter parting %r", user_id)
yield self._part_user(user_id)
yield self.store.del_user_pending_deactivation(user_id)
logger.info("User parter finished parting %r", user_id)
logger.info("User parter finished: stopping")
finally:
self._user_parter_running = False

@defer.inlineCallbacks
def _part_user(self, user_id):
user = UserID.from_string(user_id)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Short docstring pls


rooms_for_user = yield self.store.get_rooms_for_user(user_id)
for room_id in rooms_for_user:
logger.info("User parter parting %r from %r", user_id, room_id)
yield self._room_member_handler.update_membership(
create_requester(user),
user,
room_id,
"leave",
ratelimit=False,
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this throws an exception then we're going to be stuck constantly trying to retry this. We should probably catch the exception, log loudly and move on maybe? Or something?

27 changes: 27 additions & 0 deletions synapse/storage/registration.py
Original file line number Diff line number Diff line change
Expand Up @@ -526,3 +526,30 @@ def insert(txn):
except self.database_engine.module.IntegrityError:
ret = yield self.get_3pid_guest_access_token(medium, address)
defer.returnValue(ret)

def add_user_pending_deactivation(self, user_id):
return self._simple_insert(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Docstring pls

"users_pending_deactivation",
values={
"user_id": user_id,
},
desc="add_user_pending_deactivation",
)

def del_user_pending_deactivation(self, user_id):
return self._simple_delete_one(
"users_pending_deactivation",
keyvalues={
"user_id": user_id,
},
desc="del_user_pending_deactivation",
)

def get_user_pending_deactivation(self):
return self._simple_select_one_onecol(
"users_pending_deactivation",
keyvalues={},
retcol="user_id",
allow_none=True,
desc="get_users_pending_deactivation",
)
25 changes: 25 additions & 0 deletions synapse/storage/schema/delta/48/deactivated_users.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/* Copyright 2018 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/*
* Store any accounts that have been requested to be deactivated.
* We part the account from all the rooms its in when its
* deactivated. This can take some time and synapse may be restarted
* before it completes, so store the user IDs here until the process
* is complete.
*/
CREATE TABLE users_pending_deactivation (
user_id TEXT NOT NULL
);