summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--service/pixelated/adapter/mail_service.py27
-rw-r--r--service/pixelated/adapter/pixelated_mail.py27
-rw-r--r--service/pixelated/bitmask_libraries/session.py10
-rw-r--r--service/pixelated/bitmask_libraries/smtp.py4
-rw-r--r--service/pixelated/user_agent.py26
-rw-r--r--service/setup.cfg2
-rw-r--r--service/test/adapter/mail_service_test.py19
-rw-r--r--service/test/adapter/pixelated_mail_test.py7
-rw-r--r--service/test/user_agent_test.py34
9 files changed, 120 insertions, 36 deletions
diff --git a/service/pixelated/adapter/mail_service.py b/service/pixelated/adapter/mail_service.py
index 5a60d1bb..416c7bfc 100644
--- a/service/pixelated/adapter/mail_service.py
+++ b/service/pixelated/adapter/mail_service.py
@@ -16,6 +16,8 @@
import traceback
import sys
import os
+import smtplib
+from pixelated.bitmask_libraries.smtp import LeapSmtp
from twisted.internet import defer
from pixelated.bitmask_libraries.config import LeapConfig
from pixelated.bitmask_libraries.provider import LeapProvider
@@ -44,8 +46,27 @@ class MailService:
def __init__(self, leap_session):
self.leap_session = leap_session
self.account = leap_session.account
+ self.user_email = leap_session.account_email()
self.mailbox_name = 'INBOX'
+ def start(self):
+ try:
+ self.smtp_server = self._create_smtp_server()
+ self.smtp_client = self._create_smtp_client(self.smtp_server.smtp_info())
+ except:
+ traceback.print_exc(file=sys.stdout)
+ raise
+
+ def _create_smtp_server(self):
+ server = LeapSmtp(self.leap_session.provider, self.leap_session.nicknym.keymanager, self.leap_session.srp_session)
+ server.start()
+ return server
+
+ def _create_smtp_client(self, smtp_info):
+ smtp_servername, smtp_port = smtp_info
+ client = smtplib.SMTP(smtp_servername, smtp_port)
+ return client
+
@property
def mailbox(self):
return PixelatedMailbox(self.account.getMailbox(self.mailbox_name))
@@ -98,6 +119,12 @@ class MailService:
def mail(self, mail_id):
return self.mailbox.mail(mail_id)
+ def send(self, mail):
+ _from = self.user_email
+ _to = mail.get_to()
+
+ self.smtp_client.sendmail(_from, _to, mail.to_smtp_format(_from=_from))
+
def all_tags(self):
return self.mailbox.all_tags()
diff --git a/service/pixelated/adapter/pixelated_mail.py b/service/pixelated/adapter/pixelated_mail.py
index 547927a6..e43d5510 100644
--- a/service/pixelated/adapter/pixelated_mail.py
+++ b/service/pixelated/adapter/pixelated_mail.py
@@ -38,6 +38,12 @@ class PixelatedMail:
mail.tags = mail._extract_tags()
return mail
+ def set_from(self, _from):
+ self.headers['from'] = [_from]
+
+ def get_to(self):
+ return self.headers['to'][0]
+
def _extract_status(self):
return Status.from_flags(self.leap_mail.getFlags())
@@ -80,11 +86,20 @@ class PixelatedMail:
mime_multipart.attach(MIMEText(self.body, 'plain'))
return mime_multipart
+ def to_smtp_format(self, _from=None):
+ mime_multipart = self.to_mime_multipart()
+ mime_multipart['From'] = _from
+ return mime_multipart.as_string()
+
@staticmethod
def from_dict(mail_dict):
- mail = PixelatedMail()
- mail.headers = mail_dict['header']
- mail.body = mail_dict['body']
- mail.ident = mail_dict['ident']
- mail.tags = mail_dict['tags']
- return mail
+ return from_dict(mail_dict)
+
+
+def from_dict(mail_dict):
+ mail = PixelatedMail()
+ mail.headers = mail_dict['header']
+ mail.body = mail_dict['body']
+ mail.ident = mail_dict['ident']
+ mail.tags = mail_dict['tags']
+ return mail
diff --git a/service/pixelated/bitmask_libraries/session.py b/service/pixelated/bitmask_libraries/session.py
index 7fccc250..bb9bd3fe 100644
--- a/service/pixelated/bitmask_libraries/session.py
+++ b/service/pixelated/bitmask_libraries/session.py
@@ -118,12 +118,7 @@ class LeapSessionFactory(object):
incoming_mail_fetcher = self._create_incoming_mail_fetcher(nicknym, soledad,
account, auth)
- smtp = self._create_smtp_service(nicknym, auth)
- smtp.start()
-
- session = LeapSession(self._provider, auth, soledad, nicknym, account, incoming_mail_fetcher)
-
- return session
+ return LeapSession(self._provider, auth, soledad, nicknym, account, incoming_mail_fetcher)
def _lookup_session(self, key):
global SESSIONS
@@ -162,9 +157,6 @@ class LeapSessionFactory(object):
return LeapIncomingMail(nicknym.keymanager, soledad_session.soledad, account,
self._config.fetch_interval_in_s, self._account_email(auth))
- def _create_smtp_service(self, nicknym, auth):
- return LeapSmtp(self._provider, nicknym.keymanager, auth)
-
def _account_email(self, auth):
domain = self._provider.domain
name = auth.user_name
diff --git a/service/pixelated/bitmask_libraries/smtp.py b/service/pixelated/bitmask_libraries/smtp.py
index 94214e4c..76a232a6 100644
--- a/service/pixelated/bitmask_libraries/smtp.py
+++ b/service/pixelated/bitmask_libraries/smtp.py
@@ -35,7 +35,7 @@ class LeapSmtp(object):
print "## SMTP port: " + str(self._twisted_port)
def smtp_info(self):
- return ('localhost', LeapSmtp.SMTP_PORT)
+ return ('localhost', self._twisted_port)
def _discover_smtp_server(self):
json_data = self._provider.fetch_smtp_json()
@@ -79,7 +79,7 @@ class LeapSmtp(object):
email = '%s@%s' % (self._srp_session.user_name, self._provider.domain)
self._smtp_service, self._smtp_port = setup_smtp_gateway(
- port=(self._twisted_port),
+ port=self._twisted_port,
userid=email,
keymanager=self._keymanager,
smtp_host=self._hostname.encode('UTF-8'),
diff --git a/service/pixelated/user_agent.py b/service/pixelated/user_agent.py
index 433d4770..4b234fe8 100644
--- a/service/pixelated/user_agent.py
+++ b/service/pixelated/user_agent.py
@@ -36,7 +36,6 @@ app.config.from_pyfile(os.path.join(os.environ['HOME'], '.pixelated'))
leap_session = open_leap_session(app.config['LEAP_USERNAME'], app.config['LEAP_PASSWORD'], app.config['LEAP_SERVER_NAME'])
mail_service = MailService(leap_session)
-
def respond_json(entity):
response = json.dumps(entity)
return Response(response=response, mimetype="application/json")
@@ -54,14 +53,10 @@ def disabled_features():
@app.route('/mails', methods=['POST'])
-def save_draft_or_send():
- ident = None
- if 'sent' in request.json['tags']:
- ident = mail_service.send_draft(converter.to_mail(request.json, account))
- else:
- ident = mail_service.save_draft(converter.to_mail(request.json, account))
- return respond_json({'ident': ident})
-
+def send_mail():
+ mail = PixelatedMail.from_dict(request.json)
+ mail_service.send(mail)
+ return respond_json(None)
@app.route('/mails', methods=['PUT'])
def update_draft():
@@ -130,19 +125,11 @@ def mark_mail_as_read(mail_id):
@app.route('/contacts')
def contacts():
- query = search_query.compile(request.args.get("q"))
- desired_contacts = [converter.from_contact(contact) for contact in mail_service.all_contacts(query)]
- return respond_json({'contacts': desired_contacts})
-
+ pass
@app.route('/draft_reply_for/<mail_id>')
def draft_reply_for(mail_id):
- draft = mail_service.draft_reply_for(mail_id)
- if draft:
- return respond_json(converter.from_mail(draft))
- else:
- return respond_json(None)
-
+ pass
@app.route('/')
def index():
@@ -152,6 +139,7 @@ def index():
def setup():
debug_enabled = os.environ.get('DEBUG', False)
reactor_manager.start_reactor(logging=debug_enabled)
+ mail_service.start()
app.run(host=app.config['HOST'], debug=debug_enabled, port=app.config['PORT'])
diff --git a/service/setup.cfg b/service/setup.cfg
new file mode 100644
index 00000000..dd36c937
--- /dev/null
+++ b/service/setup.cfg
@@ -0,0 +1,2 @@
+[nosetests]
+nocapture=1
diff --git a/service/test/adapter/mail_service_test.py b/service/test/adapter/mail_service_test.py
index d736e0d0..225c08f8 100644
--- a/service/test/adapter/mail_service_test.py
+++ b/service/test/adapter/mail_service_test.py
@@ -77,3 +77,22 @@ class TestMailService(unittest.TestCase):
# then
self.assertEqual(1, len(mails))
self.assertEqual(set([Tag('custom_tag')]), mails[0].tags)
+
+
+ def test_send_mail(self):
+ leap_session = Mock(account_email=lambda: "username@leap_server")
+ mail_service = MailService(leap_session)
+ mail_service._create_smtp_server = lambda: None
+ mail_service._create_smtp_server = lambda: None
+
+ mail_service.smtp_client = Mock()
+ mail = Mock(
+ to_smtp_format=lambda _from=None: "mail as string",
+ get_to=lambda: 'to@pixelated.org'
+ )
+
+ mail_service.send(mail)
+
+ mail_service.smtp_client.sendmail.assert_called_with('username@leap_server', 'to@pixelated.org', "mail as string")
+
+
diff --git a/service/test/adapter/pixelated_mail_test.py b/service/test/adapter/pixelated_mail_test.py
index b6bf623f..7dfdc6d9 100644
--- a/service/test/adapter/pixelated_mail_test.py
+++ b/service/test/adapter/pixelated_mail_test.py
@@ -85,3 +85,10 @@ class TestPixelatedMail(unittest.TestCase):
self.assertRegexpMatches(mime_multipart.as_string(), "\nSubject: Oi\n")
self.assertRegexpMatches(mime_multipart.as_string(), "\nEste \xe9 o corpo")
+ def test_smtp_format(self):
+ mail = PixelatedMail.from_dict(self.mail_dict)
+
+ smtp_format = mail.to_smtp_format(_from='pixelated@org')
+
+ self.assertRegexpMatches(smtp_format, "\nFrom: pixelated@org")
+
diff --git a/service/test/user_agent_test.py b/service/test/user_agent_test.py
new file mode 100644
index 00000000..7c701a54
--- /dev/null
+++ b/service/test/user_agent_test.py
@@ -0,0 +1,34 @@
+#
+# Copyright (c) 2014 ThoughtWorks, Inc.
+#
+# Pixelated is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Pixelated is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# 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 unittest
+import pixelated.user_agent
+from mock import Mock
+import pixelated.adapter.pixelated_mail
+
+
+class UserAgentTest(unittest.TestCase):
+
+ def setUp(self):
+ self.app = pixelated.user_agent.app.test_client()
+
+ def test_send_mail_should_add_user_account(self):
+ pixelated.user_agent.mail_service = Mock()
+ pixelated.adapter.pixelated_mail.from_dict = lambda self: 'mail'
+
+ self.app.post('/mails', data='{}', content_type="application/json")
+
+ pixelated.user_agent.mail_service.send.assert_called_with('mail')