From cf594bbeb2c5c14138b4f10d1406aafc02fcc1b8 Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Mon, 17 Dec 2018 12:43:06 +0100 Subject: [PATCH 3/6] =?UTF-8?q?d=C3=A9placement=20impl=C3=A9mentation=20cl?= =?UTF-8?q?ean=5Fdeleted=5Fusers=20(=C3=A0=20fixuper)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/test_users.py | 4 ++-- wcs/publisher.py | 6 ++++++ wcs/sql.py | 12 ++++++++++++ wcs/users.py | 24 ++++++++++++++---------- 4 files changed, 34 insertions(+), 12 deletions(-) diff --git a/tests/test_users.py b/tests/test_users.py index 6f6f2a29..82025fdb 100644 --- a/tests/test_users.py +++ b/tests/test_users.py @@ -7,7 +7,7 @@ import time import pytest -from quixote import cleanup +from quixote import cleanup, get_publisher from wcs import publisher from wcs import fields @@ -111,7 +111,7 @@ def test_clean_deleted_users(): assert User.count() == 2 - User.clean_deleted_users() + get_publisher().clean_deleted_users() assert User.count() == 1 assert len(User.select([st.Equal('name', 'Pierre')])) == 1 diff --git a/wcs/publisher.py b/wcs/publisher.py index 3880e182..d0f2590d 100644 --- a/wcs/publisher.py +++ b/wcs/publisher.py @@ -115,6 +115,7 @@ class WcsPublisher(StubWcsPublisher): super(WcsPublisher, cls).register_cronjobs() # every hour: check for global action timeouts cls.register_cronjob(CronJob(cls.apply_global_action_timeouts, hourly=True)) + cls.register_cronjob(CronJob(cls.clean_deleted_users, hourly=True)) def is_using_postgresql(self): return bool(self.has_site_option('postgresql') and self.cfg.get('postgresql', {})) @@ -309,6 +310,11 @@ class WcsPublisher(StubWcsPublisher): import sql sql.cleanup_connection() + def clean_deleted_users(self): + for user_id in self.user_class.get_to_delete_ids(): + self.user_class.remove_object(user_id) + + set_publisher_class(WcsPublisher) WcsPublisher.register_extra_dir(os.path.join(os.path.dirname(__file__), 'extra')) diff --git a/wcs/sql.py b/wcs/sql.py index 315d508a..7ff45dc8 100644 --- a/wcs/sql.py +++ b/wcs/sql.py @@ -1794,6 +1794,18 @@ class SqlUser(SqlMixin, wcs.users.User): return objects + @classmethod + def get_to_delete_ids(cls): + from .formdef import FormDef + + deleted_ids = set(str(user.id) for user in cls.select([Equal('deleted', True)])) + for formdef in FormDef.select(): + for formdata in formdef.data_class().select([Contains('user_id', deleted_ids)], iterator=True): + user_id = str(formdata.user_id) + if user_id in deleted_ids: + deleted_ids.remove(str(formdata.user_id)) + return deleted_ids + class Session(SqlMixin, wcs.sessions.BasicSession): _table_name = 'sessions' diff --git a/wcs/users.py b/wcs/users.py index 04fab6d8..18e304d1 100644 --- a/wcs/users.py +++ b/wcs/users.py @@ -227,12 +227,20 @@ class User(StorableObject): return self.display_name @classmethod - def clean_deleted_users(cls): - # really delete users without any form - if get_publisher().is_using_postgresql(): - cls.clean_deleted_users_sql() - else: - cls.clean_deleted_users_pickle() + def get_to_delete_ids(cls): + from .formdef import FormDef + + deleted_ids = set(str(user.id) for user in cls.select([st.Equal('deleted', True)])) + for formdef in FormDef.select(): + data_class = formdef.data_class() + formdatas = data_class.select( + [st.Contains('user_id', deleted_ids)], + iterator=True) + for formdata in formdatas: + user_id = str(formdata.user_id) + if user_id in deleted_ids: + deleted_ids.remove(str(formdata.user_id)) + return deleted_ids @classmethod def clean_deleted_users_sql(cls): @@ -268,7 +276,3 @@ class User(StorableObject): Substitutions.register('session_user_display_name', category=N_('User'), comment=N_('Session User Display Name')) Substitutions.register('session_user_email', category=N_('User'), comment=N_('Session User Email')) Substitutions.register_dynamic_source(User) - -if get_publisher_class(): - # clean deleted users hourly - get_publisher_class().register_cronjob(CronJob(User.clean_deleted_users, minutes=[20], hours=[6])) -- 2.18.0