# -*- coding: utf-8 -*- # advanced_key_management.py # Copyright (C) 2013 LEAP # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . """ Advanced Key Management """ from PySide import QtGui from leap.bitmask.logs.utils import get_logger from leap.bitmask.services import get_service_display_name, MX_SERVICE from ui_advanced_key_management import Ui_AdvancedKeyManagement logger = get_logger() class AdvancedKeyManagement(QtGui.QDialog): """ Advanced Key Management """ def __init__(self, parent, has_mx, user, backend, soledad_started): """ :param parent: parent object of AdvancedKeyManagement. :parent type: QWidget :param has_mx: defines whether the current provider provides email or not. :type has_mx: bool :param user: the current logged in user. :type user: unicode :param backend: Backend being used :type backend: Backend :param soledad_started: whether soledad has started or not :type soledad_started: bool """ QtGui.QDialog.__init__(self, parent) self.ui = Ui_AdvancedKeyManagement() self.ui.setupUi(self) # XXX: Temporarily disable the key import. self.ui.pbImportKeys.setVisible(False) if not has_mx: msg = self.tr("The provider that you are using " "does not support {0}.") msg = msg.format(get_service_display_name(MX_SERVICE)) self._disable_ui(msg) return if not soledad_started: msg = self.tr("To use this, you need to enable/start {0}.") msg = msg.format(get_service_display_name(MX_SERVICE)) self._disable_ui(msg) return # XXX: since import is disabled this is no longer a dangerous feature. # else: # msg = self.tr( # "WARNING:
" # "This is an experimental feature, you can lose access to " # "existing e-mails.") # self.ui.lblStatus.setText(msg) self._user = user self._backend = backend self._backend_connect() # show current key information self.ui.leUser.setText(user) # set up connections self.ui.pbImportKeys.clicked.connect(self._import_keys) self.ui.pbExportKeys.clicked.connect(self._export_keys) # Stretch columns to content self.ui.twPublicKeys.horizontalHeader().setResizeMode( 0, QtGui.QHeaderView.Stretch) self._backend.keymanager_get_key_details(user) self._backend.keymanager_list_keys() def _keymanager_key_details(self, details): """ Set the current user's key details into the gui. """ # XXX: We should avoid the key-id self.ui.leKeyID.setText(details[0]) self.ui.leFingerprint.setText(details[1]) def _disable_ui(self, msg): """ Disable the UI and set a note in the status bar. :param msg: note to display in the status bar. :type msg: unicode """ self.ui.gbMyKeyPair.setEnabled(False) self.ui.gbStoredPublicKeys.setEnabled(False) msg = self.tr("NOTE: ") + msg self.ui.lblStatus.setText(msg) def _import_keys(self): """ Imports the user's key pair. Those keys need to be ascii armored. """ file_name, filtr = QtGui.QFileDialog.getOpenFileName( self, self.tr("Open keys file"), options=QtGui.QFileDialog.DontUseNativeDialog) if file_name: question = self.tr("Are you sure that you want to replace " "the current key pair with the imported?") res = QtGui.QMessageBox.question( None, "Change key pair", question, QtGui.QMessageBox.Yes | QtGui.QMessageBox.No, QtGui.QMessageBox.No) # default No if res == QtGui.QMessageBox.Yes: self._backend.keymanager_import_keys(self._user, file_name) else: logger.debug('Import canceled by the user.') def _keymanager_import_ok(self): """ TRIGGERS: Signaler.keymanager_import_ok Notify the user that the key import went OK. """ QtGui.QMessageBox.information( self, self.tr("Import Successful"), self.tr("The key pair was imported successfully.")) def _import_ioerror(self): """ TRIGGERS: Signaler.keymanager_import_ioerror Notify the user that the key import had an IOError problem. """ QtGui.QMessageBox.critical( self, self.tr("Input/Output error"), self.tr("There was an error accessing the file.\n" "Import canceled.")) def _import_datamismatch(self): """ TRIGGERS: Signaler.keymanager_import_datamismatch Notify the user that the key import had an data mismatch problem. """ QtGui.QMessageBox.warning( self, self.tr("Data mismatch"), self.tr("The public and private key should have the " "same address and fingerprint.\n" "Import canceled.")) def _import_missingkey(self): """ TRIGGERS: Signaler.keymanager_import_missingkey Notify the user that the key import failed due a missing key. """ QtGui.QMessageBox.warning( self, self.tr("Missing key"), self.tr("You need to provide the public AND private " "key in the same file.\n" "Import canceled.")) def _import_addressmismatch(self): """ TRIGGERS: Signaler.keymanager_import_addressmismatch Notify the user that the key import failed due an address mismatch. """ QtGui.QMessageBox.warning( self, self.tr("Address mismatch"), self.tr("The identity for the key needs to be the same " "as your user address.\n" "Import canceled.")) def _export_keys(self): """ Exports the user's key pair. """ file_name, filtr = QtGui.QFileDialog.getSaveFileName( self, self.tr("Save keys file"), options=QtGui.QFileDialog.DontUseNativeDialog) if file_name: self._backend.keymanager_export_keys(self._user, file_name) else: logger.debug('Export canceled by the user.') def _keymanager_export_ok(self): """ TRIGGERS: Signaler.keymanager_export_ok Notify the user that the key export went OK. """ QtGui.QMessageBox.information( self, self.tr("Export Successful"), self.tr("The key pair was exported successfully.\n" "Please, store your private key in a safe place.")) def _keymanager_export_error(self): """ TRIGGERS: Signaler.keymanager_export_error Notify the user that the key export didn't go well. """ QtGui.QMessageBox.critical( self, self.tr("Input/Output error"), self.tr("There was an error accessing the file.\n" "Export canceled.")) def _keymanager_keys_list(self, keys): """ TRIGGERS: Signaler.keymanager_keys_list Load the keys given as parameter in the table. :param keys: the list of keys to load. :type keys: list """ keys_table = self.ui.twPublicKeys for key in keys: row = keys_table.rowCount() keys_table.insertRow(row) keys_table.setItem(row, 0, QtGui.QTableWidgetItem(key.address)) keys_table.setItem(row, 1, QtGui.QTableWidgetItem(key.fingerprint)) def _backend_connect(self): """ Connect to backend signals. """ sig = self._backend.signaler sig.keymanager_export_ok.connect(self._keymanager_export_ok) sig.keymanager_export_error.connect(self._keymanager_export_error) sig.keymanager_keys_list.connect(self._keymanager_keys_list) sig.keymanager_key_details.connect(self._keymanager_key_details) sig.keymanager_import_ok.connect(self._keymanager_import_ok) sig.keymanager_import_ioerror.connect(self._import_ioerror) sig.keymanager_import_datamismatch.connect(self._import_datamismatch) sig.keymanager_import_missingkey.connect(self._import_missingkey) sig.keymanager_import_addressmismatch.connect( self._import_addressmismatch)