From c49293b7f3eff7a478fc388768366e7b025f7da0 Mon Sep 17 00:00:00 2001 From: Ruben Pollan Date: Wed, 2 Aug 2017 00:05:25 +0200 Subject: [feat] Display mixnet status on outgoing emails --- service/src/pixelated/resources/mixnet_resource.py | 61 ++++++++++++++++++++++ service/src/pixelated/resources/root_resource.py | 2 + web-ui/app/js/mail_view/ui/recipients/recipient.js | 20 +++++++ web-ui/app/scss/base/_colors.scss | 3 ++ web-ui/app/scss/views/_compose-view.scss | 29 ++++++++++ web-ui/app/templates/compose/fixed_recipient.hbs | 2 +- 6 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 service/src/pixelated/resources/mixnet_resource.py diff --git a/service/src/pixelated/resources/mixnet_resource.py b/service/src/pixelated/resources/mixnet_resource.py new file mode 100644 index 00000000..aa895c91 --- /dev/null +++ b/service/src/pixelated/resources/mixnet_resource.py @@ -0,0 +1,61 @@ +# +# Copyright (c) 2017 LEAP +# +# 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 . + +import json + +from email.utils import parseaddr +from pixelated.resources import respond_json_deferred, BaseResource +from twisted.web import server +from twisted.logger import Logger +from txzmq import ZmqEndpoint, ZmqEndpointType +from txzmq import ZmqFactory, ZmqREQConnection + +from leap.bitmask.core import ENDPOINT + + +class MixnetResource(BaseResource): + # XXX: this is hacky, we should use bitmask.js properly in the web-ui + # But, if we and up doing zmq interface, we can do + # something more generic for all the API. + + isLeaf = True + log = Logger() + + def render_GET(self, request): + zf = ZmqFactory() + e = ZmqEndpoint(ZmqEndpointType.connect, ENDPOINT) + _conn = ZmqREQConnection(zf, e) + + _mail = self.mail_service(request) + userid = _mail.account_email + _, address = parseaddr(request.args.get('search')[0]) + + def callback(resp_json): + response = json.loads(resp_json[0]) + if response['error'] is not None: + respond_json_deferred(response['error'], request, status_code=404) + else: + respond_json_deferred(response['result'], request, status_code=200) + + def err(fail): + respond_json_deferred(str(fail), request, status_code=404) + + data = ["mail", "mixnet_status", userid, address] + d = _conn.sendMsg(*data) + d.addCallback(callback) + d.addErrback(err) + + return server.NOT_DONE_YET diff --git a/service/src/pixelated/resources/root_resource.py b/service/src/pixelated/resources/root_resource.py index b014a590..6398c000 100644 --- a/service/src/pixelated/resources/root_resource.py +++ b/service/src/pixelated/resources/root_resource.py @@ -35,6 +35,7 @@ from pixelated.resources.mail_resource import MailResource from pixelated.resources.mails_resource import MailsResource from pixelated.resources.tags_resource import TagsResource from pixelated.resources.keys_resource import KeysResource +from pixelated.resources.mixnet_resource import MixnetResource from twisted.web.resource import NoResource from twisted.web.static import File @@ -96,6 +97,7 @@ class RootResource(BaseResource): self._child_resources.add('backup-account', BackupAccountResource(self._services_factory, authenticator, provider)) self._child_resources.add('sandbox', SandboxResource(self._protected_static_folder)) self._child_resources.add('keys', KeysResource(self._services_factory)) + self._child_resources.add('mixnet', MixnetResource(self._services_factory)) self._child_resources.add(AttachmentsResource.BASE_URL, AttachmentsResource(self._services_factory)) self._child_resources.add('contacts', ContactsResource(self._services_factory)) self._child_resources.add('features', FeaturesResource(provider)) diff --git a/web-ui/app/js/mail_view/ui/recipients/recipient.js b/web-ui/app/js/mail_view/ui/recipients/recipient.js index c13a52b1..19866108 100644 --- a/web-ui/app/js/mail_view/ui/recipients/recipient.js +++ b/web-ui/app/js/mail_view/ui/recipients/recipient.js @@ -89,6 +89,25 @@ define( }.bind(this)); }; + this.discoverMixnet = function () { + var p = $.getJSON('/mixnet?search=' + this.attr.address).promise(); + p.done(function (stat) { + switch (stat.status) { + case 'ok': + this.$node.find('.recipient-mixnet').addClass('mixnet'); + break; + case 'unsuported': + this.$node.find('.recipient-mixnet').addClass('unsuported-mixnet'); + break; + default: + this.$node.find('.recipient-mixnet').addClass('not-mixnet'); + } + }.bind(this)); + p.fail(function () { + this.$node.find('.recipient-mixnet').addClass('not-mixnet'); + }.bind(this)); + }; + this.getMailAddress = function() { return this.$node.find('input[type=hidden]').val(); }; @@ -105,6 +124,7 @@ define( this.sinalizeInvalid(); } else { this.discoverEncryption(); + this.discoverMixnet(); } }); } diff --git a/web-ui/app/scss/base/_colors.scss b/web-ui/app/scss/base/_colors.scss index c7807e8f..c23714f1 100644 --- a/web-ui/app/scss/base/_colors.scss +++ b/web-ui/app/scss/base/_colors.scss @@ -59,6 +59,9 @@ $will_be_encrypted: $success; $wont_be_encrypted: $attention; $recipients_font_color: #828282; +$will_be_mixed: $success; +$unsuported_mixed: $light_gray; + /* Attachments */ $attachment_text: #555; $attachment_icon: lighten($attachment_text, 30); diff --git a/web-ui/app/scss/views/_compose-view.scss b/web-ui/app/scss/views/_compose-view.scss index 61e785a0..be193186 100644 --- a/web-ui/app/scss/views/_compose-view.scss +++ b/web-ui/app/scss/views/_compose-view.scss @@ -344,6 +344,35 @@ background-color: $background_light_grey; border: 1px solid $border_light_grey; border-radius: 2px; + + .recipient-mixnet { + &:before { + font-family: FontAwesome; + padding-right: 6px; + font-size: 1.4em; + } + + &.mixnet { + &:before { + color: $will_be_mixed; + content: "\f135"; + } + } + + &.unsuported-mixnet { + &:before { + color: $unsuported_mixed; + content: "\f135"; + } + } + + &.not-mixnet { + &:before { + color: $unsuported_mixed; + content: ""; + } + } + } } .recipient-del { diff --git a/web-ui/app/templates/compose/fixed_recipient.hbs b/web-ui/app/templates/compose/fixed_recipient.hbs index 8b01717c..59efd7e3 100644 --- a/web-ui/app/templates/compose/fixed_recipient.hbs +++ b/web-ui/app/templates/compose/fixed_recipient.hbs @@ -1,7 +1,7 @@