diff options
author | Philipp Hörist <philipp@hoerist.com> | 2019-02-24 01:49:10 +0300 |
---|---|---|
committer | Philipp Hörist <philipp@hoerist.com> | 2019-02-24 01:49:10 +0300 |
commit | eff7d037f7f2804039d0ea86059f9cea089c66eb (patch) | |
tree | 21523adcec631502ae0d54b615fb1a6374767b59 /omemo/gtk | |
parent | 77b7762cb5e2ce596bf23ce532df8b5d495697e3 (diff) |
[omemo] Show QR code in Key Dialog
Diffstat (limited to 'omemo/gtk')
-rw-r--r-- | omemo/gtk/config.py | 47 | ||||
-rw-r--r-- | omemo/gtk/config.ui | 113 | ||||
-rw-r--r-- | omemo/gtk/key.py | 95 | ||||
-rw-r--r-- | omemo/gtk/key.ui | 158 | ||||
-rw-r--r-- | omemo/gtk/style.css | 2 |
5 files changed, 228 insertions, 187 deletions
diff --git a/omemo/gtk/config.py b/omemo/gtk/config.py index fdbd343..952d4b7 100644 --- a/omemo/gtk/config.py +++ b/omemo/gtk/config.py @@ -17,12 +17,8 @@ # along with OMEMO Gajim Plugin. If not, see <http://www.gnu.org/licenses/>. import logging -import os - -from gi.repository import GdkPixbuf from gajim.common import app -from gajim.common import configpaths from gajim.plugins.gui import GajimPluginConfigDialog from gajim.plugins.helpers import get_builder @@ -30,14 +26,6 @@ from omemo.backend.util import get_fingerprint log = logging.getLogger('gajim.plugin_system.omemo') -PILLOW = False -try: - import qrcode - PILLOW = True -except ImportError as error: - log.debug(error) - log.error('python-qrcode or dependencies of it are not available') - class OMEMOConfigDialog(GajimPluginConfigDialog): def init(self): @@ -97,27 +85,6 @@ class OMEMOConfigDialog(GajimPluginConfigDialog): def account_combobox_changed_cb(self, box, *args): self.update_context_list() - @staticmethod - def _get_qrcode(jid, sid, identity_key): - fingerprint = get_fingerprint(identity_key) - file_name = 'omemo_{}.png'.format(jid) - path = os.path.join( - configpaths.get('MY_DATA'), file_name) - - ver_string = 'xmpp:{}?omemo-sid-{}={}'.format(jid, sid, fingerprint) - log.debug('Verification String: %s', ver_string) - - if os.path.exists(path): - return path - - qr = qrcode.QRCode(version=None, error_correction=2, - box_size=4, border=1) - qr.add_data(ver_string) - qr.make(fit=True) - img = qr.make_image() - img.save(path) - return path - def update_disabled_account_view(self): self._ui.disabled_account_store.clear() for account in self.disabled_accounts: @@ -168,7 +135,6 @@ class OMEMOConfigDialog(GajimPluginConfigDialog): self._ui.fingerprint_label.set_markup('') self._ui.refresh.set_sensitive(False) self._ui.cleardevice_button.set_sensitive(False) - self._ui.qrcode.clear() return active = self._ui.account_combobox.get_active() account = self._ui.account_store[active][0] @@ -192,16 +158,3 @@ class OMEMOConfigDialog(GajimPluginConfigDialog): # Set Device ID List for item in omemo.backend.get_devices(own_jid): self._ui.deviceid_store.append([item]) - - # Set QR Verification Code - if PILLOW: - path = self._get_qrcode(own_jid, - omemo.backend.own_device, - identity_key) - pixbuf = GdkPixbuf.Pixbuf.new_from_file(path) - self._ui.qrcode.set_from_pixbuf(pixbuf) - self._ui.qrcode.show() - self._ui.qrinfo.hide() - else: - self._ui.qrcode.hide() - self._ui.qrinfo.show() diff --git a/omemo/gtk/config.ui b/omemo/gtk/config.ui index b114fa0..d80a188 100644 --- a/omemo/gtk/config.ui +++ b/omemo/gtk/config.ui @@ -31,74 +31,6 @@ <property name="orientation">vertical</property> <property name="spacing">6</property> <child> - <object class="GtkInfoBar" id="qrinfo"> - <property name="can_focus">False</property> - <property name="no_show_all">True</property> - <property name="margin_bottom">6</property> - <child internal-child="action_area"> - <object class="GtkButtonBox"> - <property name="can_focus">False</property> - <property name="spacing">6</property> - <property name="layout_style">end</property> - <child> - <placeholder/> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child internal-child="content_area"> - <object class="GtkBox"> - <property name="can_focus">False</property> - <property name="halign">start</property> - <property name="spacing">6</property> - <child> - <object class="GtkLabel"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="no_show_all">True</property> - <property name="halign">start</property> - <property name="label" translatable="yes">For verification via QR-Code you have to install</property> - <property name="wrap">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkLabel"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="halign">start</property> - <property name="label" translatable="yes">python-qrcode</property> - <property name="selectable">True</property> - </object> - <packing> - <property name="expand">True</property> - <property name="fill">True</property> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">0</property> - </packing> - </child> - <child> <object class="GtkGrid"> <property name="visible">True</property> <property name="can_focus">False</property> @@ -213,40 +145,14 @@ </packing> </child> <child> - <object class="GtkImage" id="qrcode"> - <property name="can_focus">False</property> - <property name="no_show_all">True</property> - <property name="tooltip_text" translatable="yes">Scan this QR-Code with your mobile device for easy verification</property> - <property name="halign">start</property> - <property name="margin_top">6</property> - <property name="margin_bottom">6</property> - <property name="stock">gtk-missing-image</property> - <property name="icon_size">1</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">3</property> - </packing> - </child> - <child> - <object class="GtkImage" id="image"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="tooltip_text">OMEMO</property> - <property name="valign">start</property> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">3</property> - </packing> - </child> - <child> <object class="GtkLabel"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="halign">start</property> <property name="label" translatable="yes">Note: Fingerprints of your contacts are managed in the message window.</property> <property name="wrap">True</property> + <property name="max_width_chars">50</property> + <property name="xalign">0</property> <attributes> <attribute name="style" value="italic"/> </attributes> @@ -256,17 +162,26 @@ </object> <packing> <property name="left_attach">1</property> - <property name="top_attach">4</property> + <property name="top_attach">3</property> </packing> </child> <child> - <placeholder/> + <object class="GtkImage" id="image"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="halign">end</property> + <property name="stock">gtk-missing-image</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">3</property> + </packing> </child> </object> <packing> <property name="expand">False</property> <property name="fill">True</property> - <property name="position">1</property> + <property name="position">0</property> </packing> </child> </object> diff --git a/omemo/gtk/key.py b/omemo/gtk/key.py index 73524cf..f1bc575 100644 --- a/omemo/gtk/key.py +++ b/omemo/gtk/key.py @@ -14,14 +14,17 @@ # You should have received a copy of the GNU General Public License # along with OMEMO Gajim Plugin. If not, see <http://www.gnu.org/licenses/>. +import os import time import logging +import tempfile from gi.repository import Gtk from gi.repository import GdkPixbuf from gajim.common import app from gajim.plugins.plugins_i18n import _ +from gajim.plugins.helpers import get_builder from omemo.gtk.util import DialogButton, ButtonAction from omemo.gtk.util import NewConfirmationDialog @@ -31,6 +34,7 @@ from omemo.backend.util import get_fingerprint log = logging.getLogger('gajim.plugin_system.omemo') + TRUST_DATA = { Trust.NOT_TRUSTED: ('dialog-error-symbolic', _('Not Trusted'), @@ -64,56 +68,27 @@ class KeyDialog(Gtk.Dialog): self._omemo = self._plugin.get_omemo(self._account) self._own_jid = app.get_jid_from_account(self._account) - # Header - jid = self._contact.jid - self._header = Gtk.Label(label=_('Fingerprints for %s') % jid) - self._header.get_style_context().add_class('bold') - self._header.get_style_context().add_class('dim-label') + path = self._plugin.local_file_path('gtk/key.ui') + self._ui = get_builder(path) - # Fingerprints list - self._listbox = Gtk.ListBox() - self._listbox.set_selection_mode(Gtk.SelectionMode.NONE) + self._ui.header.set_text(_('Fingerprints for %s') % self._contact.jid) - self._scrolled = Gtk.ScrolledWindow() - self._scrolled.set_policy(Gtk.PolicyType.NEVER, - Gtk.PolicyType.AUTOMATIC) - self._scrolled.add(self._listbox) + omemo_img_path = self._plugin.local_file_path('omemo.png') + self._ui.omemo_image.set_from_file(omemo_img_path) - # Own fingerprint - self._label = Gtk.Label(label=_('Own Fingerprint')) - self._label.get_style_context().add_class('bold') - self._label.get_style_context().add_class('dim-label') + self._identity_key = self._omemo.backend.storage.getIdentityKeyPair() + ownfpr_format = get_fingerprint(self._identity_key, formatted=True) + self._ui.own_fingerprint.set_text(ownfpr_format) - self._omemo_logo = Gtk.Image() - omemo_img_path = self._plugin.local_file_path('omemo.png') - omemo_pixbuf = GdkPixbuf.Pixbuf.new_from_file(omemo_img_path) - self._omemo_logo.set_from_pixbuf(omemo_pixbuf) - - identity_key = self._omemo.backend.storage.getIdentityKeyPair() - ownfpr_format = get_fingerprint(identity_key, formatted=True) - self._ownfpr = Gtk.Label(label=ownfpr_format) - self._ownfpr.get_style_context().add_class('omemo-mono') - self._ownfpr.set_selectable(True) - - self._ownfpr_box = Gtk.Box(spacing=12) - self._ownfpr_box.set_halign(Gtk.Align.CENTER) - self._ownfpr_box.pack_start(self._omemo_logo, True, True, 0) - self._ownfpr_box.pack_start(self._ownfpr, True, True, 0) - - box = self.get_content_area() - box.set_orientation(Gtk.Orientation.VERTICAL) - box.set_spacing(12) - box.pack_start(self._header, False, True, 0) - box.pack_start(self._scrolled, True, True, 0) - box.pack_start(self._label, False, True, 0) - box.pack_start(self._ownfpr_box, False, True, 0) + self.get_content_area().add(self._ui.grid) self.update() + self._load_qrcode() self.connect('destroy', self._on_destroy) self.show_all() def update(self): - self._listbox.foreach(self._listbox.remove) + self._ui.list.foreach(self._ui.list.remove) self._load_fingerprints(self._own_jid) self._load_fingerprints(self._contact.jid, self._groupchat is True) @@ -153,7 +128,45 @@ class KeyDialog(Gtk.Dialog): key_row.device_id = item.device_id for row in rows.values(): - self._listbox.add(row) + self._ui.list.add(row) + + @staticmethod + def _get_qrcode(jid, sid, identity_key): + fingerprint = get_fingerprint(identity_key) + path = os.path.join(tempfile.gettempdir(), + 'omemo_{}.png'.format(jid)) + + ver_string = 'xmpp:{}?omemo-sid-{}={}'.format(jid, sid, fingerprint) + log.debug('Verification String: %s', ver_string) + + import qrcode + qr = qrcode.QRCode(version=None, error_correction=2, + box_size=4, border=1) + qr.add_data(ver_string) + qr.make(fit=True) + qr.make() + + back_color = 'transparent' + if app.css_config.prefer_dark: + back_color = 'white' + img = qr.make_image(fill_color='black', back_color=back_color) + img.save(path) + return path + + def _load_qrcode(self): + try: + path = self._get_qrcode(self._own_jid, + self._omemo.backend.own_device, + self._identity_key) + except ImportError: + log.exception('Failed to generate QR code') + self._ui.qrcode.hide() + self._ui.qrinfo.show() + else: + pixbuf = GdkPixbuf.Pixbuf.new_from_file(path) + self._ui.qrcode.set_from_pixbuf(pixbuf) + self._ui.qrcode.show() + self._ui.qrinfo.hide() def _on_destroy(self, *args): del self._windows['dialog'] diff --git a/omemo/gtk/key.ui b/omemo/gtk/key.ui new file mode 100644 index 0000000..b02e498 --- /dev/null +++ b/omemo/gtk/key.ui @@ -0,0 +1,158 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Generated with glade 3.22.1 --> +<interface> + <requires lib="gtk+" version="3.20"/> + <object class="GtkPopover" id="popover"> + <property name="can_focus">False</property> + <property name="constrain_to">none</property> + <child> + <object class="GtkBox"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="margin_left">12</property> + <property name="margin_right">12</property> + <property name="margin_top">12</property> + <property name="margin_bottom">12</property> + <property name="orientation">vertical</property> + <property name="spacing">12</property> + <child> + <object class="GtkLabel" id="own_fingerprint"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="selectable">True</property> + <style> + <class name="omemo-mono"/> + </style> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkImage" id="qrcode"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="stock">gtk-missing-image</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="qrinfo"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">For verification via QR-Code +you have to install python-qrcode</property> + <style> + <class name="omemo-qr-not-available"/> + </style> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">2</property> + </packing> + </child> + </object> + </child> + </object> + <object class="GtkGrid" id="grid"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="row_spacing">12</property> + <child> + <object class="GtkScrolledWindow"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="vexpand">True</property> + <property name="hscrollbar_policy">never</property> + <property name="shadow_type">in</property> + <property name="min_content_height">270</property> + <property name="overlay_scrolling">False</property> + <child> + <object class="GtkViewport"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <child> + <object class="GtkListBox" id="list"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="selection_mode">none</property> + </object> + </child> + </object> + </child> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">1</property> + </packing> + </child> + <child> + <object class="GtkMenuButton"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="halign">center</property> + <property name="valign">center</property> + <property name="direction">up</property> + <property name="popover">popover</property> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Own Fingerprint</property> + </object> + </child> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">2</property> + </packing> + </child> + <child> + <object class="GtkBox"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="halign">center</property> + <property name="spacing">11</property> + <child> + <object class="GtkImage" id="omemo_image"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="stock">gtk-missing-image</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="header"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <style> + <class name="dim-label"/> + <class name="bold"/> + </style> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">0</property> + </packing> + </child> + </object> +</interface> diff --git a/omemo/gtk/style.css b/omemo/gtk/style.css index 5d1003a..0361536 100644 --- a/omemo/gtk/style.css +++ b/omemo/gtk/style.css @@ -1,6 +1,8 @@ .omemo-dark-success-color { color: darker(@success_color); } .omemo-inactive-color { color: @insensitive_fg_color; } +.omemo-qr-not-available {color: red;} + .omemo-mono { font-size: 12px; font-family: monospace; } .omemo-last-seen { font-size: 11px; } |