From e2ea44e2b042e86c0eb3a02eb52a92457b6bf179 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Thu, 20 Mar 2014 10:41:48 -0300 Subject: Refactor EIPBootstrapper to the backend --- src/leap/bitmask/backend.py | 84 +++++++++++++++++++++++ src/leap/bitmask/gui/mainwindow.py | 34 ++++----- src/leap/bitmask/provider/providerbootstrapper.py | 2 + src/leap/bitmask/services/abstractbootstrapper.py | 4 +- src/leap/bitmask/services/eip/eipbootstrapper.py | 22 +++--- 5 files changed, 113 insertions(+), 33 deletions(-) (limited to 'src') diff --git a/src/leap/bitmask/backend.py b/src/leap/bitmask/backend.py index 45ea451c..e4efa09f 100644 --- a/src/leap/bitmask/backend.py +++ b/src/leap/bitmask/backend.py @@ -32,6 +32,7 @@ from leap.bitmask.config.providerconfig import ProviderConfig from leap.bitmask.crypto.srpregister import SRPRegister from leap.bitmask.provider import get_provider_path from leap.bitmask.provider.providerbootstrapper import ProviderBootstrapper +from leap.bitmask.services.eip.eipbootstrapper import EIPBootstrapper # Frontend side from PySide import QtCore @@ -238,6 +239,60 @@ class Register(object): logger.error("Could not load provider configuration.") +class EIP(object): + """ + Interfaces with setup and launch of EIP + """ + + zope.interface.implements(ILEAPComponent) + + def __init__(self, signaler=None): + """ + Constructor for the EIP component + + :param signaler: Object in charge of handling communication + back to the frontend + :type signaler: Signaler + """ + object.__init__(self) + self.key = "eip" + self._eip_bootstrapper = EIPBootstrapper(signaler) + self._eip_setup_defer = None + self._provider_config = ProviderConfig() + + def setup_eip(self, domain): + """ + Initiates the setup for a provider + + :param domain: URL for the provider + :type domain: unicode + + :returns: the defer for the operation running in a thread. + :rtype: twisted.internet.defer.Deferred + """ + if (not self._provider_config.loaded() or + self._provider_config.get_domain() != domain): + self._provider_config.load(get_provider_path(domain)) + + if self._provider_config.loaded(): + log.msg("") + eb = self._eip_bootstrapper + d = eb.run_eip_setup_checks(self._provider_config, + download_if_needed=True) + self._eip_setup_defer = d + return d + else: + raise Exception("No provider setup loaded") + + def cancel_setup_eip(self): + """ + Cancel the ongoing setup eip defer (if any). + """ + d = self._eip_setup_defer + if d is not None: + d.cancel() + + class Signaler(QtCore.QObject): """ Signaler object, handles converting string commands to Qt signals. @@ -269,6 +324,12 @@ class Signaler(QtCore.QObject): srp_registration_failed = QtCore.Signal(object) srp_registration_taken = QtCore.Signal(object) + # Signals for EIP + eip_download_config = QtCore.Signal(object) + eip_download_client_certificate = QtCore.Signal(object) + + eip_cancelled_setup = QtCore.Signal(object) + #################### # These will exist both in the backend AND the front end. # The frontend might choose to not "interpret" all the signals @@ -289,6 +350,18 @@ class Signaler(QtCore.QObject): SRP_REGISTRATION_FAILED = "srp_registration_failed" SRP_REGISTRATION_TAKEN = "srp_registration_taken" + # TODO change the name of "download_config" signal to + # something less confusing (config_ready maybe) + EIP_DOWNLOAD_CONFIG = "eip_download_config" + EIP_DOWNLOAD_CLIENT_CERTIFICATE = "eip_download_client_certificate" + EIP_CANCELLED_SETUP = "eip_cancelled_setup" + + # TODO change the name of "download_config" signal to + # something less confusing (config_ready maybe) + EIP_DOWNLOAD_CONFIG = "eip_download_config" + EIP_DOWNLOAD_CLIENT_CERTIFICATE = "eip_download_client_certificate" + EIP_CANCELLED_SETUP = "eip_cancelled_setup" + def __init__(self): """ Constructor for the Signaler @@ -311,6 +384,10 @@ class Signaler(QtCore.QObject): self.SRP_REGISTRATION_FINISHED, self.SRP_REGISTRATION_FAILED, self.SRP_REGISTRATION_TAKEN, + + self.EIP_DOWNLOAD_CONFIG, + self.EIP_DOWNLOAD_CLIENT_CERTIFICATE, + self.EIP_CANCELLED_SETUP, ] for sig in signals: @@ -370,6 +447,7 @@ class Backend(object): # Component registration self._register(Provider(self._signaler, bypass_checks)) self._register(Register(self._signaler)) + self._register(EIP(self._signaler)) # We have a looping call on a thread executing all the # commands in queue. Right now this queue is an actual Queue @@ -487,3 +565,9 @@ class Backend(object): def register_user(self, provider, username, password): self._call_queue.put(("register", "register_user", None, provider, username, password)) + + def setup_eip(self, provider): + self._call_queue.put(("eip", "setup_eip", None, provider)) + + def cancel_setup_eip(self): + self._call_queue.put(("eip", "cancel_setup_eip", None)) diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py index 56ac1545..61aff5f9 100644 --- a/src/leap/bitmask/gui/mainwindow.py +++ b/src/leap/bitmask/gui/mainwindow.py @@ -61,7 +61,6 @@ from leap.bitmask.services.mail import conductor as mail_conductor from leap.bitmask.services import EIP_SERVICE, MX_SERVICE from leap.bitmask.services.eip import eipconfig from leap.bitmask.services.eip import get_openvpn_management -from leap.bitmask.services.eip.eipbootstrapper import EIPBootstrapper from leap.bitmask.services.eip.connection import EIPConnection from leap.bitmask.services.eip.vpnprocess import VPN from leap.bitmask.services.eip.vpnprocess import OpenVPNAlreadyRunning @@ -230,17 +229,6 @@ class MainWindow(QtGui.QMainWindow): self._backend_connect() - # This thread is similar to the provider bootstrapper - self._eip_bootstrapper = EIPBootstrapper() - - # EIP signals ---- move to eip conductor. - # TODO change the name of "download_config" signal to - # something less confusing (config_ready maybe) - self._eip_bootstrapper.download_config.connect( - self._eip_intermediate_stage) - self._eip_bootstrapper.download_client_certificate.connect( - self._finish_eip_bootstrap) - self._vpn = VPN(openvpn_verb=openvpn_verb) # connect vpn process signals @@ -410,6 +398,9 @@ class MainWindow(QtGui.QMainWindow): sig.prov_cancelled_setup.connect(self._set_login_cancelled) + sig.eip_download_config.connect(self._eip_intermediate_stage) + sig.eip_download_client_certificate.connect(self._finish_eip_bootstrap) + def _backend_disconnect(self): """ Helper to disconnect from backend signals. @@ -1802,17 +1793,16 @@ class MainWindow(QtGui.QMainWindow): Start the EIP bootstrapping sequence if the client is configured to do so. """ - leap_assert(self._eip_bootstrapper, "We need an eip bootstrapper!") - provider_config = self._get_best_provider_config() if self._provides_eip_and_enabled() and not self._already_started_eip: # XXX this should be handled by the state machine. self._eip_status.set_eip_status( self.tr("Starting...")) - self._eip_bootstrapper.run_eip_setup_checks( - provider_config, - download_if_needed=True) + + domain = self._login_widget.get_selected_provider() + self._backend.setup_eip(domain) + self._already_started_eip = True # we want to start soledad anyway after a certain timeout if eip # fails to come up @@ -1834,18 +1824,18 @@ class MainWindow(QtGui.QMainWindow): def _finish_eip_bootstrap(self, data): """ SLOT - TRIGGER: self._eip_bootstrapper.download_client_certificate + TRIGGER: self._backend.signaler.eip_download_client_certificate Starts the VPN thread if the eip configuration is properly loaded """ leap_assert(self._eip_config, "We need an eip config!") - passed = data[self._eip_bootstrapper.PASSED_KEY] + passed = data[self._backend.PASSED_KEY] if not passed: error_msg = self.tr("There was a problem with the provider") self._eip_status.set_eip_status(error_msg, error=True) - logger.error(data[self._eip_bootstrapper.ERROR_KEY]) + logger.error(data[self._backend.ERROR_KEY]) self._already_started_eip = False return @@ -1869,7 +1859,7 @@ class MainWindow(QtGui.QMainWindow): """ SLOT TRIGGERS: - self._eip_bootstrapper.download_config + self._backend.signaler.eip_download_config If there was a problem, displays it, otherwise it does nothing. This is used for intermediate bootstrapping stages, in case @@ -1964,7 +1954,7 @@ class MainWindow(QtGui.QMainWindow): self._backend.signaler.prov_name_resolution self._backend.signaler.prov_https_connection self._backend.signaler.prov_download_ca_cert - self._eip_bootstrapper.download_config + self._backend.signaler.eip_download_config If there was a problem, displays it, otherwise it does nothing. This is used for intermediate bootstrapping stages, in case diff --git a/src/leap/bitmask/provider/providerbootstrapper.py b/src/leap/bitmask/provider/providerbootstrapper.py index 2a519206..6cdfe4f4 100644 --- a/src/leap/bitmask/provider/providerbootstrapper.py +++ b/src/leap/bitmask/provider/providerbootstrapper.py @@ -88,6 +88,8 @@ class ProviderBootstrapper(AbstractBootstrapper): self._domain = None self._provider_config = None self._download_if_needed = False + if signaler is not None: + self._cancel_signal = signaler.PROV_CANCELLED_SETUP @property def verify(self): diff --git a/src/leap/bitmask/services/abstractbootstrapper.py b/src/leap/bitmask/services/abstractbootstrapper.py index fc6bd3e9..77929b75 100644 --- a/src/leap/bitmask/services/abstractbootstrapper.py +++ b/src/leap/bitmask/services/abstractbootstrapper.py @@ -78,6 +78,7 @@ class AbstractBootstrapper(QtCore.QObject): self._signal_to_emit = None self._err_msg = None self._signaler = signaler + self._cancel_signal = None def _gui_errback(self, failure): """ @@ -95,7 +96,8 @@ class AbstractBootstrapper(QtCore.QObject): if failure.check(CancelledError): logger.debug("Defer cancelled.") failure.trap(Exception) - self._signaler.signal(self._signaler.PROV_CANCELLED_SETUP) + if self._signaler is not None and self._cancel_signal is not None: + self._signaler.signal(self._cancel_signal) return if self._signal_to_emit: diff --git a/src/leap/bitmask/services/eip/eipbootstrapper.py b/src/leap/bitmask/services/eip/eipbootstrapper.py index 5a238a1c..aacf3b7e 100644 --- a/src/leap/bitmask/services/eip/eipbootstrapper.py +++ b/src/leap/bitmask/services/eip/eipbootstrapper.py @@ -20,8 +20,6 @@ EIP bootstrapping import logging import os -from PySide import QtCore - from leap.bitmask.config.providerconfig import ProviderConfig from leap.bitmask.crypto.certs import download_client_cert from leap.bitmask.services import download_service_config @@ -41,17 +39,21 @@ class EIPBootstrapper(AbstractBootstrapper): If a check fails, the subsequent checks are not executed """ - # All dicts returned are of the form - # {"passed": bool, "error": str} - download_config = QtCore.Signal(dict) - download_client_certificate = QtCore.Signal(dict) + def __init__(self, signaler=None): + """ + Constructor for the EIP bootstrapper object - def __init__(self): - AbstractBootstrapper.__init__(self) + :param signaler: Signaler object used to receive notifications + from the backend + :type signaler: Signaler + """ + AbstractBootstrapper.__init__(self, signaler) self._provider_config = None self._eip_config = None self._download_if_needed = False + if signaler is not None: + self._cancel_signal = signaler.EIP_CANCELLED_SETUP def _download_config(self, *args): """ @@ -114,9 +116,9 @@ class EIPBootstrapper(AbstractBootstrapper): self._download_if_needed = download_if_needed cb_chain = [ - (self._download_config, self.download_config), + (self._download_config, self._signaler.EIP_DOWNLOAD_CONFIG), (self._download_client_certificates, - self.download_client_certificate) + self._signaler.EIP_DOWNLOAD_CLIENT_CERTIFICATE) ] return self.addCallbackChain(cb_chain) -- cgit v1.2.3