summary refs log tree commit diff
path: root/synapse/push/mailer.py
diff options
context:
space:
mode:
Diffstat (limited to 'synapse/push/mailer.py')
-rw-r--r--synapse/push/mailer.py134
1 files changed, 29 insertions, 105 deletions
diff --git a/synapse/push/mailer.py b/synapse/push/mailer.py
index d57a66a697..c38e037281 100644
--- a/synapse/push/mailer.py
+++ b/synapse/push/mailer.py
@@ -16,18 +16,17 @@
 import email.mime.multipart
 import email.utils
 import logging
-import time
+import urllib.parse
 from email.mime.multipart import MIMEMultipart
 from email.mime.text import MIMEText
 from typing import Iterable, List, TypeVar
 
-from six.moves import urllib
-
 import bleach
 import jinja2
 
 from synapse.api.constants import EventTypes
 from synapse.api.errors import StoreError
+from synapse.config.emailconfig import EmailSubjectConfig
 from synapse.logging.context import make_deferred_yieldable
 from synapse.push.presentable_names import (
     calculate_room_name,
@@ -43,23 +42,6 @@ logger = logging.getLogger(__name__)
 T = TypeVar("T")
 
 
-MESSAGE_FROM_PERSON_IN_ROOM = (
-    "You have a message on %(app)s from %(person)s in the %(room)s room..."
-)
-MESSAGE_FROM_PERSON = "You have a message on %(app)s from %(person)s..."
-MESSAGES_FROM_PERSON = "You have messages on %(app)s from %(person)s..."
-MESSAGES_IN_ROOM = "You have messages on %(app)s in the %(room)s room..."
-MESSAGES_IN_ROOM_AND_OTHERS = (
-    "You have messages on %(app)s in the %(room)s room and others..."
-)
-MESSAGES_FROM_PERSON_AND_OTHERS = (
-    "You have messages on %(app)s from %(person)s and others..."
-)
-INVITE_FROM_PERSON_TO_ROOM = (
-    "%(person)s has invited you to join the %(room)s room on %(app)s..."
-)
-INVITE_FROM_PERSON = "%(person)s has invited you to chat on %(app)s..."
-
 CONTEXT_BEFORE = 1
 CONTEXT_AFTER = 1
 
@@ -122,6 +104,7 @@ class Mailer(object):
         self.state_handler = self.hs.get_state_handler()
         self.storage = hs.get_storage()
         self.app_name = app_name
+        self.email_subjects = hs.config.email_subjects  # type: EmailSubjectConfig
 
         logger.info("Created Mailer for app_name %s" % app_name)
 
@@ -148,7 +131,8 @@ class Mailer(object):
 
         await self.send_email(
             email_address,
-            "[%s] Password Reset" % self.hs.config.server_name,
+            self.email_subjects.password_reset
+            % {"server_name": self.hs.config.server_name},
             template_vars,
         )
 
@@ -175,7 +159,8 @@ class Mailer(object):
 
         await self.send_email(
             email_address,
-            "[%s] Register your Email Address" % self.hs.config.server_name,
+            self.email_subjects.email_validation
+            % {"server_name": self.hs.config.server_name},
             template_vars,
         )
 
@@ -203,7 +188,8 @@ class Mailer(object):
 
         await self.send_email(
             email_address,
-            "[%s] Validate Your Email" % self.hs.config.server_name,
+            self.email_subjects.email_validation
+            % {"server_name": self.hs.config.server_name},
             template_vars,
         )
 
@@ -270,16 +256,13 @@ class Mailer(object):
                 user_id, app_id, email_address
             ),
             "summary_text": summary_text,
-            "app_name": self.app_name,
             "rooms": rooms,
             "reason": reason,
         }
 
-        await self.send_email(
-            email_address, "[%s] %s" % (self.app_name, summary_text), template_vars
-        )
+        await self.send_email(email_address, summary_text, template_vars)
 
-    async def send_email(self, email_address, subject, template_vars):
+    async def send_email(self, email_address, subject, extra_template_vars):
         """Send an email with the given information and template text"""
         try:
             from_string = self.hs.config.email_notif_from % {"app": self.app_name}
@@ -292,6 +275,13 @@ class Mailer(object):
         if raw_to == "":
             raise RuntimeError("Invalid 'to' address")
 
+        template_vars = {
+            "app_name": self.app_name,
+            "server_name": self.hs.config.server.server_name,
+        }
+
+        template_vars.update(extra_template_vars)
+
         html_text = self.template_html.render(**template_vars)
         html_part = MIMEText(html_text, "html", "utf8")
 
@@ -477,12 +467,12 @@ class Mailer(object):
                 inviter_name = name_from_member_event(inviter_member_event)
 
                 if room_name is None:
-                    return INVITE_FROM_PERSON % {
+                    return self.email_subjects.invite_from_person % {
                         "person": inviter_name,
                         "app": self.app_name,
                     }
                 else:
-                    return INVITE_FROM_PERSON_TO_ROOM % {
+                    return self.email_subjects.invite_from_person_to_room % {
                         "person": inviter_name,
                         "room": room_name,
                         "app": self.app_name,
@@ -500,13 +490,13 @@ class Mailer(object):
                     sender_name = name_from_member_event(state_event)
 
                 if sender_name is not None and room_name is not None:
-                    return MESSAGE_FROM_PERSON_IN_ROOM % {
+                    return self.email_subjects.message_from_person_in_room % {
                         "person": sender_name,
                         "room": room_name,
                         "app": self.app_name,
                     }
                 elif sender_name is not None:
-                    return MESSAGE_FROM_PERSON % {
+                    return self.email_subjects.message_from_person % {
                         "person": sender_name,
                         "app": self.app_name,
                     }
@@ -514,7 +504,10 @@ class Mailer(object):
                 # There's more than one notification for this room, so just
                 # say there are several
                 if room_name is not None:
-                    return MESSAGES_IN_ROOM % {"room": room_name, "app": self.app_name}
+                    return self.email_subjects.messages_in_room % {
+                        "room": room_name,
+                        "app": self.app_name,
+                    }
                 else:
                     # If the room doesn't have a name, say who the messages
                     # are from explicitly to avoid, "messages in the Bob room"
@@ -532,7 +525,7 @@ class Mailer(object):
                         ]
                     )
 
-                    return MESSAGES_FROM_PERSON % {
+                    return self.email_subjects.messages_from_person % {
                         "person": descriptor_from_member_events(member_events.values()),
                         "app": self.app_name,
                     }
@@ -541,7 +534,7 @@ class Mailer(object):
 
             # ...but we still refer to the 'reason' room which triggered the mail
             if reason["room_name"] is not None:
-                return MESSAGES_IN_ROOM_AND_OTHERS % {
+                return self.email_subjects.messages_in_room_and_others % {
                     "room": reason["room_name"],
                     "app": self.app_name,
                 }
@@ -561,7 +554,7 @@ class Mailer(object):
                     [room_state_ids[room_id][("m.room.member", s)] for s in sender_ids]
                 )
 
-                return MESSAGES_FROM_PERSON_AND_OTHERS % {
+                return self.email_subjects.messages_from_person_and_others % {
                     "person": descriptor_from_member_events(member_events.values()),
                     "app": self.app_name,
                 }
@@ -646,72 +639,3 @@ def string_ordinal_total(s):
     for c in s:
         tot += ord(c)
     return tot
-
-
-def format_ts_filter(value, format):
-    return time.strftime(format, time.localtime(value / 1000))
-
-
-def load_jinja2_templates(
-    template_dir,
-    template_filenames,
-    apply_format_ts_filter=False,
-    apply_mxc_to_http_filter=False,
-    public_baseurl=None,
-):
-    """Loads and returns one or more jinja2 templates and applies optional filters
-
-    Args:
-        template_dir (str): The directory where templates are stored
-        template_filenames (list[str]): A list of template filenames
-        apply_format_ts_filter (bool): Whether to apply a template filter that formats
-            timestamps
-        apply_mxc_to_http_filter (bool): Whether to apply a template filter that converts
-            mxc urls to http urls
-        public_baseurl (str|None): The public baseurl of the server. Required for
-            apply_mxc_to_http_filter to be enabled
-
-    Returns:
-        A list of jinja2 templates corresponding to the given list of filenames,
-        with order preserved
-    """
-    logger.info(
-        "loading email templates %s from '%s'", template_filenames, template_dir
-    )
-    loader = jinja2.FileSystemLoader(template_dir)
-    env = jinja2.Environment(loader=loader)
-
-    if apply_format_ts_filter:
-        env.filters["format_ts"] = format_ts_filter
-
-    if apply_mxc_to_http_filter and public_baseurl:
-        env.filters["mxc_to_http"] = _create_mxc_to_http_filter(public_baseurl)
-
-    templates = []
-    for template_filename in template_filenames:
-        template = env.get_template(template_filename)
-        templates.append(template)
-
-    return templates
-
-
-def _create_mxc_to_http_filter(public_baseurl):
-    def mxc_to_http_filter(value, width, height, resize_method="crop"):
-        if value[0:6] != "mxc://":
-            return ""
-
-        serverAndMediaId = value[6:]
-        fragment = None
-        if "#" in serverAndMediaId:
-            (serverAndMediaId, fragment) = serverAndMediaId.split("#", 1)
-            fragment = "#" + fragment
-
-        params = {"width": width, "height": height, "method": resize_method}
-        return "%s_matrix/media/v1/thumbnail/%s?%s%s" % (
-            public_baseurl,
-            serverAndMediaId,
-            urllib.parse.urlencode(params),
-            fragment or "",
-        )
-
-    return mxc_to_http_filter