diff options
Diffstat (limited to 'src/leap')
-rw-r--r-- | src/leap/bitmask/app.py | 1 | ||||
-rw-r--r-- | src/leap/bitmask/backend.py | 12 | ||||
-rw-r--r-- | src/leap/bitmask/config/flags.py | 3 | ||||
-rw-r--r-- | src/leap/bitmask/gui/advanced_key_management.py | 38 | ||||
-rw-r--r-- | src/leap/bitmask/gui/eip_preferenceswindow.py | 15 | ||||
-rw-r--r-- | src/leap/bitmask/gui/eip_status.py | 20 | ||||
-rw-r--r-- | src/leap/bitmask/gui/login.py | 14 | ||||
-rw-r--r-- | src/leap/bitmask/gui/mail_status.py | 28 | ||||
-rw-r--r-- | src/leap/bitmask/gui/mainwindow.py | 206 | ||||
-rw-r--r-- | src/leap/bitmask/gui/preferenceswindow.py | 28 | ||||
-rw-r--r-- | src/leap/bitmask/gui/twisted_main.py | 15 | ||||
-rw-r--r-- | src/leap/bitmask/gui/ui/advanced_key_management.ui | 2 | ||||
-rw-r--r-- | src/leap/bitmask/gui/wizard.py | 83 | ||||
-rw-r--r-- | src/leap/bitmask/services/mail/conductor.py | 5 | ||||
-rw-r--r-- | src/leap/bitmask/util/leap_argparse.py | 4 |
15 files changed, 275 insertions, 199 deletions
diff --git a/src/leap/bitmask/app.py b/src/leap/bitmask/app.py index 0a315be7..146743b5 100644 --- a/src/leap/bitmask/app.py +++ b/src/leap/bitmask/app.py @@ -214,6 +214,7 @@ def main(): flags.APP_VERSION_CHECK = opts.app_version_check flags.API_VERSION_CHECK = opts.api_version_check flags.OPENVPN_VERBOSITY = opts.openvpn_verb + flags.SKIP_WIZARD_CHECKS = opts.skip_wizard_checks flags.CA_CERT_FILE = opts.ca_cert_file diff --git a/src/leap/bitmask/backend.py b/src/leap/bitmask/backend.py index d208a6cd..d5a8a4e9 100644 --- a/src/leap/bitmask/backend.py +++ b/src/leap/bitmask/backend.py @@ -340,11 +340,11 @@ class EIP(object): try: self._start_eip() except vpnprocess.OpenVPNAlreadyRunning: - signaler.signal(signaler.EIP_OPEN_VPN_ALREADY_RUNNING) + signaler.signal(signaler.EIP_OPENVPN_ALREADY_RUNNING) except vpnprocess.AlienOpenVPNAlreadyRunning: - signaler.signal(signaler.EIP_ALIEN_OPEN_VPN_ALREADY_RUNNING) + signaler.signal(signaler.EIP_ALIEN_OPENVPN_ALREADY_RUNNING) except vpnlauncher.OpenVPNNotFoundException: - signaler.signal(signaler.EIP_OPEN_VPN_NOT_FOUND_ERROR) + signaler.signal(signaler.EIP_OPENVPN_NOT_FOUND_ERROR) except vpnlauncher.VPNLauncherException: # TODO: this seems to be used for 'gateway not found' only. # see vpnlauncher.py @@ -1027,15 +1027,15 @@ class Backend(object): Signals: backend_bad_call - eip_alien_open_vpn_already_running + eip_alien_openvpn_already_running eip_connected eip_connection_aborted eip_network_unreachable eip_no_pkexec_error eip_no_polkit_agent_error eip_no_tun_kext_error - eip_open_vpn_already_running - eip_open_vpn_not_found_error + eip_openvpn_already_running + eip_openvpn_not_found_error eip_process_finished eip_process_restart_ping eip_process_restart_tls diff --git a/src/leap/bitmask/config/flags.py b/src/leap/bitmask/config/flags.py index 7cc8711c..6b70659d 100644 --- a/src/leap/bitmask/config/flags.py +++ b/src/leap/bitmask/config/flags.py @@ -52,3 +52,6 @@ CA_CERT_FILE = None # OpenVPN verbosity level OPENVPN_VERBOSITY = 1 + +# Skip the checks in the wizard, use for testing purposes only! +SKIP_WIZARD_CHECKS = False diff --git a/src/leap/bitmask/gui/advanced_key_management.py b/src/leap/bitmask/gui/advanced_key_management.py index cbc8c3e3..be6b4410 100644 --- a/src/leap/bitmask/gui/advanced_key_management.py +++ b/src/leap/bitmask/gui/advanced_key_management.py @@ -30,12 +30,17 @@ from ui_advanced_key_management import Ui_AdvancedKeyManagement logger = logging.getLogger(__name__) -class AdvancedKeyManagement(QtGui.QWidget): +class AdvancedKeyManagement(QtGui.QDialog): """ Advanced Key Management """ - def __init__(self, user, keymanager, soledad): + def __init__(self, parent, has_mx, user, keymanager, soledad): """ + :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 keymanager: the existing keymanager instance @@ -43,7 +48,7 @@ class AdvancedKeyManagement(QtGui.QWidget): :param soledad: a loaded instance of Soledad :type soledad: Soledad """ - QtGui.QWidget.__init__(self) + QtGui.QDialog.__init__(self, parent) self.ui = Ui_AdvancedKeyManagement() self.ui.setupUi(self) @@ -52,13 +57,18 @@ class AdvancedKeyManagement(QtGui.QWidget): self.ui.pbImportKeys.setVisible(False) # if Soledad is not started yet + 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 Soledad is not started yet if sameProxiedObjects(soledad, None): - self.ui.gbMyKeyPair.setEnabled(False) - self.ui.gbStoredPublicKeys.setEnabled(False) - msg = self.tr("<span style='color:#0000FF;'>NOTE</span>: " - "To use this, you need to enable/start {0}.") + msg = self.tr("To use this, you need to enable/start {0}.") msg = msg.format(get_service_display_name(MX_SERVICE)) - self.ui.lblStatus.setText(msg) + self._disable_ui(msg) return # XXX: since import is disabled this is no longer a dangerous feature. # else: @@ -90,6 +100,18 @@ class AdvancedKeyManagement(QtGui.QWidget): self._list_keys() + 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("<span style='color:#0000FF;'>NOTE</span>: ") + msg + self.ui.lblStatus.setText(msg) + def _import_keys(self): """ Imports the user's key pair. diff --git a/src/leap/bitmask/gui/eip_preferenceswindow.py b/src/leap/bitmask/gui/eip_preferenceswindow.py index baf17395..530cd38d 100644 --- a/src/leap/bitmask/gui/eip_preferenceswindow.py +++ b/src/leap/bitmask/gui/eip_preferenceswindow.py @@ -98,9 +98,9 @@ class EIPPreferencesWindow(QtGui.QDialog): self._backend.eip_get_initialized_providers(providers) + @QtCore.Slot(list) def _load_providers_in_combo(self, providers): """ - SLOT TRIGGERS: Signaler.eip_get_initialized_providers @@ -128,9 +128,9 @@ class EIPPreferencesWindow(QtGui.QDialog): domain, QtCore.Qt.MatchStartsWith) self.ui.cbProvidersGateway.setCurrentIndex(provider_index) + @QtCore.Slot(str) def _save_selected_gateway(self, provider): """ - SLOT TRIGGERS: self.ui.pbSaveGateway.clicked @@ -153,9 +153,9 @@ class EIPPreferencesWindow(QtGui.QDialog): "Gateway settings for provider '{0}' saved.").format(provider) self._set_providers_gateway_status(msg, success=True) + @QtCore.Slot(int) def _populate_gateways(self, domain_idx): """ - SLOT TRIGGERS: self.ui.cbProvidersGateway.currentIndexChanged[unicode] @@ -176,12 +176,15 @@ class EIPPreferencesWindow(QtGui.QDialog): self._backend.eip_get_gateways_list(domain) + @QtCore.Slot(list) def _update_gateways_list(self, gateways): """ - SLOT TRIGGERS: Signaler.eip_get_gateways_list + :param gateways: a list of gateways + :type gateways: list of unicode + Add the available gateways and select the one stored in configuration file. """ @@ -214,9 +217,9 @@ class EIPPreferencesWindow(QtGui.QDialog): self.ui.cbGateways.setCurrentIndex(index) + @QtCore.Slot() def _gateways_list_error(self): """ - SLOT TRIGGERS: Signaler.eip_get_gateways_list_error @@ -229,9 +232,9 @@ class EIPPreferencesWindow(QtGui.QDialog): self.ui.pbSaveGateway.setEnabled(False) self.ui.cbGateways.setEnabled(False) + @QtCore.Slot() def _gateways_list_uninitialized(self): """ - SLOT TRIGGERS: Signaler.eip_uninitialized_provider diff --git a/src/leap/bitmask/gui/eip_status.py b/src/leap/bitmask/gui/eip_status.py index f24d87c7..0d75b8e5 100644 --- a/src/leap/bitmask/gui/eip_status.py +++ b/src/leap/bitmask/gui/eip_status.py @@ -88,11 +88,12 @@ class EIPStatusWidget(QtGui.QWidget): self.ui.btnUpload.clicked.connect(onclicked) self.ui.btnDownload.clicked.connect(onclicked) + @QtCore.Slot() def _on_VPN_status_clicked(self): """ - SLOT - TRIGGER: self.ui.btnUpload.clicked - self.ui.btnDownload.clicked + TRIGGERS: + self.ui.btnUpload.clicked + self.ui.btnDownload.clicked Toggles between rate and total throughput display for vpn status figures. @@ -347,10 +348,11 @@ class EIPStatusWidget(QtGui.QWidget): self.tr("Traffic is being routed in the clear")) self.ui.lblEIPStatus.show() + @QtCore.Slot(dict) def update_vpn_status(self, data=None): """ - SLOT - TRIGGER: Signaler.eip_status_changed + TRIGGERS: + Signaler.eip_status_changed Updates the download/upload labels based on the data provided by the VPN thread. @@ -381,14 +383,18 @@ class EIPStatusWidget(QtGui.QWidget): self.ui.btnUpload.setText(upload_str) self.ui.btnDownload.setText(download_str) + @QtCore.Slot(dict) def update_vpn_state(self, vpn_state): """ - SLOT - TRIGGER: Signaler.eip_state_changed + TRIGGERS: + Signaler.eip_state_changed Updates the displayed VPN state based on the data provided by the VPN thread. + :param vpn_state: the state of the VPN + :type vpn_state: dict + Emits: If the vpn_state is connected, we emit EIPConnection.qtsigs. connected_signal diff --git a/src/leap/bitmask/gui/login.py b/src/leap/bitmask/gui/login.py index 4a483c32..ac7ad878 100644 --- a/src/leap/bitmask/gui/login.py +++ b/src/leap/bitmask/gui/login.py @@ -259,12 +259,16 @@ class LoginWidget(QtGui.QWidget): """ self.ui.lnPassword.setFocus() - def _current_provider_changed(self, param): + @QtCore.Slot(int) + def _current_provider_changed(self, idx): """ - SLOT - TRIGGERS: self.ui.cmbProviders.currentIndexChanged + TRIGGERS: + self.ui.cmbProviders.currentIndexChanged + + :param idx: the index of the new selected item + :type idx: int """ - if param == (self.ui.cmbProviders.count() - 1): + if idx == (self.ui.cmbProviders.count() - 1): self.show_wizard.emit() # Leave the previously selected provider in the combobox prev_provider = 0 @@ -274,7 +278,7 @@ class LoginWidget(QtGui.QWidget): self.ui.cmbProviders.setCurrentIndex(prev_provider) self.ui.cmbProviders.blockSignals(False) else: - self._selected_provider_index = param + self._selected_provider_index = idx def start_login(self): """ diff --git a/src/leap/bitmask/gui/mail_status.py b/src/leap/bitmask/gui/mail_status.py index 44a138e2..d3346780 100644 --- a/src/leap/bitmask/gui/mail_status.py +++ b/src/leap/bitmask/gui/mail_status.py @@ -184,10 +184,10 @@ class MailStatusWidget(QtGui.QWidget): leap_assert_type(action_mail_status, QtGui.QAction) self._action_mail_status = action_mail_status + @QtCore.Slot() def set_soledad_failed(self): """ - SLOT - TRIGGER: + TRIGGERS: SoledadBootstrapper.soledad_failed This method is called whenever soledad has a failure. @@ -195,10 +195,10 @@ class MailStatusWidget(QtGui.QWidget): msg = self.tr("There was an unexpected problem with Soledad.") self._set_mail_status(msg, ready=-1) + @QtCore.Slot() def set_soledad_invalid_auth_token(self): """ - SLOT - TRIGGER: + TRIGGERS: SoledadBootstrapper.soledad_invalid_token This method is called when the auth token is invalid @@ -250,10 +250,11 @@ class MailStatusWidget(QtGui.QWidget): """ self._soledad_event.emit(req) + @QtCore.Slot(object) def _mail_handle_soledad_events_slot(self, req): """ - SLOT - TRIGGER: _mail_handle_soledad_events + TRIGGERS: + _mail_handle_soledad_events Reacts to an Soledad event @@ -284,10 +285,11 @@ class MailStatusWidget(QtGui.QWidget): """ self._keymanager_event.emit(req) + @QtCore.Slot(object) def _mail_handle_keymanager_events_slot(self, req): """ - SLOT - TRIGGER: _mail_handle_keymanager_events + TRIGGERS: + _mail_handle_keymanager_events Reacts to an KeyManager event @@ -330,10 +332,11 @@ class MailStatusWidget(QtGui.QWidget): """ self._smtp_event.emit(req) + @QtCore.Slot(object) def _mail_handle_smtp_events_slot(self, req): """ - SLOT - TRIGGER: _mail_handle_smtp_events + TRIGGERS: + _mail_handle_smtp_events Reacts to an SMTP event @@ -364,10 +367,11 @@ class MailStatusWidget(QtGui.QWidget): """ self._imap_event.emit(req) + @QtCore.Slot(object) def _mail_handle_imap_events_slot(self, req): """ - SLOT - TRIGGER: _mail_handle_imap_events + TRIGGERS: + _mail_handle_imap_events Reacts to an IMAP event diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py index e5c11eb7..e4443434 100644 --- a/src/leap/bitmask/gui/mainwindow.py +++ b/src/leap/bitmask/gui/mainwindow.py @@ -457,10 +457,11 @@ class MainWindow(QtGui.QMainWindow): self._backend_connected_signals = {} + @QtCore.Slot() def _rejected_wizard(self): """ - SLOT - TRIGGERS: self._wizard.rejected + TRIGGERS: + self._wizard.rejected Called if the wizard has been cancelled or closed before finishing. @@ -481,12 +482,12 @@ class MainWindow(QtGui.QMainWindow): if self._wizard_firstrun: self._finish_init() + @QtCore.Slot() def _launch_wizard(self): """ - SLOT TRIGGERS: - self._login_widget.show_wizard - self.ui.action_wizard.triggered + self._login_widget.show_wizard + self.ui.action_wizard.triggered Also called in first run. @@ -509,11 +510,11 @@ class MainWindow(QtGui.QMainWindow): self._wizard.finished.connect(self._wizard_finished) self._settings.set_skip_first_run(True) + @QtCore.Slot() def _wizard_finished(self): """ - SLOT - TRIGGERS - self._wizard.finished + TRIGGERS: + self._wizard.finished Called when the wizard has finished. """ @@ -534,11 +535,11 @@ class MainWindow(QtGui.QMainWindow): return h return None + @QtCore.Slot() def _show_logger_window(self): """ - SLOT TRIGGERS: - self.ui.action_show_logs.triggered + self.ui.action_show_logs.triggered Displays the window with the history of messages logged until now and displays the new ones on arrival. @@ -555,9 +556,9 @@ class MainWindow(QtGui.QMainWindow): else: self._logger_window.setVisible(not self._logger_window.isVisible()) + @QtCore.Slot() def _show_AKM(self): """ - SLOT TRIGGERS: self.ui.action_advanced_key_management.triggered @@ -565,16 +566,22 @@ class MainWindow(QtGui.QMainWindow): """ domain = self._login_widget.get_selected_provider() logged_user = "{0}@{1}".format(self._logged_user, domain) - self._akm = AdvancedKeyManagement( - logged_user, self._keymanager, self._soledad) - self._akm.show() + has_mx = True + if self._logged_user is not None: + provider_config = self._get_best_provider_config() + has_mx = provider_config.provides_mx() + + akm = AdvancedKeyManagement( + self, has_mx, logged_user, self._keymanager, self._soledad) + akm.show() + + @QtCore.Slot() def _show_preferences(self): """ - SLOT TRIGGERS: - self.ui.btnPreferences.clicked (disabled for now) - self.ui.action_preferences + self.ui.btnPreferences.clicked (disabled for now) + self.ui.action_preferences Displays the preferences window. """ @@ -586,9 +593,9 @@ class MainWindow(QtGui.QMainWindow): preferences.show() preferences.preferences_saved.connect(self._update_eip_enabled_status) + @QtCore.Slot() def _update_eip_enabled_status(self): """ - SLOT TRIGGER: PreferencesWindow.preferences_saved @@ -622,12 +629,12 @@ class MainWindow(QtGui.QMainWindow): return eip_enabled + @QtCore.Slot() def _show_eip_preferences(self): """ - SLOT TRIGGERS: - self.ui.btnEIPPreferences.clicked - self.ui.action_eip_preferences (disabled for now) + self.ui.btnEIPPreferences.clicked + self.ui.action_eip_preferences (disabled for now) Displays the EIP preferences window. """ @@ -647,22 +654,27 @@ class MainWindow(QtGui.QMainWindow): """ self.new_updates.emit(req) + @QtCore.Slot(object) def _react_to_new_updates(self, req): """ - SLOT - TRIGGER: self._new_updates_available + TRIGGERS: + self.new_updates Displays the new updates label and sets the updates_content + + :param req: Request type + :type req: leap.common.events.events_pb2.SignalRequest """ self.moveToThread(QtCore.QCoreApplication.instance().thread()) self.ui.lblNewUpdates.setVisible(True) self.ui.btnMore.setVisible(True) self._updates_content = req.content + @QtCore.Slot() def _updates_details(self): """ - SLOT - TRIGGER: self.ui.btnMore.clicked + TRIGGERS: + self.ui.btnMore.clicked Parses and displays the updates details """ @@ -686,11 +698,11 @@ class MainWindow(QtGui.QMainWindow): self.tr("Updates available"), msg) + @QtCore.Slot() def _finish_init(self): """ - SLOT TRIGGERS: - self._wizard.accepted + self._wizard.accepted Also called at the end of the constructor if not first run. @@ -826,16 +838,21 @@ class MainWindow(QtGui.QMainWindow): self._mail_status.set_systray(self._systray) self._eip_status.set_systray(self._systray) - hello = lambda: self._systray.showMessage( - self.tr('Hello!'), - self.tr('Bitmask has started in the tray.')) - # we wait for the systray to be ready - reactor.callLater(1, hello) + if self._start_hidden: + hello = lambda: self._systray.showMessage( + self.tr('Hello!'), + self.tr('Bitmask has started in the tray.')) + # we wait for the systray to be ready + reactor.callLater(1, hello) + @QtCore.Slot(int) def _tray_activated(self, reason=None): """ - SLOT - TRIGGER: self._systray.activated + TRIGGERS: + self._systray.activated + + :param reason: the reason why the tray got activated. + :type reason: int Displays the context menu from the tray icon """ @@ -862,10 +879,11 @@ class MainWindow(QtGui.QMainWindow): visible = self.isVisible() and self.isActiveWindow() self._action_visible.setText(get_action(visible)) + @QtCore.Slot() def _toggle_visible(self): """ - SLOT - TRIGGER: self._action_visible.triggered + TRIGGERS: + self._action_visible.triggered Toggles the window visibility """ @@ -909,10 +927,11 @@ class MainWindow(QtGui.QMainWindow): if state is not None: self.restoreState(state) + @QtCore.Slot() def _about(self): """ - SLOT - TRIGGERS: self.ui.action_about_leap.triggered + TRIGGERS: + self.ui.action_about_leap.triggered Display the About Bitmask dialog """ @@ -936,10 +955,11 @@ class MainWindow(QtGui.QMainWindow): "<a href='https://leap.se'>More about LEAP" "</a>") % (VERSION, VERSION_HASH[:10], greet)) + @QtCore.Slot() def _help(self): """ - SLOT - TRIGGERS: self.ui.action_help.triggered + TRIGGERS: + self.ui.action_help.triggered Display the Bitmask help dialog. """ @@ -1036,10 +1056,11 @@ class MainWindow(QtGui.QMainWindow): provider = self._login_widget.get_selected_provider() self._backend.setup_provider(provider) + @QtCore.Slot(dict) def _load_provider_config(self, data): """ - SLOT - TRIGGER: self._backend.signaler.prov_download_provider_info + 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 @@ -1054,8 +1075,9 @@ class MainWindow(QtGui.QMainWindow): self._backend.provider_bootstrap(selected_provider) else: logger.error(data[self._backend.ERROR_KEY]) - self._login_widget.set_enabled(True) + self._login_problem_provider() + @QtCore.Slot() def _login_problem_provider(self): """ Warns the user about a problem with the provider during login. @@ -1064,11 +1086,11 @@ class MainWindow(QtGui.QMainWindow): self.tr("Unable to login: Problem with provider")) self._login_widget.set_enabled(True) + @QtCore.Slot() def _login(self): """ - SLOT TRIGGERS: - self._login_widget.login + self._login_widget.login Starts the login sequence. Which involves bootstrapping the selected provider if the selection is valid (not empty), then @@ -1092,9 +1114,9 @@ class MainWindow(QtGui.QMainWindow): if self._login_widget.start_login(): self._download_provider_config() + @QtCore.Slot(unicode) def _authentication_error(self, msg): """ - SLOT TRIGGERS: Signaler.srp_auth_error Signaler.srp_auth_server_error @@ -1110,11 +1132,11 @@ class MainWindow(QtGui.QMainWindow): self._login_widget.set_enabled(True) self.ui.action_create_new_account.setEnabled(True) + @QtCore.Slot() def _cancel_login(self): """ - SLOT TRIGGERS: - self._login_widget.cancel_login + self._login_widget.cancel_login Stops the login sequence. """ @@ -1134,9 +1156,9 @@ class MainWindow(QtGui.QMainWindow): self._soledad_defer.cancel() self._soledad_defer = None + @QtCore.Slot() def _set_login_cancelled(self): """ - SLOT TRIGGERS: Signaler.prov_cancelled_setup fired by self._backend.cancel_setup_provider() @@ -1147,10 +1169,11 @@ class MainWindow(QtGui.QMainWindow): self._login_widget.set_status(self.tr("Log in cancelled by the user.")) self._login_widget.set_enabled(True) + @QtCore.Slot(dict) def _provider_config_loaded(self, data): """ - SLOT - TRIGGER: self._backend.signaler.prov_check_api_certificate + TRIGGERS: + self._backend.signaler.prov_check_api_certificate Once the provider configuration is loaded, this starts the SRP authentication @@ -1166,15 +1189,14 @@ class MainWindow(QtGui.QMainWindow): domain = self._provider_config.get_domain() self._backend.login(domain, username, password) else: - self._login_widget.set_status( - "Unable to login: Problem with provider") logger.error(data[self._backend.ERROR_KEY]) - self._login_widget.set_enabled(True) + self._login_problem_provider() + @QtCore.Slot() def _authentication_finished(self): """ - SLOT - TRIGGER: self._srp_auth.authentication_finished + TRIGGERS: + self._srp_auth.authentication_finished Once the user is properly authenticated, try starting the EIP service @@ -1285,12 +1307,12 @@ class MainWindow(QtGui.QMainWindow): ################################################################### # Service control methods: soledad + @QtCore.Slot(dict) def _soledad_intermediate_stage(self, data): # TODO missing param docstring """ - SLOT TRIGGERS: - self._soledad_bootstrapper.download_config + self._soledad_bootstrapper.download_config If there was a problem, displays it, otherwise it does nothing. This is used for intermediate bootstrapping stages, in case @@ -1320,12 +1342,12 @@ class MainWindow(QtGui.QMainWindow): logger.warning("Max number of soledad initialization " "retries reached.") + @QtCore.Slot(dict) def _soledad_bootstrapped_stage(self, data): """ - SLOT TRIGGERS: - self._soledad_bootstrapper.gen_key - self._soledad_bootstrapper.local_only_ready + self._soledad_bootstrapper.gen_key + self._soledad_bootstrapper.local_only_ready If there was a problem, displays it, otherwise it does nothing. This is used for intermediate bootstrapping stages, in case @@ -1364,7 +1386,6 @@ class MainWindow(QtGui.QMainWindow): @QtCore.Slot() def _start_smtp_bootstrapping(self): """ - SLOT TRIGGERS: self.soledad_ready """ @@ -1385,7 +1406,6 @@ class MainWindow(QtGui.QMainWindow): @QtCore.Slot() def _stop_smtp_service(self): """ - SLOT TRIGGERS: self.logout """ @@ -1398,7 +1418,6 @@ class MainWindow(QtGui.QMainWindow): @QtCore.Slot() def _start_imap_service(self): """ - SLOT TRIGGERS: self.soledad_ready """ @@ -1428,7 +1447,6 @@ class MainWindow(QtGui.QMainWindow): @QtCore.Slot() def _fetch_incoming_mail(self): """ - SLOT TRIGGERS: self.mail_client_logged_in """ @@ -1438,7 +1456,6 @@ class MainWindow(QtGui.QMainWindow): @QtCore.Slot() def _stop_imap_service(self): """ - SLOT TRIGGERS: self.logout """ @@ -1487,9 +1504,9 @@ class MainWindow(QtGui.QMainWindow): @QtCore.Slot() def _on_eip_connection_connected(self): """ - SLOT TRIGGERS: self._eip_status.eip_connection_connected + Emits the EIPConnection.qtsigs.connected_signal This is a little workaround for connecting the vpn-connected @@ -1589,9 +1606,9 @@ class MainWindow(QtGui.QMainWindow): self._backend.start_eip() + @QtCore.Slot() def _on_eip_connection_aborted(self): """ - SLOT TRIGGERS: Signaler.eip_connection_aborted """ @@ -1667,7 +1684,6 @@ class MainWindow(QtGui.QMainWindow): @QtCore.Slot() def _stop_eip(self): """ - SLOT TRIGGERS: self._eip_connection.qtsigs.do_disconnect_signal (via state machine) @@ -1697,7 +1713,6 @@ class MainWindow(QtGui.QMainWindow): def _on_eip_network_unreachable(self): # XXX Should move to EIP Conductor """ - SLOT TRIGGERS: self._eip_connection.qtsigs.network_unreachable @@ -1711,7 +1726,7 @@ class MainWindow(QtGui.QMainWindow): def _do_eip_restart(self): # XXX Should move to EIP Conductor """ - SLOT + TRIGGERS: self._eip_connection.qtsigs.process_restart Restart the connection. @@ -1729,9 +1744,9 @@ class MainWindow(QtGui.QMainWindow): self._eip_status.set_eip_status("", error=error) self._eip_status.set_eip_status_icon("error") + @QtCore.Slot(int) def _eip_finished(self, exitCode): """ - SLOT TRIGGERS: Signaler.eip_process_finished @@ -1794,8 +1809,6 @@ class MainWindow(QtGui.QMainWindow): Start the EIP bootstrapping sequence if the client is configured to do so. """ - 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( @@ -1822,10 +1835,11 @@ class MainWindow(QtGui.QMainWindow): # eip will not start, so we start soledad anyway self._maybe_run_soledad_setup_checks() + @QtCore.Slot(dict) def _finish_eip_bootstrap(self, data): """ - SLOT - TRIGGER: self._backend.signaler.eip_client_certificate_ready + TRIGGERS: + self._backend.signaler.eip_client_certificate_ready Starts the VPN thread if the eip configuration is properly loaded @@ -1842,12 +1856,12 @@ class MainWindow(QtGui.QMainWindow): # DO START EIP Connection! self._eip_connection.qtsigs.do_connect_signal.emit() + @QtCore.Slot(dict) def _eip_intermediate_stage(self, data): # TODO missing param """ - SLOT TRIGGERS: - self._backend.signaler.eip_config_ready + self._backend.signaler.eip_config_ready If there was a problem, displays it, otherwise it does nothing. This is used for intermediate bootstrapping stages, in case @@ -1889,8 +1903,8 @@ class MainWindow(QtGui.QMainWindow): @QtCore.Slot() def _logout(self): """ - SLOT - TRIGGER: self._login_widget.logout + TRIGGERS: + self._login_widget.logout Starts the logout sequence """ @@ -1907,10 +1921,11 @@ class MainWindow(QtGui.QMainWindow): self._backend.logout() self.logout.emit() + @QtCore.Slot() def _logout_error(self): """ - SLOT - TRIGGER: self._srp_auth.logout_error + TRIGGER: + self._srp_auth.logout_error Inform the user about a logout error. """ @@ -1919,10 +1934,11 @@ class MainWindow(QtGui.QMainWindow): self._login_widget.set_status( self.tr("Something went wrong with the logout.")) + @QtCore.Slot() def _logout_ok(self): """ - SLOT - TRIGGER: self._srp_auth.logout_ok + TRIGGER: + self._srp_auth.logout_ok Switches the stackedWidget back to the login stage after logging out @@ -1934,15 +1950,14 @@ class MainWindow(QtGui.QMainWindow): self._login_widget.logged_out() self._mail_status.mail_state_disabled() + @QtCore.Slot(dict) def _intermediate_stage(self, data): # TODO this method name is confusing as hell. """ - SLOT TRIGGERS: - self._backend.signaler.prov_name_resolution - self._backend.signaler.prov_https_connection - self._backend.signaler.prov_download_ca_cert - self._backend.signaler.eip_config_ready + self._backend.signaler.prov_name_resolution + self._backend.signaler.prov_https_connection + self._backend.signaler.prov_download_ca_cert If there was a problem, displays it, otherwise it does nothing. This is used for intermediate bootstrapping stages, in case @@ -1950,10 +1965,8 @@ class MainWindow(QtGui.QMainWindow): """ passed = data[self._backend.PASSED_KEY] if not passed: - msg = self.tr("Unable to connect: Problem with provider") - self._login_widget.set_status(msg) - self._login_widget.set_enabled(True) logger.error(data[self._backend.ERROR_KEY]) + self._login_problem_provider() # # window handling methods @@ -1967,9 +1980,9 @@ class MainWindow(QtGui.QMainWindow): raise_window_ack() self.raise_window.emit() + @QtCore.Slot() def _do_raise_mainwindow(self): """ - SLOT TRIGGERS: self._on_raise_window_event @@ -2033,9 +2046,10 @@ class MainWindow(QtGui.QMainWindow): # first thing to do quitting, hide the mainwindow and show tooltip. self.hide() - self._systray.showMessage( - self.tr('Quitting...'), - self.tr('The app is quitting, please wait.')) + if self._systray is not None: + self._systray.showMessage( + self.tr('Quitting...'), + self.tr('The app is quitting, please wait.')) # explicitly process events to display tooltip immediately QtCore.QCoreApplication.processEvents() diff --git a/src/leap/bitmask/gui/preferenceswindow.py b/src/leap/bitmask/gui/preferenceswindow.py index f6bd1ed3..014a0a4f 100644 --- a/src/leap/bitmask/gui/preferenceswindow.py +++ b/src/leap/bitmask/gui/preferenceswindow.py @@ -89,9 +89,9 @@ class PreferencesWindow(QtGui.QDialog): self._select_provider_by_name(domain) + @QtCore.Slot() def _is_logged_in(self): """ - SLOT TRIGGERS: Signaler.srp_status_logged_in @@ -123,9 +123,9 @@ class PreferencesWindow(QtGui.QDialog): self.ui.gbPasswordChange.setEnabled(pw_enabled) + @QtCore.Slot() def _not_logged_in(self): """ - SLOT TRIGGERS: Signaler.srp_status_not_logged_in @@ -136,9 +136,9 @@ class PreferencesWindow(QtGui.QDialog): self._set_password_change_status(msg) self.ui.gbPasswordChange.setEnabled(False) + @QtCore.Slot() def set_soledad_ready(self): """ - SLOT TRIGGERS: parent.soledad_ready @@ -183,9 +183,9 @@ class PreferencesWindow(QtGui.QDialog): self.ui.leNewPassword2.setEnabled(not disable) self.ui.pbChangePassword.setEnabled(not disable) + @QtCore.Slot() def _change_password(self): """ - SLOT TRIGGERS: self.ui.pbChangePassword.clicked @@ -207,11 +207,11 @@ class PreferencesWindow(QtGui.QDialog): self._set_changing_password(True) self._backend.change_password(current_password, new_password) + @QtCore.Slot() def _change_password_ok(self): """ - SLOT TRIGGERS: - self._backend.signaler.srp_password_change_ok + self._backend.signaler.srp_password_change_ok Callback used to display a successfully changed password. """ @@ -229,12 +229,12 @@ class PreferencesWindow(QtGui.QDialog): self._clear_password_inputs() self._set_changing_password(False) + @QtCore.Slot(unicode) def _change_password_problem(self, msg): """ - SLOT TRIGGERS: - self._backend.signaler.srp_password_change_error - self._backend.signaler.srp_password_change_badpw + self._backend.signaler.srp_password_change_error + self._backend.signaler.srp_password_change_badpw Callback used to display an error on changing password. @@ -287,10 +287,12 @@ class PreferencesWindow(QtGui.QDialog): provider_index = self.ui.cbProvidersServices.findText(name) self.ui.cbProvidersServices.setCurrentIndex(provider_index) + @QtCore.Slot(str, int) def _service_selection_changed(self, service, state): """ - SLOT - TRIGGER: service_checkbox.stateChanged + TRIGGERS: + service_checkbox.stateChanged + Adds the service to the state if the state is checked, removes it otherwise @@ -309,9 +311,9 @@ class PreferencesWindow(QtGui.QDialog): # We hide the maybe-visible status label after a change self.ui.lblProvidersServicesStatus.setVisible(False) + @QtCore.Slot(str) def _populate_services(self, domain): """ - SLOT TRIGGERS: self.ui.cbProvidersServices.currentIndexChanged[unicode] @@ -368,9 +370,9 @@ class PreferencesWindow(QtGui.QDialog): logger.error("Something went wrong while trying to " "load service %s" % (service,)) + @QtCore.Slot(str) def _save_enabled_services(self, provider): """ - SLOT TRIGGERS: self.ui.pbSaveServices.clicked diff --git a/src/leap/bitmask/gui/twisted_main.py b/src/leap/bitmask/gui/twisted_main.py index ece32ca2..f39d0bbe 100644 --- a/src/leap/bitmask/gui/twisted_main.py +++ b/src/leap/bitmask/gui/twisted_main.py @@ -22,9 +22,6 @@ import logging from twisted.internet import error, reactor from PySide import QtCore -# Resist the temptation of putting the import reactor here, -# it will raise an "reactor already imported" error. - logger = logging.getLogger(__name__) @@ -32,7 +29,11 @@ def stop(): logger.debug("Really stoping all the things...") QtCore.QCoreApplication.sendPostedEvents() QtCore.QCoreApplication.flush() - reactor.stop() + try: + reactor.stop() + logger.debug('Twisted reactor stopped') + except error.ReactorNotRunning: + logger.debug('Twisted reactor not running') logger.debug("Done stopping all the things.") @@ -43,8 +44,4 @@ def quit(app): :param app: the main qt QApplication instance. :type app: QtCore.QApplication """ - logger.debug('Stopping twisted reactor') - try: - reactor.callLater(0, stop) - except error.ReactorNotRunning: - logger.debug('Reactor not running') + reactor.callLater(0, stop) diff --git a/src/leap/bitmask/gui/ui/advanced_key_management.ui b/src/leap/bitmask/gui/ui/advanced_key_management.ui index 1112670f..3b567347 100644 --- a/src/leap/bitmask/gui/ui/advanced_key_management.ui +++ b/src/leap/bitmask/gui/ui/advanced_key_management.ui @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>AdvancedKeyManagement</class> - <widget class="QWidget" name="AdvancedKeyManagement"> + <widget class="QDialog" name="AdvancedKeyManagement"> <property name="geometry"> <rect> <x>0</x> diff --git a/src/leap/bitmask/gui/wizard.py b/src/leap/bitmask/gui/wizard.py index ebcee400..020a58e2 100644 --- a/src/leap/bitmask/gui/wizard.py +++ b/src/leap/bitmask/gui/wizard.py @@ -24,6 +24,7 @@ from functools import partial 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 @@ -145,8 +146,7 @@ class Wizard(QtGui.QWizard): @QtCore.Slot() def _wizard_finished(self): """ - SLOT - TRIGGER: + TRIGGERS: self.finished This method is called when the wizard is accepted or rejected. @@ -210,15 +210,19 @@ class Wizard(QtGui.QWizard): def get_services(self): return self._selected_services - @QtCore.Slot() + @QtCore.Slot(unicode) def _enable_check(self, reset=True): """ - SLOT - TRIGGER: + TRIGGERS: self.ui.lnProvider.textChanged Enables/disables the 'check' button in the SELECT_PROVIDER_PAGE depending on the lnProvider content. + + :param reset: this contains the text of the line edit, and when is + called directly defines whether we want to reset the + checks. + :type reset: unicode or bool """ enabled = len(self.ui.lnProvider.text()) != 0 enabled = enabled or self.ui.rbExistingProvider.isChecked() @@ -282,11 +286,11 @@ class Wizard(QtGui.QWizard): # register button self.ui.btnRegister.setVisible(visible) + @QtCore.Slot() def _registration_finished(self): """ - SLOT TRIGGERS: - self._backend.signaler.srp_registration_finished + self._backend.signaler.srp_registration_finished The registration has finished successfully, so we do some final steps. """ @@ -308,11 +312,11 @@ class Wizard(QtGui.QWizard): self.page(self.REGISTER_USER_PAGE).set_completed() self.button(QtGui.QWizard.BackButton).setEnabled(False) + @QtCore.Slot() def _registration_failed(self): """ - SLOT TRIGGERS: - self._backend.signaler.srp_registration_failed + self._backend.signaler.srp_registration_failed The registration has failed, so we report the problem. """ @@ -322,11 +326,11 @@ class Wizard(QtGui.QWizard): self._set_register_status(error_msg, error=True) self.ui.btnRegister.setEnabled(True) + @QtCore.Slot() def _registration_taken(self): """ - SLOT TRIGGERS: - self._backend.signaler.srp_registration_taken + self._backend.signaler.srp_registration_taken The requested username is taken, warn the user about that. """ @@ -358,7 +362,8 @@ class Wizard(QtGui.QWizard): self.ui.lblProviderSelectStatus.setText("") self._domain = None self.button(QtGui.QWizard.NextButton).setEnabled(False) - self.page(self.SELECT_PROVIDER_PAGE).set_completed(False) + self.page(self.SELECT_PROVIDER_PAGE).set_completed( + flags.SKIP_WIZARD_CHECKS) def _reset_provider_setup(self): """ @@ -368,12 +373,12 @@ class Wizard(QtGui.QWizard): self.ui.lblCheckCaFpr.setPixmap(None) self.ui.lblCheckApiCert.setPixmap(None) + @QtCore.Slot() def _check_provider(self): """ - SLOT TRIGGERS: - self.ui.btnCheck.clicked - self.ui.lnProvider.returnPressed + self.ui.btnCheck.clicked + self.ui.lnProvider.returnPressed Starts the checks for a given provider """ @@ -403,10 +408,10 @@ class Wizard(QtGui.QWizard): self._provider_select_defer = self._backend.\ setup_provider(self._domain) + @QtCore.Slot(bool) def _skip_provider_checks(self, skip): """ - SLOT - Triggered: + TRIGGERS: self.ui.rbExistingProvider.toggled Allows the user to move to the next page without make any checks, @@ -447,10 +452,11 @@ class Wizard(QtGui.QWizard): label.setPixmap(self.ERROR_ICON) logger.error(error) + @QtCore.Slot(dict) def _name_resolution(self, data): """ - SLOT - TRIGGER: self._backend.signaler.prov_name_resolution + TRIGGERS: + self._backend.signaler.prov_name_resolution Sets the status for the name resolution check """ @@ -466,10 +472,11 @@ class Wizard(QtGui.QWizard): self.ui.btnCheck.setEnabled(not passed) self.ui.lnProvider.setEnabled(not passed) + @QtCore.Slot(dict) def _https_connection(self, data): """ - SLOT - TRIGGER: self._backend.signaler.prov_https_connection + TRIGGERS: + self._backend.signaler.prov_https_connection Sets the status for the https connection check """ @@ -485,10 +492,11 @@ class Wizard(QtGui.QWizard): self.ui.btnCheck.setEnabled(not passed) self.ui.lnProvider.setEnabled(not passed) + @QtCore.Slot(dict) def _download_provider_info(self, data): """ - SLOT - TRIGGER: self._backend.signaler.prov_download_provider_info + TRIGGERS: + self._backend.signaler.prov_download_provider_info Sets the status for the provider information download check. Since this check is the last of this set, it also @@ -519,10 +527,11 @@ class Wizard(QtGui.QWizard): else: self.ui.cbProviders.setEnabled(True) + @QtCore.Slot(dict) def _download_ca_cert(self, data): """ - SLOT - TRIGGER: self._backend.signaler.prov_download_ca_cert + TRIGGERS: + self._backend.signaler.prov_download_ca_cert Sets the status for the download of the CA certificate check """ @@ -531,10 +540,11 @@ class Wizard(QtGui.QWizard): if passed: self.ui.lblCheckCaFpr.setPixmap(self.QUESTION_ICON) + @QtCore.Slot(dict) def _check_ca_fingerprint(self, data): """ - SLOT - TRIGGER: self._backend.signaler.prov_check_ca_fingerprint + TRIGGERS: + self._backend.signaler.prov_check_ca_fingerprint Sets the status for the CA fingerprint check """ @@ -543,10 +553,11 @@ class Wizard(QtGui.QWizard): if passed: self.ui.lblCheckApiCert.setPixmap(self.QUESTION_ICON) + @QtCore.Slot(dict) def _check_api_certificate(self, data): """ - SLOT - TRIGGER: self._backend.signaler.prov_check_api_certificate + TRIGGERS: + self._backend.signaler.prov_check_api_certificate Sets the status for the API certificate check. Also finishes the provider bootstrapper thread since it's not needed anymore @@ -556,10 +567,12 @@ class Wizard(QtGui.QWizard): True, self.SETUP_PROVIDER_PAGE) self._provider_setup_ok = True + @QtCore.Slot(str, int) def _service_selection_changed(self, service, state): """ - SLOT - TRIGGER: service_checkbox.stateChanged + TRIGGERS: + service_checkbox.stateChanged + Adds the service to the state if the state is checked, removes it otherwise @@ -604,12 +617,16 @@ class Wizard(QtGui.QWizard): self.tr("Something went wrong while trying to " "load service %s" % (service,))) + @QtCore.Slot(int) def _current_id_changed(self, pageId): """ - SLOT - TRIGGER: self.currentIdChanged + TRIGGERS: + self.currentIdChanged Prepares the pages when they appear + + :param pageId: the new current page id. + :type pageId: int """ if pageId == self.SELECT_PROVIDER_PAGE: self._clear_register_widgets() diff --git a/src/leap/bitmask/services/mail/conductor.py b/src/leap/bitmask/services/mail/conductor.py index 79f324dc..c1761afa 100644 --- a/src/leap/bitmask/services/mail/conductor.py +++ b/src/leap/bitmask/services/mail/conductor.py @@ -238,12 +238,11 @@ class SMTPControl(object): self._smtp_port.stopListening() self._smtp_service.doStop() - @QtCore.Slot() + @QtCore.Slot(dict) def smtp_bootstrapped_stage(self, data): """ - SLOT TRIGGERS: - self.smtp_bootstrapper.download_config + self.smtp_bootstrapper.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/util/leap_argparse.py b/src/leap/bitmask/util/leap_argparse.py index 8aacc85d..84af4e8d 100644 --- a/src/leap/bitmask/util/leap_argparse.py +++ b/src/leap/bitmask/util/leap_argparse.py @@ -62,6 +62,10 @@ def build_parser(): parser.add_argument('-H', '--start-hidden', default=False, action="store_true", dest="start_hidden", help='Starts the application just in the taskbar.') + parser.add_argument('-S', '--skip-wizard-checks', default=False, + action="store_true", dest="skip_wizard_checks", + help='Skips the provider checks in the wizard (use ' + 'for testing purposes only).') # openvpn options parser.add_argument('--openvpn-verbosity', nargs='?', |