summaryrefslogtreecommitdiff
path: root/src/leap/bitmask/gui
diff options
context:
space:
mode:
authorTomás Touceda <chiiph@leap.se>2014-05-28 11:05:25 -0300
committerTomás Touceda <chiiph@leap.se>2014-05-28 11:05:25 -0300
commitc85b1d594225cb71d744f387ab82107c499da947 (patch)
treee583f8bf852665c67f91d49c5e911199cb60c03b /src/leap/bitmask/gui
parent19140b9b1959218c1d6bbfec105a1d62125c2635 (diff)
parent027aff14f3ea9c6965100a625071505f63271ffd (diff)
Merge remote-tracking branch 'refs/remotes/ivan/feature/cleanup-backend-from-hacks' into develop
Diffstat (limited to 'src/leap/bitmask/gui')
-rw-r--r--src/leap/bitmask/gui/advanced_key_management.py237
-rw-r--r--src/leap/bitmask/gui/mainwindow.py217
-rw-r--r--src/leap/bitmask/gui/preferenceswindow.py114
-rw-r--r--src/leap/bitmask/gui/wizard.py73
4 files changed, 328 insertions, 313 deletions
diff --git a/src/leap/bitmask/gui/advanced_key_management.py b/src/leap/bitmask/gui/advanced_key_management.py
index 1681caca..b3a4ed8e 100644
--- a/src/leap/bitmask/gui/advanced_key_management.py
+++ b/src/leap/bitmask/gui/advanced_key_management.py
@@ -19,10 +19,8 @@ Advanced Key Management
"""
import logging
-from PySide import QtGui
+from PySide import QtCore, QtGui
-from leap.keymanager import openpgp
-from leap.keymanager.errors import KeyAddressMismatch, KeyFingerprintMismatch
from leap.bitmask.services import get_service_display_name, MX_SERVICE
from ui_advanced_key_management import Ui_AdvancedKeyManagement
@@ -33,7 +31,7 @@ class AdvancedKeyManagement(QtGui.QDialog):
"""
Advanced Key Management
"""
- def __init__(self, parent, has_mx, user, keymanager, soledad_started):
+ def __init__(self, parent, has_mx, user, backend, soledad_started):
"""
:param parent: parent object of AdvancedKeyManagement.
:parent type: QWidget
@@ -42,8 +40,8 @@ class AdvancedKeyManagement(QtGui.QDialog):
:type has_mx: bool
:param user: the current logged in user.
:type user: unicode
- :param keymanager: the existing keymanager instance
- :type keymanager: KeyManager
+ :param backend: Backend being used
+ :type backend: Backend
:param soledad_started: whether soledad has started or not
:type soledad_started: bool
"""
@@ -75,16 +73,12 @@ class AdvancedKeyManagement(QtGui.QDialog):
# "existing e-mails.")
# self.ui.lblStatus.setText(msg)
- self._keymanager = keymanager
-
- self._key = keymanager.get_key(user, openpgp.OpenPGPKey)
- self._key_priv = keymanager.get_key(
- user, openpgp.OpenPGPKey, private=True)
+ self._user = user
+ self._backend = backend
+ self._backend_connect()
# show current key information
self.ui.leUser.setText(user)
- self.ui.leKeyID.setText(self._key.key_id)
- self.ui.leFingerprint.setText(self._key.fingerprint)
# set up connections
self.ui.pbImportKeys.clicked.connect(self._import_keys)
@@ -94,7 +88,15 @@ class AdvancedKeyManagement(QtGui.QDialog):
self.ui.twPublicKeys.horizontalHeader().setResizeMode(
0, QtGui.QHeaderView.Stretch)
- self._list_keys()
+ 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.
+ """
+ self.ui.leKeyID.setText(details[0])
+ self.ui.leFingerprint.setText(details[1])
def _disable_ui(self, msg):
"""
@@ -113,53 +115,11 @@ class AdvancedKeyManagement(QtGui.QDialog):
Imports the user's key pair.
Those keys need to be ascii armored.
"""
- fileName, filtr = QtGui.QFileDialog.getOpenFileName(
+ file_name, filtr = QtGui.QFileDialog.getOpenFileName(
self, self.tr("Open keys file"),
options=QtGui.QFileDialog.DontUseNativeDialog)
- if fileName:
- new_key = ''
- try:
- with open(fileName, 'r') as keys_file:
- new_key = keys_file.read()
- except IOError as e:
- logger.error("IOError importing key. {0!r}".format(e))
- QtGui.QMessageBox.critical(
- self, self.tr("Input/Output error"),
- self.tr("There was an error accessing the file.\n"
- "Import canceled."))
- return
-
- keymanager = self._keymanager
- try:
- public_key, private_key = keymanager.parse_openpgp_ascii_key(
- new_key)
- except (KeyAddressMismatch, KeyFingerprintMismatch) as e:
- logger.error(repr(e))
- 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."))
- return
-
- if public_key is None or private_key is None:
- 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."))
- return
-
- if public_key.address != self._key.address:
- logger.error("The key does not match the ID")
- 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."))
- return
-
+ if file_name:
question = self.tr("Are you sure that you want to replace "
"the current key pair whith the imported?")
res = QtGui.QMessageBox.question(
@@ -167,61 +127,152 @@ class AdvancedKeyManagement(QtGui.QDialog):
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No,
QtGui.QMessageBox.No) # default No
- if res == QtGui.QMessageBox.No:
- return
+ if res == QtGui.QMessageBox.Yes:
+ self._backend.keymanager_import_keys(self._user, file_name)
+ else:
+ logger.debug('Import canceled by the user.')
- keymanager.delete_key(self._key)
- keymanager.delete_key(self._key_priv)
- keymanager.put_key(public_key)
- keymanager.put_key(private_key)
- keymanager.send_key(openpgp.OpenPGPKey)
+ @QtCore.Slot()
+ def _keymanager_import_ok(self):
+ """
+ TRIGGERS:
+ Signaler.keymanager_import_ok
- logger.debug('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."))
- QtGui.QMessageBox.information(
- self, self.tr("Import Successful"),
- self.tr("The key pair was imported successfully."))
- else:
- logger.debug('Import canceled by the user.')
+ @QtCore.Slot()
+ 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."))
+
+ @QtCore.Slot()
+ 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."))
+
+ @QtCore.Slot()
+ 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."))
+
+ @QtCore.Slot()
+ 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.
"""
- fileName, filtr = QtGui.QFileDialog.getSaveFileName(
+ file_name, filtr = QtGui.QFileDialog.getSaveFileName(
self, self.tr("Save keys file"),
options=QtGui.QFileDialog.DontUseNativeDialog)
- if fileName:
- try:
- with open(fileName, 'w') as keys_file:
- keys_file.write(self._key.key_data)
- keys_file.write(self._key_priv.key_data)
-
- logger.debug('Export 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."))
- except IOError as e:
- logger.error("IOError exporting key. {0!r}".format(e))
- QtGui.QMessageBox.critical(
- self, self.tr("Input/Output error"),
- self.tr("There was an error accessing the file.\n"
- "Export canceled."))
- return
+ if file_name:
+ self._backend.keymanager_export_keys(self._user, file_name)
else:
logger.debug('Export canceled by the user.')
- def _list_keys(self):
+ @QtCore.Slot()
+ def _keymanager_export_ok(self):
+ """
+ TRIGGERS:
+ Signaler.keymanager_export_ok
+
+ Notify the user that the key export went OK.
"""
- Loads all the public keys stored in the local db to the keys table.
+ 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."))
+
+ @QtCore.Slot()
+ 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."))
+
+ @QtCore.Slot()
+ def _keymanager_keys_list(self, keys):
"""
- keys = self._keymanager.get_all_keys_in_local_db()
+ 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.key_id))
+
+ 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)
diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py
index 201a24ec..cf6614be 100644
--- a/src/leap/bitmask/gui/mainwindow.py
+++ b/src/leap/bitmask/gui/mainwindow.py
@@ -23,14 +23,12 @@ import socket
from datetime import datetime
from PySide import QtCore, QtGui
-from zope.proxy import ProxyBase, setProxiedObject
from twisted.internet import reactor, threads
from leap.bitmask import __version__ as VERSION
from leap.bitmask import __version_hash__ as VERSION_HASH
from leap.bitmask.config import flags
from leap.bitmask.config.leapsettings import LeapSettings
-from leap.bitmask.config.providerconfig import ProviderConfig
from leap.bitmask.gui import statemachines
from leap.bitmask.gui.advanced_key_management import AdvancedKeyManagement
@@ -43,7 +41,6 @@ from leap.bitmask.gui.preferenceswindow import PreferencesWindow
from leap.bitmask.gui.systray import SysTray
from leap.bitmask.gui.wizard import Wizard
-from leap.bitmask import provider
from leap.bitmask.platform_init import IS_WIN, IS_MAC, IS_LINUX
from leap.bitmask.platform_init.initializers import init_platform
@@ -64,7 +61,6 @@ if IS_WIN:
from leap.bitmask.platform_init.locks import WindowsLock
from leap.bitmask.platform_init.locks import raise_window_ack
-from leap.common.check import leap_assert
from leap.common.events import register
from leap.common.events import events_pb2 as proto
@@ -178,15 +174,6 @@ class MainWindow(QtGui.QMainWindow):
self._trying_to_start_eip = False
- # This is loaded only once, there's a bug when doing that more
- # than once
- # XXX HACK!! But we need it as long as we are using
- # provider_config in here
- self._provider_config = self._backend.get_provider_config()
-
- # Used for automatic start of EIP
- self._provisional_provider_config = ProviderConfig()
-
self._already_started_eip = False
self._soledad_started = False
@@ -247,6 +234,8 @@ class MainWindow(QtGui.QMainWindow):
self._ui_mx_visible = True
self._ui_eip_visible = True
+ self._provider_details = None
+
# last minute UI manipulations
self._center_window()
@@ -279,8 +268,6 @@ class MainWindow(QtGui.QMainWindow):
self._bypass_checks = bypass_checks
self._start_hidden = start_hidden
- self._keymanager = ProxyBase(None)
-
self._mail_conductor = mail_conductor.MailConductor(self._backend)
self._mail_conductor.connect_mail_signals(self._mail_status)
@@ -383,6 +370,9 @@ class MainWindow(QtGui.QMainWindow):
self._connect_and_track(sig.prov_cancelled_setup,
self._set_login_cancelled)
+ self._connect_and_track(sig.prov_get_details,
+ self._provider_get_details)
+
# Login signals
self._connect_and_track(sig.srp_auth_ok, self._authentication_finished)
@@ -430,9 +420,14 @@ class MainWindow(QtGui.QMainWindow):
sig.backend_bad_call.connect(self._backend_bad_call)
+ sig.prov_check_api_certificate.connect(self._get_provider_details)
+
sig.prov_unsupported_client.connect(self._needs_update)
sig.prov_unsupported_api.connect(self._incompatible_api)
+ sig.prov_get_all_services.connect(
+ self._provider_get_all_services)
+
# EIP start signals
sig.eip_openvpn_already_running.connect(
self._on_eip_openvpn_already_running)
@@ -597,13 +592,14 @@ class MainWindow(QtGui.QMainWindow):
domain = self._login_widget.get_selected_provider()
logged_user = "{0}@{1}".format(self._logged_user, domain)
- has_mx = True
- if self._logged_user is not None:
- provider_config = self._get_best_provider_config()
- has_mx = provider_config.provides_mx()
+ details = self._provider_details
+ mx_provided = False
+ if details is not None:
+ mx_provided = MX_SERVICE in details.services
- akm = AdvancedKeyManagement(self, has_mx, logged_user,
- self._keymanager, self._soledad_started)
+ # XXX: handle differently not logged in user?
+ akm = AdvancedKeyManagement(self, mx_provided, logged_user,
+ self._backend, self._soledad_started)
akm.show()
@QtCore.Slot()
@@ -618,8 +614,7 @@ class MainWindow(QtGui.QMainWindow):
user = self._login_widget.get_user()
prov = self._login_widget.get_selected_provider()
preferences = PreferencesWindow(
- self, self._backend, self._provider_config,
- self._soledad_started, user, prov)
+ self, self._backend, self._soledad_started, user, prov)
self.soledad_ready.connect(preferences.set_soledad_ready)
preferences.show()
@@ -857,16 +852,9 @@ class MainWindow(QtGui.QMainWindow):
"""
providers = self._settings.get_configured_providers()
- services = set()
-
- for prov in providers:
- provider_config = ProviderConfig()
- loaded = provider_config.load(
- provider.get_provider_path(prov))
- if loaded:
- for service in provider_config.get_services():
- services.add(service)
+ self._backend.provider_get_all_services(providers)
+ def _provider_get_all_services(self, services):
self._set_eip_visible(EIP_SERVICE in services)
self._set_mx_visible(MX_SERVICE in services)
@@ -904,14 +892,11 @@ class MainWindow(QtGui.QMainWindow):
"""
Set the login label to reflect offline status.
"""
- if self._logged_in_offline:
- provider = ""
- else:
+ provider = ""
+ if not self._logged_in_offline:
provider = self.ui.lblLoginProvider.text()
- self.ui.lblLoginProvider.setText(
- provider +
- self.tr(" (offline mode)"))
+ self.ui.lblLoginProvider.setText(provider + self.tr(" (offline mode)"))
#
# systray
@@ -1165,9 +1150,8 @@ class MainWindow(QtGui.QMainWindow):
provider configuration if it's not present, otherwise will
emit the corresponding signals inmediately
"""
- # XXX should rename this provider, name clash.
- provider = self._login_widget.get_selected_provider()
- self._backend.provider_setup(provider)
+ domain = self._login_widget.get_selected_provider()
+ self._backend.provider_setup(domain)
@QtCore.Slot(dict)
def _load_provider_config(self, data):
@@ -1175,12 +1159,11 @@ class MainWindow(QtGui.QMainWindow):
TRIGGERS:
self._backend.signaler.prov_download_provider_info
- Once the provider config has been downloaded, this loads the
- self._provider_config instance with it and starts the second
- part of the bootstrapping sequence
+ Once the provider config has been downloaded, start the second
+ part of the bootstrapping sequence.
:param data: result from the last stage of the
- run_provider_select_checks
+ backend.provider_setup()
:type data: dict
"""
if data[self._backend.PASSED_KEY]:
@@ -1222,7 +1205,6 @@ class MainWindow(QtGui.QMainWindow):
self._set_label_offline()
self.offline_mode_bypass_login.emit()
else:
- leap_assert(self._provider_config, "We need a provider config")
self.ui.action_create_new_account.setEnabled(False)
if self._login_widget.start_login():
self._download_provider_config()
@@ -1290,15 +1272,13 @@ class MainWindow(QtGui.QMainWindow):
Once the provider configuration is loaded, this starts the SRP
authentication
"""
- leap_assert(self._provider_config, "We need a provider config!")
-
if data[self._backend.PASSED_KEY]:
username = self._login_widget.get_user()
password = self._login_widget.get_password()
self._show_hide_unsupported_services()
- domain = self._provider_config.get_domain()
+ domain = self._login_widget.get_selected_provider()
self._backend.user_login(domain, username, password)
else:
logger.error(data[self._backend.ERROR_KEY])
@@ -1317,7 +1297,7 @@ class MainWindow(QtGui.QMainWindow):
self._logged_user = self._login_widget.get_user()
user = self._logged_user
- domain = self._provider_config.get_domain()
+ domain = self._login_widget.get_selected_provider()
full_user_id = make_address(user, domain)
self._mail_conductor.userid = full_user_id
self._start_eip_bootstrap()
@@ -1331,7 +1311,7 @@ class MainWindow(QtGui.QMainWindow):
sig.soledad_bootstrap_failed.connect(lambda: btn_enabled(True))
sig.soledad_bootstrap_finished.connect(lambda: btn_enabled(True))
- if not self._get_best_provider_config().provides_mx():
+ if not MX_SERVICE in self._provider_details.services:
self._set_mx_visible(False)
def _start_eip_bootstrap(self):
@@ -1341,11 +1321,10 @@ class MainWindow(QtGui.QMainWindow):
"""
self._login_widget.logged_in()
- provider = self._provider_config.get_domain()
- self.ui.lblLoginProvider.setText(provider)
+ domain = self._login_widget.get_selected_provider()
+ self.ui.lblLoginProvider.setText(domain)
- self._enabled_services = self._settings.get_enabled_services(
- self._provider_config.get_domain())
+ self._enabled_services = self._settings.get_enabled_services(domain)
# TODO separate UI from logic.
if self._provides_mx_and_enabled():
@@ -1355,6 +1334,30 @@ class MainWindow(QtGui.QMainWindow):
self._maybe_start_eip()
+ @QtCore.Slot()
+ def _get_provider_details(self):
+ """
+ TRIGGERS:
+ prov_check_api_certificate
+
+ Set the attributes to know if the EIP and MX services are supported
+ and enabled.
+ This is triggered right after the provider has been set up.
+ """
+ domain = self._login_widget.get_selected_provider()
+ lang = QtCore.QLocale.system().name()
+ self._backend.provider_get_details(domain, lang)
+
+ @QtCore.Slot()
+ def _provider_get_details(self, details):
+ """
+ Set the details for the just downloaded provider.
+
+ :param details: the details of the provider.
+ :type details: ProviderConfigLight
+ """
+ self._provider_details = details
+
def _provides_mx_and_enabled(self):
"""
Defines if the current provider provides mx and if we have it enabled.
@@ -1362,9 +1365,15 @@ class MainWindow(QtGui.QMainWindow):
:returns: True if provides and is enabled, False otherwise
:rtype: bool
"""
- provider_config = self._get_best_provider_config()
- return (provider_config.provides_mx() and
- MX_SERVICE in self._enabled_services)
+ domain = self._login_widget.get_selected_provider()
+ enabled_services = self._settings.get_enabled_services(domain)
+
+ mx_enabled = MX_SERVICE in enabled_services
+ mx_provided = False
+ if self._provider_details is not None:
+ mx_provided = MX_SERVICE in self._provider_details.services
+
+ return mx_enabled and mx_provided
def _provides_eip_and_enabled(self):
"""
@@ -1373,16 +1382,23 @@ class MainWindow(QtGui.QMainWindow):
:returns: True if provides and is enabled, False otherwise
:rtype: bool
"""
- provider_config = self._get_best_provider_config()
- return (provider_config.provides_eip() and
- EIP_SERVICE in self._enabled_services)
+ domain = self._login_widget.get_selected_provider()
+ enabled_services = self._settings.get_enabled_services(domain)
+
+ eip_enabled = EIP_SERVICE in enabled_services
+ eip_provided = False
+ if self._provider_details is not None:
+ eip_provided = EIP_SERVICE in self._provider_details.services
+
+ return eip_enabled and eip_provided
def _maybe_run_soledad_setup_checks(self):
"""
Conditionally start Soledad.
"""
# TODO split.
- if not self._provides_mx_and_enabled():
+ if not self._provides_mx_and_enabled() and not flags.OFFLINE:
+ logger.debug("Does not provides and enabled MX")
return
username = self._login_widget.get_user()
@@ -1390,9 +1406,6 @@ class MainWindow(QtGui.QMainWindow):
provider_domain = self._login_widget.get_selected_provider()
if flags.OFFLINE:
- self._provisional_provider_config.load(
- provider.get_provider_path(provider_domain))
-
full_user_id = make_address(username, provider_domain)
uuid = self._settings.get_uuid(full_user_id)
self._mail_conductor.userid = full_user_id
@@ -1405,7 +1418,7 @@ class MainWindow(QtGui.QMainWindow):
self._backend.soledad_load_offline(full_user_id, password, uuid)
else:
if self._logged_user is not None:
- domain = self._provider_config.get_domain()
+ domain = self._login_widget.get_selected_provider()
self._backend.soledad_bootstrap(username, domain, password)
###################################################################
@@ -1421,12 +1434,7 @@ class MainWindow(QtGui.QMainWindow):
"""
logger.debug("Done bootstrapping Soledad")
- # Update the proxy objects to point to the initialized instances.
- # setProxiedObject(self._soledad, self._backend.get_soledad())
- setProxiedObject(self._keymanager, self._backend.get_keymanager())
-
self._soledad_started = True
-
self.soledad_ready.emit()
###################################################################
@@ -1457,19 +1465,8 @@ class MainWindow(QtGui.QMainWindow):
# TODO in the OFFLINE mode we should also modify the rules
# in the mail state machine so it shows that imap is active
# (but not smtp since it's not yet ready for offline use)
- start_fun = self._mail_conductor.start_imap_service
- if flags.OFFLINE:
- provider_domain = self._login_widget.get_selected_provider()
- self._provider_config.load(
- provider.get_provider_path(provider_domain))
- provides_mx = self._provider_config.provides_mx()
-
- if flags.OFFLINE and provides_mx:
- start_fun()
- return
-
- if self._provides_mx_and_enabled():
- start_fun()
+ if self._provides_mx_and_enabled() or flags.OFFLINE:
+ self._mail_conductor.start_imap_service()
# end service control methods (imap)
@@ -1519,9 +1516,7 @@ class MainWindow(QtGui.QMainWindow):
"""
self._eip_connection.qtsigs.connected_signal.emit()
- provider_config = self._get_best_provider_config()
- domain = provider_config.get_domain()
-
+ domain = self._login_widget.get_selected_provider()
self._eip_status.set_provider(domain)
self._settings.set_defaultprovider(domain)
self._already_started_eip = True
@@ -1582,19 +1577,8 @@ class MainWindow(QtGui.QMainWindow):
self._enabled_services = settings.get_enabled_services(
default_provider)
- loaded = self._provisional_provider_config.load(
- provider.get_provider_path(default_provider))
- if loaded and settings.get_autostart_eip():
- # XXX I think we should not try to re-download config every time,
- # it adds some delay.
- # Maybe if it's the first run in a session,
- # or we can try only if it fails.
+ if settings.get_autostart_eip():
self._maybe_start_eip()
- elif settings.get_autostart_eip():
- # XXX: Display a proper message to the user
- self.eip_needs_login.emit()
- logger.error("Unable to load %s config, cannot autostart." %
- (default_provider,))
@QtCore.Slot()
def _start_EIP(self):
@@ -1700,11 +1684,12 @@ class MainWindow(QtGui.QMainWindow):
logger.debug('Setting autostart to: False')
self._settings.set_autostart_eip(False)
- if self._logged_user:
- self._eip_status.set_provider(
- make_address(
- self._logged_user,
- self._get_best_provider_config().get_domain()))
+ user = self._logged_user
+ if user:
+ domain = self._login_widget.get_selected_provider()
+ full_user_id = make_address(user, domain)
+ self._eip_status.set_provider(full_user_id)
+
self._eip_status.eip_stopped()
@QtCore.Slot()
@@ -1874,30 +1859,6 @@ class MainWindow(QtGui.QMainWindow):
# end of EIP methods ---------------------------------------------
- def _get_best_provider_config(self):
- """
- Returns the best ProviderConfig to use at a moment. We may
- have to use self._provider_config or
- self._provisional_provider_config depending on the start
- status.
-
- :rtype: ProviderConfig
- """
- # TODO move this out of gui.
- leap_assert(self._provider_config is not None or
- self._provisional_provider_config is not None,
- "We need a provider config")
-
- provider_config = None
- if self._provider_config.loaded():
- provider_config = self._provider_config
- elif self._provisional_provider_config.loaded():
- provider_config = self._provisional_provider_config
- else:
- leap_assert(False, "We could not find any usable ProviderConfig.")
-
- return provider_config
-
@QtCore.Slot()
def _logout(self):
"""
diff --git a/src/leap/bitmask/gui/preferenceswindow.py b/src/leap/bitmask/gui/preferenceswindow.py
index 0a4c7f56..c67052f3 100644
--- a/src/leap/bitmask/gui/preferenceswindow.py
+++ b/src/leap/bitmask/gui/preferenceswindow.py
@@ -24,12 +24,9 @@ from functools import partial
from PySide import QtCore, QtGui
-from leap.bitmask.provider import get_provider_path
from leap.bitmask.config.leapsettings import LeapSettings
from leap.bitmask.gui.ui_preferences import Ui_Preferences
from leap.bitmask.util.credentials import password_checks
-from leap.bitmask.services import get_supported
-from leap.bitmask.config.providerconfig import ProviderConfig
from leap.bitmask.services import get_service_display_name, MX_SERVICE
logger = logging.getLogger(__name__)
@@ -41,15 +38,12 @@ class PreferencesWindow(QtGui.QDialog):
"""
preferences_saved = QtCore.Signal()
- def __init__(self, parent, backend, provider_config, soledad_started,
- username, domain):
+ def __init__(self, parent, backend, soledad_started, username, domain):
"""
:param parent: parent object of the PreferencesWindow.
:parent type: QWidget
:param backend: Backend being used
:type backend: Backend
- :param provider_config: ProviderConfig object.
- :type provider_config: ProviderConfig
:param soledad_started: whether soledad has started or not
:type soledad_started: bool
:param username: the user set in the login widget
@@ -62,7 +56,6 @@ class PreferencesWindow(QtGui.QDialog):
self._backend = backend
self._settings = LeapSettings()
- self._provider_config = provider_config
self._soledad_started = soledad_started
self._username = username
self._domain = domain
@@ -99,31 +92,7 @@ class PreferencesWindow(QtGui.QDialog):
Actions to perform is the user is logged in.
"""
- settings = self._settings
- pw_enabled = True
-
- # check if provider has 'mx' ...
- # TODO: we should move this to the backend.
- if self._provider_config.provides_mx():
- enabled_services = settings.get_enabled_services(self._domain)
- mx_name = get_service_display_name(MX_SERVICE)
-
- # ... and if the user have it enabled
- if MX_SERVICE not in enabled_services:
- msg = self.tr("You need to enable {0} in order to change "
- "the password.".format(mx_name))
- self._set_password_change_status(msg, error=True)
- pw_enabled = False
- else:
- # check if Soledad is bootstrapped
- if not self._soledad_started:
- msg = self.tr(
- "You need to wait until {0} is ready in "
- "order to change the password.".format(mx_name))
- self._set_password_change_status(msg)
- pw_enabled = False
-
- self.ui.gbPasswordChange.setEnabled(pw_enabled)
+ self._backend.provider_provides_mx()
@QtCore.Slot()
def _not_logged_in(self):
@@ -139,6 +108,44 @@ class PreferencesWindow(QtGui.QDialog):
self.ui.gbPasswordChange.setEnabled(False)
@QtCore.Slot()
+ def _provides_mx(self):
+ """
+ TRIGGERS:
+ Signaler.prov_provides_mx
+
+ Actions to perform if the provider provides MX.
+ """
+ pw_enabled = True
+ enabled_services = self._settings.get_enabled_services(self._domain)
+ mx_name = get_service_display_name(MX_SERVICE)
+
+ if MX_SERVICE not in enabled_services:
+ msg = self.tr("You need to enable {0} in order to change "
+ "the password.".format(mx_name))
+ self._set_password_change_status(msg, error=True)
+ pw_enabled = False
+ else:
+ # check if Soledad is bootstrapped
+ if not self._soledad_started:
+ msg = self.tr(
+ "You need to wait until {0} is ready in "
+ "order to change the password.".format(mx_name))
+ self._set_password_change_status(msg)
+ pw_enabled = False
+
+ self.ui.gbPasswordChange.setEnabled(pw_enabled)
+
+ @QtCore.Slot()
+ def _not_provides_mx(self):
+ """
+ TRIGGERS:
+ Signaler.prov_not_provides_mx
+
+ Actions to perform if the provider does not provides MX.
+ """
+ self.ui.gbPasswordChange.setEnabled(False)
+
+ @QtCore.Slot()
def set_soledad_ready(self):
"""
TRIGGERS:
@@ -339,8 +346,7 @@ class PreferencesWindow(QtGui.QDialog):
TRIGGERS:
self.ui.cbProvidersServices.currentIndexChanged[unicode]
- Loads the services that the provider provides into the UI for
- the user to enable or disable.
+ Fill the services list with the selected provider's services.
:param domain: the domain of the provider to load services from.
:type domain: str
@@ -351,10 +357,6 @@ class PreferencesWindow(QtGui.QDialog):
if not domain:
return
- provider_config = self._get_provider_config(domain)
- if provider_config is None:
- return
-
# set the proper connection for the 'save' button
try:
self.ui.pbSaveServices.clicked.disconnect()
@@ -364,7 +366,21 @@ class PreferencesWindow(QtGui.QDialog):
save_services = partial(self._save_enabled_services, domain)
self.ui.pbSaveServices.clicked.connect(save_services)
- services = get_supported(provider_config.get_services())
+ self._backend.provider_get_supported_services(domain)
+
+ @QtCore.Slot(str)
+ def _load_services(self, services):
+ """
+ TRIGGERS:
+ self.ui.cbProvidersServices.currentIndexChanged[unicode]
+
+ Loads the services that the provider provides into the UI for
+ the user to enable or disable.
+
+ :param domain: the domain of the provider to load services from.
+ :type domain: str
+ """
+ domain = self.ui.cbProvidersServices.currentText()
services_conf = self._settings.get_enabled_services(domain)
# discard changes if other provider is selected
@@ -412,27 +428,15 @@ class PreferencesWindow(QtGui.QDialog):
self._set_providers_services_status(msg, success=True)
self.preferences_saved.emit()
- def _get_provider_config(self, domain):
- """
- Helper to return a valid Provider Config from the domain name.
-
- :param domain: the domain name of the provider.
- :type domain: str
-
- :rtype: ProviderConfig or None if there is a problem loading the config
- """
- provider_config = ProviderConfig()
- if not provider_config.load(get_provider_path(domain)):
- provider_config = None
-
- return provider_config
-
def _backend_connect(self):
"""
Helper to connect to backend signals
"""
sig = self._backend.signaler
+ sig.prov_provides_mx.connect(self._provides_mx)
+ sig.prov_get_supported_services.connect(self._load_services)
+
sig.srp_status_logged_in.connect(self._is_logged_in)
sig.srp_status_not_logged_in.connect(self._not_logged_in)
diff --git a/src/leap/bitmask/gui/wizard.py b/src/leap/bitmask/gui/wizard.py
index ce45b431..4d774907 100644
--- a/src/leap/bitmask/gui/wizard.py
+++ b/src/leap/bitmask/gui/wizard.py
@@ -26,8 +26,6 @@ from PySide import QtCore, QtGui
from leap.bitmask.config import flags
from leap.bitmask.config.leapsettings import LeapSettings
-from leap.bitmask.config.providerconfig import ProviderConfig
-from leap.bitmask.provider import get_provider_path
from leap.bitmask.services import get_service_display_name, get_supported
from leap.bitmask.util.credentials import password_checks, username_checks
from leap.bitmask.util.credentials import USERNAME_REGEX
@@ -88,10 +86,9 @@ class Wizard(QtGui.QWizard):
self._backend_connect()
self._domain = None
- # HACK!! We need provider_config for the time being, it'll be
- # removed
- self._provider_config = (
- self._backend._components["provider"]._provider_config)
+
+ # this details are set when the provider download is complete.
+ self._provider_details = None
# We will store a reference to the defers for eventual use
# (eg, to cancel them) but not doing anything with them right now.
@@ -513,10 +510,12 @@ class Wizard(QtGui.QWizard):
check. Since this check is the last of this set, it also
completes the page if passed
"""
- if self._provider_config.load(get_provider_path(self._domain)):
+ if data[self._backend.PASSED_KEY]:
self._complete_task(data, self.ui.lblProviderInfo,
True, self.SELECT_PROVIDER_PAGE)
self._provider_checks_ok = True
+ lang = QtCore.QLocale.system().name()
+ self._backend.provider_get_details(self._domain, lang)
else:
new_data = {
self._backend.PASSED_KEY: False,
@@ -538,6 +537,16 @@ class Wizard(QtGui.QWizard):
else:
self.ui.cbProviders.setEnabled(True)
+ @QtCore.Slot()
+ def _provider_get_details(self, details):
+ """
+ Set the details for the just downloaded provider.
+
+ :param details: the details of the provider.
+ :type details: ProviderConfigLight
+ """
+ self._provider_details = details
+
@QtCore.Slot(dict)
def _download_ca_cert(self, data):
"""
@@ -605,11 +614,9 @@ class Wizard(QtGui.QWizard):
the user to enable or disable.
"""
self.ui.grpServices.setTitle(
- self.tr("Services by %s") %
- (self._provider_config.get_name(),))
+ self.tr("Services by {0}").format(self._provider_details.name))
- services = get_supported(
- self._provider_config.get_services())
+ services = get_supported(self._provider_details.services)
for service in services:
try:
@@ -652,38 +659,31 @@ class Wizard(QtGui.QWizard):
if not self._provider_setup_ok:
self._reset_provider_setup()
sub_title = self.tr("Gathering configuration options for {0}")
- sub_title = sub_title.format(self._provider_config.get_name())
+ sub_title = sub_title.format(self._provider_details.name)
self.page(pageId).setSubTitle(sub_title)
self.ui.lblDownloadCaCert.setPixmap(self.QUESTION_ICON)
self._provider_setup_defer = self._backend.\
provider_bootstrap(self._domain)
if pageId == self.PRESENT_PROVIDER_PAGE:
- self.page(pageId).setSubTitle(self.tr("Description of services "
- "offered by %s") %
- (self._provider_config
- .get_name(),))
-
- lang = QtCore.QLocale.system().name()
- self.ui.lblProviderName.setText(
- "<b>%s</b>" %
- (self._provider_config.get_name(lang=lang),))
- self.ui.lblProviderURL.setText(
- "https://%s" % (self._provider_config.get_domain(),))
- self.ui.lblProviderDesc.setText(
- "<i>%s</i>" %
- (self._provider_config.get_description(lang=lang),))
-
- self.ui.lblServicesOffered.setText(self._provider_config
- .get_services_string())
- self.ui.lblProviderPolicy.setText(self._provider_config
- .get_enrollment_policy())
+ sub_title = self.tr("Description of services offered by {0}")
+ sub_title = sub_title.format(self._provider_details.name)
+ self.page(pageId).setSubTitle(sub_title)
+
+ details = self._provider_details
+ name = "<b>{0}</b>".format(details.name)
+ domain = "https://{0}".format(details.domain)
+ description = "<i>{0}</i>".format(details.description)
+ self.ui.lblProviderName.setText(name)
+ self.ui.lblProviderURL.setText(domain)
+ self.ui.lblProviderDesc.setText(description)
+ self.ui.lblServicesOffered.setText(details.services_string)
+ self.ui.lblProviderPolicy.setText(details.enrollment_policy)
if pageId == self.REGISTER_USER_PAGE:
- self.page(pageId).setSubTitle(self.tr("Register a new user with "
- "%s") %
- (self._provider_config
- .get_name(),))
+ sub_title = self.tr("Register a new user with {0}")
+ sub_title = sub_title.format(self._provider_details.name)
+ self.page(pageId).setSubTitle(sub_title)
self.ui.chkRemember.setVisible(False)
if pageId == self.SERVICES_PAGE:
@@ -706,8 +706,6 @@ class Wizard(QtGui.QWizard):
if self.currentPage() == self.page(self.SELECT_PROVIDER_PAGE):
if self._use_existing_provider:
self._domain = self.ui.cbProviders.currentText()
- self._provider_config = ProviderConfig.get_provider_config(
- self._domain)
if self._show_register:
return self.REGISTER_USER_PAGE
else:
@@ -732,6 +730,7 @@ class Wizard(QtGui.QWizard):
sig.prov_name_resolution.connect(self._name_resolution)
sig.prov_https_connection.connect(self._https_connection)
sig.prov_download_provider_info.connect(self._download_provider_info)
+ sig.prov_get_details.connect(self._provider_get_details)
sig.prov_download_ca_cert.connect(self._download_ca_cert)
sig.prov_check_ca_fingerprint.connect(self._check_ca_fingerprint)