Projet

Général

Profil

0003-misc-do-no-clear-last_account_deletion_start-on-logi.patch

Benjamin Dauvergne, 03 avril 2020 12:29

Télécharger (5,48 ko)

Voir les différences:

Subject: [PATCH 3/3] misc: do no clear last_account_deletion_start on login
 (#41284)

 .../commands/clean-unused-accounts.py         | 46 +++++++++++--------
 src/authentic2/utils/__init__.py              |  2 -
 2 files changed, 28 insertions(+), 20 deletions(-)
src/authentic2/management/commands/clean-unused-accounts.py
21 21
from datetime import timedelta
22 22
from django.contrib.auth import get_user_model
23 23
from django.core.management.base import BaseCommand
24
from django.db.transaction import atomic
25
from django.db.models import F
24 26
from django.utils import timezone
25 27
from django.utils.six.moves.urllib import parse as urlparse
26 28
from django_rbac.utils import get_ou_model
......
59 61
        if self.fake:
60 62
            logger.propagate = False
61 63

  
64
        self.now = timezone.now()
62 65
        try:
63 66
            self.clean_unused_accounts()
64 67
        except Exception:
65 68
            logger.exception('clean-unused-accounts failed')
66 69

  
67 70
    def clean_unused_accounts(self):
68
        now = timezone.now()
69

  
70 71
        for ou in get_ou_model().objects.filter(clean_unused_accounts_alert__isnull=False):
71 72
            alert_delay = timedelta(days=ou.clean_unused_accounts_alert)
72 73
            deletion_delay = timedelta(days=ou.clean_unused_accounts_deletion)
73
            users = User.objects.filter(ou=ou, last_login__lte=now - alert_delay)
74
            ou_users = User.objects.filter(ou=ou)
75

  
76
            # reset last_account_deletion_alert for users which connected since last alert
77
            active_users = ou_users.filter(last_login__gte=F('last_account_deletion_alert'))
78
            active_users.update(last_account_deletion_alert=None)
79

  
80
            inactive_users = ou_users.filter(last_login__lte=self.now - alert_delay)
74 81

  
75
            for user in users.filter(last_account_deletion_alert__isnull=True):
82
            # send first alert
83
            inactive_users_first_alert = inactive_users.filter(last_account_deletion_alert__isnull=True)
84
            days_to_deletion = ou.clean_unused_accounts_deletion - ou.clean_unused_accounts_alert
85
            for user in inactive_users_first_alert:
76 86
                logger.info('%s last login %d days ago, sending alert', user, ou.clean_unused_accounts_alert)
77
                self.send_alert(user)
87
                self.send_alert(user, days_to_deletion)
78 88

  
79
            to_delete = users.filter(
80
                last_login__lte=now - deletion_delay,
89
            inactive_users_to_delete = inactive_users.filter(
90
                last_login__lte=self.now - deletion_delay,
81 91
                # ensure respect of alert delay before deletion
82
                last_account_deletion_alert__lte=now - (deletion_delay - alert_delay)
92
                last_account_deletion_alert__lte=self.now - (deletion_delay - alert_delay)
83 93
            )
84
            for user in to_delete:
94
            for user in inactive_users_to_delete:
85 95
                logger.info(
86 96
                    '%s last login more than %d days ago, deleting user', user,
87 97
                    ou.clean_unused_accounts_deletion)
88 98
                self.delete_user(user)
89 99

  
90
    def send_alert(self, user):
91
        days_to_deletion = user.ou.clean_unused_accounts_deletion - user.ou.clean_unused_accounts_alert
100
    def send_alert(self, user, days_to_deletion):
92 101
        ctx = {
93 102
            'user': user,
94 103
            'days_to_deletion': days_to_deletion,
95 104
            'login_url': urlparse.urljoin(settings.SITE_BASE_URL, settings.LOGIN_URL),
96 105
        }
97
        self.send_mail('authentic2/unused_account_alert', user, ctx)
98
        if not self.fake:
99
            user.last_account_deletion_alert = timezone.now()
100
            user.save()
106
        with atomic():
107
            if not self.fake:
108
                User.objects.filter(pk=user.pk).update(last_account_deletion_alert=self.now)
109
            self.send_mail('authentic2/unused_account_alert', user, ctx)
101 110

  
102 111
    def send_mail(self, prefix, user, ctx):
103 112
        if not user.email:
......
109 118

  
110 119
    def delete_user(self, user):
111 120
        ctx = {'user': user}
112
        self.send_mail('authentic2/unused_account_delete', user, ctx)
113
        if not self.fake:
114
            DeletedUser.objects.delete_user(user)
121
        with atomic():
122
            if not self.fake:
123
                DeletedUser.objects.delete_user(user)
124
            self.send_mail('authentic2/unused_account_delete', user, ctx)
src/authentic2/utils/__init__.py
437 437
    if constants.LAST_LOGIN_SESSION_KEY not in request.session:
438 438
        request.session[constants.LAST_LOGIN_SESSION_KEY] = \
439 439
            localize(to_current_timezone(last_login), True)
440
    user.last_account_deletion_alert = None
441
    user.save()
442 440
    record_authentication_event(request, how, nonce=nonce)
443 441
    hooks.call_hooks('event', name='login', user=user, how=how, service=service_slug)
444 442
    return continue_to_next_url(request, **kwargs)
445
-