Commit ae8f802e authored by Tijmen de Mes's avatar Tijmen de Mes

Added dialog to import private key

parent 9039ac25
import os
import re
import uuid
from collections import deque
from PyQt5 import uic
from PyQt5.QtCore import Qt, QObject, pyqtSignal
from PyQt5.QtWidgets import QApplication, QDialogButtonBox, QStyle, QDialog
from pgpy import PGPMessage
from pgpy.errors import PGPEncryptionError, PGPDecryptionError
from application import log
from application.notification import IObserver, NotificationCenter, NotificationData
from application.python import Null
......@@ -21,13 +30,109 @@ from sipsimple.streams.msrp.chat import CPIMPayload, CPIMParserError, CPIMNamesp
from sipsimple.threading import run_in_thread
from sipsimple.util import ISOTimestamp
from blink.sessions import SessionManager, StreamDescription
from blink.resources import Resources
from blink.sessions import SessionManager, StreamDescription, IncomingDialogBase
from blink.util import run_in_gui_thread
__all__ = ['MessageManager', 'BlinkMessage']
ui_class, base_class = uic.loadUiType(Resources.get('import_private_key_dialog.ui'))
class ImportDialog(IncomingDialogBase, ui_class):
def __init__(self, parent=None):
super(ImportDialog, self).__init__(parent)
self.setWindowFlags(self.windowFlags() | Qt.WindowStaysOnTopHint)
self.setAttribute(Qt.WA_DeleteOnClose)
with Resources.directory:
self.setupUi(self)
self.slot = None
self.import_button = self.dialog_button_box.addButton("Import", QDialogButtonBox.AcceptRole)
self.import_button.setIcon(QApplication.style().standardIcon(QStyle.SP_DialogApplyButton))
self.import_button.setEnabled(False)
def show(self, activate=True):
self.setAttribute(Qt.WA_ShowWithoutActivating, not activate)
super(ImportDialog, self).show()
class ImportPrivateKeyRequest(QObject):
finished = pyqtSignal(object)
accepted = pyqtSignal(object, str)
rejected = pyqtSignal(object)
sip_prefix_re = re.compile('^sips?:')
priority = 6
def __init__(self, dialog, body, account):
super(ImportPrivateKeyRequest, self).__init__()
self.account = account
self.dialog = dialog
self.dialog.pin_code_input.textChanged.connect(self._SH_ChatInputTextChanged)
self.stylesheet = self.dialog.pin_code_input.styleSheet()
self.reset = False
self.dialog.finished.connect(self._SH_DialogFinished)
uri = self.sip_prefix_re.sub('', str(account.uri))
self.dialog.account_value_label.setText(uri)
regex = "(?P<before>.*)(?P<pgp_message>-----BEGIN PGP MESSAGE-----.*-----END PGP MESSAGE-----)(?P<after>.*)"
matches = re.search(regex, body, re.DOTALL)
pgp_message = matches.group('pgp_message')
self.before = matches.group('before')
self.after = matches.group('after')
self.pgp_message = PGPMessage.from_blob(pgp_message.encode())
def __eq__(self, other):
return self is other
def __ne__(self, other):
return self is not other
def __lt__(self, other):
return self.priority < other.priority
def __le__(self, other):
return self.priority <= other.priority
def __gt__(self, other):
return self.priority > other.priority
def __ge__(self, other):
return self.priority >= other.priority
def _SH_ChatInputTextChanged(self, text):
if len(text) == 6:
try:
decrypted_pgp_key = self.pgp_message.decrypt(text.strip())
self.private_key = decrypted_pgp_key.message
except PGPDecryptionError as e:
log.warning(f'Decryption of public_key import failed: {e}')
new_stylesheet = f"color: #800000; background-color: #ffcfcf; {self.stylesheet}"
self.dialog.pin_code_input.setStyleSheet(new_stylesheet)
self.reset = True
else:
self.dialog.import_button.setEnabled(True)
self.dialog.pin_code_input.setEnabled(False)
new_stylesheet = f"color: #00a000; background-color: #d8ffd8; {self.stylesheet}"
self.dialog.pin_code_input.setStyleSheet(new_stylesheet)
else:
self.dialog.import_button.setEnabled(False)
if self.reset:
self.dialog.pin_code_input.setStyleSheet(self.stylesheet)
self.reset = False
def _SH_DialogFinished(self, result):
self.finished.emit(self)
if result == QDialog.Accepted:
self.accepted.emit(self, f'{self.before}{self.private_key}{self.after}')
elif result == QDialog.Rejected:
self.rejected.emit(self)
class BlinkMessage(MSRPChatMessage):
__slots__ = 'id', 'disposition'
......
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>dialog</class>
<widget class="QDialog" name="dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>660</width>
<height>260</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>660</width>
<height>260</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>660</width>
<height>260</height>
</size>
</property>
<property name="windowTitle">
<string>Import Private Key</string>
</property>
<property name="windowIcon">
<iconset>
<normaloff>icons/blink48.png</normaloff>icons/blink48.png</iconset>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="leftMargin">
<number>10</number>
</property>
<property name="topMargin">
<number>10</number>
</property>
<property name="rightMargin">
<number>10</number>
</property>
<property name="bottomMargin">
<number>10</number>
</property>
<property name="spacing">
<number>5</number>
</property>
<item row="0" column="0">
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>5</number>
</property>
<property name="rightMargin">
<number>5</number>
</property>
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap>icons/work/lock.svg</pixmap>
</property>
<property name="margin">
<number>10</number>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="1">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="label">
<property name="font">
<font>
<pointsize>14</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Import Private Key</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Blink uses end-to-end encryption for messaging for which it needs a private key.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLineEdit" name="pin_code_input">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="baseSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="font">
<font>
<pointsize>16</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
<property name="styleSheet">
<string notr="true">letter-spacing: 12px;</string>
</property>
<property name="inputMethodHints">
<set>Qt::ImhDigitsOnly|Qt::ImhNoPredictiveText|Qt::ImhPreferNumbers</set>
</property>
<property name="maxLength">
<number>6</number>
</property>
<property name="frame">
<bool>true</bool>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="font">
<font>
<kerning>true</kerning>
</font>
</property>
<property name="text">
<string> A private key has been sent from one of your other devices. Enter the code shown on the sending device to import it.</string>
</property>
<property name="scaledContents">
<bool>false</bool>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="1" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="account_value_label">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="acceptDrops">
<bool>false</bool>
</property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="text">
<string notr="true">user@domain.com</string>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="dialog_button_box">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel</set>
</property>
<property name="centerButtons">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>dialog_button_box</sender>
<signal>rejected()</signal>
<receiver>dialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>402</x>
<y>229</y>
</hint>
<hint type="destinationlabel">
<x>329</x>
<y>129</y>
</hint>
</hints>
</connection>
<connection>
<sender>dialog_button_box</sender>
<signal>accepted()</signal>
<receiver>dialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>402</x>
<y>229</y>
</hint>
<hint type="destinationlabel">
<x>329</x>
<y>129</y>
</hint>
</hints>
</connection>
</connections>
</ui>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment