From dd189164ef0b39132daafcbe5d163bc259ccec8e Mon Sep 17 00:00:00 2001 From: Denis Costa Date: Thu, 13 Apr 2017 16:39:30 -0300 Subject: [#927] Add recovery code mail template with @tuliocasagrande --- service/pixelated/account_recovery.py | 18 +++++++++++++++- service/pixelated/assets/recovery.mail.en-US | 20 ++++++++++++++++++ .../test/functional/features/steps/mail_list.py | 6 ------ .../test/functional/features/steps/mail_view.py | 6 ++++++ service/test/unit/test_account_recovery.py | 24 +++++++++++++++++++++- 5 files changed, 66 insertions(+), 8 deletions(-) create mode 100644 service/pixelated/assets/recovery.mail.en-US (limited to 'service') diff --git a/service/pixelated/account_recovery.py b/service/pixelated/account_recovery.py index 2208faf5..723d4048 100644 --- a/service/pixelated/account_recovery.py +++ b/service/pixelated/account_recovery.py @@ -14,12 +14,15 @@ # You should have received a copy of the GNU Affero General Public License # along with Pixelated. If not, see . +import pkg_resources + from twisted.internet.defer import inlineCallbacks, returnValue from twisted.logger import Logger from twisted.mail import smtp from email.mime.text import MIMEText +from pixelated.resources.account_recovery_resource import AccountRecoveryResource log = Logger() @@ -53,7 +56,7 @@ class AccountRecovery(object): log.info('Sending mail containing the user\'s recovery code') sender = 'team@{}'.format(self._domain) - msg = MIMEText('Your code %s' % code) + msg = MIMEText(self._get_recovery_mail(code)) msg['Subject'] = 'Recovery Code' msg['From'] = sender msg['To'] = backup_email @@ -68,3 +71,16 @@ class AccountRecovery(object): except Exception as e: log.error('Failed trying to send the email with the recovery code') raise e + + def _get_recovery_mail(self, code, language='en-US'): + recovery_mail = pkg_resources.resource_filename( + 'pixelated.assets', + 'recovery.mail.%s' % (language)) + + account_recovery_url = '{}/{}'.format(self._domain, AccountRecoveryResource.BASE_URL) + + with open(recovery_mail) as mail_template_file: + return mail_template_file.read().format( + domain=self._domain, + recovery_code=code, + account_recovery_url=account_recovery_url) diff --git a/service/pixelated/assets/recovery.mail.en-US b/service/pixelated/assets/recovery.mail.en-US new file mode 100644 index 00000000..d14ca712 --- /dev/null +++ b/service/pixelated/assets/recovery.mail.en-US @@ -0,0 +1,20 @@ +Hello, + +You are receiving this email because you registered at a Pixelated provider, on {domain}. +In case you ever forget your password, you can access this link {account_recovery_url} and put the following recovery code: + +{recovery_code} + +This code is they only way to recover access to your account in case you lose your password. +Be careful and keep it safe!!! + +Why is this so important? + +Pixelated is an email client that respects your privacy and uses PGP Encryption to do so. +Your password also gives you access to your keys, so if you forget it you will lose access to your account and the ability to decrypt your messages. +We understand that forgetting passwords is a common thing, so we developed a more secure way to recover access to your account, therefore, a little bit more annoying ;) +This code is half of a big code to recover your account, the other half is with the account administrator. In case you forget your password, use this code and your administrator code to recover access to your account. It's like those locks with two keys :) +You will only succeed if you have both codes, so, never hurts to ask again: SAVE THIS CODE! + + +PS: If you didn't create an account at {domain}, please ignore this email. diff --git a/service/test/functional/features/steps/mail_list.py b/service/test/functional/features/steps/mail_list.py index 2953c1af..21694153 100644 --- a/service/test/functional/features/steps/mail_list.py +++ b/service/test/functional/features/steps/mail_list.py @@ -138,9 +138,3 @@ def impl(context): @then('I should not see any email') def impl(context): _wait_for_mail_list_to_be_empty(context) - - -@then(u'I see the mail has the recovery code') -def step_impl(context): - expected_body = 'Your code' - context.execute_steps(u"Then I see that the body has '%s'" % expected_body) diff --git a/service/test/functional/features/steps/mail_view.py b/service/test/functional/features/steps/mail_view.py index d10f86e7..9b49e6e5 100644 --- a/service/test/functional/features/steps/mail_view.py +++ b/service/test/functional/features/steps/mail_view.py @@ -109,3 +109,9 @@ def impl(context): assert cc is not None assert bcc is not None + + +@then(u'I see the mail has the recovery code') +def step_impl(context): + expected_body = 'This code is they only way to recover access to your account in case you lose your password.' + context.execute_steps(u"Then I see that the body has '%s'" % expected_body) diff --git a/service/test/unit/test_account_recovery.py b/service/test/unit/test_account_recovery.py index 08298419..8d52676e 100644 --- a/service/test/unit/test_account_recovery.py +++ b/service/test/unit/test_account_recovery.py @@ -24,6 +24,28 @@ from mockito import when, any as ANY from pixelated.account_recovery import AccountRecovery +RECOVERY_CODE_EMAIL = '''Hello, + +You are receiving this email because you registered at a Pixelated provider, on test.com. +In case you ever forget your password, you can access this link test.com/account-recovery and put the following recovery code: + +4645a2f8997e5d0d + +This code is they only way to recover access to your account in case you lose your password. +Be careful and keep it safe!!! + +Why is this so important? + +Pixelated is an email client that respects your privacy and uses PGP Encryption to do so. +Your password also gives you access to your keys, so if you forget it you will lose access to your account and the ability to decrypt your messages. +We understand that forgetting passwords is a common thing, so we developed a more secure way to recover access to your account, therefore, a little bit more annoying ;) +This code is half of a big code to recover your account, the other half is with the account administrator. In case you forget your password, use this code and your administrator code to recover access to your account. It\'s like those locks with two keys :) +You will only succeed if you have both codes, so, never hurts to ask again: SAVE THIS CODE! + + +PS: If you didn\'t create an account at test.com, please ignore this email. +''' + class AccountRecoveryTest(unittest.TestCase): def setUp(self): @@ -53,7 +75,7 @@ class AccountRecoveryTest(unittest.TestCase): @defer.inlineCallbacks def test_send_recovery_code_by_email(self): sender = 'team@{}'.format(self.domain) - msg = MIMEText('Your code %s' % self.generated_code) + msg = MIMEText(RECOVERY_CODE_EMAIL) msg['Subject'] = 'Recovery Code' msg['From'] = sender msg['To'] = self.backup_email -- cgit v1.2.3 From 9a8585ea9419790d0067ccbe5bc6b49eaaa80810 Mon Sep 17 00:00:00 2001 From: Anike Arni Date: Tue, 18 Apr 2017 14:23:29 -0300 Subject: [#927] Fixes type in account recovery email with @deniscostadsc --- service/pixelated/assets/recovery.mail.en-US | 2 +- service/test/unit/test_account_recovery.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'service') diff --git a/service/pixelated/assets/recovery.mail.en-US b/service/pixelated/assets/recovery.mail.en-US index d14ca712..d17f8a28 100644 --- a/service/pixelated/assets/recovery.mail.en-US +++ b/service/pixelated/assets/recovery.mail.en-US @@ -5,7 +5,7 @@ In case you ever forget your password, you can access this link {account_recover {recovery_code} -This code is they only way to recover access to your account in case you lose your password. +This code is the only way to recover access to your account in case you lose your password. Be careful and keep it safe!!! Why is this so important? diff --git a/service/test/unit/test_account_recovery.py b/service/test/unit/test_account_recovery.py index 8d52676e..7a01ca7d 100644 --- a/service/test/unit/test_account_recovery.py +++ b/service/test/unit/test_account_recovery.py @@ -31,7 +31,7 @@ In case you ever forget your password, you can access this link test.com/account 4645a2f8997e5d0d -This code is they only way to recover access to your account in case you lose your password. +This code is the only way to recover access to your account in case you lose your password. Be careful and keep it safe!!! Why is this so important? -- cgit v1.2.3 From 6061af542abbb293660eedc5fe583234112bfdaa Mon Sep 17 00:00:00 2001 From: Anike Arni Date: Tue, 18 Apr 2017 14:52:01 -0300 Subject: [#927] Mocks email test to not assert on full text with @deniscostadsc --- service/test/unit/test_account_recovery.py | 36 +++++++++--------------------- 1 file changed, 10 insertions(+), 26 deletions(-) (limited to 'service') diff --git a/service/test/unit/test_account_recovery.py b/service/test/unit/test_account_recovery.py index 7a01ca7d..b0edc466 100644 --- a/service/test/unit/test_account_recovery.py +++ b/service/test/unit/test_account_recovery.py @@ -19,33 +19,11 @@ from twisted.internet import defer from twisted.trial import unittest from twisted.mail import smtp -from mock import patch, Mock +from mock import patch, Mock, mock_open from mockito import when, any as ANY from pixelated.account_recovery import AccountRecovery -RECOVERY_CODE_EMAIL = '''Hello, - -You are receiving this email because you registered at a Pixelated provider, on test.com. -In case you ever forget your password, you can access this link test.com/account-recovery and put the following recovery code: - -4645a2f8997e5d0d - -This code is the only way to recover access to your account in case you lose your password. -Be careful and keep it safe!!! - -Why is this so important? - -Pixelated is an email client that respects your privacy and uses PGP Encryption to do so. -Your password also gives you access to your keys, so if you forget it you will lose access to your account and the ability to decrypt your messages. -We understand that forgetting passwords is a common thing, so we developed a more secure way to recover access to your account, therefore, a little bit more annoying ;) -This code is half of a big code to recover your account, the other half is with the account administrator. In case you forget your password, use this code and your administrator code to recover access to your account. It\'s like those locks with two keys :) -You will only succeed if you have both codes, so, never hurts to ask again: SAVE THIS CODE! - - -PS: If you didn\'t create an account at test.com, please ignore this email. -''' - class AccountRecoveryTest(unittest.TestCase): def setUp(self): @@ -72,15 +50,21 @@ class AccountRecoveryTest(unittest.TestCase): yield self.account_recovery.update_recovery_code() self.mock_bonafide_session.update_recovery_code.assert_called_once_with(self.generated_code) + @patch('pixelated.account_recovery.smtp.sendmail') + @patch('pixelated.account_recovery.pkg_resources.resource_filename') @defer.inlineCallbacks - def test_send_recovery_code_by_email(self): + def test_send_recovery_code_by_email(self, mock_resource, mock_sendmail): + mock_sendmail.return_value = defer.succeed(None) + sender = 'team@{}'.format(self.domain) - msg = MIMEText(RECOVERY_CODE_EMAIL) + mock_file_content = '{domain}, {recovery_code}, {account_recovery_url}' + recovery_code_email = 'test.com, 4645a2f8997e5d0d, test.com/account-recovery' + msg = MIMEText(recovery_code_email) msg['Subject'] = 'Recovery Code' msg['From'] = sender msg['To'] = self.backup_email - with patch.object(smtp, 'sendmail', return_value=defer.succeed(None)) as mock_sendmail: + with patch('pixelated.account_recovery.open', mock_open(read_data=mock_file_content), create=True): yield self.account_recovery._send_mail(self.generated_code, self.backup_email) mock_sendmail.assert_called_with( -- cgit v1.2.3