summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--service/pixelated/adapter/mailstore/leap_mailstore.py25
-rw-r--r--service/pixelated/extensions/incoming_decrypt_header.py35
-rw-r--r--service/test/integration/test_leap_mailstore.py2
-rw-r--r--service/test/unit/adapter/mailstore/test_leap_mail.py23
-rw-r--r--web-ui/app/js/mail_view/ui/mail_view.js36
5 files changed, 68 insertions, 53 deletions
diff --git a/service/pixelated/adapter/mailstore/leap_mailstore.py b/service/pixelated/adapter/mailstore/leap_mailstore.py
index 993f413c..a27ce5c4 100644
--- a/service/pixelated/adapter/mailstore/leap_mailstore.py
+++ b/service/pixelated/adapter/mailstore/leap_mailstore.py
@@ -16,13 +16,13 @@
import base64
from email.header import decode_header
import quopri
-import re
from uuid import uuid4
+
+import re
from leap.mail.adaptors.soledad import SoledadMailAdaptor, ContentDocWrapper
from twisted.internet import defer
from pixelated.adapter.mailstore.body_parser import BodyParser
from pixelated.adapter.mailstore.mailstore import MailStore, underscore_uuid
-
from leap.mail.mail import Message
from pixelated.adapter.model.mail import Mail, InputMail
@@ -75,6 +75,26 @@ class LeapMail(Mail):
return self._mailbox_name
@property
+ def security_casing(self):
+ casing = dict(imprints=self._signature_information(), locks=[])
+ if self._encrypted() == "decrypted":
+ casing["locks"] = [{"state": "valid"}]
+ return casing
+
+ def _encrypted(self):
+ return self.headers.get("X-Leap-Encryption", "false")
+
+ def _signature_information(self):
+ signature = self.headers.get("X-Leap-Signature", None)
+ if signature is None or signature.startswith("could not verify"):
+ return [{"state": "no_signature_information"}]
+ else:
+ if signature.startswith("valid"):
+ return [{"state": "valid", "seal": {"validity": "valid"}}]
+ else:
+ return []
+
+ @property
def raw(self):
result = u''
for k, v in self._headers.items():
@@ -107,6 +127,7 @@ class LeapMail(Mail):
'tags': self.tags,
'status': list(self.status),
'body': self._body,
+ 'security_casing': self.security_casing,
'textPlainBody': self._body,
'replying': self._replying_dict(),
'mailbox': self._mailbox_name.lower(),
diff --git a/service/pixelated/extensions/incoming_decrypt_header.py b/service/pixelated/extensions/incoming_decrypt_header.py
deleted file mode 100644
index 2db5dd1d..00000000
--- a/service/pixelated/extensions/incoming_decrypt_header.py
+++ /dev/null
@@ -1,35 +0,0 @@
-import leap.mail.imap.fetch as fetch
-
-
-def mark_as_encrypted_inline(f):
-
- def w(*args, **kwargs):
- msg, valid_sign = f(*args)
- is_encrypted = fetch.PGP_BEGIN in args[1].as_string() and fetch.PGP_END in args[1].as_string()
- decrypted_successfully = fetch.PGP_BEGIN not in msg.as_string() and fetch.PGP_END not in msg.as_string()
-
- if not is_encrypted:
- encrypted = 'false'
- else:
- if decrypted_successfully:
- encrypted = 'true'
- else:
- encrypted = 'fail'
-
- msg.add_header('X-Pixelated-encryption-status', encrypted)
- return msg, valid_sign
-
- return w
-
-
-def mark_as_encrypted_multipart(f):
-
- def w(*args, **kwargs):
- msg, valid_sign = f(*args)
- msg.add_header('X-Pixelated-encryption-status', 'true')
- return msg, valid_sign
- return w
-
-
-fetch.LeapIncomingMail._maybe_decrypt_inline_encrypted_msg = mark_as_encrypted_inline(fetch.LeapIncomingMail._maybe_decrypt_inline_encrypted_msg)
-fetch.LeapIncomingMail._decrypt_multipart_encrypted_msg = mark_as_encrypted_multipart(fetch.LeapIncomingMail._decrypt_multipart_encrypted_msg)
diff --git a/service/test/integration/test_leap_mailstore.py b/service/test/integration/test_leap_mailstore.py
index abe5d584..8f401bdd 100644
--- a/service/test/integration/test_leap_mailstore.py
+++ b/service/test/integration/test_leap_mailstore.py
@@ -31,7 +31,7 @@ class LeapMailStoreTest(SoledadTestBase):
self.maxDiff = None
mail = load_mail_from_file('mbox00000000')
mail_id = yield self._create_mail_in_soledad(mail)
- expected_mail_dict = {'body': u'Dignissimos ducimus veritatis. Est tenetur consequatur quia occaecati. Vel sit sit voluptas.\n\nEarum distinctio eos. Accusantium qui sint ut quia assumenda. Facere dignissimos inventore autem sit amet. Pariatur voluptatem sint est.\n\nUt recusandae praesentium aspernatur. Exercitationem amet placeat deserunt quae consequatur eum. Unde doloremque suscipit quia.\n\n', 'header': {u'date': u'Tue, 21 Apr 2015 08:43:27 +0000 (UTC)', u'to': [u'carmel@murazikortiz.name'], u'x-tw-pixelated-tags': u'nite, macro, trash', u'from': u'darby.senger@zemlak.biz', u'subject': u'Itaque consequatur repellendus provident sunt quia.'}, 'ident': mail_id, 'status': [], 'tags': set([]), 'replying': {'all': {'cc-field': [], 'to-field': [u'carmel@murazikortiz.name', u'darby.senger@zemlak.biz']}, 'single': u'darby.senger@zemlak.biz'}, 'textPlainBody': u'Dignissimos ducimus veritatis. Est tenetur consequatur quia occaecati. Vel sit sit voluptas.\n\nEarum distinctio eos. Accusantium qui sint ut quia assumenda. Facere dignissimos inventore autem sit amet. Pariatur voluptatem sint est.\n\nUt recusandae praesentium aspernatur. Exercitationem amet placeat deserunt quae consequatur eum. Unde doloremque suscipit quia.\n\n', 'mailbox': u'inbox', 'attachments': []}
+ expected_mail_dict = {'body': u'Dignissimos ducimus veritatis. Est tenetur consequatur quia occaecati. Vel sit sit voluptas.\n\nEarum distinctio eos. Accusantium qui sint ut quia assumenda. Facere dignissimos inventore autem sit amet. Pariatur voluptatem sint est.\n\nUt recusandae praesentium aspernatur. Exercitationem amet placeat deserunt quae consequatur eum. Unde doloremque suscipit quia.\n\n', 'header': {u'date': u'Tue, 21 Apr 2015 08:43:27 +0000 (UTC)', u'to': [u'carmel@murazikortiz.name'], u'x-tw-pixelated-tags': u'nite, macro, trash', u'from': u'darby.senger@zemlak.biz', u'subject': u'Itaque consequatur repellendus provident sunt quia.'}, 'ident': mail_id, 'status': [], 'tags': set([]), 'replying': {'all': {'cc-field': [], 'to-field': [u'carmel@murazikortiz.name', u'darby.senger@zemlak.biz']}, 'single': u'darby.senger@zemlak.biz'}, 'textPlainBody': u'Dignissimos ducimus veritatis. Est tenetur consequatur quia occaecati. Vel sit sit voluptas.\n\nEarum distinctio eos. Accusantium qui sint ut quia assumenda. Facere dignissimos inventore autem sit amet. Pariatur voluptatem sint est.\n\nUt recusandae praesentium aspernatur. Exercitationem amet placeat deserunt quae consequatur eum. Unde doloremque suscipit quia.\n\n', 'mailbox': u'inbox', 'attachments': [], 'security_casing': {'imprints': [{'state': 'no_signature_information'}], 'locks': []}}
result = yield self.mail_store.get_mail(mail_id, include_body=True)
self.assertIsNotNone(result)
diff --git a/service/test/unit/adapter/mailstore/test_leap_mail.py b/service/test/unit/adapter/mailstore/test_leap_mail.py
index 9b72d8c3..571e2f60 100644
--- a/service/test/unit/adapter/mailstore/test_leap_mail.py
+++ b/service/test/unit/adapter/mailstore/test_leap_mail.py
@@ -62,6 +62,10 @@ class TestLeapMail(TestCase):
'status': [],
'body': None,
'textPlainBody': None,
+ 'security_casing': {
+ 'imprints': [{'state': 'no_signature_information'}],
+ 'locks': []
+ },
'replying': {'all': {'cc-field': [],
'to-field': ['receiver@example.test',
'test@example.test',
@@ -125,3 +129,22 @@ class TestLeapMail(TestCase):
self.assertEquals([], mail.headers['To'])
self.assertEquals([], mail.headers['Cc'])
self.assertEquals([], mail.headers['Bcc'])
+
+ def test_security_casing(self):
+ # No Encryption, no Signature
+ mail = LeapMail('id', 'INBOX', {})
+ self.assertEqual({'locks': [], 'imprints': [{'state': 'no_signature_information'}]}, mail.security_casing)
+
+ # Encryption
+ mail = LeapMail('id', 'INBOX', {'X-Leap-Encryption': 'decrypted'})
+ self.assertEqual([{'state': 'valid'}], mail.security_casing['locks'])
+
+ mail = LeapMail('id', 'INBOX', {'X-Leap-Encryption': 'false'})
+ self.assertEqual([], mail.security_casing['locks'])
+
+ # Signature
+ mail = LeapMail('id', 'INBOX', {'X-Leap-Signature': 'valid'})
+ self.assertEqual([{'seal': {'validity': 'valid'}, 'state': 'valid'}], mail.security_casing['imprints'])
+
+ mail = LeapMail('id', 'INBOX', {'X-Leap-Signature': 'invalid'})
+ self.assertEqual([], mail.security_casing['imprints'])
diff --git a/web-ui/app/js/mail_view/ui/mail_view.js b/web-ui/app/js/mail_view/ui/mail_view.js
index 7caf813a..fb640529 100644
--- a/web-ui/app/js/mail_view/ui/mail_view.js
+++ b/web-ui/app/js/mail_view/ui/mail_view.js
@@ -25,11 +25,10 @@ define(
'mixins/with_hide_and_show',
'mixins/with_mail_tagging',
'page/events',
- 'views/i18n',
- 'features'
+ 'views/i18n'
],
- function (defineComponent, templates, mailActions, viewHelpers, withHideAndShow, withMailTagging, events, i18n, features) {
+ function (defineComponent, templates, mailActions, viewHelpers, withHideAndShow, withMailTagging, events, i18n) {
return defineComponent(mailView, mailActions, withHideAndShow, withMailTagging);
@@ -50,12 +49,8 @@ define(
var signed, encrypted;
data.mail.security_casing = data.mail.security_casing || {};
- if(features.isEnabled('signatureStatus')) {
- signed = this.checkSigned(data.mail);
- }
- if(features.isEnabled('encryptionStatus')) {
- encrypted = this.checkEncrypted(data.mail);
- }
+ signed = this.checkSigned(data.mail);
+ encrypted = this.checkEncrypted(data.mail);
var attachments = _.map(data.mail.attachments, function(a){
return { 'encoding': a.encoding, 'name': a.name, 'ident': a.ident };
@@ -69,7 +64,6 @@ define(
tags: data.mail.tags,
encryptionStatus: encrypted,
signatureStatus: signed,
- features: features,
attachments: attachments
}));
@@ -104,16 +98,29 @@ define(
var status = ['encrypted'];
- if(_.any(mail.security_casing.locks, function (lock) { return lock.state === 'valid'; })) { status.push('encryption-valid'); }
- else { status.push('encryption-error'); }
+ var hasAnyEncryptionInfo = _.any(mail.security_casing.locks, function (lock) {
+ return lock.state === 'valid';
+ });
+
+ if(hasAnyEncryptionInfo) {
+ status.push('encryption-valid');
+ } else {
+ status.push('encryption-error');
+ }
return status.join(' ');
};
this.checkSigned = function(mail) {
- if(_.isEmpty(mail.security_casing.imprints)) { return 'not-signed'; }
+ if(_.isEmpty(mail.security_casing.imprints)) {
+ return 'not-signed';
+ }
+
+ var hasNoSignatureInformation = _.any(mail.security_casing.imprints, function (imprint) {
+ return imprint.state === 'no_signature_information';
+ });
- if(_.any(mail.security_casing.imprints, function(imprint) { return imprint.state === 'no_signature_information'; })) {
+ if(hasNoSignatureInformation) {
return '';
}
@@ -130,7 +137,6 @@ define(
status.push('signature-not-trusted');
}
-
return status.join(' ');
};