From 8c88de475c95535fa26d9265e3ba498591827d0e Mon Sep 17 00:00:00 2001
From: Valentin Deniaud <vdeniaud@entrouvert.com>
Date: Wed, 16 Oct 2019 11:03:32 +0200
Subject: [PATCH 1/2] utils: handle per ou template in send_templated_mail
 (#35774)

---
 src/authentic2/utils/__init__.py              | 23 +++++++----
 src/django_rbac/test_settings.py              |  3 ++
 tests/settings.py                             |  4 ++
 .../templates/custom_mail_template_body.html  |  1 +
 tests/templates/custom_mail_template_body.txt |  1 +
 .../custom_mail_template_ou_name_body.html    |  1 +
 .../custom_mail_template_ou_name_body.txt     |  1 +
 .../custom_mail_template_ou_name_subject.txt  |  1 +
 .../custom_mail_template_subject.txt          |  1 +
 .../templates/default_mail_template_body.html |  1 +
 .../templates/default_mail_template_body.txt  |  1 +
 .../default_mail_template_ou_name_body.html   |  1 +
 .../default_mail_template_ou_name_body.txt    |  1 +
 .../default_mail_template_ou_name_subject.txt |  1 +
 .../default_mail_template_subject.txt         |  1 +
 tests/test_utils.py                           | 41 ++++++++++++++++++-
 16 files changed, 73 insertions(+), 10 deletions(-)
 create mode 100644 tests/templates/custom_mail_template_body.html
 create mode 100644 tests/templates/custom_mail_template_body.txt
 create mode 100644 tests/templates/custom_mail_template_ou_name_body.html
 create mode 100644 tests/templates/custom_mail_template_ou_name_body.txt
 create mode 100644 tests/templates/custom_mail_template_ou_name_subject.txt
 create mode 100644 tests/templates/custom_mail_template_subject.txt
 create mode 100644 tests/templates/default_mail_template_body.html
 create mode 100644 tests/templates/default_mail_template_body.txt
 create mode 100644 tests/templates/default_mail_template_ou_name_body.html
 create mode 100644 tests/templates/default_mail_template_ou_name_body.txt
 create mode 100644 tests/templates/default_mail_template_ou_name_subject.txt
 create mode 100644 tests/templates/default_mail_template_subject.txt

diff --git a/src/authentic2/utils/__init__.py b/src/authentic2/utils/__init__.py
index 5147915c..7e699ab0 100644
--- a/src/authentic2/utils/__init__.py
+++ b/src/authentic2/utils/__init__.py
@@ -613,7 +613,8 @@ def get_fields_and_labels(*args):
 
 def send_templated_mail(user_or_email, template_names, context=None, with_html=True,
                         from_email=None, request=None, legacy_subject_templates=None,
-                        legacy_body_templates=None, legacy_html_body_templates=None, **kwargs):
+                        legacy_body_templates=None, legacy_html_body_templates=None,
+                        per_ou_templates=False, **kwargs):
     '''Send mail to an user by using templates:
        - <template_name>_subject.txt for the subject
        - <template_name>_body.txt for the plain text body
@@ -622,6 +623,12 @@ def send_templated_mail(user_or_email, template_names, context=None, with_html=T
     from .. import middleware
     if isinstance(template_names, six.string_types):
         template_names = [template_names]
+    if per_ou_templates and getattr(user_or_email, 'ou', None):
+        new_template_names = []
+        for template in template_names:
+            new_template_names.append('_'.join((template, user_or_email.ou.slug)))
+            new_template_names.append(template)
+        template_names = new_template_names
     if hasattr(user_or_email, 'email'):
         user_or_email = user_or_email.email
     if not request:
@@ -645,6 +652,7 @@ def send_templated_mail(user_or_email, template_names, context=None, with_html=T
             html_body = render_to_string(html_body_template_names, ctx, request=request)
         except TemplateDoesNotExist:
             html_body = None
+
     send_mail(subject, body, from_email or settings.DEFAULT_FROM_EMAIL, [user_or_email],
               html_message=html_body, **kwargs)
 
@@ -751,9 +759,7 @@ def send_account_deletion_code(request, user):
         'deletion_url': deletion_url}
     template_names = [
         'authentic2/account_deletion_code']
-    if user.ou:
-        template_names.insert(0, 'authentic2/account_deletion_code_%s' % user.ou.slug)
-    send_templated_mail(user.email, template_names, context, request=request)
+    send_templated_mail(user, template_names, context, request=request, per_ou_templates=True)
     logger.info(u'account deletion code sent to %s', user.email)
 
 
@@ -769,9 +775,7 @@ def send_account_deletion_mail(request, user):
         'site': request.get_host()}
     template_names = [
         'authentic2/account_delete_notification']
-    if user.ou:
-        template_names.insert(0, 'authentic2/account_delete_notification_%s' % user.ou.slug)
-    send_templated_mail(user.email, template_names, context, request=request)
+    send_templated_mail(user, template_names, context, request=request, per_ou_templates=True)
     logger.info(u'account deletion mail sent to %s', user.email)
 
 
@@ -826,9 +830,10 @@ def send_password_reset_mail(user, template_names=None, request=None,
                                                        set_random_password=set_random_password,
                                                        sign_next_url=sign_next_url)
 
-    send_templated_mail(user.email, template_names, ctx, request=request,
+    send_templated_mail(user, template_names, ctx, request=request,
                         legacy_subject_templates=legacy_subject_templates,
-                        legacy_body_templates=legacy_body_templates, **kwargs)
+                        legacy_body_templates=legacy_body_templates,
+                        per_ou_templates=True, **kwargs)
     logger.info(u'password reset request for user %s, email sent to %s '
                 'with token %s', user, user.email, token[:9])
 
diff --git a/src/django_rbac/test_settings.py b/src/django_rbac/test_settings.py
index c6a520ac..68829a8c 100644
--- a/src/django_rbac/test_settings.py
+++ b/src/django_rbac/test_settings.py
@@ -21,6 +21,9 @@ INSTALLED_APPS = (
 
 ALLOWED_HOSTS = []
 
+BASE_DIR = os.path.dirname(__file__)
+TEMPLATES = [{'DIRS': []}]
+
 if 'AUTHENTIC2_SETTINGS_FILE' in os.environ:
     with open(os.environ['AUTHENTIC2_SETTINGS_FILE']) as fd:
         exec(fd.read())
diff --git a/tests/settings.py b/tests/settings.py
index 43402230..37d41837 100644
--- a/tests/settings.py
+++ b/tests/settings.py
@@ -40,3 +40,7 @@ if 'postgres' in DATABASES['default']['ENGINE']:
 
 
 ALLOWED_HOSTS = ALLOWED_HOSTS + ['example.net', 'cache1.example.com', 'cache2.example.com']
+
+BASE_TEST_DIR = os.path.join(os.path.dirname(os.path.dirname(BASE_DIR)), 'tests')
+
+TEMPLATES[0]['DIRS'].append(os.path.join(BASE_TEST_DIR, 'templates'))
diff --git a/tests/templates/custom_mail_template_body.html b/tests/templates/custom_mail_template_body.html
new file mode 100644
index 00000000..7e8f6650
--- /dev/null
+++ b/tests/templates/custom_mail_template_body.html
@@ -0,0 +1 @@
+custom_mail_template
\ No newline at end of file
diff --git a/tests/templates/custom_mail_template_body.txt b/tests/templates/custom_mail_template_body.txt
new file mode 100644
index 00000000..7e8f6650
--- /dev/null
+++ b/tests/templates/custom_mail_template_body.txt
@@ -0,0 +1 @@
+custom_mail_template
\ No newline at end of file
diff --git a/tests/templates/custom_mail_template_ou_name_body.html b/tests/templates/custom_mail_template_ou_name_body.html
new file mode 100644
index 00000000..1d862c54
--- /dev/null
+++ b/tests/templates/custom_mail_template_ou_name_body.html
@@ -0,0 +1 @@
+custom_mail_template_ou_name
\ No newline at end of file
diff --git a/tests/templates/custom_mail_template_ou_name_body.txt b/tests/templates/custom_mail_template_ou_name_body.txt
new file mode 100644
index 00000000..1d862c54
--- /dev/null
+++ b/tests/templates/custom_mail_template_ou_name_body.txt
@@ -0,0 +1 @@
+custom_mail_template_ou_name
\ No newline at end of file
diff --git a/tests/templates/custom_mail_template_ou_name_subject.txt b/tests/templates/custom_mail_template_ou_name_subject.txt
new file mode 100644
index 00000000..1d862c54
--- /dev/null
+++ b/tests/templates/custom_mail_template_ou_name_subject.txt
@@ -0,0 +1 @@
+custom_mail_template_ou_name
\ No newline at end of file
diff --git a/tests/templates/custom_mail_template_subject.txt b/tests/templates/custom_mail_template_subject.txt
new file mode 100644
index 00000000..7e8f6650
--- /dev/null
+++ b/tests/templates/custom_mail_template_subject.txt
@@ -0,0 +1 @@
+custom_mail_template
\ No newline at end of file
diff --git a/tests/templates/default_mail_template_body.html b/tests/templates/default_mail_template_body.html
new file mode 100644
index 00000000..369ecfe8
--- /dev/null
+++ b/tests/templates/default_mail_template_body.html
@@ -0,0 +1 @@
+default_mail_template
\ No newline at end of file
diff --git a/tests/templates/default_mail_template_body.txt b/tests/templates/default_mail_template_body.txt
new file mode 100644
index 00000000..369ecfe8
--- /dev/null
+++ b/tests/templates/default_mail_template_body.txt
@@ -0,0 +1 @@
+default_mail_template
\ No newline at end of file
diff --git a/tests/templates/default_mail_template_ou_name_body.html b/tests/templates/default_mail_template_ou_name_body.html
new file mode 100644
index 00000000..8889ccbe
--- /dev/null
+++ b/tests/templates/default_mail_template_ou_name_body.html
@@ -0,0 +1 @@
+default_mail_template_ou_name
\ No newline at end of file
diff --git a/tests/templates/default_mail_template_ou_name_body.txt b/tests/templates/default_mail_template_ou_name_body.txt
new file mode 100644
index 00000000..8889ccbe
--- /dev/null
+++ b/tests/templates/default_mail_template_ou_name_body.txt
@@ -0,0 +1 @@
+default_mail_template_ou_name
\ No newline at end of file
diff --git a/tests/templates/default_mail_template_ou_name_subject.txt b/tests/templates/default_mail_template_ou_name_subject.txt
new file mode 100644
index 00000000..8889ccbe
--- /dev/null
+++ b/tests/templates/default_mail_template_ou_name_subject.txt
@@ -0,0 +1 @@
+default_mail_template_ou_name
\ No newline at end of file
diff --git a/tests/templates/default_mail_template_subject.txt b/tests/templates/default_mail_template_subject.txt
new file mode 100644
index 00000000..369ecfe8
--- /dev/null
+++ b/tests/templates/default_mail_template_subject.txt
@@ -0,0 +1 @@
+default_mail_template
\ No newline at end of file
diff --git a/tests/test_utils.py b/tests/test_utils.py
index 69c2c7b6..ce803b98 100644
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -17,10 +17,14 @@
 
 from django.contrib.auth.middleware import AuthenticationMiddleware
 from django.contrib.sessions.middleware import SessionMiddleware
+from django.core import mail
+
+from django_rbac.utils import get_ou_model
 
 from authentic2.utils import (good_next_url, same_origin, select_next_url,
                               user_can_change_password, login,
-                              get_authentication_events, authenticate)
+                              get_authentication_events, authenticate,
+                              send_templated_mail)
 
 
 def test_good_next_url(db, rf, settings):
@@ -116,3 +120,38 @@ def test_remember_cookie(rf):
     request.COOKIES['preferrence'] = '1 2 3 4 5'
     prepend_remember_cookie(request, response, 'preferrence', 7)
     assert response.cookies['preferrence'].value == '7 1 2 3 4'
+
+
+def test_send_templated_mail_template_selection(simple_user):
+    ou = get_ou_model().objects.create(slug='ou_name')
+    simple_user.ou = ou
+    default_template = 'default_mail_template'
+    specific_template = 'custom_mail_template'
+    default_template_ou = '_'.join((default_template, ou.slug))
+    specific_template_ou = '_'.join((specific_template, ou.slug))
+    template_names = [default_template]
+
+    send_templated_mail(simple_user, template_names)
+    assert len(mail.outbox) == 1
+    sent_mail = mail.outbox.pop()
+    assert sent_mail.subject == default_template
+    assert sent_mail.body == default_template
+
+    send_templated_mail(simple_user, template_names, per_ou_templates=True)
+    assert len(mail.outbox) == 1
+    sent_mail = mail.outbox.pop()
+    assert sent_mail.subject == default_template_ou
+    assert sent_mail.body == default_template_ou
+
+    template_names.insert(0, specific_template)
+    send_templated_mail(simple_user, template_names)
+    assert len(mail.outbox) == 1
+    sent_mail = mail.outbox.pop()
+    assert sent_mail.subject == specific_template
+    assert sent_mail.body == specific_template
+
+    send_templated_mail(simple_user, template_names, per_ou_templates=True)
+    assert len(mail.outbox) == 1
+    sent_mail = mail.outbox.pop()
+    assert sent_mail.subject == specific_template_ou
+    assert sent_mail.body == specific_template_ou
-- 
2.20.1

