[omemo] Show QR code in Key Dialog
This commit is contained in:
@@ -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()
|
||||
|
||||
@@ -30,74 +30,6 @@
|
||||
<property name="border_width">18</property>
|
||||
<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>
|
||||
@@ -213,15 +145,20 @@
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage" id="qrcode">
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<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>
|
||||
<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>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
@@ -232,41 +169,19 @@
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
||||
<attributes>
|
||||
<attribute name="style" value="italic"/>
|
||||
</attributes>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</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>
|
||||
|
||||
@@ -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)
|
||||
|
||||
# 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._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)
|
||||
self._ui.omemo_image.set_from_file(omemo_img_path)
|
||||
|
||||
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._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._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']
|
||||
|
||||
158
omemo/gtk/key.ui
Normal file
158
omemo/gtk/key.ui
Normal file
@@ -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>
|
||||
@@ -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; }
|
||||
|
||||
Reference in New Issue
Block a user