Browse Source

Merge pull request #301 from lebouquetin/master

Tracim 7 years ago
parent
commit
6348248f4c

+ 4 - 1
tracim/development.ini.base View File

183
 website.server_name = 127.0.0.1
183
 website.server_name = 127.0.0.1
184
 
184
 
185
 email.notification.activated = False
185
 email.notification.activated = False
186
-email.notification.from.email = noreply@trac.im
186
+# email notifications can be sent with the user_id added as an identifier
187
+# this way email clients like Thunderbird will be able to distinguish
188
+# notifications generated by a user or another one
189
+email.notification.from.email = noreply+{user_id}@trac.im
187
 email.notification.from.default_label = Tracim Notifications
190
 email.notification.from.default_label = Tracim Notifications
188
 email.notification.content_update.template.html = ./tracim/templates/mail/content_update_body_html.mak
191
 email.notification.content_update.template.html = ./tracim/templates/mail/content_update_body_html.mak
189
 email.notification.content_update.template.text = ./tracim/templates/mail/content_update_body_text.mak
192
 email.notification.content_update.template.text = ./tracim/templates/mail/content_update_body_text.mak

+ 19 - 19
tracim/tracim/lib/notifications.py View File

168
             cls.WORKSPACE_LABEL
168
             cls.WORKSPACE_LABEL
169
         ]
169
         ]
170
 
170
 
171
+
171
 class EmailNotifier(object):
172
 class EmailNotifier(object):
172
 
173
 
173
     """
174
     """
188
         :param user: user to extract display name
189
         :param user: user to extract display name
189
         :return: sender string
190
         :return: sender string
190
         """
191
         """
191
-        if user is None:
192
-            return '{0} <{1}>'.format(
193
-                self._global_config.EMAIL_NOTIFICATION_FROM_DEFAULT_LABEL,
194
-                self._global_config.EMAIL_NOTIFICATION_FROM_EMAIL,
195
-            )
196
 
192
 
197
-        # We add a suffix to email to prevent client like Thunderbird to
198
-        # display personal adressbook label.
199
-        email = self._global_config.EMAIL_NOTIFICATION_FROM_EMAIL
200
-        email_name, domain = email.split('@')
201
-        arranged_email = '{0}+{1}@{2}'.format(
202
-            email_name,
203
-            str(user.user_id),
204
-            domain,
205
-        )
206
-
207
-        return '{0} {1} <{2}>'.format(
208
-            Header(user.display_name).encode(),
209
-            'via Tracim',
210
-            arranged_email,
193
+        email_template = self._global_config.EMAIL_NOTIFICATION_FROM_EMAIL
194
+        mail_sender_name = self._global_config.EMAIL_NOTIFICATION_FROM_DEFAULT_LABEL  # nopep8
195
+        if user:
196
+            mail_sender_name = '{name} via Tracim'.format(name=user.display_name)
197
+            email_address = email_template.replace('{user_id}', str(user.user_id))
198
+            # INFO - D.A. - 2017-08-04
199
+            # We use email_template.replace() instead of .format() because this
200
+            # method is more robust to errors in config file.
201
+            #
202
+            # For example, if the email is info+{userid}@tracim.fr
203
+            # email.format(user_id='bob') will raise an exception
204
+            # email.replace('{user_id}', 'bob') will just ignore {userid}
205
+        else:
206
+            email_address = email_template.replace('{user_id}', '0')
207
+
208
+        return '{label} <{email_address}>'.format(
209
+            label = Header(mail_sender_name).encode(),
210
+            email_address = email_address
211
         )
211
         )
212
 
212
 
213
     def notify_content_update(self, event_actor_id: int, event_content_id: int):
213
     def notify_content_update(self, event_actor_id: int, event_content_id: int):

+ 1 - 1
tracim/tracim/model/auth.py View File

250
          remove @xxx.xxx part of email in returned value
250
          remove @xxx.xxx part of email in returned value
251
         :return: display name based on user name or email.
251
         :return: display name based on user name or email.
252
         """
252
         """
253
-        if self.display_name!=None and self.display_name!='':
253
+        if self.display_name != None and self.display_name != '':
254
             return self.display_name
254
             return self.display_name
255
         else:
255
         else:
256
             if remove_email_part:
256
             if remove_email_part:

+ 49 - 0
tracim/tracim/tests/library/test_notification.py View File

10
 
10
 
11
 from tracim.config.app_cfg import CFG
11
 from tracim.config.app_cfg import CFG
12
 from tracim.lib.notifications import DummyNotifier
12
 from tracim.lib.notifications import DummyNotifier
13
+from tracim.lib.notifications import EmailNotifier
13
 from tracim.lib.notifications import EST
14
 from tracim.lib.notifications import EST
14
 from tracim.lib.notifications import NotifierFactory
15
 from tracim.lib.notifications import NotifierFactory
15
 from tracim.lib.notifications import RealNotifier
16
 from tracim.lib.notifications import RealNotifier
47
         ok_('{workspace_label}' in tags)
48
         ok_('{workspace_label}' in tags)
48
         ok_('{content_label}' in tags)
49
         ok_('{content_label}' in tags)
49
         ok_('{content_status_label}' in tags)
50
         ok_('{content_status_label}' in tags)
51
+
52
+
53
+class TestEmailNotifier(TestStandard):
54
+    def test_email_notifier__build_name_with_user_id(self):
55
+        u = User()
56
+        u.user_id = 3
57
+        u.display_name = 'François Michâlié'
58
+
59
+        config = CFG.get_instance()
60
+        config.EMAIL_NOTIFICATION_FROM_EMAIL = 'noreply+{user_id}@tracim.io'
61
+
62
+        notifier = EmailNotifier(smtp_config=None, global_config=config)
63
+        email = notifier._get_sender(user=u)
64
+        eq_('=?utf-8?q?Fran=C3=A7ois_Mich=C3=A2li=C3=A9_via_Tracim?= <noreply+3@tracim.io>', email)  # nopep8
65
+
66
+    def test_email_notifier__build_name_without_user_id(self):
67
+        u = User()
68
+        u.user_id = 3
69
+        u.display_name = 'François Michâlié'
70
+
71
+        config = CFG.get_instance()
72
+        config.EMAIL_NOTIFICATION_FROM_EMAIL = 'noreply@tracim.io'
73
+
74
+        notifier = EmailNotifier(smtp_config=None, global_config=config)
75
+        email = notifier._get_sender(user=u)
76
+        eq_('=?utf-8?q?Fran=C3=A7ois_Mich=C3=A2li=C3=A9_via_Tracim?= <noreply@tracim.io>', email)  # nopep8
77
+
78
+    def test_email_notifier__build_name_with_user_id_wrong_syntax(self):
79
+        u = User()
80
+        u.user_id = 3
81
+        u.display_name = 'François Michâlié'
82
+
83
+        config = CFG.get_instance()
84
+        config.EMAIL_NOTIFICATION_FROM_EMAIL = 'noreply+{userid}@tracim.io'
85
+
86
+        notifier = EmailNotifier(smtp_config=None, global_config=config)
87
+        email = notifier._get_sender(user=u)
88
+        eq_('=?utf-8?q?Fran=C3=A7ois_Mich=C3=A2li=C3=A9_via_Tracim?= <noreply+{userid}@tracim.io>', email)  # nopep8
89
+
90
+    def test_email_notifier__build_name_with_no_user(self):
91
+        config = CFG.get_instance()
92
+        config.EMAIL_NOTIFICATION_FROM_DEFAULT_LABEL = 'Robot'
93
+        config.EMAIL_NOTIFICATION_FROM_EMAIL = 'noreply@tracim.io'
94
+
95
+        notifier = EmailNotifier(smtp_config=None, global_config=config)
96
+        email = notifier._get_sender()
97
+        eq_('Robot <noreply@tracim.io>', email)
98
+

+ 24 - 8
tracim/tracim/tests/library/test_resetpassword.py View File

1
 # -*- coding: utf-8 -*-
1
 # -*- coding: utf-8 -*-
2
+
3
+import sys
4
+
2
 from nose.tools import assert_raises
5
 from nose.tools import assert_raises
3
 from resetpassword.lib import _plain_send_mail
6
 from resetpassword.lib import _plain_send_mail
4
 
7
 
9
     application_under_test = 'nosmtp'
12
     application_under_test = 'nosmtp'
10
 
13
 
11
     def test_unit__plain_send_mail__ok(self):
14
     def test_unit__plain_send_mail__ok(self):
12
-        assert_raises(
13
-            ConnectionRefusedError,
14
-            _plain_send_mail,
15
-            'Name of sender <email@sender.local>',
16
-            'Recipient name <recipient@recipient.local>',
17
-            'hello',
18
-            'How are you ?',
19
-        )
15
+        if sys.version_info >= (3, 5):
16
+            from smtplib import SMTPNotSupportedError
17
+
18
+            assert_raises(
19
+                (ConnectionRefusedError, SMTPNotSupportedError),
20
+                _plain_send_mail,
21
+                'Name of sender <email@sender.local>',
22
+                'Recipient name <recipient@recipient.local>',
23
+                'hello',
24
+                'How are you ?',
25
+            )
26
+        else:
27
+            from smtplib import SMTPException
28
+            assert_raises(
29
+                (SMTPException, ConnectionRefusedError),
30
+                _plain_send_mail,
31
+                'Name of sender <email@sender.local>',
32
+                'Recipient name <recipient@recipient.local>',
33
+                'hello',
34
+                'How are you ?',
35
+            )

+ 0 - 0
tracim/tracim/tests/unit/__init__.py View File