mirror of
https://git.anonymousland.org/anonymousland/synapse.git
synced 2025-05-03 00:44:49 -04:00
Track deactivated accounts in the database (#5378)
This commit is contained in:
parent
f03f8b7f4c
commit
d0530382ee
5 changed files with 183 additions and 0 deletions
|
@ -15,6 +15,7 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import logging
|
||||
import re
|
||||
|
||||
from six import iterkeys
|
||||
|
@ -31,6 +32,8 @@ from synapse.util.caches.descriptors import cached, cachedInlineCallbacks
|
|||
|
||||
THIRTY_MINUTES_IN_MS = 30 * 60 * 1000
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class RegistrationWorkerStore(SQLBaseStore):
|
||||
def __init__(self, db_conn, hs):
|
||||
|
@ -598,11 +601,75 @@ class RegistrationStore(
|
|||
"user_threepids_grandfather", self._bg_user_threepids_grandfather,
|
||||
)
|
||||
|
||||
self.register_background_update_handler(
|
||||
"users_set_deactivated_flag", self._backgroud_update_set_deactivated_flag,
|
||||
)
|
||||
|
||||
# Create a background job for culling expired 3PID validity tokens
|
||||
hs.get_clock().looping_call(
|
||||
self.cull_expired_threepid_validation_tokens, THIRTY_MINUTES_IN_MS,
|
||||
)
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def _backgroud_update_set_deactivated_flag(self, progress, batch_size):
|
||||
"""Retrieves a list of all deactivated users and sets the 'deactivated' flag to 1
|
||||
for each of them.
|
||||
"""
|
||||
|
||||
last_user = progress.get("user_id", "")
|
||||
|
||||
def _backgroud_update_set_deactivated_flag_txn(txn):
|
||||
txn.execute(
|
||||
"""
|
||||
SELECT
|
||||
users.name,
|
||||
COUNT(access_tokens.token) AS count_tokens,
|
||||
COUNT(user_threepids.address) AS count_threepids
|
||||
FROM users
|
||||
LEFT JOIN access_tokens ON (access_tokens.user_id = users.name)
|
||||
LEFT JOIN user_threepids ON (user_threepids.user_id = users.name)
|
||||
WHERE password_hash IS NULL OR password_hash = ''
|
||||
AND users.name > ?
|
||||
GROUP BY users.name
|
||||
ORDER BY users.name ASC
|
||||
LIMIT ?;
|
||||
""",
|
||||
(last_user, batch_size),
|
||||
)
|
||||
|
||||
rows = self.cursor_to_dict(txn)
|
||||
|
||||
if not rows:
|
||||
return True
|
||||
|
||||
rows_processed_nb = 0
|
||||
|
||||
for user in rows:
|
||||
if not user["count_tokens"] and not user["count_threepids"]:
|
||||
self.set_user_deactivated_status_txn(txn, user["user_id"], True)
|
||||
rows_processed_nb += 1
|
||||
|
||||
logger.info("Marked %d rows as deactivated", rows_processed_nb)
|
||||
|
||||
self._background_update_progress_txn(
|
||||
txn, "users_set_deactivated_flag", {"user_id": rows[-1]["user_id"]}
|
||||
)
|
||||
|
||||
if batch_size > len(rows):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
end = yield self.runInteraction(
|
||||
"users_set_deactivated_flag",
|
||||
_backgroud_update_set_deactivated_flag_txn,
|
||||
)
|
||||
|
||||
if end:
|
||||
yield self._end_background_update("users_set_deactivated_flag")
|
||||
|
||||
defer.returnValue(batch_size)
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def add_access_token_to_user(self, user_id, token, device_id=None):
|
||||
"""Adds an access token for the given user.
|
||||
|
@ -1268,3 +1335,50 @@ class RegistrationStore(
|
|||
"delete_threepid_session",
|
||||
delete_threepid_session_txn,
|
||||
)
|
||||
|
||||
def set_user_deactivated_status_txn(self, txn, user_id, deactivated):
|
||||
self._simple_update_one_txn(
|
||||
txn=txn,
|
||||
table="users",
|
||||
keyvalues={"name": user_id},
|
||||
updatevalues={"deactivated": 1 if deactivated else 0},
|
||||
)
|
||||
self._invalidate_cache_and_stream(
|
||||
txn, self.get_user_deactivated_status, (user_id,),
|
||||
)
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def set_user_deactivated_status(self, user_id, deactivated):
|
||||
"""Set the `deactivated` property for the provided user to the provided value.
|
||||
|
||||
Args:
|
||||
user_id (str): The ID of the user to set the status for.
|
||||
deactivated (bool): The value to set for `deactivated`.
|
||||
"""
|
||||
|
||||
yield self.runInteraction(
|
||||
"set_user_deactivated_status",
|
||||
self.set_user_deactivated_status_txn,
|
||||
user_id, deactivated,
|
||||
)
|
||||
|
||||
@cachedInlineCallbacks()
|
||||
def get_user_deactivated_status(self, user_id):
|
||||
"""Retrieve the value for the `deactivated` property for the provided user.
|
||||
|
||||
Args:
|
||||
user_id (str): The ID of the user to retrieve the status for.
|
||||
|
||||
Returns:
|
||||
defer.Deferred(bool): The requested value.
|
||||
"""
|
||||
|
||||
res = yield self._simple_select_one_onecol(
|
||||
table="users",
|
||||
keyvalues={"name": user_id},
|
||||
retcol="deactivated",
|
||||
desc="get_user_deactivated_status",
|
||||
)
|
||||
|
||||
# Convert the integer into a boolean.
|
||||
defer.returnValue(res == 1)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue