diff options
Diffstat (limited to 'service/pixelated')
-rw-r--r-- | service/pixelated/adapter/services/mail_sender.py | 36 | ||||
-rw-r--r-- | service/pixelated/bitmask_libraries/session.py | 9 | ||||
-rw-r--r-- | service/pixelated/bitmask_libraries/smtp.py | 13 | ||||
-rw-r--r-- | service/pixelated/config/app_factory.py | 3 | ||||
-rw-r--r-- | service/pixelated/resources/__init__.py | 5 | ||||
-rw-r--r-- | service/pixelated/resources/mails_resource.py | 6 |
6 files changed, 50 insertions, 22 deletions
diff --git a/service/pixelated/adapter/services/mail_sender.py b/service/pixelated/adapter/services/mail_sender.py index 24ae839d..9f42fbbc 100644 --- a/service/pixelated/adapter/services/mail_sender.py +++ b/service/pixelated/adapter/services/mail_sender.py @@ -16,14 +16,20 @@ from StringIO import StringIO import re -from twisted.internet.defer import Deferred +from twisted.internet.defer import Deferred, fail from twisted.mail.smtp import SMTPSenderFactory from twisted.internet import reactor from pixelated.support.functional import flatten +class SMTPDownException(Exception): + def __init__(self): + Exception.__init__(self, "Couldn't send mail now, try again later.") + + class MailSender(object): - def __init__(self, account_email_address, smtp_client=None): + def __init__(self, account_email_address, ensure_smtp_is_running_cb): + self.ensure_smtp_is_running_cb = ensure_smtp_is_running_cb self.account_email_address = account_email_address def recepients_normalizer(self, mail_list): @@ -40,15 +46,17 @@ class MailSender(object): return self.recepients_normalizer(clean_mail_list) def sendmail(self, mail): - recipients = flatten([mail.to, mail.cc, mail.bcc]) - normalized_recipients = self.get_email_addresses(recipients) - resultDeferred = Deferred() - senderFactory = SMTPSenderFactory( - fromEmail=self.account_email_address, - toEmail=normalized_recipients, - file=StringIO(mail.to_smtp_format()), - deferred=resultDeferred) - - reactor.connectTCP('localhost', 4650, senderFactory) - - return resultDeferred + if self.ensure_smtp_is_running_cb(): + recipients = flatten([mail.to, mail.cc, mail.bcc]) + normalized_recipients = self.get_email_addresses(recipients) + resultDeferred = Deferred() + senderFactory = SMTPSenderFactory( + fromEmail=self.account_email_address, + toEmail=normalized_recipients, + file=StringIO(mail.to_smtp_format()), + deferred=resultDeferred) + + reactor.connectTCP('localhost', 4650, senderFactory) + + return resultDeferred + return fail(SMTPDownException()) diff --git a/service/pixelated/bitmask_libraries/session.py b/service/pixelated/bitmask_libraries/session.py index 158d6605..9f21fbe6 100644 --- a/service/pixelated/bitmask_libraries/session.py +++ b/service/pixelated/bitmask_libraries/session.py @@ -14,6 +14,7 @@ # You should have received a copy of the GNU Affero General Public License # along with Pixelated. If not, see <http://www.gnu.org/licenses/>. import errno +import logging import traceback import sys @@ -65,7 +66,7 @@ class LeapSession(object): - ``incoming_mail_fetcher`` Background job for fetching incoming mails from LEAP server (LeapIncomingMail) """ - def __init__(self, provider, srp_session, soledad_session, nicknym, soledad_account, incoming_mail_fetcher): + def __init__(self, provider, srp_session, soledad_session, nicknym, soledad_account, incoming_mail_fetcher, smtp): """ Constructor. @@ -73,6 +74,7 @@ class LeapSession(object): :type leap_config: LeapConfig """ + self.smtp = smtp self.config = provider.config self.provider = provider self.srp_session = srp_session @@ -133,9 +135,10 @@ class LeapSessionFactory(object): account, auth) smtp = LeapSmtp(self._provider, nicknym.keymanager, auth) - smtp.start() - return LeapSession(self._provider, auth, soledad, nicknym, account, incoming_mail_fetcher) + smtp.ensure_running() + + return LeapSession(self._provider, auth, soledad, nicknym, account, incoming_mail_fetcher, smtp) def _lookup_session(self, key): global SESSIONS diff --git a/service/pixelated/bitmask_libraries/smtp.py b/service/pixelated/bitmask_libraries/smtp.py index 6bbe0051..d5236e8e 100644 --- a/service/pixelated/bitmask_libraries/smtp.py +++ b/service/pixelated/bitmask_libraries/smtp.py @@ -13,12 +13,16 @@ # # You should have received a copy of the GNU Affero General Public License # along with Pixelated. If not, see <http://www.gnu.org/licenses/>. +import logging import os import requests from .certs import which_bundle from leap.mail.smtp import setup_smtp_gateway +logger = logging.getLogger(__name__) + + class LeapSmtp(object): TWISTED_PORT = 4650 @@ -86,6 +90,15 @@ class LeapSmtp(object): encrypted_only=False ) + def ensure_running(self): + if not self._smtp_service: + try: + self.start() + except Exception as e: + logger.warning("Couldn't start the SMTP server now, will try again when the user tries to use it") + return False + return True + def stop(self): if self._smtp_service is not None: self._smtp_port.stopListening() diff --git a/service/pixelated/config/app_factory.py b/service/pixelated/config/app_factory.py index 8671eaa6..f63b49ed 100644 --- a/service/pixelated/config/app_factory.py +++ b/service/pixelated/config/app_factory.py @@ -102,7 +102,8 @@ def init_app(app, leap_home, leap_session): tag_service = TagService() search_engine = SearchEngine(soledad_querier, agent_home=leap_home) - pixelated_mail_sender = MailSender(leap_session.account_email()) + pixelated_mail_sender = MailSender(leap_session.account_email(), + lambda: leap_session.smtp.ensure_running()) pixelated_mailboxes = Mailboxes(leap_session.account, soledad_querier, search_engine) draft_service = DraftService(pixelated_mailboxes) diff --git a/service/pixelated/resources/__init__.py b/service/pixelated/resources/__init__.py index a2e4c9d4..b244900a 100644 --- a/service/pixelated/resources/__init__.py +++ b/service/pixelated/resources/__init__.py @@ -14,6 +14,8 @@ # You should have received a copy of the GNU Affero General Public License # along with Pixelated. If not, see <http://www.gnu.org/licenses/>. +import json + def respond_json(entity, request, status_code=200): json_response = json.dumps(entity) @@ -28,6 +30,3 @@ def respond_json_deferred(entity, request, status_code=200): request.code = status_code request.write(json_response) request.finish() - - -import json diff --git a/service/pixelated/resources/mails_resource.py b/service/pixelated/resources/mails_resource.py index f387076b..c057031a 100644 --- a/service/pixelated/resources/mails_resource.py +++ b/service/pixelated/resources/mails_resource.py @@ -1,4 +1,5 @@ import json +from pixelated.adapter.services.mail_sender import SMTPDownException from pixelated.adapter.model.mail import InputMail from pixelated.resources import respond_json, respond_json_deferred from twisted.web.resource import Resource @@ -95,7 +96,10 @@ class MailsResource(Resource): respond_json_deferred(data, request) def onError(error): - respond_json_deferred({'message': str(error)}, request, status_code=422) + if isinstance(error.value, SMTPDownException): + respond_json_deferred({'message': str(error.value)}, request, status_code=503) + else: + respond_json_deferred({'message': str(error)}, request, status_code=422) deferred.addCallback(onSuccess) deferred.addErrback(onError) |