From 9188da5fa14d2c2861df72f09cbd12ee8dbf2245 Mon Sep 17 00:00:00 2001
From: Paul Marillonnet <pmarillonnet@entrouvert.com>
Date: Wed, 14 Nov 2018 11:04:13 +0100
Subject: [PATCH] warn user after account self-deletion (#26910)

---
 src/authentic2/registration_backend/views.py     |  1 +
 .../account_delete_notification_body.html        | 11 +++++++++++
 .../account_delete_notification_body.txt         |  6 ++++++
 .../account_delete_notification_subject.txt      |  1 +
 src/authentic2/utils.py                          | 16 ++++++++++++++++
 tests/test_views.py                              |  4 +++-
 6 files changed, 38 insertions(+), 1 deletion(-)
 create mode 100644 src/authentic2/templates/authentic2/account_delete_notification_body.html
 create mode 100644 src/authentic2/templates/authentic2/account_delete_notification_body.txt
 create mode 100644 src/authentic2/templates/authentic2/account_delete_notification_subject.txt

diff --git a/src/authentic2/registration_backend/views.py b/src/authentic2/registration_backend/views.py
index f56b18f2..2d3e73a5 100644
--- a/src/authentic2/registration_backend/views.py
+++ b/src/authentic2/registration_backend/views.py
@@ -389,6 +389,7 @@ class DeleteView(FormView):
         return kwargs
 
     def form_valid(self, form):
+        utils.send_account_deletion_mail(self.request, self.request.user)
         models.DeletedUser.objects.delete_user(self.request.user)
         self.request.user.email += '#%d' % random.randint(1, 10000000)
         self.request.user.email_verified = False
diff --git a/src/authentic2/templates/authentic2/account_delete_notification_body.html b/src/authentic2/templates/authentic2/account_delete_notification_body.html
new file mode 100644
index 00000000..997bbf22
--- /dev/null
+++ b/src/authentic2/templates/authentic2/account_delete_notification_body.html
@@ -0,0 +1,11 @@
+{% load i18n %}
+<html>
+  <body style="max-width: 90ex">
+    {% blocktrans %}
+        <p>{{ full_name }},</p>
+        <p>Your account on {{ site }} has been deleted.
+        All related data will be deleted today.
+        You cannot log in with it anymore.</p>
+    {% endblocktrans %}
+  </body>
+</html>
diff --git a/src/authentic2/templates/authentic2/account_delete_notification_body.txt b/src/authentic2/templates/authentic2/account_delete_notification_body.txt
new file mode 100644
index 00000000..06789bbb
--- /dev/null
+++ b/src/authentic2/templates/authentic2/account_delete_notification_body.txt
@@ -0,0 +1,6 @@
+{% load i18n %}{% autoescape off %}{% blocktrans %}{{ full_name }},
+
+Your account on {{ site }} has been deleted.
+All related data will be deleted today.
+You cannot log in with it anymore.
+{% endblocktrans %}{% endautoescape %}
diff --git a/src/authentic2/templates/authentic2/account_delete_notification_subject.txt b/src/authentic2/templates/authentic2/account_delete_notification_subject.txt
new file mode 100644
index 00000000..fcd51d65
--- /dev/null
+++ b/src/authentic2/templates/authentic2/account_delete_notification_subject.txt
@@ -0,0 +1 @@
+{% load i18n %}{% autoescape off %}{% trans "Account deletion request on" %} {{ site }}{% endautoescape %}
diff --git a/src/authentic2/utils.py b/src/authentic2/utils.py
index 486cf915..e91f7582 100644
--- a/src/authentic2/utils.py
+++ b/src/authentic2/utils.py
@@ -698,6 +698,22 @@ def send_registration_mail(request, email, ou, template_names=None, next_url=Non
                 registration_url)
 
 
+def send_account_deletion_mail(request, user):
+    '''Send an account deletion notification mail to an user.
+
+       Can raise an smtplib.SMTPException
+    '''
+    logger = logging.getLogger(__name__)
+    context = {
+        'full_name': user.get_full_name(),
+        'site': request.get_host()}
+    template_names = [
+        'authentic2/account_delete_notification_%s' % user.ou,
+        'authentic2/account_delete_notification']
+    send_templated_mail(user.email, template_names, context, request=request)
+    logger.info(u'account deletion mail sent to %s', user.email)
+
+
 def build_reset_password_url(user, request=None, next_url=None, set_random_password=True):
     '''Build a reset password URL'''
     from .compat import default_token_generator
diff --git a/tests/test_views.py b/tests/test_views.py
index 1963564e..3b23d4e6 100644
--- a/tests/test_views.py
+++ b/tests/test_views.py
@@ -20,14 +20,16 @@ def test_password_change(app, simple_user):
     page = page.form.submit('cancel').follow()
 
 
-def test_account_delete(app, simple_user):
+def test_account_delete(app, simple_user, mailoutbox):
     assert simple_user.is_active
+    assert not len(mailoutbox)
     page = login(app, simple_user, path=reverse('delete_account'))
     page.form.set('password', simple_user.username)
     # FIXME: webtest does not set the Referer header, so the logout page will always ask for
     # confirmation under tests
     response = page.form.submit(name='submit').follow()
     response = response.form.submit()
+    assert len(mailoutbox) == 1
     assert not User.objects.get(pk=simple_user.pk).is_active
     assert urlparse(response.location).path == '/'
     response = response.follow().follow()
-- 
2.20.1

