Commit 0f2f3ab8 authored by Dan Pascu's avatar Dan Pascu

Added OTR encryption support for chat

parent 8d54d56e
This diff is collapsed.
This diff is collapsed.
import re
from PyQt4 import uic
from PyQt4.QtCore import Qt, pyqtSignal
from PyQt4.QtGui import QStyle, QStyleOption, QStylePainter
from blink.resources import Resources
from blink.sessions import SMPVerification
__all__ = ['OTRWidget']
ui_class, base_class = uic.loadUiType(Resources.get('otr_widget.ui'))
class OTRWidget(base_class, ui_class):
closed = pyqtSignal()
nameChanged = pyqtSignal()
statusChanged = pyqtSignal()
color_table = {'green': 'hsv(100, 85%, 100%)', 'orange': 'hsv(20, 85%, 100%)'}
def __init__(self, parent=None):
super(OTRWidget, self).__init__(parent)
with Resources.directory:
self.setupUi(self)
self.__dict__.update(peer_verified=False, smp_status=SMPVerification.Unavailable) # interdependent properties (they need to preexist as their setters read each other)
self.peer_name = ''
self.peer_verified = False
self.peer_fingerprint = ''
self.my_fingerprint = ''
self.smp_status = SMPVerification.Unavailable
self.verification_stack.wrap = True
self.verification_stack.animationDuration = 200
self.close_button.clicked.connect(self.hide)
self.switch_button.clicked.connect(self.verification_stack.slideInNext)
self.peer_name_value.editingFinished.connect(self._check_name_changes)
self.validate_button.clicked.connect(self._SH_ValidateButtonClicked)
self.verification_stack.currentChanged.connect(self._SH_VerificationStackPanelChanged)
@property
def peer_name(self):
return self.peer_name_value.text()
@peer_name.setter
def peer_name(self, name):
self.__dict__['peer_name'] = name
self.peer_name_value.setText(name)
@property
def peer_verified(self):
return self.__dict__['peer_verified']
@peer_verified.setter
def peer_verified(self, verified):
self.__dict__['peer_verified'] = verified
self.validate_button.setText(u'Invalidate' if verified else u'Validate')
self.validate_button.setChecked(verified)
self.validate_button.setEnabled(verified or self.verification_stack.currentWidget() is not self.smp_panel or self.smp_status is SMPVerification.Succeeded)
self.peer_fingerprint_value.setStyleSheet(u'QLabel {{ color: {}; }}'.format(self.color_table['green'] if verified else self.color_table['orange']))
self.smp_status_value.setText(self.smp_status_text)
@property
def peer_fingerprint(self):
return self.__dict__['peer_fingerprint']
@peer_fingerprint.setter
def peer_fingerprint(self, fingerprint):
self.__dict__['peer_fingerprint'] = fingerprint
self.peer_fingerprint_value.setText(self._encode_fingerprint(fingerprint))
@property
def my_fingerprint(self):
return self.__dict__['my_fingerprint']
@my_fingerprint.setter
def my_fingerprint(self, fingerprint):
self.__dict__['my_fingerprint'] = fingerprint
self.my_fingerprint_value.setText(self._encode_fingerprint(fingerprint))
@property
def smp_status(self):
return self.__dict__['smp_status']
@smp_status.setter
def smp_status(self, status):
self.__dict__['smp_status'] = status
self.validate_button.setEnabled(self.peer_verified or self.verification_stack.currentWidget() is not self.smp_panel or self.smp_status is SMPVerification.Succeeded)
self.smp_status_value.setText(self.smp_status_text)
@property
def smp_status_text(self):
if self.peer_verified:
return u'<span style="color: {[green]};">Verified</span>'.format(self.color_table)
elif self.smp_status is SMPVerification.Succeeded:
return u'<span style="color: {[green]};">Succeeded</span>'.format(self.color_table)
elif self.smp_status is SMPVerification.Failed:
return u'<span style="color: {[orange]};">Failed</span>'.format(self.color_table)
else:
return u'{}'.format(self.smp_status.value)
def hideEvent(self, event):
if not event.spontaneous():
self.closed.emit()
self._check_name_changes()
def paintEvent(self, event):
option = QStyleOption()
option.initFrom(self)
painter = QStylePainter(self)
painter.setRenderHint(QStylePainter.Antialiasing, True)
painter.drawPrimitive(QStyle.PE_Widget if self.testAttribute(Qt.WA_NoSystemBackground) else QStyle.PE_Frame, option)
@staticmethod
def _encode_fingerprint(fingerprint):
return re.sub('....', lambda match: match.group(0) + {match.endpos: '', match.endpos//2: '<br/>'}.get(match.end(), ' '), fingerprint.encode('hex').upper())
def _check_name_changes(self):
peer_name = self.peer_name_value.text()
if peer_name != self.__dict__['peer_name']:
self.__dict__['peer_name'] = peer_name
self.nameChanged.emit()
def _SH_ValidateButtonClicked(self, checked):
self.hide()
self.peer_verified = checked
self.statusChanged.emit()
def _SH_VerificationStackPanelChanged(self, index):
self.validate_button.setEnabled(self.peer_verified or self.verification_stack.currentWidget() is not self.smp_panel or self.smp_status is SMPVerification.Succeeded)
del ui_class, base_class
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>lock_widget</class>
<widget class="QWidget" name="lock_widget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>655</width>
<height>22</height>
</rect>
</property>
<property name="windowTitle">
<string>Lock</string>
</property>
<property name="styleSheet">
<string notr="true">#lock_widget {
background: hsva(0, 0, 100%, 80%);
border: 0px;
border-radius: 3px;
}
#note_label {
margin: 0px;
padding-left: 4px;
}
#confirm_button {
background: hsv(20, 67%, 100%);
background-origin: border;
border: 0px;
border-left: 1px solid palette(dark);
border-top-right-radius: 3px;
border-bottom-right-radius: 3px;
margin: 0px;
padding: 0px 5px 0px 5px;
}
#confirm_button:hover {
background: hsv(20, 60%, 100%);
}
#confirm_button:pressed {
background: hsv(20, 60%, 90%);
}
</string>
</property>
<layout class="QHBoxLayout" name="lock_layout">
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="ElidedLabel" name="note_label">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Encryption has been terminated by the other party</string>
</property>
<property name="indent">
<number>0</number>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="confirm_button">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>Confirm</string>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>ElidedLabel</class>
<extends>QLabel</extends>
<header>blink.widgets.labels</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
This diff is collapsed.
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