diff options
Diffstat (limited to 'src/leap/bitmask/gui/mainwindow.py')
-rw-r--r-- | src/leap/bitmask/gui/mainwindow.py | 148 |
1 files changed, 92 insertions, 56 deletions
diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py index 53a7d95a..6959650b 100644 --- a/src/leap/bitmask/gui/mainwindow.py +++ b/src/leap/bitmask/gui/mainwindow.py @@ -18,6 +18,7 @@ Main window for Bitmask. """ import logging +import time from datetime import datetime @@ -25,6 +26,11 @@ from PySide import QtCore, QtGui from leap.bitmask import __version__ as VERSION from leap.bitmask import __version_hash__ as VERSION_HASH + +# TODO: we should use a more granular signaling instead of passing error/ok as +# a result. +from leap.bitmask.backend.leapbackend import ERROR_KEY, PASSED_KEY + from leap.bitmask.config import flags from leap.bitmask.config.leapsettings import LeapSettings @@ -37,13 +43,13 @@ from leap.bitmask.gui.mail_status import MailStatusWidget from leap.bitmask.gui.preferenceswindow import PreferencesWindow from leap.bitmask.gui.systray import SysTray from leap.bitmask.gui.wizard import Wizard -from leap.bitmask.gui import twisted_main from leap.bitmask.platform_init import IS_WIN, IS_MAC, IS_LINUX from leap.bitmask.platform_init.initializers import init_platform from leap.bitmask.platform_init.initializers import init_signals -from leap.bitmask.backend import leapbackend +from leap.bitmask.backend.backend_proxy import BackendProxy +from leap.bitmask.backend.leapsignaler import LeapSignaler from leap.bitmask.services.eip import conductor as eip_conductor from leap.bitmask.services.mail import conductor as mail_conductor @@ -91,13 +97,10 @@ class MainWindow(QtGui.QMainWindow): # We give the services some time to a halt before forcing quit. SERVICES_STOP_TIMEOUT = 20000 # in milliseconds - def __init__(self, bypass_checks=False, start_hidden=False): + def __init__(self, start_hidden=False): """ Constructor for the client main window - :param bypass_checks: Set to true if the app should bypass first round - of checks for CA certificates at bootstrap - :type bypass_checks: bool :param start_hidden: Set to true if the app should not show the window but just the tray. :type start_hidden: bool @@ -119,15 +122,18 @@ class MainWindow(QtGui.QMainWindow): self.ui = Ui_MainWindow() self.ui.setupUi(self) self.menuBar().setNativeMenuBar(not IS_LINUX) - self._backend = leapbackend.Backend(bypass_checks) - self._backend.start() + + self._backend = BackendProxy() + + self._leap_signaler = LeapSignaler() + self._leap_signaler.start() self._settings = LeapSettings() + # gateway = self._settings.get_selected_gateway(provider) + # self._backend.settings_set_selected_gateway(provider, gateway) # Login Widget - self._login_widget = LoginWidget( - self._settings, - self) + self._login_widget = LoginWidget(self._settings, self) self.ui.loginLayout.addWidget(self._login_widget) # Mail Widget @@ -144,8 +150,9 @@ class MainWindow(QtGui.QMainWindow): # EIP Control redux ######################################### self._eip_conductor = eip_conductor.EIPConductor( - self._settings, self._backend) - self._eip_status = EIPStatusWidget(self, self._eip_conductor) + self._settings, self._backend, self._leap_signaler) + self._eip_status = EIPStatusWidget(self, self._eip_conductor, + self._leap_signaler) init_signals.eip_missing_helpers.connect( self._disable_eip_missing_helpers) @@ -180,6 +187,7 @@ class MainWindow(QtGui.QMainWindow): self._services_being_stopped = {} # used to know if we are in the final steps of quitting + self._quitting = False self._finally_quitting = False self._backend_connected_signals = [] @@ -249,7 +257,7 @@ class MainWindow(QtGui.QMainWindow): # XXX should connect to mail_conductor.start_mail_service instead self.soledad_ready.connect(self._start_smtp_bootstrapping) self.soledad_ready.connect(self._start_imap_service) - ################################# end Qt Signals connection ######## + # ################################ end Qt Signals connection ######## init_platform() @@ -258,7 +266,6 @@ class MainWindow(QtGui.QMainWindow): self._logger_window = None - self._bypass_checks = bypass_checks self._start_hidden = start_hidden self._mail_conductor = mail_conductor.MailConductor(self._backend) @@ -283,7 +290,7 @@ class MainWindow(QtGui.QMainWindow): self._wizard_firstrun = True self._disconnect_and_untrack() self._wizard = Wizard(backend=self._backend, - bypass_checks=bypass_checks) + leap_signaler=self._leap_signaler) # Give this window time to finish init and then show the wizard QtDelayedCall(1, self._launch_wizard) self._wizard.accepted.connect(self._finish_init) @@ -342,7 +349,7 @@ class MainWindow(QtGui.QMainWindow): that we are tracking to disconnect later. :type only_tracked: bool """ - sig = self._backend.signaler + sig = self._leap_signaler conntrack = self._connect_and_track auth_err = self._authentication_error @@ -407,6 +414,9 @@ class MainWindow(QtGui.QMainWindow): sig.eip_dns_error.connect(self._eip_dns_error) + sig.eip_get_gateway_country_code.connect(self._set_eip_provider) + sig.eip_no_gateway.connect(self._set_eip_provider) + # ================================================================== # Soledad signals @@ -480,7 +490,7 @@ class MainWindow(QtGui.QMainWindow): if self._wizard is None: self._disconnect_and_untrack() self._wizard = Wizard(backend=self._backend, - bypass_checks=self._bypass_checks) + leap_signaler=self._leap_signaler) self._wizard.accepted.connect(self._finish_init) self._wizard.rejected.connect(self._rejected_wizard) @@ -575,7 +585,8 @@ class MainWindow(QtGui.QMainWindow): if self._provider_details is not None: mx_provided = MX_SERVICE in self._provider_details['services'] preferences = PreferencesWindow(self, user, domain, self._backend, - self._soledad_started, mx_provided) + self._soledad_started, mx_provided, + self._leap_signaler) self.soledad_ready.connect(preferences.set_soledad_ready) preferences.show() @@ -604,12 +615,13 @@ class MainWindow(QtGui.QMainWindow): return self._trying_to_start_eip = settings.get_autostart_eip() - self._backend.eip_can_start(default_provider) + self._backend.eip_can_start(domain=default_provider) # If we don't want to start eip, we leave everything # initialized to quickly start it if not self._trying_to_start_eip: - self._backend.eip_setup(default_provider, skip_network=True) + self._backend.eip_setup(provider=default_provider, + skip_network=True) def _backend_can_start_eip(self): """ @@ -686,7 +698,9 @@ class MainWindow(QtGui.QMainWindow): Displays the EIP preferences window. """ domain = self._login_widget.get_selected_provider() - EIPPreferencesWindow(self, domain, self._backend).show() + pref = EIPPreferencesWindow(self, domain, + self._backend, self._leap_signaler) + pref.show() # # updates @@ -821,7 +835,7 @@ class MainWindow(QtGui.QMainWindow): """ providers = self._settings.get_configured_providers() - self._backend.provider_get_all_services(providers) + self._backend.provider_get_all_services(providers=providers) def _provider_get_all_services(self, services): self._set_eip_visible(EIP_SERVICE in services) @@ -1121,7 +1135,7 @@ class MainWindow(QtGui.QMainWindow): emit the corresponding signals inmediately """ domain = self._login_widget.get_selected_provider() - self._backend.provider_setup(domain) + self._backend.provider_setup(provider=domain) @QtCore.Slot(dict) def _load_provider_config(self, data): @@ -1136,11 +1150,11 @@ class MainWindow(QtGui.QMainWindow): backend.provider_setup() :type data: dict """ - if data[self._backend.PASSED_KEY]: + if data[PASSED_KEY]: selected_provider = self._login_widget.get_selected_provider() - self._backend.provider_bootstrap(selected_provider) + self._backend.provider_bootstrap(provider=selected_provider) else: - logger.error(data[self._backend.ERROR_KEY]) + logger.error(data[ERROR_KEY]) self._login_problem_provider() @QtCore.Slot() @@ -1242,16 +1256,17 @@ class MainWindow(QtGui.QMainWindow): Once the provider configuration is loaded, this starts the SRP authentication """ - if data[self._backend.PASSED_KEY]: + if data[PASSED_KEY]: username = self._login_widget.get_user() password = self._login_widget.get_password() self._show_hide_unsupported_services() domain = self._login_widget.get_selected_provider() - self._backend.user_login(domain, username, password) + self._backend.user_login(provider=domain, + username=username, password=password) else: - logger.error(data[self._backend.ERROR_KEY]) + logger.error(data[ERROR_KEY]) self._login_problem_provider() @QtCore.Slot() @@ -1277,11 +1292,11 @@ class MainWindow(QtGui.QMainWindow): if MX_SERVICE in self._enabled_services: btn_enabled = self._login_widget.set_logout_btn_enabled btn_enabled(False) - sig = self._backend.signaler + sig = self._leap_signaler sig.soledad_bootstrap_failed.connect(lambda: btn_enabled(True)) sig.soledad_bootstrap_finished.connect(lambda: btn_enabled(True)) - if not MX_SERVICE in self._provider_details['services']: + if MX_SERVICE not in self._provider_details['services']: self._set_mx_visible(False) def _start_eip_bootstrap(self): @@ -1316,7 +1331,7 @@ class MainWindow(QtGui.QMainWindow): """ domain = self._login_widget.get_selected_provider() lang = QtCore.QLocale.system().name() - self._backend.provider_get_details(domain, lang) + self._backend.provider_get_details(domain=domain, lang=lang) @QtCore.Slot() def _provider_get_details(self, details): @@ -1385,11 +1400,14 @@ class MainWindow(QtGui.QMainWindow): # this is mostly for internal use/debug for now. logger.warning("Sorry! Log-in at least one time.") return - self._backend.soledad_load_offline(full_user_id, password, uuid) + self._backend.soledad_load_offline(username=full_user_id, + password=password, uuid=uuid) else: if self._logged_user is not None: domain = self._login_widget.get_selected_provider() - self._backend.soledad_bootstrap(username, domain, password) + self._backend.soledad_bootstrap(username=username, + domain=domain, + password=password) ################################################################### # Service control methods: soledad @@ -1468,14 +1486,27 @@ class MainWindow(QtGui.QMainWindow): signal that currently is beeing processed under status_panel. After the refactor to EIPConductor this should not be necessary. """ - domain = self._login_widget.get_selected_provider() + self._already_started_eip = True - self._eip_status.set_provider(domain) + domain = self._login_widget.get_selected_provider() self._settings.set_defaultprovider(domain) - self._already_started_eip = True + + self._backend.eip_get_gateway_country_code(domain=domain) # check for connectivity - self._backend.eip_check_dns(domain) + self._backend.eip_check_dns(domain=domain) + + @QtCore.Slot() + def _set_eip_provider(self, country_code=None): + """ + TRIGGERS: + Signaler.eip_get_gateway_country_code + Signaler.eip_no_gateway + + Set the current provider and country code in the eip status widget. + """ + domain = self._login_widget.get_selected_provider() + self._eip_status.set_provider(domain, country_code) @QtCore.Slot() def _eip_dns_error(self): @@ -1539,7 +1570,7 @@ class MainWindow(QtGui.QMainWindow): self._eip_status.eip_button.setEnabled(False) domain = self._login_widget.get_selected_provider() - self._backend.eip_setup(domain) + self._backend.eip_setup(provider=domain) self._already_started_eip = True # we want to start soledad anyway after a certain timeout if eip @@ -1571,12 +1602,12 @@ class MainWindow(QtGui.QMainWindow): Start the VPN thread if the eip configuration is properly loaded. """ - passed = data[self._backend.PASSED_KEY] + passed = data[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._backend.ERROR_KEY]) + logger.error(data[ERROR_KEY]) self._already_started_eip = False return @@ -1594,11 +1625,11 @@ class MainWindow(QtGui.QMainWindow): This is used for intermediate bootstrapping stages, in case they fail. """ - passed = data[self._backend.PASSED_KEY] + passed = data[PASSED_KEY] if not passed: self._login_widget.set_status( self.tr("Unable to connect: Problem with provider")) - logger.error(data[self._backend.ERROR_KEY]) + logger.error(data[ERROR_KEY]) self._already_started_eip = False self._eip_status.aborted() @@ -1663,9 +1694,9 @@ class MainWindow(QtGui.QMainWindow): This is used for intermediate bootstrapping stages, in case they fail. """ - passed = data[self._backend.PASSED_KEY] + passed = data[PASSED_KEY] if not passed: - logger.error(data[self._backend.ERROR_KEY]) + logger.error(data[ERROR_KEY]) self._login_problem_provider() # @@ -1708,13 +1739,13 @@ class MainWindow(QtGui.QMainWindow): self._cancel_ongoing_defers() - self._services_being_stopped = {'imap', 'eip'} + self._services_being_stopped = set(('imap', 'eip')) imap_stopped = lambda: self._remove_service('imap') - self._backend.signaler.imap_stopped.connect(imap_stopped) + self._leap_signaler.imap_stopped.connect(imap_stopped) eip_stopped = lambda: self._remove_service('eip') - self._backend.signaler.eip_stopped.connect(eip_stopped) + self._leap_signaler.eip_stopped.connect(eip_stopped) logger.debug('Stopping mail services') self._backend.imap_stop_service() @@ -1732,8 +1763,10 @@ class MainWindow(QtGui.QMainWindow): Start the quit sequence and wait for services to finish. Cleanup and close the main window before quitting. """ - # TODO separate the shutting down of services from the - # UI stuff. + if self._quitting: + return + + self._quitting = True # first thing to do quitting, hide the mainwindow and show tooltip. self.hide() @@ -1786,8 +1819,6 @@ class MainWindow(QtGui.QMainWindow): Final steps to quit the app, starting from here we don't care about running services or user interaction, just quitting. """ - logger.debug('Final quit...') - # We can reach here because all the services are stopped or because a # timeout was triggered. Since we want to run this only once, we exit # if this is called twice. @@ -1796,12 +1827,17 @@ class MainWindow(QtGui.QMainWindow): self._finally_quitting = True + logger.debug('Closing soledad...') + self._backend.soledad_close() + logger.debug('Final quit...') + + self._leap_signaler.stop() + self._backend.stop() + time.sleep(0.05) # give the thread a little time to finish. + # Remove lockfiles on a clean shutdown. logger.debug('Cleaning pidfiles') if IS_WIN: WindowsLock.release_all_locks() - self._backend.stop() self.close() - - QtDelayedCall(100, twisted_main.quit) |