From 361a18b0e727a68d6e0d1e9d03273630b9c14692 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Wed, 6 Mar 2013 15:43:36 -0300 Subject: Add UI merging all the code Also add resources --- src/leap/gui/mainwindow.py | 600 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 600 insertions(+) create mode 100644 src/leap/gui/mainwindow.py (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py new file mode 100644 index 00000000..1821e4a6 --- /dev/null +++ b/src/leap/gui/mainwindow.py @@ -0,0 +1,600 @@ +# -*- coding: utf-8 -*- +# mainwindow.py +# Copyright (C) 2013 LEAP +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +""" +Main window for the leap client +""" +import os +import logging + +from PySide import QtCore, QtGui + +from ui_mainwindow import Ui_MainWindow +from leap.config.providerconfig import ProviderConfig +from leap.crypto.srpauth import SRPAuth +from leap.services.eip.vpn import VPN +from leap.services.eip.providerbootstrapper import ProviderBootstrapper +from leap.services.eip.eipbootstrapper import EIPBootstrapper +from leap.services.eip.eipconfig import EIPConfig +from leap.gui.wizard import Wizard + +logger = logging.getLogger(__name__) + + +class MainWindow(QtGui.QMainWindow): + """ + Main window for login and presenting status updates to the user + """ + + # StackedWidget indexes + LOGIN_INDEX = 0 + EIP_STATUS_INDEX = 1 + + def __init__(self): + QtGui.QMainWindow.__init__(self) + + self.CONNECTING_ICON = QtGui.QPixmap(":/images/conn_connecting.png") + self.CONNECTED_ICON = QtGui.QPixmap(":/images/conn_connected.png") + self.ERROR_ICON = QtGui.QPixmap(":/images/conn_error.png") + + self.ui = Ui_MainWindow() + self.ui.setupUi(self) + + self.ui.lnPassword.setEchoMode(QtGui.QLineEdit.Password) + + self.ui.btnLogin.clicked.connect(self._login) + self.ui.lnUser.returnPressed.connect(self._focus_password) + self.ui.lnPassword.returnPressed.connect(self._login) + + self.ui.stackedWidget.setCurrentIndex(self.LOGIN_INDEX) + + # This is loaded only once, there's a bug when doing that more + # than once + self._provider_config = ProviderConfig() + self._eip_config = EIPConfig() + # This is created once we have a valid provider config + self._srp_auth = None + + # This thread is always running, although it's quite + # lightweight when it's done setting up provider + # configuration and certificate. + self._provider_bootstrapper = ProviderBootstrapper() + + # TODO: add sigint handler + + # Intermediate stages, only do something if there was an error + self._provider_bootstrapper.name_resolution.connect( + self._intermediate_stage) + self._provider_bootstrapper.https_connection.connect( + self._intermediate_stage) + self._provider_bootstrapper.download_ca_cert.connect( + self._intermediate_stage) + + # Important stages, loads the provider config and checks + # certificates + self._provider_bootstrapper.download_provider_info.connect( + self._load_provider_config) + self._provider_bootstrapper.check_api_certificate.connect( + self._provider_config_loaded) + + # This thread is similar to the provider bootstrapper + self._eip_bootstrapper = EIPBootstrapper() + + self._eip_bootstrapper.download_config.connect( + self._intermediate_stage) + self._eip_bootstrapper.download_client_certificate.connect( + self._start_eip) + + self._vpn = VPN() + self._vpn.state_changed.connect(self._update_vpn_state) + self._vpn.status_changed.connect(self._update_vpn_status) + + QtCore.QCoreApplication.instance().connect( + QtCore.QCoreApplication.instance(), + QtCore.SIGNAL("aboutToQuit()"), + self._vpn.set_should_quit) + QtCore.QCoreApplication.instance().connect( + QtCore.QCoreApplication.instance(), + QtCore.SIGNAL("aboutToQuit()"), + self._provider_bootstrapper.set_should_quit) + QtCore.QCoreApplication.instance().connect( + QtCore.QCoreApplication.instance(), + QtCore.SIGNAL("aboutToQuit()"), + self._eip_bootstrapper.set_should_quit) + + self.ui.action_sign_out.setEnabled(False) + self.ui.action_sign_out.triggered.connect(self._logout) + self.ui.action_about_leap.triggered.connect(self._about) + self.ui.action_quit.triggered.connect(self.quit) + self.ui.action_wizard.triggered.connect(self._launch_wizard) + + # Used to differentiate between real quits and close to tray + self._really_quit = False + + self._systray = None + self._action_visible = QtGui.QAction("Hide", self) + self._action_visible.triggered.connect(self._toggle_visible) + + self._center_window() + self._wizard = None + if self._first_run(): + self._wizard = Wizard() + # Give this window time to finish init and then show the wizard + QtCore.QTimer.singleShot(1, self._launch_wizard) + self._wizard.finished.connect(self._finish_init) + else: + self._finish_init() + + def _launch_wizard(self): + if self._wizard is None: + self._wizard = Wizard() + self._wizard.exec_() + + def _finish_init(self): + self.ui.cmbProviders.addItems(self._configured_providers()) + self._show_systray() + self.show() + if self._wizard: + possible_username = self._wizard.get_username() + if possible_username is not None: + self.ui.lnUser.setText(possible_username) + self._focus_password() + self._wizard = None + + def _show_systray(self): + """ + Sets up the systray icon + """ + systrayMenu = QtGui.QMenu(self) + systrayMenu.addAction(self._action_visible) + systrayMenu.addAction(self.ui.action_sign_out) + systrayMenu.addSeparator() + systrayMenu.addAction(self.ui.action_quit) + self._systray = QtGui.QSystemTrayIcon(self) + self._systray.setContextMenu(systrayMenu) + self._systray.setIcon(QtGui.QIcon(self.ERROR_ICON)) + self._systray.setVisible(True) + self._systray.activated.connect(self._toggle_visible) + + def _toggle_visible(self): + """ + SLOT + TRIGGER: self._systray.activated + + Toggles the window visibility + """ + self.setVisible(not self.isVisible()) + action_visible_text = "Hide" + if not self.isVisible(): + action_visible_text = "Show" + self._action_visible.setText(action_visible_text) + + def _center_window(self): + """ + Centers the mainwindow based on the desktop geometry + """ + app = QtGui.QApplication.instance() + width = app.desktop().width() + height = app.desktop().height() + window_width = self.size().width() + window_height = self.size().height() + x = (width / 2.0) - (window_width / 2.0) + y = (height / 2.0) - (window_height / 2.0) + self.move(x, y) + + def _about(self): + """ + Display the About LEAP dialog + """ + QtGui.QMessageBox.about(self, "About LEAP", + "LEAP is a non-profit dedicated to giving " + "all internet users access to secure " + "communication. Our focus is on adapting " + "encryption technology to make it easy to use " + "and widely available. " + "More about LEAP" + "") + + def quit(self): + self._really_quit = True + if self._wizard: + self._wizard.accept() + self.close() + + def changeEvent(self, e): + """ + Reimplements the changeEvent method to minimize to tray + """ + if QtGui.QSystemTrayIcon.isSystemTrayAvailable() and \ + e.type() == QtCore.QEvent.WindowStateChange and \ + self.isMinimized(): + self._toggle_visible() + e.accept() + return + QtGui.QMainWindow.changeEvent(self, e) + + def closeEvent(self, e): + """ + Reimplementation of closeEvent to close to tray + """ + if QtGui.QSystemTrayIcon.isSystemTrayAvailable() and \ + not self._really_quit: + self._toggle_visible() + e.ignore() + return + QtGui.QMainWindow.closeEvent(self, e) + + def _configured_providers(self): + """ + Returns the available providers based on the file structure + + @rtype: list + """ + providers = os.listdir( + os.path.join(self._provider_config.get_path_prefix(), + "leap", + "providers")) + return providers + + def _first_run(self): + """ + Returns True if there are no configured providers. False otherwise + + @rtype: bool + """ + return len(self._configured_providers()) == 0 + + def _focus_password(self): + """ + Focuses in the password lineedit + """ + self.ui.lnPassword.setFocus() + + def _set_status(self, status): + """ + Sets the status label at the login stage to status + + @param status: status message + @type status: str + """ + self.ui.lblStatus.setText(status) + + def _set_eip_status(self, status): + """ + Sets the status label at the VPN stage to status + + @param status: status message + @type status: str + """ + self.ui.lblEIPStatus.setText(status) + + def _login_set_enabled(self, enabled=False): + """ + Enables or disables all the login widgets + + @param enabled: wether they should be enabled or not + @type enabled: bool + """ + self.ui.lnUser.setEnabled(enabled) + self.ui.lnPassword.setEnabled(enabled) + self.ui.btnLogin.setEnabled(enabled) + self.ui.chkRemember.setEnabled(enabled) + self.ui.cmbProviders.setEnabled(enabled) + + def _download_provider_config(self): + """ + Starts the bootstrapping sequence. It will download the + provider configuration if it's not present, otherwise will + emit the corresponding signals inmediately + """ + provider = self.ui.cmbProviders.currentText() + + self._provider_bootstrapper.start() + self._provider_bootstrapper.run_provider_select_checks( + provider, + download_if_needed=True) + + def _load_provider_config(self, data): + """ + SLOT + TRIGGER: self._provider_bootstrapper.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 + + @param data: result from the last stage of the + run_provider_select_checks + @type data: dict + """ + if data[self._provider_bootstrapper.PASSED_KEY]: + provider = self.ui.cmbProviders.currentText() + if self._provider_config.loaded() or \ + self._provider_config.load(os.path.join("leap", + "providers", + provider, + "provider.json")): + self._provider_bootstrapper.run_provider_setup_checks( + self._provider_config, + download_if_needed=True) + else: + self._set_status("Could not load provider configuration") + self._login_set_enabled(True) + else: + self._set_status(data[self._provider_bootstrapper.ERROR_KEY]) + self._login_set_enabled(True) + + def _login(self): + """ + SLOT + TRIGGERS: + self.ui.btnLogin.clicked + self.ui.lnPassword.returnPressed + + Starts the login sequence. Which involves bootstrapping the + selected provider if the selection is valid (not empty), then + start the SRP authentication, and as the last step + bootstrapping the EIP service + """ + assert self._provider_config, "We need a provider config" + + username = self.ui.lnUser.text() + password = self.ui.lnPassword.text() + provider = self.ui.cmbProviders.currentText() + + if len(provider) == 0: + self._set_status("Please select a valid provider") + return + + if len(username) == 0: + self._set_status("Please provide a valid username") + return + + if len(password) == 0: + self._set_status("Please provide a valid Password") + return + + self._set_status("Logging in...") + self._login_set_enabled(False) + + self._download_provider_config() + + def _provider_config_loaded(self, data): + """ + SLOT + TRIGGER: self._provider_bootstrapper.check_api_certificate + + Once the provider configuration is loaded, this starts the SRP + authentication + """ + assert self._provider_config, "We need a provider config!" + + self._provider_bootstrapper.set_should_quit() + + if data[self._provider_bootstrapper.PASSED_KEY]: + username = self.ui.lnUser.text() + password = self.ui.lnPassword.text() + + if self._srp_auth is None: + self._srp_auth = SRPAuth(self._provider_config) + self._srp_auth.authentication_finished.connect( + self._authentication_finished) + self._srp_auth.logout_finished.connect( + self._done_logging_out) + + self._srp_auth.authenticate(username, password) + else: + self._set_status(data[self._provider_bootstrapper.ERROR_KEY]) + self._login_set_enabled(True) + + def _authentication_finished(self, ok, message): + """ + SLOT + TRIGGER: self._srp_auth.authentication_finished + + Once the user is properly authenticated, try starting the EIP + service + """ + self._set_status(message) + if ok: + self.ui.action_sign_out.setEnabled(True) + # We leave a bit of room for the user to see the + # "Succeeded" message and then we switch to the EIP status + # panel + QtCore.QTimer.singleShot(1000, self._switch_to_status) + else: + self._login_set_enabled(True) + + def _switch_to_status(self): + """ + Changes the stackedWidget index to the EIP status one and + triggers the eip bootstrapping + """ + self.ui.stackedWidget.setCurrentIndex(self.EIP_STATUS_INDEX) + self._download_eip_config() + + def _download_eip_config(self): + """ + Starts the EIP bootstrapping sequence + """ + assert self._eip_bootstrapper, "We need an eip bootstrapper!" + assert self._provider_config, "We need a provider config" + + self._set_eip_status("Checking configuration, please wait...") + + if self._provider_config.provides_eip(): + self._eip_bootstrapper.start() + self._eip_bootstrapper.run_eip_setup_checks( + self._provider_config, + download_if_needed=True) + else: + self._set_eip_status("%s does not support EIP" % + (self._provider_config.get_domain(),)) + + def _set_eip_status_icon(self, status): + """ + Given a status step from the VPN thread, set the icon properly + + @param status: status step + @type status: str + """ + selected_pixmap = self.ERROR_ICON + if status in ("AUTH", "GET_CONFIG"): + selected_pixmap = self.CONNECTING_ICON + elif status in ("CONNECTED"): + selected_pixmap = self.CONNECTED_ICON + + self.ui.lblVPNStatusIcon.setPixmap(selected_pixmap) + self._systray.setIcon(QtGui.QIcon(selected_pixmap)) + + def _update_vpn_state(self, data): + """ + SLOT + TRIGGER: self._vpn.state_changed + + Updates the displayed VPN state based on the data provided by + the VPN thread + """ + status = data[self._vpn.STATUS_STEP_KEY] + self._set_eip_status_icon(status) + if status == "AUTH": + self._set_eip_status("VPN: Authenticating...") + elif status == "GET_CONFIG": + self._set_eip_status("VPN: Retrieving configuration...") + elif status == "CONNECTED": + self._set_eip_status("VPN: Connected!") + else: + self._set_eip_status(status) + + def _update_vpn_status(self, data): + """ + SLOT + TRIGGER: self._vpn.status_changed + + Updates the download/upload labels based on the data provided + by the VPN thread + """ + upload = float(data[self._vpn.TUNTAP_WRITE_KEY]) + upload = upload / 1000.0 + self.ui.lblUpload.setText("%s Kb" % (upload,)) + download = float(data[self._vpn.TUNTAP_READ_KEY]) + download = download / 1000.0 + self.ui.lblDownload.setText("%s Kb" % (download,)) + + def _start_eip(self, data): + """ + SLOT + TRIGGER: self._eip_bootstrapper.download_client_certificate + + Starts the VPN thread if the eip configuration is properly + loaded + """ + assert self._eip_config, "We need an eip config!" + assert self._provider_config, "We need a provider config!" + + self._eip_bootstrapper.set_should_quit() + if self._eip_config.loaded() or \ + self._eip_config.load(os.path.join("leap", + "providers", + self._provider_config + .get_domain(), + "eip-service.json")): + self._vpn.start(eipconfig=self._eip_config, + providerconfig=self._provider_config, + socket_host="/home/chiiph/vpnsock", + socket_port="unix") + # TODO: display a message if the EIP configuration cannot be + # loaded + + def _logout(self): + """ + SLOT + TRIGGER: self.ui.action_sign_out.triggered + + Starts the logout sequence + """ + self._set_eip_status_icon("error") + self._set_eip_status("Signing out...") + self._srp_auth.logout() + + def _done_logging_out(self, ok, message): + """ + SLOT + TRIGGER: self._srp_auth.logout_finished + + Switches the stackedWidget back to the login stage after + logging out + """ + self._set_status(message) + self.ui.action_sign_out.setEnabled(False) + self.ui.stackedWidget.setCurrentIndex(self.LOGIN_INDEX) + self.ui.lnPassword.setText("") + self._login_set_enabled(True) + self._set_status("") + self._vpn.set_should_quit() + + def _intermediate_stage(self, data): + """ + SLOT + TRIGGERS: + self._provider_bootstrapper.name_resolution + self._provider_bootstrapper.https_connection + self._provider_bootstrapper.download_ca_cert + self._eip_bootstrapper.download_config + + If there was a problem, displays it, otherwise it does nothing. + This is used for intermediate bootstrapping stages, in case + they fail. + """ + passed = data[self._provider_bootstrapper.PASSED_KEY] + if not passed: + self._login_set_enabled(True) + self._set_status(data[self._provider_bootstrapper.ERROR_KEY]) + +if __name__ == "__main__": + import signal + from functools import partial + + def sigint_handler(*args, **kwargs): + logger.debug('SIGINT catched. shutting down...') + mainwindow = args[0] + mainwindow.quit() + + import sys + + logger = logging.getLogger(name='leap') + logger.setLevel(logging.DEBUG) + console = logging.StreamHandler() + console.setLevel(logging.DEBUG) + formatter = logging.Formatter( + '%(asctime)s ' + '- %(name)s - %(levelname)s - %(message)s') + console.setFormatter(formatter) + logger.addHandler(console) + + app = QtGui.QApplication(sys.argv) + mainwindow = MainWindow() + mainwindow.show() + + timer = QtCore.QTimer() + timer.start(500) + timer.timeout.connect(lambda: None) + + sigint = partial(sigint_handler, mainwindow) + signal.signal(signal.SIGINT, sigint) + + sys.exit(app.exec_()) -- cgit v1.2.3 From 751638b4eb8208e1eaa1beaaed284da6b412bca7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Thu, 7 Mar 2013 19:05:11 -0300 Subject: Change asserts for a custom leap_assert method Also: - Make SRPAuth and the Bootstrappers be a QObject instead of a QThread so we can use them inside another more generic thread - Add a generic CheckerThread that runs checks or whatever operation as long as it returns a boolean value - Closes the whole application if the wizard is rejected at the first run - Do not fail when the config directory doesn't exist - Set the wizard pixmap logo as LEAP's logo - Improve wizard checks - Make SRPRegister play nice with the CheckerThread --- src/leap/gui/mainwindow.py | 91 ++++++++++++++++++++++++++++++---------------- 1 file changed, 60 insertions(+), 31 deletions(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 1821e4a6..50a03fb9 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -31,6 +31,8 @@ from leap.services.eip.providerbootstrapper import ProviderBootstrapper from leap.services.eip.eipbootstrapper import EIPBootstrapper from leap.services.eip.eipconfig import EIPConfig from leap.gui.wizard import Wizard +from leap.util.check import leap_assert +from leap.util.checkerthread import CheckerThread logger = logging.getLogger(__name__) @@ -44,6 +46,9 @@ class MainWindow(QtGui.QMainWindow): LOGIN_INDEX = 0 EIP_STATUS_INDEX = 1 + GEOMETRY_KEY = "Geometry" + WINDOWSTATE_KEY = "WindowState" + def __init__(self): QtGui.QMainWindow.__init__(self) @@ -69,6 +74,9 @@ class MainWindow(QtGui.QMainWindow): # This is created once we have a valid provider config self._srp_auth = None + self._checker_thread = CheckerThread() + self._checker_thread.start() + # This thread is always running, although it's quite # lightweight when it's done setting up provider # configuration and certificate. @@ -110,11 +118,7 @@ class MainWindow(QtGui.QMainWindow): QtCore.QCoreApplication.instance().connect( QtCore.QCoreApplication.instance(), QtCore.SIGNAL("aboutToQuit()"), - self._provider_bootstrapper.set_should_quit) - QtCore.QCoreApplication.instance().connect( - QtCore.QCoreApplication.instance(), - QtCore.SIGNAL("aboutToQuit()"), - self._eip_bootstrapper.set_should_quit) + self._checker_thread.set_should_quit) self.ui.action_sign_out.setEnabled(False) self.ui.action_sign_out.triggered.connect(self._logout) @@ -131,17 +135,26 @@ class MainWindow(QtGui.QMainWindow): self._center_window() self._wizard = None + self._wizard_firstrun = False if self._first_run(): - self._wizard = Wizard() + self._wizard_firstrun = True + self._wizard = Wizard(self._checker_thread) # Give this window time to finish init and then show the wizard QtCore.QTimer.singleShot(1, self._launch_wizard) - self._wizard.finished.connect(self._finish_init) + self._wizard.accepted.connect(self._finish_init) + self._wizard.rejected.connect(self._rejected_wizard) + else: + self._finish_init() + + def _rejected_wizard(self): + if self._wizard_firstrun: + self.quit() else: self._finish_init() def _launch_wizard(self): if self._wizard is None: - self._wizard = Wizard() + self._wizard = Wizard(self._checker_thread) self._wizard.exec_() def _finish_init(self): @@ -187,14 +200,23 @@ class MainWindow(QtGui.QMainWindow): """ Centers the mainwindow based on the desktop geometry """ - app = QtGui.QApplication.instance() - width = app.desktop().width() - height = app.desktop().height() - window_width = self.size().width() - window_height = self.size().height() - x = (width / 2.0) - (window_width / 2.0) - y = (height / 2.0) - (window_height / 2.0) - self.move(x, y) + settings = QtCore.QSettings() + geometry = settings.value(self.GEOMETRY_KEY, None) + state = settings.value(self.WINDOWSTATE_KEY, None) + if geometry is None: + app = QtGui.QApplication.instance() + width = app.desktop().width() + height = app.desktop().height() + window_width = self.size().width() + window_height = self.size().height() + x = (width / 2.0) - (window_width / 2.0) + y = (height / 2.0) - (window_height / 2.0) + self.move(x, y) + else: + self.restoreGeometry(geometry) + + if state is not None: + self.restoreState(state) def _about(self): """ @@ -236,6 +258,9 @@ class MainWindow(QtGui.QMainWindow): self._toggle_visible() e.ignore() return + settings = QtCore.QSettings() + settings.setValue(self.GEOMETRY_KEY, self.saveGeometry()) + settings.setValue(self.WINDOWSTATE_KEY, self.saveState()) QtGui.QMainWindow.closeEvent(self, e) def _configured_providers(self): @@ -244,10 +269,16 @@ class MainWindow(QtGui.QMainWindow): @rtype: list """ - providers = os.listdir( - os.path.join(self._provider_config.get_path_prefix(), - "leap", - "providers")) + providers = [] + try: + providers = os.listdir( + os.path.join(self._provider_config.get_path_prefix(), + "leap", + "providers")) + except Exception as e: + logger.debug("Error listing providers, assume there are none. %r" + % (e,)) + return providers def _first_run(self): @@ -303,8 +334,8 @@ class MainWindow(QtGui.QMainWindow): """ provider = self.ui.cmbProviders.currentText() - self._provider_bootstrapper.start() self._provider_bootstrapper.run_provider_select_checks( + self._checker_thread, provider, download_if_needed=True) @@ -329,6 +360,7 @@ class MainWindow(QtGui.QMainWindow): provider, "provider.json")): self._provider_bootstrapper.run_provider_setup_checks( + self._checker_thread, self._provider_config, download_if_needed=True) else: @@ -350,7 +382,7 @@ class MainWindow(QtGui.QMainWindow): start the SRP authentication, and as the last step bootstrapping the EIP service """ - assert self._provider_config, "We need a provider config" + leap_assert(self._provider_config, "We need a provider config") username = self.ui.lnUser.text() password = self.ui.lnPassword.text() @@ -381,9 +413,7 @@ class MainWindow(QtGui.QMainWindow): Once the provider configuration is loaded, this starts the SRP authentication """ - assert self._provider_config, "We need a provider config!" - - self._provider_bootstrapper.set_should_quit() + leap_assert(self._provider_config, "We need a provider config!") if data[self._provider_bootstrapper.PASSED_KEY]: username = self.ui.lnUser.text() @@ -431,14 +461,14 @@ class MainWindow(QtGui.QMainWindow): """ Starts the EIP bootstrapping sequence """ - assert self._eip_bootstrapper, "We need an eip bootstrapper!" - assert self._provider_config, "We need a provider config" + leap_assert(self._eip_bootstrapper, "We need an eip bootstrapper!") + leap_assert(self._provider_config, "We need a provider config") self._set_eip_status("Checking configuration, please wait...") if self._provider_config.provides_eip(): - self._eip_bootstrapper.start() self._eip_bootstrapper.run_eip_setup_checks( + self._checker_thread, self._provider_config, download_if_needed=True) else: @@ -503,10 +533,9 @@ class MainWindow(QtGui.QMainWindow): Starts the VPN thread if the eip configuration is properly loaded """ - assert self._eip_config, "We need an eip config!" - assert self._provider_config, "We need a provider config!" + leap_assert(self._eip_config, "We need an eip config!") + leap_assert(self._provider_config, "We need a provider config!") - self._eip_bootstrapper.set_should_quit() if self._eip_config.loaded() or \ self._eip_config.load(os.path.join("leap", "providers", -- cgit v1.2.3 From 01a7faa2033ef3ce85bc5a346eca3601f0f4f7c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Fri, 8 Mar 2013 11:09:23 -0300 Subject: Migrate VPN process to QProcess Also: - Add a new tray icon for the whole app and a VPN specific one - Add a way to start/stop EIP independently - Improve reaction to the process dying --- src/leap/gui/mainwindow.py | 98 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 88 insertions(+), 10 deletions(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 50a03fb9..df21a2bb 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -56,6 +56,9 @@ class MainWindow(QtGui.QMainWindow): self.CONNECTED_ICON = QtGui.QPixmap(":/images/conn_connected.png") self.ERROR_ICON = QtGui.QPixmap(":/images/conn_error.png") + self.LOGGED_OUT_ICON = QtGui.QPixmap(":/images/leap-gray-big.png") + self.LOGGED_IN_ICON = QtGui.QPixmap(":/images/leap-color-big.png") + self.ui = Ui_MainWindow() self.ui.setupUi(self) @@ -67,6 +70,10 @@ class MainWindow(QtGui.QMainWindow): self.ui.stackedWidget.setCurrentIndex(self.LOGIN_INDEX) + self.ui.btnEipStartStop.setEnabled(False) + self.ui.btnEipStartStop.clicked.connect( + self._stop_eip) + # This is loaded only once, there's a bug when doing that more # than once self._provider_config = ProviderConfig() @@ -105,11 +112,13 @@ class MainWindow(QtGui.QMainWindow): self._eip_bootstrapper.download_config.connect( self._intermediate_stage) self._eip_bootstrapper.download_client_certificate.connect( - self._start_eip) + self._finish_eip_bootstrap) self._vpn = VPN() self._vpn.state_changed.connect(self._update_vpn_state) self._vpn.status_changed.connect(self._update_vpn_status) + self._vpn.process_finished.connect( + self._eip_finished) QtCore.QCoreApplication.instance().connect( QtCore.QCoreApplication.instance(), @@ -130,6 +139,22 @@ class MainWindow(QtGui.QMainWindow): self._really_quit = False self._systray = None + self._vpn_systray = None + + self._action_eip_status = QtGui.QAction("Encryption is OFF", self) + self._action_eip_status.setEnabled(False) + self._action_eip_stop = QtGui.QAction("Stop", self) + self._action_eip_stop.triggered.connect( + self._stop_eip) + self._action_eip_write = QtGui.QAction( + QtGui.QIcon(":/images/Arrow-Up-32.png"), + "0.0 Kb", self) + self._action_eip_write.setEnabled(False) + self._action_eip_read = QtGui.QAction( + QtGui.QIcon(":/images/Arrow-Down-32.png"), + "0.0 Kb", self) + self._action_eip_read.setEnabled(False) + self._action_visible = QtGui.QAction("Hide", self) self._action_visible.triggered.connect(self._toggle_visible) @@ -179,10 +204,20 @@ class MainWindow(QtGui.QMainWindow): systrayMenu.addAction(self.ui.action_quit) self._systray = QtGui.QSystemTrayIcon(self) self._systray.setContextMenu(systrayMenu) - self._systray.setIcon(QtGui.QIcon(self.ERROR_ICON)) + self._systray.setIcon(QtGui.QIcon(self.LOGGED_OUT_ICON)) self._systray.setVisible(True) self._systray.activated.connect(self._toggle_visible) + vpn_systrayMenu = QtGui.QMenu(self) + vpn_systrayMenu.addAction(self._action_eip_status) + vpn_systrayMenu.addAction(self._action_eip_stop) + vpn_systrayMenu.addAction(self._action_eip_read) + vpn_systrayMenu.addAction(self._action_eip_write) + self._vpn_systray = QtGui.QSystemTrayIcon(self) + self._vpn_systray.setContextMenu(vpn_systrayMenu) + self._vpn_systray.setIcon(QtGui.QIcon(self.ERROR_ICON)) + self._vpn_systray.setVisible(False) + def _toggle_visible(self): """ SLOT @@ -455,8 +490,33 @@ class MainWindow(QtGui.QMainWindow): triggers the eip bootstrapping """ self.ui.stackedWidget.setCurrentIndex(self.EIP_STATUS_INDEX) + self._systray.setIcon(self.LOGGED_IN_ICON) self._download_eip_config() + def _start_eip(self): + self._vpn.start(eipconfig=self._eip_config, + providerconfig=self._provider_config, + socket_host="/home/chiiph/vpnsock", + socket_port="unix") + self._vpn_systray.setVisible(True) + self.ui.btnEipStartStop.setEnabled(True) + self.ui.btnEipStartStop.setText("Stop EIP") + self.ui.btnEipStartStop.clicked.disconnect( + self._start_eip) + self.ui.btnEipStartStop.clicked.connect( + self._stop_eip) + + def _stop_eip(self): + self._vpn.set_should_quit() + self._vpn_systray.setVisible(False) + self._set_eip_status("EIP has stopped") + self._set_eip_status_icon("error") + self.ui.btnEipStartStop.setText("Start EIP") + self.ui.btnEipStartStop.clicked.disconnect( + self._stop_eip) + self.ui.btnEipStartStop.clicked.connect( + self._start_eip) + def _download_eip_config(self): """ Starts the EIP bootstrapping sequence @@ -483,13 +543,16 @@ class MainWindow(QtGui.QMainWindow): @type status: str """ selected_pixmap = self.ERROR_ICON + tray_message = "Encryption is OFF" if status in ("AUTH", "GET_CONFIG"): selected_pixmap = self.CONNECTING_ICON elif status in ("CONNECTED"): + tray_message = "Encryption is ON" selected_pixmap = self.CONNECTED_ICON self.ui.lblVPNStatusIcon.setPixmap(selected_pixmap) - self._systray.setIcon(QtGui.QIcon(selected_pixmap)) + self._vpn_systray.setIcon(QtGui.QIcon(selected_pixmap)) + self._action_eip_status.setText(tray_message) def _update_vpn_state(self, data): """ @@ -520,12 +583,16 @@ class MainWindow(QtGui.QMainWindow): """ upload = float(data[self._vpn.TUNTAP_WRITE_KEY]) upload = upload / 1000.0 - self.ui.lblUpload.setText("%s Kb" % (upload,)) + upload_str = "%s Kb" % (upload,) + self.ui.lblUpload.setText(upload_str) + self._action_eip_write.setText(upload_str) download = float(data[self._vpn.TUNTAP_READ_KEY]) download = download / 1000.0 - self.ui.lblDownload.setText("%s Kb" % (download,)) + download_str = "%s Kb" % (download,) + self.ui.lblDownload.setText(download_str) + self._action_eip_read.setText(download_str) - def _start_eip(self, data): + def _finish_eip_bootstrap(self, data): """ SLOT TRIGGER: self._eip_bootstrapper.download_client_certificate @@ -542,10 +609,7 @@ class MainWindow(QtGui.QMainWindow): self._provider_config .get_domain(), "eip-service.json")): - self._vpn.start(eipconfig=self._eip_config, - providerconfig=self._provider_config, - socket_host="/home/chiiph/vpnsock", - socket_port="unix") + self._start_eip() # TODO: display a message if the EIP configuration cannot be # loaded @@ -569,12 +633,14 @@ class MainWindow(QtGui.QMainWindow): logging out """ self._set_status(message) + self._vpn_systray.setIcon(self.LOGGED_OUT_ICON) self.ui.action_sign_out.setEnabled(False) self.ui.stackedWidget.setCurrentIndex(self.LOGIN_INDEX) self.ui.lnPassword.setText("") self._login_set_enabled(True) self._set_status("") self._vpn.set_should_quit() + self._vpn_systray.setVisible(False) def _intermediate_stage(self, data): """ @@ -594,6 +660,18 @@ class MainWindow(QtGui.QMainWindow): self._login_set_enabled(True) self._set_status(data[self._provider_bootstrapper.ERROR_KEY]) + def _eip_finished(self, exitCode): + """ + SLOT + TRIGGERS: + self._vpn.process_finished + + Triggered when the EIP/VPN process finishes to set the UI + accordingly + """ + logger.debug("Finished VPN with exitCode %s" % (exitCode,)) + self._stop_eip() + if __name__ == "__main__": import signal from functools import partial -- cgit v1.2.3 From 926575bc811e8382100695a3396da7191fb43eb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Fri, 8 Mar 2013 13:15:38 -0300 Subject: Add translation support Also: - Make OpenVPN use a random port every time - Logout in parallel so the UI doesn't block - Add the WAIT status from OpenVPN to the mainwindow displays - Support non-unix sockets in the LinuxVPNLauncher --- src/leap/gui/mainwindow.py | 72 +++++++++++++++++++++++++--------------------- 1 file changed, 39 insertions(+), 33 deletions(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index df21a2bb..d66ddbb5 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -20,6 +20,7 @@ Main window for the leap client """ import os import logging +import random from PySide import QtCore, QtGui @@ -141,9 +142,10 @@ class MainWindow(QtGui.QMainWindow): self._systray = None self._vpn_systray = None - self._action_eip_status = QtGui.QAction("Encryption is OFF", self) + self._action_eip_status = QtGui.QAction(self.tr("Encryption is OFF"), + self) self._action_eip_status.setEnabled(False) - self._action_eip_stop = QtGui.QAction("Stop", self) + self._action_eip_stop = QtGui.QAction(self.tr("Stop"), self) self._action_eip_stop.triggered.connect( self._stop_eip) self._action_eip_write = QtGui.QAction( @@ -155,7 +157,7 @@ class MainWindow(QtGui.QMainWindow): "0.0 Kb", self) self._action_eip_read.setEnabled(False) - self._action_visible = QtGui.QAction("Hide", self) + self._action_visible = QtGui.QAction(self.tr("Hide"), self) self._action_visible.triggered.connect(self._toggle_visible) self._center_window() @@ -226,9 +228,9 @@ class MainWindow(QtGui.QMainWindow): Toggles the window visibility """ self.setVisible(not self.isVisible()) - action_visible_text = "Hide" + action_visible_text = self.tr("Hide") if not self.isVisible(): - action_visible_text = "Show" + action_visible_text = self.tr("Show") self._action_visible.setText(action_visible_text) def _center_window(self): @@ -257,14 +259,15 @@ class MainWindow(QtGui.QMainWindow): """ Display the About LEAP dialog """ - QtGui.QMessageBox.about(self, "About LEAP", - "LEAP is a non-profit dedicated to giving " - "all internet users access to secure " - "communication. Our focus is on adapting " - "encryption technology to make it easy to use " - "and widely available. " - "More about LEAP" - "") + QtGui.QMessageBox.about( + self, self.tr("About LEAP"), + self.tr("LEAP is a non-profit dedicated to giving " + "all internet users access to secure " + "communication. Our focus is on adapting " + "encryption technology to make it easy to use " + "and widely available. " + "More about LEAP" + "")) def quit(self): self._really_quit = True @@ -399,7 +402,8 @@ class MainWindow(QtGui.QMainWindow): self._provider_config, download_if_needed=True) else: - self._set_status("Could not load provider configuration") + self._set_status( + self.tr("Could not load provider configuration")) self._login_set_enabled(True) else: self._set_status(data[self._provider_bootstrapper.ERROR_KEY]) @@ -424,18 +428,18 @@ class MainWindow(QtGui.QMainWindow): provider = self.ui.cmbProviders.currentText() if len(provider) == 0: - self._set_status("Please select a valid provider") + self._set_status(self.tr("Please select a valid provider")) return if len(username) == 0: - self._set_status("Please provide a valid username") + self._set_status(self.tr("Please provide a valid username")) return if len(password) == 0: - self._set_status("Please provide a valid Password") + self._set_status(self.tr("Please provide a valid Password")) return - self._set_status("Logging in...") + self._set_status(self.tr("Logging in...")) self._login_set_enabled(False) self._download_provider_config() @@ -496,11 +500,11 @@ class MainWindow(QtGui.QMainWindow): def _start_eip(self): self._vpn.start(eipconfig=self._eip_config, providerconfig=self._provider_config, - socket_host="/home/chiiph/vpnsock", - socket_port="unix") + socket_host="localhost", + socket_port=str(random.randint(1000, 9999))) self._vpn_systray.setVisible(True) self.ui.btnEipStartStop.setEnabled(True) - self.ui.btnEipStartStop.setText("Stop EIP") + self.ui.btnEipStartStop.setText(self.tr("Stop EIP")) self.ui.btnEipStartStop.clicked.disconnect( self._start_eip) self.ui.btnEipStartStop.clicked.connect( @@ -509,9 +513,9 @@ class MainWindow(QtGui.QMainWindow): def _stop_eip(self): self._vpn.set_should_quit() self._vpn_systray.setVisible(False) - self._set_eip_status("EIP has stopped") + self._set_eip_status(self.tr("EIP has stopped")) self._set_eip_status_icon("error") - self.ui.btnEipStartStop.setText("Start EIP") + self.ui.btnEipStartStop.setText(self.tr("Start EIP")) self.ui.btnEipStartStop.clicked.disconnect( self._stop_eip) self.ui.btnEipStartStop.clicked.connect( @@ -524,7 +528,7 @@ class MainWindow(QtGui.QMainWindow): leap_assert(self._eip_bootstrapper, "We need an eip bootstrapper!") leap_assert(self._provider_config, "We need a provider config") - self._set_eip_status("Checking configuration, please wait...") + self._set_eip_status(self.tr("Checking configuration, please wait...")) if self._provider_config.provides_eip(): self._eip_bootstrapper.run_eip_setup_checks( @@ -532,7 +536,7 @@ class MainWindow(QtGui.QMainWindow): self._provider_config, download_if_needed=True) else: - self._set_eip_status("%s does not support EIP" % + self._set_eip_status(self.tr("%s does not support EIP") % (self._provider_config.get_domain(),)) def _set_eip_status_icon(self, status): @@ -543,11 +547,11 @@ class MainWindow(QtGui.QMainWindow): @type status: str """ selected_pixmap = self.ERROR_ICON - tray_message = "Encryption is OFF" - if status in ("AUTH", "GET_CONFIG"): + tray_message = self.tr("Encryption is OFF") + if status in ("WAIT", "AUTH", "GET_CONFIG"): selected_pixmap = self.CONNECTING_ICON elif status in ("CONNECTED"): - tray_message = "Encryption is ON" + tray_message = self.tr("Encryption is ON") selected_pixmap = self.CONNECTED_ICON self.ui.lblVPNStatusIcon.setPixmap(selected_pixmap) @@ -565,11 +569,13 @@ class MainWindow(QtGui.QMainWindow): status = data[self._vpn.STATUS_STEP_KEY] self._set_eip_status_icon(status) if status == "AUTH": - self._set_eip_status("VPN: Authenticating...") + self._set_eip_status(self.tr("VPN: Authenticating...")) elif status == "GET_CONFIG": - self._set_eip_status("VPN: Retrieving configuration...") + self._set_eip_status(self.tr("VPN: Retrieving configuration...")) elif status == "CONNECTED": - self._set_eip_status("VPN: Connected!") + self._set_eip_status(self.tr("VPN: Connected!")) + elif status == "WAIT": + self._set_eip_status(self.tr("VPN: Waiting to start...")) else: self._set_eip_status(status) @@ -621,8 +627,8 @@ class MainWindow(QtGui.QMainWindow): Starts the logout sequence """ self._set_eip_status_icon("error") - self._set_eip_status("Signing out...") - self._srp_auth.logout() + self._set_eip_status(self.tr("Signing out...")) + self._checker_thread.add_checks([self._srp_auth.logout]) def _done_logging_out(self, ok, message): """ -- cgit v1.2.3 From e4e5f35c3fc7ff02bc20a6ef7eaffae09f485061 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Fri, 8 Mar 2013 14:24:05 -0300 Subject: Add keyring and username/password saving capabilities Also: - Fix translations in SRPAuth - Support non-ascii passwords - Make the server check if the characters are allowed, just check for easy passwords --- src/leap/gui/mainwindow.py | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index d66ddbb5..68c73e4d 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -21,6 +21,7 @@ Main window for the leap client import os import logging import random +import keyring from PySide import QtCore, QtGui @@ -49,6 +50,9 @@ class MainWindow(QtGui.QMainWindow): GEOMETRY_KEY = "Geometry" WINDOWSTATE_KEY = "WindowState" + USER_KEY = "User" + + KEYRING_KEY = "leap_client" def __init__(self): QtGui.QMainWindow.__init__(self) @@ -183,6 +187,7 @@ class MainWindow(QtGui.QMainWindow): if self._wizard is None: self._wizard = Wizard(self._checker_thread) self._wizard.exec_() + self._wizard = None def _finish_init(self): self.ui.cmbProviders.addItems(self._configured_providers()) @@ -194,6 +199,17 @@ class MainWindow(QtGui.QMainWindow): self.ui.lnUser.setText(possible_username) self._focus_password() self._wizard = None + else: + settings = QtCore.QSettings() + saved_user = settings.value(self.USER_KEY, None) + + if saved_user is not None: + self.ui.lnUser.setText(saved_user) + self.ui.chkRemember.setChecked(True) + saved_password = keyring.get_password(self.KEYRING_KEY, + saved_user + .encode("utf8")) + self.ui.lnPassword.setText(saved_password.decode("utf8")) def _show_systray(self): """ @@ -442,6 +458,19 @@ class MainWindow(QtGui.QMainWindow): self._set_status(self.tr("Logging in...")) self._login_set_enabled(False) + if self.ui.chkRemember.isChecked(): + try: + keyring.set_password(self.KEYRING_KEY, + username.encode("utf8"), + password.encode("utf8")) + # Only save the username if it was saved correctly in + # the keyring + settings = QtCore.QSettings() + settings.setValue(self.USER_KEY, username) + except Exception as e: + logger.error("Problem saving data to keyring. %r" + % (e,)) + self._download_provider_config() def _provider_config_loaded(self, data): @@ -455,8 +484,8 @@ class MainWindow(QtGui.QMainWindow): leap_assert(self._provider_config, "We need a provider config!") if data[self._provider_bootstrapper.PASSED_KEY]: - username = self.ui.lnUser.text() - password = self.ui.lnPassword.text() + username = self.ui.lnUser.text().encode("utf8") + password = self.ui.lnPassword.text().encode("utf8") if self._srp_auth is None: self._srp_auth = SRPAuth(self._provider_config) -- cgit v1.2.3 From 1e3631c9a21f99e08bbb4bace61590b1221bc9f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Mon, 11 Mar 2013 10:24:25 -0300 Subject: Add AutoLogin checkbox --- src/leap/gui/mainwindow.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 68c73e4d..399a7cb4 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -48,10 +48,13 @@ class MainWindow(QtGui.QMainWindow): LOGIN_INDEX = 0 EIP_STATUS_INDEX = 1 + # Settings GEOMETRY_KEY = "Geometry" WINDOWSTATE_KEY = "WindowState" USER_KEY = "User" + AUTOLOGIN_KEY = "AutoLogin" + # Keyring KEYRING_KEY = "leap_client" def __init__(self): @@ -202,15 +205,22 @@ class MainWindow(QtGui.QMainWindow): else: settings = QtCore.QSettings() saved_user = settings.value(self.USER_KEY, None) + auto_login = settings.value(self.AUTOLOGIN_KEY, None) if saved_user is not None: self.ui.lnUser.setText(saved_user) self.ui.chkRemember.setChecked(True) + self.ui.chkAutoLogin.setEnabled(True) saved_password = keyring.get_password(self.KEYRING_KEY, saved_user .encode("utf8")) self.ui.lnPassword.setText(saved_password.decode("utf8")) + # Only automatically login if there is a saved user + if auto_login is not None: + self.ui.chkAutoLogin.setChecked(True) + self._login() + def _show_systray(self): """ Sets up the systray icon @@ -315,6 +325,7 @@ class MainWindow(QtGui.QMainWindow): settings = QtCore.QSettings() settings.setValue(self.GEOMETRY_KEY, self.saveGeometry()) settings.setValue(self.WINDOWSTATE_KEY, self.saveState()) + settings.setValue(self.AUTOLOGIN_KEY, self.ui.chkAutoLogin.isChecked()) QtGui.QMainWindow.closeEvent(self, e) def _configured_providers(self): @@ -378,6 +389,7 @@ class MainWindow(QtGui.QMainWindow): self.ui.lnPassword.setEnabled(enabled) self.ui.btnLogin.setEnabled(enabled) self.ui.chkRemember.setEnabled(enabled) + self.ui.chkAutoLogin.setEnabled(enabled) self.ui.cmbProviders.setEnabled(enabled) def _download_provider_config(self): @@ -458,6 +470,8 @@ class MainWindow(QtGui.QMainWindow): self._set_status(self.tr("Logging in...")) self._login_set_enabled(False) + settings = QtCore.QSettings() + if self.ui.chkRemember.isChecked(): try: keyring.set_password(self.KEYRING_KEY, @@ -465,7 +479,6 @@ class MainWindow(QtGui.QMainWindow): password.encode("utf8")) # Only save the username if it was saved correctly in # the keyring - settings = QtCore.QSettings() settings.setValue(self.USER_KEY, username) except Exception as e: logger.error("Problem saving data to keyring. %r" @@ -577,7 +590,7 @@ class MainWindow(QtGui.QMainWindow): """ selected_pixmap = self.ERROR_ICON tray_message = self.tr("Encryption is OFF") - if status in ("WAIT", "AUTH", "GET_CONFIG"): + if status in ("WAIT", "AUTH", "GET_CONFIG", "RECONNECTING"): selected_pixmap = self.CONNECTING_ICON elif status in ("CONNECTED"): tray_message = self.tr("Encryption is ON") -- cgit v1.2.3 From eaec4a9fff67134284f45eb850f0d7e0f7f275f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Mon, 11 Mar 2013 13:37:14 -0300 Subject: Finish up translation support Also: - Add spanish translations - Fix an issue when disabling autologin --- src/leap/gui/mainwindow.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 399a7cb4..4e6bb5fe 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -205,7 +205,7 @@ class MainWindow(QtGui.QMainWindow): else: settings = QtCore.QSettings() saved_user = settings.value(self.USER_KEY, None) - auto_login = settings.value(self.AUTOLOGIN_KEY, None) + auto_login = settings.value(self.AUTOLOGIN_KEY, "false") != "false" if saved_user is not None: self.ui.lnUser.setText(saved_user) @@ -217,8 +217,8 @@ class MainWindow(QtGui.QMainWindow): self.ui.lnPassword.setText(saved_password.decode("utf8")) # Only automatically login if there is a saved user - if auto_login is not None: - self.ui.chkAutoLogin.setChecked(True) + self.ui.chkAutoLogin.setChecked(auto_login) + if auto_login: self._login() def _show_systray(self): -- cgit v1.2.3 From 1580197229ce01ebdc6a655d2f5b67ca4b32da88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Mon, 11 Mar 2013 16:07:13 -0300 Subject: Auto login after the first run wizard if registered a new user Also add pyxdg as a dep --- src/leap/gui/mainwindow.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 4e6bb5fe..78ff9101 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -198,9 +198,14 @@ class MainWindow(QtGui.QMainWindow): self.show() if self._wizard: possible_username = self._wizard.get_username() + possible_password = self._wizard.get_password() if possible_username is not None: self.ui.lnUser.setText(possible_username) self._focus_password() + if possible_password is not None: + self.ui.lnPassword.setText(possible_password) + self.ui.chkRemember.setChecked(True) + self._login() self._wizard = None else: settings = QtCore.QSettings() @@ -214,7 +219,8 @@ class MainWindow(QtGui.QMainWindow): saved_password = keyring.get_password(self.KEYRING_KEY, saved_user .encode("utf8")) - self.ui.lnPassword.setText(saved_password.decode("utf8")) + if saved_password is not None: + self.ui.lnPassword.setText(saved_password.decode("utf8")) # Only automatically login if there is a saved user self.ui.chkAutoLogin.setChecked(auto_login) -- cgit v1.2.3 From 060984df444dbf407e9078de638ef7486ef7b0a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Mon, 11 Mar 2013 16:42:23 -0300 Subject: Notify if openvpn is not found --- src/leap/gui/mainwindow.py | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 78ff9101..8464d313 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -29,6 +29,7 @@ from ui_mainwindow import Ui_MainWindow from leap.config.providerconfig import ProviderConfig from leap.crypto.srpauth import SRPAuth from leap.services.eip.vpn import VPN +from leap.services.eip.vpnlaunchers import VPNLauncherException from leap.services.eip.providerbootstrapper import ProviderBootstrapper from leap.services.eip.eipbootstrapper import EIPBootstrapper from leap.services.eip.eipconfig import EIPConfig @@ -546,17 +547,20 @@ class MainWindow(QtGui.QMainWindow): self._download_eip_config() def _start_eip(self): - self._vpn.start(eipconfig=self._eip_config, - providerconfig=self._provider_config, - socket_host="localhost", - socket_port=str(random.randint(1000, 9999))) - self._vpn_systray.setVisible(True) + try: + self._vpn.start(eipconfig=self._eip_config, + providerconfig=self._provider_config, + socket_host="localhost", + socket_port=str(random.randint(1000, 9999))) + self._vpn_systray.setVisible(True) + self.ui.btnEipStartStop.setText(self.tr("Stop EIP")) + self.ui.btnEipStartStop.clicked.disconnect( + self._start_eip) + self.ui.btnEipStartStop.clicked.connect( + self._stop_eip) + except VPNLauncherException as e: + self._set_eip_status("%s" % (e,)) self.ui.btnEipStartStop.setEnabled(True) - self.ui.btnEipStartStop.setText(self.tr("Stop EIP")) - self.ui.btnEipStartStop.clicked.disconnect( - self._start_eip) - self.ui.btnEipStartStop.clicked.connect( - self._stop_eip) def _stop_eip(self): self._vpn.set_should_quit() -- cgit v1.2.3 From 1371b450a3e4cd8bc1d8b50133eb4b7a8f1d9aad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Mon, 11 Mar 2013 17:23:08 -0300 Subject: First run checks for a complete valid run of the wizard Not just the files on disk --- src/leap/gui/mainwindow.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 8464d313..cf795a8e 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -54,6 +54,7 @@ class MainWindow(QtGui.QMainWindow): WINDOWSTATE_KEY = "WindowState" USER_KEY = "User" AUTOLOGIN_KEY = "AutoLogin" + PROPER_PROVIDER = "ProperProvider" # Keyring KEYRING_KEY = "leap_client" @@ -183,6 +184,8 @@ class MainWindow(QtGui.QMainWindow): def _rejected_wizard(self): if self._wizard_firstrun: + settings = QtCore.QSettings() + settings.setValue(self.PROPER_PROVIDER, False) self.quit() else: self._finish_init() @@ -194,9 +197,11 @@ class MainWindow(QtGui.QMainWindow): self._wizard = None def _finish_init(self): + settings = QtCore.QSettings() self.ui.cmbProviders.addItems(self._configured_providers()) self._show_systray() self.show() + if self._wizard: possible_username = self._wizard.get_username() possible_password = self._wizard.get_password() @@ -208,8 +213,8 @@ class MainWindow(QtGui.QMainWindow): self.ui.chkRemember.setChecked(True) self._login() self._wizard = None + settings.setValue(self.PROPER_PROVIDER, True) else: - settings = QtCore.QSettings() saved_user = settings.value(self.USER_KEY, None) auto_login = settings.value(self.AUTOLOGIN_KEY, "false") != "false" @@ -305,7 +310,7 @@ class MainWindow(QtGui.QMainWindow): def quit(self): self._really_quit = True if self._wizard: - self._wizard.accept() + self._wizard.close() self.close() def changeEvent(self, e): @@ -359,7 +364,11 @@ class MainWindow(QtGui.QMainWindow): @rtype: bool """ - return len(self._configured_providers()) == 0 + settings = QtCore.QSettings() + has_provider_on_disk = len(self._configured_providers()) != 0 + is_proper_provider = settings.value(self.PROPER_PROVIDER, + "false") != "false" + return not (has_provider_on_disk and is_proper_provider) def _focus_password(self): """ -- cgit v1.2.3 From 461721850ee668d1a5e612de6af4cf1d2eeeca74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Mon, 11 Mar 2013 18:43:02 -0300 Subject: Disable remember checkbox if no keyring is available Also set properly the enabledness of chkAutoLogin --- src/leap/gui/mainwindow.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index cf795a8e..7b03eabb 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -139,6 +139,10 @@ class MainWindow(QtGui.QMainWindow): QtCore.SIGNAL("aboutToQuit()"), self._checker_thread.set_should_quit) + self.ui.chkRemember.stateChanged.connect( + self._remember_state_changed) + self.ui.chkRemember.setEnabled(keyring.get_keyring() is not None) + self.ui.action_sign_out.setEnabled(False) self.ui.action_sign_out.triggered.connect(self._logout) self.ui.action_about_leap.triggered.connect(self._about) @@ -196,6 +200,9 @@ class MainWindow(QtGui.QMainWindow): self._wizard.exec_() self._wizard = None + def _remember_state_changed(self, state): + self.ui.chkAutoLogin.setEnabled(state == QtCore.Qt.Checked) + def _finish_init(self): settings = QtCore.QSettings() self.ui.cmbProviders.addItems(self._configured_providers()) @@ -221,7 +228,8 @@ class MainWindow(QtGui.QMainWindow): if saved_user is not None: self.ui.lnUser.setText(saved_user) self.ui.chkRemember.setChecked(True) - self.ui.chkAutoLogin.setEnabled(True) + self.ui.chkAutoLogin.setEnabled(self.ui.chkRemember + .isEnabled()) saved_password = keyring.get_password(self.KEYRING_KEY, saved_user .encode("utf8")) @@ -405,7 +413,8 @@ class MainWindow(QtGui.QMainWindow): self.ui.lnPassword.setEnabled(enabled) self.ui.btnLogin.setEnabled(enabled) self.ui.chkRemember.setEnabled(enabled) - self.ui.chkAutoLogin.setEnabled(enabled) + if not enabled: + self.ui.chkAutoLogin.setEnabled(False) self.ui.cmbProviders.setEnabled(enabled) def _download_provider_config(self): -- cgit v1.2.3 From c0e411564a2e7c3af75e2f7c894fa46c3ca8da00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Mon, 11 Mar 2013 18:51:50 -0300 Subject: Display error messages in red and bold --- src/leap/gui/mainwindow.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 7b03eabb..08b8f08b 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -384,13 +384,15 @@ class MainWindow(QtGui.QMainWindow): """ self.ui.lnPassword.setFocus() - def _set_status(self, status): + def _set_status(self, status, error=True): """ Sets the status label at the login stage to status @param status: status message @type status: str """ + if error: + status = "%s" % (status,) self.ui.lblStatus.setText(status) def _set_eip_status(self, status): @@ -492,7 +494,7 @@ class MainWindow(QtGui.QMainWindow): self._set_status(self.tr("Please provide a valid Password")) return - self._set_status(self.tr("Logging in...")) + self._set_status(self.tr("Logging in..."), error=False) self._login_set_enabled(False) settings = QtCore.QSettings() @@ -545,7 +547,7 @@ class MainWindow(QtGui.QMainWindow): Once the user is properly authenticated, try starting the EIP service """ - self._set_status(message) + self._set_status(message, error=not ok) if ok: self.ui.action_sign_out.setEnabled(True) # We leave a bit of room for the user to see the @@ -708,7 +710,6 @@ class MainWindow(QtGui.QMainWindow): Switches the stackedWidget back to the login stage after logging out """ - self._set_status(message) self._vpn_systray.setIcon(self.LOGGED_OUT_ICON) self.ui.action_sign_out.setEnabled(False) self.ui.stackedWidget.setCurrentIndex(self.LOGIN_INDEX) -- cgit v1.2.3 From 2da60cd0f78378fdcb8f6364a798720281b34b4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Tue, 12 Mar 2013 09:56:05 -0300 Subject: Check and try to fix certificate permissions --- src/leap/gui/mainwindow.py | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 08b8f08b..aa9b4ffd 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -395,13 +395,15 @@ class MainWindow(QtGui.QMainWindow): status = "%s" % (status,) self.ui.lblStatus.setText(status) - def _set_eip_status(self, status): + def _set_eip_status(self, status, error=False): """ Sets the status label at the VPN stage to status @param status: status message @type status: str """ + if error: + status = "%s" % (status,) self.ui.lblEIPStatus.setText(status) def _login_set_enabled(self, enabled=False): @@ -579,7 +581,7 @@ class MainWindow(QtGui.QMainWindow): self.ui.btnEipStartStop.clicked.connect( self._stop_eip) except VPNLauncherException as e: - self._set_eip_status("%s" % (e,)) + self._set_eip_status("%s" % (e,), error=True) self.ui.btnEipStartStop.setEnabled(True) def _stop_eip(self): @@ -609,7 +611,8 @@ class MainWindow(QtGui.QMainWindow): download_if_needed=True) else: self._set_eip_status(self.tr("%s does not support EIP") % - (self._provider_config.get_domain(),)) + (self._provider_config.get_domain(),), + error=True) def _set_eip_status_icon(self, status): """ @@ -681,15 +684,21 @@ class MainWindow(QtGui.QMainWindow): leap_assert(self._eip_config, "We need an eip config!") leap_assert(self._provider_config, "We need a provider config!") - if self._eip_config.loaded() or \ - self._eip_config.load(os.path.join("leap", - "providers", - self._provider_config - .get_domain(), - "eip-service.json")): + if data[self._eip_bootstrapper.PASSED_KEY] and \ + (self._eip_config.loaded() or + self._eip_config.load(os.path.join("leap", + "providers", + self._provider_config + .get_domain(), + "eip-service.json"))): self._start_eip() - # TODO: display a message if the EIP configuration cannot be - # loaded + else: + if data[self._eip_bootstrapper.PASSED_KEY]: + self._set_eip_status(self.tr("Could not load EIP " + "Configuration"), error=True) + else: + self._set_eip_status(data[self._eip_bootstrapper.ERROR_KEY], + error=True) def _logout(self): """ -- cgit v1.2.3 From 295b7ed9982094b6a4aa1951561e34bfb16e16c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Tue, 12 Mar 2013 10:08:58 -0300 Subject: Gray out the systray icon after logging out --- src/leap/gui/mainwindow.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index aa9b4ffd..7209861f 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -719,7 +719,7 @@ class MainWindow(QtGui.QMainWindow): Switches the stackedWidget back to the login stage after logging out """ - self._vpn_systray.setIcon(self.LOGGED_OUT_ICON) + self._systray.setIcon(self.LOGGED_OUT_ICON) self.ui.action_sign_out.setEnabled(False) self.ui.stackedWidget.setCurrentIndex(self.LOGIN_INDEX) self.ui.lnPassword.setText("") -- cgit v1.2.3 From f3d8bf14688227cfae1efcbec606639991885c33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Tue, 12 Mar 2013 10:34:40 -0300 Subject: Set vpn systray tooltip to the latest status --- src/leap/gui/mainwindow.py | 1 + 1 file changed, 1 insertion(+) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 7209861f..65ab6632 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -402,6 +402,7 @@ class MainWindow(QtGui.QMainWindow): @param status: status message @type status: str """ + self._vpn_systray.setToolTip(status) if error: status = "%s" % (status,) self.ui.lblEIPStatus.setText(status) -- cgit v1.2.3 From 731ecfaf60d7bd0c6a52f3fd1676cfbd71696493 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Tue, 12 Mar 2013 10:34:57 -0300 Subject: Fix disconnect problem with start/stop EIP button --- src/leap/gui/mainwindow.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 65ab6632..2a72d4d6 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -82,7 +82,7 @@ class MainWindow(QtGui.QMainWindow): self.ui.btnEipStartStop.setEnabled(False) self.ui.btnEipStartStop.clicked.connect( - self._stop_eip) + self._start_eip) # This is loaded only once, there's a bug when doing that more # than once @@ -577,8 +577,7 @@ class MainWindow(QtGui.QMainWindow): socket_port=str(random.randint(1000, 9999))) self._vpn_systray.setVisible(True) self.ui.btnEipStartStop.setText(self.tr("Stop EIP")) - self.ui.btnEipStartStop.clicked.disconnect( - self._start_eip) + self.ui.btnEipStartStop.disconnect(self) self.ui.btnEipStartStop.clicked.connect( self._stop_eip) except VPNLauncherException as e: @@ -591,8 +590,7 @@ class MainWindow(QtGui.QMainWindow): self._set_eip_status(self.tr("EIP has stopped")) self._set_eip_status_icon("error") self.ui.btnEipStartStop.setText(self.tr("Start EIP")) - self.ui.btnEipStartStop.clicked.disconnect( - self._stop_eip) + self.ui.btnEipStartStop.disconnect(self) self.ui.btnEipStartStop.clicked.connect( self._start_eip) -- cgit v1.2.3 From e18eb96f09069afe538508c30acd3d95e8359a12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Tue, 12 Mar 2013 11:53:11 -0300 Subject: Add version to about --- src/leap/gui/mainwindow.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 2a72d4d6..882a5a99 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -36,6 +36,7 @@ from leap.services.eip.eipconfig import EIPConfig from leap.gui.wizard import Wizard from leap.util.check import leap_assert from leap.util.checkerthread import CheckerThread +from leap import __version__ as VERSION logger = logging.getLogger(__name__) @@ -306,7 +307,7 @@ class MainWindow(QtGui.QMainWindow): Display the About LEAP dialog """ QtGui.QMessageBox.about( - self, self.tr("About LEAP"), + self, self.tr("About LEAP - %s") % (VERSION,), self.tr("LEAP is a non-profit dedicated to giving " "all internet users access to secure " "communication. Our focus is on adapting " -- cgit v1.2.3 From cabfa92593d0c21f63f218842af8ed2bfba77cde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Tue, 12 Mar 2013 14:08:47 -0300 Subject: Make login in parallel --- src/leap/gui/mainwindow.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 882a5a99..3af87366 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -24,6 +24,7 @@ import random import keyring from PySide import QtCore, QtGui +from functools import partial from ui_mainwindow import Ui_MainWindow from leap.config.providerconfig import ProviderConfig @@ -538,7 +539,10 @@ class MainWindow(QtGui.QMainWindow): self._srp_auth.logout_finished.connect( self._done_logging_out) - self._srp_auth.authenticate(username, password) + auth_partial = partial(self._srp_auth.authenticate, + username, + password) + self._checker_thread.add_checks([auth_partial]) else: self._set_status(data[self._provider_bootstrapper.ERROR_KEY]) self._login_set_enabled(True) @@ -760,7 +764,6 @@ class MainWindow(QtGui.QMainWindow): if __name__ == "__main__": import signal - from functools import partial def sigint_handler(*args, **kwargs): logger.debug('SIGINT catched. shutting down...') -- cgit v1.2.3 From 364c6d5e9882f47ff5938f731641bc7509e32fc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Tue, 12 Mar 2013 17:12:20 -0300 Subject: Make the wizard provider setup only Also: - Add a way to enable/disable services for a provider - Run EIP only if it is enabled --- src/leap/gui/mainwindow.py | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 3af87366..f8ca4c35 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -175,6 +175,8 @@ class MainWindow(QtGui.QMainWindow): self._action_visible = QtGui.QAction(self.tr("Hide"), self) self._action_visible.triggered.connect(self._toggle_visible) + self._enabled_services = [] + self._center_window() self._wizard = None self._wizard_firstrun = False @@ -214,6 +216,11 @@ class MainWindow(QtGui.QMainWindow): if self._wizard: possible_username = self._wizard.get_username() possible_password = self._wizard.get_password() + self.ui.chkRemember.setChecked(self._wizard.get_remember()) + self._enabled_services = list(self._wizard.get_services()) + settings.setValue("%s/Services" % + (self.ui.cmbProviders.currentText(),), + self._enabled_services) if possible_username is not None: self.ui.lnUser.setText(possible_username) self._focus_password() @@ -487,6 +494,11 @@ class MainWindow(QtGui.QMainWindow): password = self.ui.lnPassword.text() provider = self.ui.cmbProviders.currentText() + settings = QtCore.QSettings() + self._enabled_services = settings.value( + "%s/Services" % + (self.ui.cmbProviders.currentText(),), "").split(",") + if len(provider) == 0: self._set_status(self.tr("Please select a valid provider")) return @@ -608,15 +620,20 @@ class MainWindow(QtGui.QMainWindow): self._set_eip_status(self.tr("Checking configuration, please wait...")) - if self._provider_config.provides_eip(): + if self._provider_config.provides_eip() and \ + self._enabled_services.count("openvpn") > 0: self._eip_bootstrapper.run_eip_setup_checks( self._checker_thread, self._provider_config, download_if_needed=True) else: - self._set_eip_status(self.tr("%s does not support EIP") % - (self._provider_config.get_domain(),), - error=True) + if self._enabled_services.count("openvpn") > 0: + self._set_eip_status(self.tr("%s does not support EIP") % + (self._provider_config.get_domain(),), + error=True) + else: + self._set_eip_status(self.tr("EIP is disabled")) + self.ui.btnEipStartStop.setEnabled(False) def _set_eip_status_icon(self, status): """ -- cgit v1.2.3 From 70c402fe170ca4e01159b03739b7cacda7b0dfd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Wed, 13 Mar 2013 09:43:13 -0300 Subject: Add mtime check for existing json definitions before download Also, wait for threads to finish when quitting --- src/leap/gui/mainwindow.py | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index f8ca4c35..6f7f646e 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -136,10 +136,18 @@ class MainWindow(QtGui.QMainWindow): QtCore.QCoreApplication.instance(), QtCore.SIGNAL("aboutToQuit()"), self._vpn.set_should_quit) + QtCore.QCoreApplication.instance().connect( + QtCore.QCoreApplication.instance(), + QtCore.SIGNAL("aboutToQuit()"), + self._vpn.wait) QtCore.QCoreApplication.instance().connect( QtCore.QCoreApplication.instance(), QtCore.SIGNAL("aboutToQuit()"), self._checker_thread.set_should_quit) + QtCore.QCoreApplication.instance().connect( + QtCore.QCoreApplication.instance(), + QtCore.SIGNAL("aboutToQuit()"), + self._checker_thread.wait) self.ui.chkRemember.stateChanged.connect( self._remember_state_changed) -- cgit v1.2.3 From 4359515dafe572398262ce91bf88d4f122042981 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Wed, 13 Mar 2013 13:39:00 -0300 Subject: Add vpn already running checks --- src/leap/gui/mainwindow.py | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 6f7f646e..9b4a70a5 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -680,6 +680,14 @@ class MainWindow(QtGui.QMainWindow): self._set_eip_status(self.tr("VPN: Connected!")) elif status == "WAIT": self._set_eip_status(self.tr("VPN: Waiting to start...")) + elif status == "ALREADYRUNNING": + # Put the following calls in Qt's event queue, otherwise + # the UI won't update properly + QtCore.QTimer.singleShot(0, self._stop_eip) + QtCore.QTimer.singleShot(0, partial(self._set_eip_status, + self.tr("Unable to start VPN, " + "it's already " + "running."))) else: self._set_eip_status(status) -- cgit v1.2.3 From ef43dff37c6db915757184ad51bc017d45e70c98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Wed, 13 Mar 2013 14:02:13 -0300 Subject: Notify the user of pkexec/polkit/openvpn checks --- src/leap/gui/mainwindow.py | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 9b4a70a5..9589bea0 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -30,7 +30,10 @@ from ui_mainwindow import Ui_MainWindow from leap.config.providerconfig import ProviderConfig from leap.crypto.srpauth import SRPAuth from leap.services.eip.vpn import VPN -from leap.services.eip.vpnlaunchers import VPNLauncherException +from leap.services.eip.vpnlaunchers import (VPNLauncherException, + OpenVPNNotFoundException, + EIPNoPkexecAvailable, + EIPNoPolkitAuthAgentAvailable) from leap.services.eip.providerbootstrapper import ProviderBootstrapper from leap.services.eip.eipbootstrapper import EIPBootstrapper from leap.services.eip.eipconfig import EIPConfig @@ -605,8 +608,25 @@ class MainWindow(QtGui.QMainWindow): self.ui.btnEipStartStop.disconnect(self) self.ui.btnEipStartStop.clicked.connect( self._stop_eip) + except EIPNoPolkitAuthAgentAvailable: + self._set_eip_status(self.tr("We could not find any " + "authentication " + "agent in your system.
" + "Make sure you have " + "polkit-gnome-authentication-" + "agent-1 " + "running and try again."), + error=True) + except EIPNoPkexecAvailable: + self._set_eip_status(self.tr("We could not find pkexec " + "in your system."), + error=True) + except OpenVPNNotFoundException: + self._set_eip_status(self.tr("We couldn't find openvpn"), + error=True) except VPNLauncherException as e: self._set_eip_status("%s" % (e,), error=True) + self.ui.btnEipStartStop.setEnabled(True) def _stop_eip(self): -- cgit v1.2.3 From 715b50b872736952d01b2c8cac9003da1e634c05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Wed, 13 Mar 2013 14:24:05 -0300 Subject: Make sure we always end up with the proper list of services --- src/leap/gui/mainwindow.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 9589bea0..af905fc0 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -508,7 +508,10 @@ class MainWindow(QtGui.QMainWindow): settings = QtCore.QSettings() self._enabled_services = settings.value( "%s/Services" % - (self.ui.cmbProviders.currentText(),), "").split(",") + (self.ui.cmbProviders.currentText(),), "") + + if isinstance(self._enabled_services, (str, unicode)): + self._enabled_services = self._enabled_services.split(",") if len(provider) == 0: self._set_status(self.tr("Please select a valid provider")) -- cgit v1.2.3 From 3ff6a5ebadca8cf6066e9db39fcbfcb3d8283430 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Wed, 13 Mar 2013 14:42:52 -0300 Subject: Add a TODO comment to not forget improve the configured providers check --- src/leap/gui/mainwindow.py | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index af905fc0..6aaf0a38 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -374,6 +374,9 @@ class MainWindow(QtGui.QMainWindow): @rtype: list """ + + # TODO: check which providers have a valid certificate among + # other things, not just the directories providers = [] try: providers = os.listdir( -- cgit v1.2.3 From 4e3b2f09f0e5fba35aef3edf8ad2b23c64a5d995 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Wed, 13 Mar 2013 15:46:50 -0300 Subject: Use a unix socket every time for now Will need a special case for windows --- src/leap/gui/mainwindow.py | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 6aaf0a38..c2c37485 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -20,7 +20,7 @@ Main window for the leap client """ import os import logging -import random +import tempfile import keyring from PySide import QtCore, QtGui @@ -603,12 +603,27 @@ class MainWindow(QtGui.QMainWindow): self._systray.setIcon(self.LOGGED_IN_ICON) self._download_eip_config() + def _get_socket_host(self): + """ + Returns the socket and port to be used for VPN + + @rtype: tuple (str, str) (host, port) + """ + + # TODO: make this properly multiplatform + host = os.path.join(tempfile.mkdtemp(prefix="leap-tmp"), + 'openvpn.socket') + port = "unix" + + return host, port + def _start_eip(self): try: + host, port = self._get_socket_host() self._vpn.start(eipconfig=self._eip_config, providerconfig=self._provider_config, - socket_host="localhost", - socket_port=str(random.randint(1000, 9999))) + socket_host=host, + socket_port=port) self._vpn_systray.setVisible(True) self.ui.btnEipStartStop.setText(self.tr("Stop EIP")) self.ui.btnEipStartStop.disconnect(self) -- cgit v1.2.3 From 9bd4a1394cfbdd555b9cb42e2aeba3dc4957ae88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Wed, 13 Mar 2013 16:08:42 -0300 Subject: Always show the eip icon if the service is available and enabled --- src/leap/gui/mainwindow.py | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index c2c37485..4db74c2d 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -104,8 +104,6 @@ class MainWindow(QtGui.QMainWindow): # configuration and certificate. self._provider_bootstrapper = ProviderBootstrapper() - # TODO: add sigint handler - # Intermediate stages, only do something if there was an error self._provider_bootstrapper.name_resolution.connect( self._intermediate_stage) @@ -171,8 +169,8 @@ class MainWindow(QtGui.QMainWindow): self._action_eip_status = QtGui.QAction(self.tr("Encryption is OFF"), self) self._action_eip_status.setEnabled(False) - self._action_eip_stop = QtGui.QAction(self.tr("Stop"), self) - self._action_eip_stop.triggered.connect( + self._action_eip_startstop = QtGui.QAction(self.tr("Stop"), self) + self._action_eip_startstop.triggered.connect( self._stop_eip) self._action_eip_write = QtGui.QAction( QtGui.QIcon(":/images/Arrow-Up-32.png"), @@ -278,7 +276,7 @@ class MainWindow(QtGui.QMainWindow): vpn_systrayMenu = QtGui.QMenu(self) vpn_systrayMenu.addAction(self._action_eip_status) - vpn_systrayMenu.addAction(self._action_eip_stop) + vpn_systrayMenu.addAction(self._action_eip_startstop) vpn_systrayMenu.addAction(self._action_eip_read) vpn_systrayMenu.addAction(self._action_eip_write) self._vpn_systray = QtGui.QSystemTrayIcon(self) @@ -624,11 +622,14 @@ class MainWindow(QtGui.QMainWindow): providerconfig=self._provider_config, socket_host=host, socket_port=port) - self._vpn_systray.setVisible(True) self.ui.btnEipStartStop.setText(self.tr("Stop EIP")) self.ui.btnEipStartStop.disconnect(self) self.ui.btnEipStartStop.clicked.connect( self._stop_eip) + self._action_eip_startstop.setText(self.tr("Stop")) + self._action_eip_startstop.disconnect(self) + self._action_eip_startstop.triggered.connect( + self._stop_eip) except EIPNoPolkitAuthAgentAvailable: self._set_eip_status(self.tr("We could not find any " "authentication " @@ -652,13 +653,16 @@ class MainWindow(QtGui.QMainWindow): def _stop_eip(self): self._vpn.set_should_quit() - self._vpn_systray.setVisible(False) self._set_eip_status(self.tr("EIP has stopped")) self._set_eip_status_icon("error") self.ui.btnEipStartStop.setText(self.tr("Start EIP")) self.ui.btnEipStartStop.disconnect(self) self.ui.btnEipStartStop.clicked.connect( self._start_eip) + self._action_eip_startstop.setText(self.tr("Start")) + self._action_eip_startstop.disconnect(self) + self._action_eip_startstop.triggered.connect( + self._start_eip) def _download_eip_config(self): """ @@ -671,6 +675,7 @@ class MainWindow(QtGui.QMainWindow): if self._provider_config.provides_eip() and \ self._enabled_services.count("openvpn") > 0: + self._vpn_systray.setVisible(True) self._eip_bootstrapper.run_eip_setup_checks( self._checker_thread, self._provider_config, @@ -804,7 +809,6 @@ class MainWindow(QtGui.QMainWindow): self._login_set_enabled(True) self._set_status("") self._vpn.set_should_quit() - self._vpn_systray.setVisible(False) def _intermediate_stage(self, data): """ -- cgit v1.2.3 From d0dfad6ac2af360de6421ce74a6831b5b81ad019 Mon Sep 17 00:00:00 2001 From: kali Date: Thu, 14 Mar 2013 07:08:31 +0900 Subject: namespace leap + leap.common split leap is a namespace package from here on. common folder will be deleted and moved to leap_pycommon repository. --- src/leap/gui/mainwindow.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 4db74c2d..a93b2e3c 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -27,6 +27,7 @@ from PySide import QtCore, QtGui from functools import partial from ui_mainwindow import Ui_MainWindow +from leap.common.check import leap_assert from leap.config.providerconfig import ProviderConfig from leap.crypto.srpauth import SRPAuth from leap.services.eip.vpn import VPN @@ -38,9 +39,8 @@ from leap.services.eip.providerbootstrapper import ProviderBootstrapper from leap.services.eip.eipbootstrapper import EIPBootstrapper from leap.services.eip.eipconfig import EIPConfig from leap.gui.wizard import Wizard -from leap.util.check import leap_assert from leap.util.checkerthread import CheckerThread -from leap import __version__ as VERSION +from leap.util import __version__ as VERSION logger = logging.getLogger(__name__) @@ -325,13 +325,14 @@ class MainWindow(QtGui.QMainWindow): """ QtGui.QMessageBox.about( self, self.tr("About LEAP - %s") % (VERSION,), - self.tr("LEAP is a non-profit dedicated to giving " + self.tr("version: %s
" + "LEAP is a non-profit dedicated to giving " "all internet users access to secure " "communication. Our focus is on adapting " "encryption technology to make it easy to use " "and widely available. " "More about LEAP" - "")) + "") % (VERSION,)) def quit(self): self._really_quit = True -- cgit v1.2.3 From ddbad58fc2b3f44a293eeac7790a06f13b56944a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Wed, 20 Mar 2013 16:44:00 -0300 Subject: Display ASSIGN_IP state correctly in the mainwindow --- src/leap/gui/mainwindow.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index a93b2e3c..eabdfe57 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -699,7 +699,8 @@ class MainWindow(QtGui.QMainWindow): """ selected_pixmap = self.ERROR_ICON tray_message = self.tr("Encryption is OFF") - if status in ("WAIT", "AUTH", "GET_CONFIG", "RECONNECTING"): + if status in ("WAIT", "AUTH", "GET_CONFIG", + "RECONNECTING", "ASSIGN_IP"): selected_pixmap = self.CONNECTING_ICON elif status in ("CONNECTED"): tray_message = self.tr("Encryption is ON") @@ -727,6 +728,8 @@ class MainWindow(QtGui.QMainWindow): self._set_eip_status(self.tr("VPN: Connected!")) elif status == "WAIT": self._set_eip_status(self.tr("VPN: Waiting to start...")) + elif status == "ASSIGN_IP": + self._set_eip_status(self.tr("VPN: Assigning IP")) elif status == "ALREADYRUNNING": # Put the following calls in Qt's event queue, otherwise # the UI won't update properly -- cgit v1.2.3 From 8f54774f6c3f779527718a0158ebd0efc4aab588 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Fri, 15 Mar 2013 13:30:01 -0300 Subject: Handle configuration and paths in a standalone way Also, abstracts QSettings under LeapSettings and adds a way to define the VPN env in a platform dependant way. --- src/leap/gui/mainwindow.py | 69 +++++++++++++++++++++------------------------- 1 file changed, 32 insertions(+), 37 deletions(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index eabdfe57..703d1e26 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -29,6 +29,7 @@ from functools import partial from ui_mainwindow import Ui_MainWindow from leap.common.check import leap_assert from leap.config.providerconfig import ProviderConfig +from leap.config.leapsettings import LeapSettings from leap.crypto.srpauth import SRPAuth from leap.services.eip.vpn import VPN from leap.services.eip.vpnlaunchers import (VPNLauncherException, @@ -54,17 +55,17 @@ class MainWindow(QtGui.QMainWindow): LOGIN_INDEX = 0 EIP_STATUS_INDEX = 1 - # Settings - GEOMETRY_KEY = "Geometry" - WINDOWSTATE_KEY = "WindowState" - USER_KEY = "User" - AUTOLOGIN_KEY = "AutoLogin" - PROPER_PROVIDER = "ProperProvider" - # Keyring KEYRING_KEY = "leap_client" - def __init__(self): + def __init__(self, standalone=False): + """ + Constructor for the client main window + + @param standalone: Set to true if the app should use configs + inside its pwd + @type standalone: bool + """ QtGui.QMainWindow.__init__(self) self.CONNECTING_ICON = QtGui.QPixmap(":/images/conn_connecting.png") @@ -91,6 +92,9 @@ class MainWindow(QtGui.QMainWindow): # This is loaded only once, there's a bug when doing that more # than once + ProviderConfig.standalone = standalone + EIPConfig.standalone = standalone + self._standalone = standalone self._provider_config = ProviderConfig() self._eip_config = EIPConfig() # This is created once we have a valid provider config @@ -185,6 +189,7 @@ class MainWindow(QtGui.QMainWindow): self._action_visible.triggered.connect(self._toggle_visible) self._enabled_services = [] + self._settings = LeapSettings(standalone) self._center_window() self._wizard = None @@ -201,8 +206,7 @@ class MainWindow(QtGui.QMainWindow): def _rejected_wizard(self): if self._wizard_firstrun: - settings = QtCore.QSettings() - settings.setValue(self.PROPER_PROVIDER, False) + self._settings.set_properprovider(False) self.quit() else: self._finish_init() @@ -217,7 +221,6 @@ class MainWindow(QtGui.QMainWindow): self.ui.chkAutoLogin.setEnabled(state == QtCore.Qt.Checked) def _finish_init(self): - settings = QtCore.QSettings() self.ui.cmbProviders.addItems(self._configured_providers()) self._show_systray() self.show() @@ -227,9 +230,9 @@ class MainWindow(QtGui.QMainWindow): possible_password = self._wizard.get_password() self.ui.chkRemember.setChecked(self._wizard.get_remember()) self._enabled_services = list(self._wizard.get_services()) - settings.setValue("%s/Services" % - (self.ui.cmbProviders.currentText(),), - self._enabled_services) + self._settings.set_enabled_services( + self.ui.cmbProviders.currentText(), + self._enabled_services) if possible_username is not None: self.ui.lnUser.setText(possible_username) self._focus_password() @@ -238,10 +241,10 @@ class MainWindow(QtGui.QMainWindow): self.ui.chkRemember.setChecked(True) self._login() self._wizard = None - settings.setValue(self.PROPER_PROVIDER, True) + self._settings.set_properprovider(True) else: - saved_user = settings.value(self.USER_KEY, None) - auto_login = settings.value(self.AUTOLOGIN_KEY, "false") != "false" + saved_user = self._settings.get_user() + auto_login = self._settings.get_autologin() if saved_user is not None: self.ui.lnUser.setText(saved_user) @@ -301,9 +304,9 @@ class MainWindow(QtGui.QMainWindow): """ Centers the mainwindow based on the desktop geometry """ - settings = QtCore.QSettings() - geometry = settings.value(self.GEOMETRY_KEY, None) - state = settings.value(self.WINDOWSTATE_KEY, None) + geometry = self._settings.get_geometry() + state = self._settings.get_windowstate() + if geometry is None: app = QtGui.QApplication.instance() width = app.desktop().width() @@ -361,10 +364,11 @@ class MainWindow(QtGui.QMainWindow): self._toggle_visible() e.ignore() return - settings = QtCore.QSettings() - settings.setValue(self.GEOMETRY_KEY, self.saveGeometry()) - settings.setValue(self.WINDOWSTATE_KEY, self.saveState()) - settings.setValue(self.AUTOLOGIN_KEY, self.ui.chkAutoLogin.isChecked()) + + self._settings.set_geometry(self.saveGeometry()) + self._settings.set_windowstate(self.saveState()) + self._settings.set_autologin(self.ui.chkAutoLogin.isChecked()) + QtGui.QMainWindow.closeEvent(self, e) def _configured_providers(self): @@ -394,10 +398,8 @@ class MainWindow(QtGui.QMainWindow): @rtype: bool """ - settings = QtCore.QSettings() has_provider_on_disk = len(self._configured_providers()) != 0 - is_proper_provider = settings.value(self.PROPER_PROVIDER, - "false") != "false" + is_proper_provider = self._settings.get_properprovider() return not (has_provider_on_disk and is_proper_provider) def _focus_password(self): @@ -507,13 +509,8 @@ class MainWindow(QtGui.QMainWindow): password = self.ui.lnPassword.text() provider = self.ui.cmbProviders.currentText() - settings = QtCore.QSettings() - self._enabled_services = settings.value( - "%s/Services" % - (self.ui.cmbProviders.currentText(),), "") - - if isinstance(self._enabled_services, (str, unicode)): - self._enabled_services = self._enabled_services.split(",") + self._enabled_services = self._settings.get_enabled_services( + self.ui.cmbProviders.currentText()) if len(provider) == 0: self._set_status(self.tr("Please select a valid provider")) @@ -530,8 +527,6 @@ class MainWindow(QtGui.QMainWindow): self._set_status(self.tr("Logging in..."), error=False) self._login_set_enabled(False) - settings = QtCore.QSettings() - if self.ui.chkRemember.isChecked(): try: keyring.set_password(self.KEYRING_KEY, @@ -539,7 +534,7 @@ class MainWindow(QtGui.QMainWindow): password.encode("utf8")) # Only save the username if it was saved correctly in # the keyring - settings.setValue(self.USER_KEY, username) + self._settings.set_user(username) except Exception as e: logger.error("Problem saving data to keyring. %r" % (e,)) -- cgit v1.2.3 From bdc3e1b840c383f0d9236ad8d4df66633e87baf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Thu, 21 Mar 2013 10:38:48 -0300 Subject: Fixes as per review --- src/leap/gui/mainwindow.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 703d1e26..3f29f957 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -28,8 +28,8 @@ from functools import partial from ui_mainwindow import Ui_MainWindow from leap.common.check import leap_assert -from leap.config.providerconfig import ProviderConfig from leap.config.leapsettings import LeapSettings +from leap.config.providerconfig import ProviderConfig from leap.crypto.srpauth import SRPAuth from leap.services.eip.vpn import VPN from leap.services.eip.vpnlaunchers import (VPNLauncherException, -- cgit v1.2.3 From 30912fed29fd652f69de5a518cf70e6fe04b04f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Thu, 21 Mar 2013 13:40:18 -0300 Subject: Make Windows use a regular socket --- src/leap/gui/mainwindow.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 3f29f957..974476a3 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -20,6 +20,7 @@ Main window for the leap client """ import os import logging +import platform import tempfile import keyring @@ -605,9 +606,14 @@ class MainWindow(QtGui.QMainWindow): """ # TODO: make this properly multiplatform - host = os.path.join(tempfile.mkdtemp(prefix="leap-tmp"), - 'openvpn.socket') - port = "unix" + + if platform.system() == "Windows": + host = "localhost" + port = "9876" + else: + host = os.path.join(tempfile.mkdtemp(prefix="leap-tmp"), + 'openvpn.socket') + port = "unix" return host, port -- cgit v1.2.3 From e267ebd09c57c869dc0ab8d57baaed6d63fb2f13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Fri, 22 Mar 2013 16:12:26 -0300 Subject: Improve systray behavior with context menu and activation --- src/leap/gui/mainwindow.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 3f29f957..e039fdf1 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -287,18 +287,19 @@ class MainWindow(QtGui.QMainWindow): self._vpn_systray.setIcon(QtGui.QIcon(self.ERROR_ICON)) self._vpn_systray.setVisible(False) - def _toggle_visible(self): + def _toggle_visible(self, reason=None): """ SLOT TRIGGER: self._systray.activated Toggles the window visibility """ - self.setVisible(not self.isVisible()) - action_visible_text = self.tr("Hide") - if not self.isVisible(): - action_visible_text = self.tr("Show") - self._action_visible.setText(action_visible_text) + if reason != QtGui.QSystemTrayIcon.Context: + self.setVisible(not self.isVisible()) + action_visible_text = self.tr("Hide") + if not self.isVisible(): + action_visible_text = self.tr("Show") + self._action_visible.setText(action_visible_text) def _center_window(self): """ -- cgit v1.2.3 From 2c30ffe4ab8a12712735b7f8fef27cd7700eaaae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Mon, 25 Mar 2013 12:00:49 -0300 Subject: Add windows platform initializer --- src/leap/gui/mainwindow.py | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 3f29f957..ca6f1a8b 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -31,6 +31,7 @@ from leap.common.check import leap_assert from leap.config.leapsettings import LeapSettings from leap.config.providerconfig import ProviderConfig from leap.crypto.srpauth import SRPAuth +from leap.platform_init.initializers import init_platform from leap.services.eip.vpn import VPN from leap.services.eip.vpnlaunchers import (VPNLauncherException, OpenVPNNotFoundException, @@ -192,6 +193,9 @@ class MainWindow(QtGui.QMainWindow): self._settings = LeapSettings(standalone) self._center_window() + + init_platform() + self._wizard = None self._wizard_firstrun = False if self._first_run(): -- cgit v1.2.3 From f6fa3ad1f1c7c4ed9d069da031bfb6dfc6511590 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Mon, 25 Mar 2013 12:55:06 -0300 Subject: Reorder imports based on rope's recommendations --- src/leap/gui/mainwindow.py | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 974476a3..aa29e843 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -18,31 +18,32 @@ """ Main window for the leap client """ -import os import logging +import os import platform import tempfile -import keyring - -from PySide import QtCore, QtGui from functools import partial -from ui_mainwindow import Ui_MainWindow +import keyring +from PySide import QtCore, QtGui from leap.common.check import leap_assert from leap.config.leapsettings import LeapSettings from leap.config.providerconfig import ProviderConfig from leap.crypto.srpauth import SRPAuth +from leap.gui.wizard import Wizard +from leap.services.eip.eipbootstrapper import EIPBootstrapper +from leap.services.eip.eipconfig import EIPConfig +from leap.services.eip.providerbootstrapper import ProviderBootstrapper from leap.services.eip.vpn import VPN from leap.services.eip.vpnlaunchers import (VPNLauncherException, OpenVPNNotFoundException, EIPNoPkexecAvailable, EIPNoPolkitAuthAgentAvailable) -from leap.services.eip.providerbootstrapper import ProviderBootstrapper -from leap.services.eip.eipbootstrapper import EIPBootstrapper -from leap.services.eip.eipconfig import EIPConfig -from leap.gui.wizard import Wizard -from leap.util.checkerthread import CheckerThread from leap.util import __version__ as VERSION +from leap.util.checkerthread import CheckerThread + +from ui_mainwindow import Ui_MainWindow + logger = logging.getLogger(__name__) -- cgit v1.2.3 From 466ccbafb38cf8fd767ed2b88d93c547a4eca9a2 Mon Sep 17 00:00:00 2001 From: kali Date: Wed, 3 Apr 2013 03:22:08 +0900 Subject: Do not populate user/pass when deselecting "remember" Closes: #2059 --- src/leap/gui/mainwindow.py | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 863640ef..e5efdbed 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -225,6 +225,7 @@ class MainWindow(QtGui.QMainWindow): def _remember_state_changed(self, state): self.ui.chkAutoLogin.setEnabled(state == QtCore.Qt.Checked) + self._settings.set_remember(bool(state)) def _finish_init(self): self.ui.cmbProviders.addItems(self._configured_providers()) @@ -249,6 +250,10 @@ class MainWindow(QtGui.QMainWindow): self._wizard = None self._settings.set_properprovider(True) else: + if not self._settings.get_remember(): + # nothing to do here + return + saved_user = self._settings.get_user() auto_login = self._settings.get_autologin() -- cgit v1.2.3 From 005b6ca29c75e0e0f583327b8afea601a90ed6e7 Mon Sep 17 00:00:00 2001 From: kali Date: Wed, 3 Apr 2013 04:37:11 +0900 Subject: Makes traffic indicators display fixed precision. Closes:#2114 --- src/leap/gui/mainwindow.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 863640ef..3fa3aad3 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -181,11 +181,11 @@ class MainWindow(QtGui.QMainWindow): self._stop_eip) self._action_eip_write = QtGui.QAction( QtGui.QIcon(":/images/Arrow-Up-32.png"), - "0.0 Kb", self) + "%12.2f Kb" % (0.0,), self) self._action_eip_write.setEnabled(False) self._action_eip_read = QtGui.QAction( QtGui.QIcon(":/images/Arrow-Down-32.png"), - "0.0 Kb", self) + "%12.2f Kb" % (0.0,), self) self._action_eip_read.setEnabled(False) self._action_visible = QtGui.QAction(self.tr("Hide"), self) @@ -758,12 +758,12 @@ class MainWindow(QtGui.QMainWindow): """ upload = float(data[self._vpn.TUNTAP_WRITE_KEY]) upload = upload / 1000.0 - upload_str = "%s Kb" % (upload,) + upload_str = "%12.2f Kb" % (upload,) self.ui.lblUpload.setText(upload_str) self._action_eip_write.setText(upload_str) download = float(data[self._vpn.TUNTAP_READ_KEY]) download = download / 1000.0 - download_str = "%s Kb" % (download,) + download_str = "%12.2f Kb" % (download,) self.ui.lblDownload.setText(download_str) self._action_eip_read.setText(download_str) -- cgit v1.2.3 From 22342664951ac32756ceb7ade59ada90f92c8793 Mon Sep 17 00:00:00 2001 From: kali Date: Thu, 4 Apr 2013 01:47:12 +0900 Subject: Several fixes in wizard Closes:#2061 o Rewording of setup steps in wizard, to make them more meaningful to the non-technical user. Closes: #2061 o Fix typo in wizard o Fix multiple drawing of services if going back o Make registration errors show in red o Add a warning if EIP service needs admin password. Addresses part of #2062 --- src/leap/gui/mainwindow.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 863640ef..7f529e2f 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -202,7 +202,7 @@ class MainWindow(QtGui.QMainWindow): self._wizard_firstrun = False if self._first_run(): self._wizard_firstrun = True - self._wizard = Wizard(self._checker_thread) + self._wizard = Wizard(self._checker_thread, standalone=standalone) # Give this window time to finish init and then show the wizard QtCore.QTimer.singleShot(1, self._launch_wizard) self._wizard.accepted.connect(self._finish_init) -- cgit v1.2.3 From bcfdc13f5450e3df695c61c44bf637b18386f31a Mon Sep 17 00:00:00 2001 From: kali Date: Tue, 9 Apr 2013 20:48:29 +0900 Subject: make state switch more readable --- src/leap/gui/mainwindow.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index e5efdbed..3c256bea 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -224,8 +224,9 @@ class MainWindow(QtGui.QMainWindow): self._wizard = None def _remember_state_changed(self, state): - self.ui.chkAutoLogin.setEnabled(state == QtCore.Qt.Checked) - self._settings.set_remember(bool(state)) + enable = True if state == QtCore.Qt.Checked else False + self.ui.chkAutoLogin.setEnabled(enable) + self._settings.set_remember(enable) def _finish_init(self): self.ui.cmbProviders.addItems(self._configured_providers()) -- cgit v1.2.3 From e1d8032f4a0c4e8e8d46c017af3ffb91ea98946c Mon Sep 17 00:00:00 2001 From: Tomas Touceda Date: Tue, 9 Apr 2013 10:27:42 -0300 Subject: Display a simple message when updates are available --- src/leap/gui/mainwindow.py | 65 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 6a73fb76..71dff1c5 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -42,6 +42,11 @@ from leap.services.eip.vpnlaunchers import (VPNLauncherException, EIPNoPolkitAuthAgentAvailable) from leap.util import __version__ as VERSION from leap.util.checkerthread import CheckerThread +from leap.common.events import server +from leap.common.events import ( + register, + events_pb2 as proto, +) from ui_mainwindow import Ui_MainWindow @@ -61,6 +66,8 @@ class MainWindow(QtGui.QMainWindow): # Keyring KEYRING_KEY = "leap_client" + new_updates = QtCore.Signal(object) + def __init__(self, standalone=False): """ Constructor for the client main window @@ -71,6 +78,12 @@ class MainWindow(QtGui.QMainWindow): """ QtGui.QMainWindow.__init__(self) + server.ensure_server(port=8090) + + register(signal=proto.UPDATER_NEW_UPDATES, + callback=self._new_updates_available) + self._updates_content = "" + self.CONNECTING_ICON = QtGui.QPixmap(":/images/conn_connecting.png") self.CONNECTED_ICON = QtGui.QPixmap(":/images/conn_connected.png") self.ERROR_ICON = QtGui.QPixmap(":/images/conn_error.png") @@ -196,6 +209,11 @@ class MainWindow(QtGui.QMainWindow): self._center_window() + self.ui.lblNewUpdates.setVisible(False) + self.ui.btnMore.setVisible(False) + self.ui.btnMore.clicked.connect(self._updates_details) + self.new_updates.connect(self._react_to_new_updates) + init_platform() self._wizard = None @@ -228,6 +246,53 @@ class MainWindow(QtGui.QMainWindow): self.ui.chkAutoLogin.setEnabled(enable) self._settings.set_remember(enable) + def _new_updates_available(self, req): + """ + Callback for the new updates event + + @param req: Request type + @type req: leap.common.events.events_pb2.SignalRequest + """ + self.new_updates.emit(req) + + def _react_to_new_updates(self, req): + """ + SLOT + TRIGGER: self._new_updates_available + + Displays the new updates label and sets the updates_content + """ + self.moveToThread(QtCore.QCoreApplication.instance().thread()) + self.ui.lblNewUpdates.setVisible(True) + self.ui.btnMore.setVisible(True) + self._updates_content = req.content + + def _updates_details(self): + """ + Parses and displays the updates details + """ + msg = "" + if len(self._updates_content) == 0: + # We assume that if there is nothing in the contents, then + # the LEAPClient bundle is what needs updating. + msg = self.tr("The LEAPClient app is ready to update, please" + " restart the application.") + else: + files = self._updates_content.split(", ") + files_str = "" + for f in files: + final_name = f.replace("/data/", "") + final_name = final_name.replace(".thp", "") + files_str += final_name + files_str += "\n" + msg = self.tr("The LEAPClient app is ready to update, please" + " restart the application so the following " + "components get updated:\n%s") % (files_str,) + + QtGui.QMessageBox.information(self, + self.tr("Updates available"), + msg) + def _finish_init(self): self.ui.cmbProviders.addItems(self._configured_providers()) self._show_systray() -- cgit v1.2.3 From 0cbff90910fa35a9489a5542d093211c61d2267f Mon Sep 17 00:00:00 2001 From: Tomas Touceda Date: Wed, 10 Apr 2013 09:27:14 -0300 Subject: Move ensure server to the very beginning Also, fix documentation for a slot and mini-refactor a method for improved translations. --- src/leap/gui/mainwindow.py | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 71dff1c5..0d59e24b 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -42,7 +42,6 @@ from leap.services.eip.vpnlaunchers import (VPNLauncherException, EIPNoPolkitAuthAgentAvailable) from leap.util import __version__ as VERSION from leap.util.checkerthread import CheckerThread -from leap.common.events import server from leap.common.events import ( register, events_pb2 as proto, @@ -78,8 +77,6 @@ class MainWindow(QtGui.QMainWindow): """ QtGui.QMainWindow.__init__(self) - server.ensure_server(port=8090) - register(signal=proto.UPDATER_NEW_UPDATES, callback=self._new_updates_available) self._updates_content = "" @@ -269,15 +266,17 @@ class MainWindow(QtGui.QMainWindow): def _updates_details(self): """ + SLOT + TRIGGER: self.ui.btnMore.clicked + Parses and displays the updates details """ - msg = "" - if len(self._updates_content) == 0: - # We assume that if there is nothing in the contents, then - # the LEAPClient bundle is what needs updating. - msg = self.tr("The LEAPClient app is ready to update, please" - " restart the application.") - else: + msg = self.tr("The LEAPClient app is ready to update, please" + " restart the application.") + + # We assume that if there is nothing in the contents, then + # the LEAPClient bundle is what needs updating. + if len(self._updates_content) > 0: files = self._updates_content.split(", ") files_str = "" for f in files: @@ -285,9 +284,8 @@ class MainWindow(QtGui.QMainWindow): final_name = final_name.replace(".thp", "") files_str += final_name files_str += "\n" - msg = self.tr("The LEAPClient app is ready to update, please" - " restart the application so the following " - "components get updated:\n%s") % (files_str,) + msg += self.tr(" The following components will be updated:\n%s") \ + % (files_str,) QtGui.QMessageBox.information(self, self.tr("Updates available"), -- cgit v1.2.3 From 816104f2983e0f6dcded621c02c4c520e2e36da6 Mon Sep 17 00:00:00 2001 From: kali Date: Thu, 4 Apr 2013 05:16:36 +0900 Subject: detection of multiple instances using flock. sending RAISE_WINDOW leap event if we are not the main instance. --- src/leap/gui/mainwindow.py | 54 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 49 insertions(+), 5 deletions(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 0d59e24b..e362663a 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -26,7 +26,10 @@ from functools import partial import keyring from PySide import QtCore, QtGui + from leap.common.check import leap_assert +from leap.common.events import register +from leap.common.events import events_pb2 as proto from leap.config.leapsettings import LeapSettings from leap.config.providerconfig import ProviderConfig from leap.crypto.srpauth import SRPAuth @@ -34,6 +37,7 @@ from leap.gui.wizard import Wizard from leap.services.eip.eipbootstrapper import EIPBootstrapper from leap.services.eip.eipconfig import EIPConfig from leap.services.eip.providerbootstrapper import ProviderBootstrapper +from leap.platform_init import IS_WIN from leap.platform_init.initializers import init_platform from leap.services.eip.vpn import VPN from leap.services.eip.vpnlaunchers import (VPNLauncherException, @@ -42,14 +46,9 @@ from leap.services.eip.vpnlaunchers import (VPNLauncherException, EIPNoPolkitAuthAgentAvailable) from leap.util import __version__ as VERSION from leap.util.checkerthread import CheckerThread -from leap.common.events import ( - register, - events_pb2 as proto, -) from ui_mainwindow import Ui_MainWindow - logger = logging.getLogger(__name__) @@ -65,7 +64,9 @@ class MainWindow(QtGui.QMainWindow): # Keyring KEYRING_KEY = "leap_client" + # Signals new_updates = QtCore.Signal(object) + raise_window = QtCore.Signal([]) def __init__(self, standalone=False): """ @@ -77,8 +78,12 @@ class MainWindow(QtGui.QMainWindow): """ QtGui.QMainWindow.__init__(self) + # register leap events register(signal=proto.UPDATER_NEW_UPDATES, callback=self._new_updates_available) + register(signal=proto.RAISE_WINDOW, + callback=self._on_raise_window_event) + self._updates_content = "" self.CONNECTING_ICON = QtGui.QPixmap(":/images/conn_connecting.png") @@ -110,6 +115,7 @@ class MainWindow(QtGui.QMainWindow): self._standalone = standalone self._provider_config = ProviderConfig() self._eip_config = EIPConfig() + # This is created once we have a valid provider config self._srp_auth = None @@ -166,6 +172,10 @@ class MainWindow(QtGui.QMainWindow): QtCore.QCoreApplication.instance(), QtCore.SIGNAL("aboutToQuit()"), self._checker_thread.wait) + QtCore.QCoreApplication.instance().connect( + QtCore.QCoreApplication.instance(), + QtCore.SIGNAL("aboutToQuit()"), + self._cleanup_pidfiles) self.ui.chkRemember.stateChanged.connect( self._remember_state_changed) @@ -176,6 +186,7 @@ class MainWindow(QtGui.QMainWindow): self.ui.action_about_leap.triggered.connect(self._about) self.ui.action_quit.triggered.connect(self.quit) self.ui.action_wizard.triggered.connect(self._launch_wizard) + self.raise_window.connect(self._do_raise_mainwindow) # Used to differentiate between real quits and close to tray self._really_quit = False @@ -920,6 +931,39 @@ class MainWindow(QtGui.QMainWindow): logger.debug("Finished VPN with exitCode %s" % (exitCode,)) self._stop_eip() + def _on_raise_window_event(self, req): + """ + Callback for the raise window event + """ + self.raise_window.emit() + + def _do_raise_mainwindow(self): + """ + SLOT + TRIGGERS: + self._on_raise_window_event + + Triggered when we receive a RAISE_WINDOW event. + """ + TOPFLAG = QtCore.Qt.WindowStaysOnTopHint + self.setWindowFlags(self.windowFlags() | TOPFLAG) + self.show() + self.setWindowFlags(self.windowFlags() & ~TOPFLAG) + self.show() + + def _cleanup_pidfiles(self): + """ + SLOT + TRIGGERS: + self.aboutToQuit + + Triggered on about to quit signal, removes lockfiles on a clean + shutdown + """ + if IS_WIN: + lockfile = WindowsLock() + lockfile.release_lock() + if __name__ == "__main__": import signal -- cgit v1.2.3 From 92a2fb893b02d1880aac3509b0550fb04d5bf876 Mon Sep 17 00:00:00 2001 From: kali Date: Thu, 11 Apr 2013 20:36:56 +0900 Subject: Use dark icons (light theme) for OSX Closes:#2130 --- src/leap/gui/mainwindow.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 0d59e24b..d9e8e3f6 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -34,6 +34,7 @@ from leap.gui.wizard import Wizard from leap.services.eip.eipbootstrapper import EIPBootstrapper from leap.services.eip.eipconfig import EIPConfig from leap.services.eip.providerbootstrapper import ProviderBootstrapper +from leap.platform_init import IS_MAC from leap.platform_init.initializers import init_platform from leap.services.eip.vpn import VPN from leap.services.eip.vpnlaunchers import (VPNLauncherException, @@ -81,9 +82,20 @@ class MainWindow(QtGui.QMainWindow): callback=self._new_updates_available) self._updates_content = "" - self.CONNECTING_ICON = QtGui.QPixmap(":/images/conn_connecting.png") - self.CONNECTED_ICON = QtGui.QPixmap(":/images/conn_connected.png") - self.ERROR_ICON = QtGui.QPixmap(":/images/conn_error.png") + if IS_MAC: + EIP_ICONS = ( + ":/images/conn_connecting-light.png" + ":/images/conn_connected-light.png", + ":/images/conn_error-light.png") + else: + EIP_ICONS = ( + ":/images/conn_connecting.png" + ":/images/conn_connected.png", + ":/images/conn_error.png") + + self.CONNECTING_ICON = QtGui.QPixmap(EIP_ICONS[0]) + self.CONNECTED_ICON = QtGui.QPixmap(EIP_ICONS[1]) + self.ERROR_ICON = QtGui.QPixmap(EIP_ICONS[2]) self.LOGGED_OUT_ICON = QtGui.QPixmap(":/images/leap-gray-big.png") self.LOGGED_IN_ICON = QtGui.QPixmap(":/images/leap-color-big.png") -- cgit v1.2.3 From b585cefa15a1d7a03dd8a6c5651220ac3fd94fd1 Mon Sep 17 00:00:00 2001 From: kali Date: Thu, 11 Apr 2013 22:04:00 +0900 Subject: missing comma in tuple --- src/leap/gui/mainwindow.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index d9e8e3f6..f84cb00c 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -84,12 +84,12 @@ class MainWindow(QtGui.QMainWindow): if IS_MAC: EIP_ICONS = ( - ":/images/conn_connecting-light.png" + ":/images/conn_connecting-light.png", ":/images/conn_connected-light.png", ":/images/conn_error-light.png") else: EIP_ICONS = ( - ":/images/conn_connecting.png" + ":/images/conn_connecting.png", ":/images/conn_connected.png", ":/images/conn_error.png") -- cgit v1.2.3 From 1fbf6db1276c5bca41c4cfbcc90818d9605c1938 Mon Sep 17 00:00:00 2001 From: Tomas Touceda Date: Fri, 12 Apr 2013 14:07:15 -0300 Subject: Add --danger option to not validate the first hop of certificates This is intended to be used while testing, not in production --- src/leap/gui/mainwindow.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index bf8491d0..c9743f95 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -68,13 +68,16 @@ class MainWindow(QtGui.QMainWindow): new_updates = QtCore.Signal(object) raise_window = QtCore.Signal([]) - def __init__(self, standalone=False): + def __init__(self, standalone=False, bypass_checks=False): """ Constructor for the client main window @param standalone: Set to true if the app should use configs inside its pwd @type standalone: bool + @param bypass_checks: Set to true if the app should bypass + first round of checks for CA certificates at bootstrap + @type bypass_checks: bool """ QtGui.QMainWindow.__init__(self) @@ -136,7 +139,7 @@ class MainWindow(QtGui.QMainWindow): # This thread is always running, although it's quite # lightweight when it's done setting up provider # configuration and certificate. - self._provider_bootstrapper = ProviderBootstrapper() + self._provider_bootstrapper = ProviderBootstrapper(bypass_checks) # Intermediate stages, only do something if there was an error self._provider_bootstrapper.name_resolution.connect( @@ -237,9 +240,14 @@ class MainWindow(QtGui.QMainWindow): self._wizard = None self._wizard_firstrun = False + + self._bypass_checks = bypass_checks + if self._first_run(): self._wizard_firstrun = True - self._wizard = Wizard(self._checker_thread, standalone=standalone) + self._wizard = Wizard(self._checker_thread, + standalone=standalone, + bypass_checks=bypass_checks) # Give this window time to finish init and then show the wizard QtCore.QTimer.singleShot(1, self._launch_wizard) self._wizard.accepted.connect(self._finish_init) @@ -256,7 +264,8 @@ class MainWindow(QtGui.QMainWindow): def _launch_wizard(self): if self._wizard is None: - self._wizard = Wizard(self._checker_thread) + self._wizard = Wizard(self._checker_thread, + bypass_checks=self._bypass_checks) self._wizard.exec_() self._wizard = None -- cgit v1.2.3 From 2dae2703fb8c2ae7e721ce83020c0dd10ff9ca33 Mon Sep 17 00:00:00 2001 From: kali Date: Fri, 3 May 2013 02:59:22 +0900 Subject: updated documentation * documentation reviewed after rewrite, ready for 0.2.1 * updated docstrings format to fit sphinx autodoc --- src/leap/gui/mainwindow.py | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index c9743f95..ccf97672 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -72,12 +72,12 @@ class MainWindow(QtGui.QMainWindow): """ Constructor for the client main window - @param standalone: Set to true if the app should use configs + :param standalone: Set to true if the app should use configs inside its pwd - @type standalone: bool - @param bypass_checks: Set to true if the app should bypass + :type standalone: bool + :param bypass_checks: Set to true if the app should bypass first round of checks for CA certificates at bootstrap - @type bypass_checks: bool + :type bypass_checks: bool """ QtGui.QMainWindow.__init__(self) @@ -278,8 +278,8 @@ class MainWindow(QtGui.QMainWindow): """ Callback for the new updates event - @param req: Request type - @type req: leap.common.events.events_pb2.SignalRequest + :param req: Request type + :type req: leap.common.events.events_pb2.SignalRequest """ self.new_updates.emit(req) @@ -482,7 +482,7 @@ class MainWindow(QtGui.QMainWindow): """ Returns the available providers based on the file structure - @rtype: list + :rtype: list """ # TODO: check which providers have a valid certificate among @@ -503,7 +503,7 @@ class MainWindow(QtGui.QMainWindow): """ Returns True if there are no configured providers. False otherwise - @rtype: bool + :rtype: bool """ has_provider_on_disk = len(self._configured_providers()) != 0 is_proper_provider = self._settings.get_properprovider() @@ -519,8 +519,8 @@ class MainWindow(QtGui.QMainWindow): """ Sets the status label at the login stage to status - @param status: status message - @type status: str + :param status: status message + :type status: str """ if error: status = "%s" % (status,) @@ -530,8 +530,8 @@ class MainWindow(QtGui.QMainWindow): """ Sets the status label at the VPN stage to status - @param status: status message - @type status: str + :param status: status message + :type status: str """ self._vpn_systray.setToolTip(status) if error: @@ -542,8 +542,8 @@ class MainWindow(QtGui.QMainWindow): """ Enables or disables all the login widgets - @param enabled: wether they should be enabled or not - @type enabled: bool + :param enabled: wether they should be enabled or not + :type enabled: bool """ self.ui.lnUser.setEnabled(enabled) self.ui.lnPassword.setEnabled(enabled) @@ -575,9 +575,9 @@ class MainWindow(QtGui.QMainWindow): self._provider_config instance with it and starts the second part of the bootstrapping sequence - @param data: result from the last stage of the + :param data: result from the last stage of the run_provider_select_checks - @type data: dict + :type data: dict """ if data[self._provider_bootstrapper.PASSED_KEY]: provider = self.ui.cmbProviders.currentText() @@ -708,7 +708,7 @@ class MainWindow(QtGui.QMainWindow): """ Returns the socket and port to be used for VPN - @rtype: tuple (str, str) (host, port) + :rtype: tuple (str, str) (host, port) """ # TODO: make this properly multiplatform @@ -801,8 +801,8 @@ class MainWindow(QtGui.QMainWindow): """ Given a status step from the VPN thread, set the icon properly - @param status: status step - @type status: str + :param status: status step + :type status: str """ selected_pixmap = self.ERROR_ICON tray_message = self.tr("Encryption is OFF") -- cgit v1.2.3 From 9a1a657593c3ee18d35936a85077ae2f7e51c392 Mon Sep 17 00:00:00 2001 From: Tomas Touceda Date: Fri, 10 May 2013 12:09:02 -0300 Subject: Fixup one instance on Windows --- src/leap/gui/mainwindow.py | 1 + 1 file changed, 1 insertion(+) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index ccf97672..358b7a41 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -38,6 +38,7 @@ from leap.services.eip.eipbootstrapper import EIPBootstrapper from leap.services.eip.eipconfig import EIPConfig from leap.services.eip.providerbootstrapper import ProviderBootstrapper from leap.platform_init import IS_MAC, IS_WIN +from leap.platform_init.locks import WindowsLock from leap.platform_init.initializers import init_platform from leap.services.eip.vpn import VPN from leap.services.eip.vpnlaunchers import (VPNLauncherException, -- cgit v1.2.3 From 6c66167ddce1682e88fae0ae106f44befb121c4d Mon Sep 17 00:00:00 2001 From: Tomas Touceda Date: Fri, 10 May 2013 16:32:48 -0300 Subject: Make the import of WindowsLock conditional --- src/leap/gui/mainwindow.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 358b7a41..b3ab56d3 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -38,7 +38,6 @@ from leap.services.eip.eipbootstrapper import EIPBootstrapper from leap.services.eip.eipconfig import EIPConfig from leap.services.eip.providerbootstrapper import ProviderBootstrapper from leap.platform_init import IS_MAC, IS_WIN -from leap.platform_init.locks import WindowsLock from leap.platform_init.initializers import init_platform from leap.services.eip.vpn import VPN from leap.services.eip.vpnlaunchers import (VPNLauncherException, @@ -48,6 +47,9 @@ from leap.services.eip.vpnlaunchers import (VPNLauncherException, from leap.util import __version__ as VERSION from leap.util.checkerthread import CheckerThread +if IS_WIN: + from leap.platform_init.locks import WindowsLock + from ui_mainwindow import Ui_MainWindow logger = logging.getLogger(__name__) -- cgit v1.2.3 From 1cb931e83522746da668f9a8bb5943aca1882086 Mon Sep 17 00:00:00 2001 From: kali Date: Thu, 16 May 2013 04:26:00 +0900 Subject: use qtreactor so twisted is driven by qt main loop aboutToQuit signal is not raised anymore with the qt4reactor. So we are calling all cleanup callbacks from the quit function. --- src/leap/gui/mainwindow.py | 76 +++++++++++++++++++++++++--------------------- 1 file changed, 41 insertions(+), 35 deletions(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index b3ab56d3..fdf84766 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -71,15 +71,22 @@ class MainWindow(QtGui.QMainWindow): new_updates = QtCore.Signal(object) raise_window = QtCore.Signal([]) - def __init__(self, standalone=False, bypass_checks=False): + def __init__(self, quit_callback, + standalone=False, bypass_checks=False): """ Constructor for the client main window + :param quit_callback: Function to be called when closing + the application. + :type quit_callback: callable + :param standalone: Set to true if the app should use configs - inside its pwd + inside its pwd :type standalone: bool + :param bypass_checks: Set to true if the app should bypass - first round of checks for CA certificates at bootstrap + first round of checks for CA + certificates at bootstrap :type bypass_checks: bool """ QtGui.QMainWindow.__init__(self) @@ -89,6 +96,7 @@ class MainWindow(QtGui.QMainWindow): callback=self._new_updates_available) register(signal=proto.RAISE_WINDOW, callback=self._on_raise_window_event) + self._quit_callback = quit_callback self._updates_content = "" @@ -173,27 +181,6 @@ class MainWindow(QtGui.QMainWindow): self._vpn.process_finished.connect( self._eip_finished) - QtCore.QCoreApplication.instance().connect( - QtCore.QCoreApplication.instance(), - QtCore.SIGNAL("aboutToQuit()"), - self._vpn.set_should_quit) - QtCore.QCoreApplication.instance().connect( - QtCore.QCoreApplication.instance(), - QtCore.SIGNAL("aboutToQuit()"), - self._vpn.wait) - QtCore.QCoreApplication.instance().connect( - QtCore.QCoreApplication.instance(), - QtCore.SIGNAL("aboutToQuit()"), - self._checker_thread.set_should_quit) - QtCore.QCoreApplication.instance().connect( - QtCore.QCoreApplication.instance(), - QtCore.SIGNAL("aboutToQuit()"), - self._checker_thread.wait) - QtCore.QCoreApplication.instance().connect( - QtCore.QCoreApplication.instance(), - QtCore.SIGNAL("aboutToQuit()"), - self._cleanup_pidfiles) - self.ui.chkRemember.stateChanged.connect( self._remember_state_changed) self.ui.chkRemember.setEnabled(keyring.get_keyring() is not None) @@ -447,12 +434,6 @@ class MainWindow(QtGui.QMainWindow): "More about LEAP" "") % (VERSION,)) - def quit(self): - self._really_quit = True - if self._wizard: - self._wizard.close() - self.close() - def changeEvent(self, e): """ Reimplements the changeEvent method to minimize to tray @@ -976,17 +957,42 @@ class MainWindow(QtGui.QMainWindow): def _cleanup_pidfiles(self): """ - SLOT - TRIGGERS: - self.aboutToQuit + Removes lockfiles on a clean shutdown. - Triggered on about to quit signal, removes lockfiles on a clean - shutdown + Triggered after aboutToQuit signal. """ if IS_WIN: lockfile = WindowsLock() lockfile.release_lock() + def _cleanup_and_quit(self): + """ + Call all the cleanup actions in a serialized way. + Should be called from the quit function. + """ + logger.debug('About to quit, doing cleanup...') + self._vpn.set_should_quit() + self._vpn.wait() + self._checker_thread.set_should_quit() + self._checker_thread.wait() + self._cleanup_pidfiles() + + def quit(self): + """ + Cleanup and tidely close the main window before quitting. + """ + self._cleanup_and_quit() + + self._really_quit = True + if self._wizard: + self._wizard.close() + self.close() + + if self._quit_callback: + self._quit_callback() + logger.debug('Bye.') + + if __name__ == "__main__": import signal -- cgit v1.2.3 From b0abf507bb8eb570328172b659ab072bc4b08634 Mon Sep 17 00:00:00 2001 From: Tomas Touceda Date: Wed, 15 May 2013 16:16:32 -0300 Subject: Integrate soledad and keymanager in the client --- src/leap/gui/mainwindow.py | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index fdf84766..7eb956cb 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -37,6 +37,7 @@ from leap.gui.wizard import Wizard from leap.services.eip.eipbootstrapper import EIPBootstrapper from leap.services.eip.eipconfig import EIPConfig from leap.services.eip.providerbootstrapper import ProviderBootstrapper +from leap.services.soledad.soledadbootstrapper import SoledadBootstrapper from leap.platform_init import IS_MAC, IS_WIN from leap.platform_init.initializers import init_platform from leap.services.eip.vpn import VPN @@ -175,6 +176,10 @@ class MainWindow(QtGui.QMainWindow): self._eip_bootstrapper.download_client_certificate.connect( self._finish_eip_bootstrap) + self._soledad_bootstrapper = SoledadBootstrapper() + self._soledad_bootstrapper.download_config.connect( + self._soledad_bootstrapped_stage) + self._vpn = VPN() self._vpn.state_changed.connect(self._update_vpn_state) self._vpn.status_changed.connect(self._update_vpn_status) @@ -233,6 +238,8 @@ class MainWindow(QtGui.QMainWindow): self._bypass_checks = bypass_checks + self._soledad = None + if self._first_run(): self._wizard_firstrun = True self._wizard = Wizard(self._checker_thread, @@ -686,8 +693,35 @@ class MainWindow(QtGui.QMainWindow): """ self.ui.stackedWidget.setCurrentIndex(self.EIP_STATUS_INDEX) self._systray.setIcon(self.LOGGED_IN_ICON) + + self._soledad_bootstrapper.run_soledad_setup_checks( + self._checker_thread, + self._provider_config, + self.ui.lnUser.text(), + self.ui.lnPassword.text(), + download_if_needed=True) + self._download_eip_config() + def _soledad_bootstrapped_stage(self, data): + """ + SLOT + TRIGGERS: + 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 + they fail. + + :param data: result from the bootstrapping stage for Soledad + :type data: dict + """ + passed = data[self._soledad_bootstrapper.PASSED_KEY] + if not passed: + logger.error(data[self._soledad_bootstrapper.ERROR_KEY]) + else: + logger.debug("Done bootstrapping Soledad") + def _get_socket_host(self): """ Returns the socket and port to be used for VPN -- cgit v1.2.3 From c2a0900868eecda3958185bf355a15b046d4e4af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Sat, 18 May 2013 12:38:29 -0300 Subject: Integrate SMTP --- src/leap/gui/mainwindow.py | 69 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 2 deletions(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 7eb956cb..d51ec3c8 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -25,7 +25,9 @@ import tempfile from functools import partial import keyring + from PySide import QtCore, QtGui +from mock import Mock from leap.common.check import leap_assert from leap.common.events import register @@ -38,6 +40,7 @@ from leap.services.eip.eipbootstrapper import EIPBootstrapper from leap.services.eip.eipconfig import EIPConfig from leap.services.eip.providerbootstrapper import ProviderBootstrapper from leap.services.soledad.soledadbootstrapper import SoledadBootstrapper +from leap.services.mail.smtpbootstrapper import SMTPBootstrapper from leap.platform_init import IS_MAC, IS_WIN from leap.platform_init.initializers import init_platform from leap.services.eip.vpn import VPN @@ -48,6 +51,8 @@ from leap.services.eip.vpnlaunchers import (VPNLauncherException, from leap.util import __version__ as VERSION from leap.util.checkerthread import CheckerThread +from leap.services.mail.smtpconfig import SMTPConfig + if IS_WIN: from leap.platform_init.locks import WindowsLock @@ -68,6 +73,10 @@ class MainWindow(QtGui.QMainWindow): # Keyring KEYRING_KEY = "leap_client" + # SMTP + PORT_KEY = "port" + IP_KEY = "ip_address" + # Signals new_updates = QtCore.Signal(object) raise_window = QtCore.Signal([]) @@ -177,9 +186,13 @@ class MainWindow(QtGui.QMainWindow): self._finish_eip_bootstrap) self._soledad_bootstrapper = SoledadBootstrapper() - self._soledad_bootstrapper.download_config.connect( + self._soledad_bootstrapper.gen_key.connect( self._soledad_bootstrapped_stage) + self._smtp_bootstrapper = SMTPBootstrapper() + self._smtp_bootstrapper.download_config.connect( + self._smtp_bootstrapped_stage) + self._vpn = VPN() self._vpn.state_changed.connect(self._update_vpn_state) self._vpn.status_changed.connect(self._update_vpn_status) @@ -239,6 +252,9 @@ class MainWindow(QtGui.QMainWindow): self._bypass_checks = bypass_checks self._soledad = None + self._keymanager = None + + self._smtp_config = SMTPConfig() if self._first_run(): self._wizard_firstrun = True @@ -707,7 +723,7 @@ class MainWindow(QtGui.QMainWindow): """ SLOT TRIGGERS: - self._soledad_bootstrapper.download_config + self._soledad_bootstrapper.gen_key If there was a problem, displays it, otherwise it does nothing. This is used for intermediate bootstrapping stages, in case @@ -722,6 +738,55 @@ class MainWindow(QtGui.QMainWindow): else: logger.debug("Done bootstrapping Soledad") + self._soledad = data[self._soledad_bootstrapper.SOLEDAD_KEY] + self._keymanager = data[self._soledad_bootstrapper.KEYMANAGER_KEY] + + self._smtp_bootstrapper.run_smtp_setup_checks( + self._checker_thread, + self._provider_config, + self._smtp_config, + True) + + def _smtp_bootstrapped_stage(self, data): + """ + SLOT + TRIGGERS: + 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 + they fail. + + :param data: result from the bootstrapping stage for Soledad + :type data: dict + """ + passed = data[self._smtp_bootstrapper.PASSED_KEY] + if not passed: + logger.error(data[self._smtp_bootstrapper.ERROR_KEY]) + else: + logger.debug("Done bootstrapping SMTP") + + hosts = self._smtp_config.get_hosts() + # TODO: handle more than one host and define how to choose + if len(hosts) > 0: + hostname = hosts.keys()[0] + logger.debug("Using hostname %s for SMTP" % (hostname,)) + host = hosts[hostname][self.IP_KEY].encode("utf-8") + port = hosts[hostname][self.PORT_KEY] + # TODO: pick local smtp port in a better way + # TODO: Make the encrypted_only configurable + + # TODO: Remove mocking!!! + self._keymanager.fetch_keys_from_server = Mock(return_value=[]) + from leap.mail.smtp import setup_smtp_relay + setup_smtp_relay(port=1234, + keymanager=self._keymanager, + smtp_host=host, + smtp_port=port, + smtp_username=".", + smtp_password=".", + encrypted_only=False) + def _get_socket_host(self): """ Returns the socket and port to be used for VPN -- cgit v1.2.3 From 8c54836c146ac1870996b0d00e116332b9b3d0a5 Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Wed, 22 May 2013 11:13:31 -0300 Subject: Handle 'Incorrect Password' exception. closes issue #2640. don not automatic login if there is no password add changes file --- src/leap/gui/mainwindow.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 7eb956cb..dad88362 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -354,15 +354,22 @@ class MainWindow(QtGui.QMainWindow): self.ui.chkRemember.setChecked(True) self.ui.chkAutoLogin.setEnabled(self.ui.chkRemember .isEnabled()) - saved_password = keyring.get_password(self.KEYRING_KEY, - saved_user - .encode("utf8")) + + saved_password = None + try: + saved_password = keyring.get_password(self.KEYRING_KEY, + saved_user + .encode("utf8")) + except ValueError, e: + logger.debug("Incorrect Password. %r." % (e,)) + if saved_password is not None: self.ui.lnPassword.setText(saved_password.decode("utf8")) # Only automatically login if there is a saved user + # and the password was retrieved right self.ui.chkAutoLogin.setChecked(auto_login) - if auto_login: + if auto_login and saved_password: self._login() def _show_systray(self): -- cgit v1.2.3 From 9516f7e34cf265f87abb67e40b9fa76682012c84 Mon Sep 17 00:00:00 2001 From: kali Date: Thu, 23 May 2013 22:47:18 +0900 Subject: fix restore from minimized. Closes #2574 --- src/leap/gui/mainwindow.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 3e8a1c83..a8aa1b1c 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -420,12 +420,21 @@ class MainWindow(QtGui.QMainWindow): Toggles the window visibility """ + get_action = lambda visible: ( + self.tr("Show"), + self.tr("Hide"))[int(visible)] + + minimized = self.isMinimized() + if reason != QtGui.QSystemTrayIcon.Context: + # do show + if minimized: + self.showNormal() self.setVisible(not self.isVisible()) - action_visible_text = self.tr("Hide") - if not self.isVisible(): - action_visible_text = self.tr("Show") - self._action_visible.setText(action_visible_text) + + # set labels + visible = self.isVisible() + self._action_visible.setText(get_action(visible)) def _center_window(self): """ -- cgit v1.2.3 From c928400ff02adf6c23c5341c2139e95f2c49976d Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Mon, 27 May 2013 15:10:49 -0300 Subject: Integrate LoggerWindow with client --- src/leap/gui/mainwindow.py | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index a8aa1b1c..12187f51 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -35,6 +35,7 @@ from leap.common.events import events_pb2 as proto from leap.config.leapsettings import LeapSettings from leap.config.providerconfig import ProviderConfig from leap.crypto.srpauth import SRPAuth +from leap.gui.loggerwindow import LoggerWindow from leap.gui.wizard import Wizard from leap.services.eip.eipbootstrapper import EIPBootstrapper from leap.services.eip.eipconfig import EIPConfig @@ -208,6 +209,7 @@ class MainWindow(QtGui.QMainWindow): self.ui.action_about_leap.triggered.connect(self._about) self.ui.action_quit.triggered.connect(self.quit) self.ui.action_wizard.triggered.connect(self._launch_wizard) + self.ui.action_show_logs.triggered.connect(self._show_logger_window) self.raise_window.connect(self._do_raise_mainwindow) # Used to differentiate between real quits and close to tray @@ -249,6 +251,8 @@ class MainWindow(QtGui.QMainWindow): self._wizard = None self._wizard_firstrun = False + self._logger_window = None + self._bypass_checks = bypass_checks self._soledad = None @@ -282,6 +286,35 @@ class MainWindow(QtGui.QMainWindow): self._wizard.exec_() self._wizard = None + def _get_leap_logging_handler(self): + """ + Gets the leap handler from the top level logger + + :return: a logging handler or None + :rtype: LeapLogHandler or None + """ + from leap.util.leap_log_handler import LeapLogHandler + leap_logger = logging.getLogger('leap') + for h in leap_logger.handlers: + if isinstance(h, LeapLogHandler): + return h + return None + + def _show_logger_window(self): + """ + Displays the window with the history of messages logged until now + and displays the new ones on arrival. + """ + if self._logger_window is None: + leap_log_handler = self._get_leap_logging_handler() + if leap_log_handler is None: + logger.error('Leap logger handler not found') + else: + self._logger_window = LoggerWindow(handler=leap_log_handler) + self._logger_window.show() + else: + self._logger_window.show() + def _remember_state_changed(self, state): enable = True if state == QtCore.Qt.Checked else False self.ui.chkAutoLogin.setEnabled(enable) @@ -1101,6 +1134,10 @@ class MainWindow(QtGui.QMainWindow): self._really_quit = True if self._wizard: self._wizard.close() + + if self._logger_window: + self._logger_window.close() + self.close() if self._quit_callback: -- cgit v1.2.3 From 4c726c1531abfe288604eaa4c1d347e85bed81eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Mon, 3 Jun 2013 15:02:41 -0300 Subject: Use Twisted's deferToThread and Deferreds to handle parallel tasks This removes CheckerThread --- src/leap/gui/mainwindow.py | 78 ++++++++++++++++++++++++++++++---------------- 1 file changed, 52 insertions(+), 26 deletions(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 12187f51..25478aa1 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -27,7 +27,7 @@ from functools import partial import keyring from PySide import QtCore, QtGui -from mock import Mock +from twisted.internet import threads from leap.common.check import leap_assert from leap.common.events import register @@ -50,7 +50,6 @@ from leap.services.eip.vpnlaunchers import (VPNLauncherException, EIPNoPkexecAvailable, EIPNoPolkitAuthAgentAvailable) from leap.util import __version__ as VERSION -from leap.util.checkerthread import CheckerThread from leap.services.mail.smtpconfig import SMTPConfig @@ -78,6 +77,9 @@ class MainWindow(QtGui.QMainWindow): PORT_KEY = "port" IP_KEY = "ip_address" + OPENVPN_SERVICE = "openvpn" + MX_SERVICE = "mx" + # Signals new_updates = QtCore.Signal(object) raise_window = QtCore.Signal([]) @@ -155,9 +157,6 @@ class MainWindow(QtGui.QMainWindow): # This is created once we have a valid provider config self._srp_auth = None - self._checker_thread = CheckerThread() - self._checker_thread.start() - # This thread is always running, although it's quite # lightweight when it's done setting up provider # configuration and certificate. @@ -187,6 +186,8 @@ class MainWindow(QtGui.QMainWindow): self._finish_eip_bootstrap) self._soledad_bootstrapper = SoledadBootstrapper() + self._soledad_bootstrapper.download_config.connect( + self._soledad_intermediate_stage) self._soledad_bootstrapper.gen_key.connect( self._soledad_bootstrapped_stage) @@ -262,8 +263,7 @@ class MainWindow(QtGui.QMainWindow): if self._first_run(): self._wizard_firstrun = True - self._wizard = Wizard(self._checker_thread, - standalone=standalone, + self._wizard = Wizard(standalone=standalone, bypass_checks=bypass_checks) # Give this window time to finish init and then show the wizard QtCore.QTimer.singleShot(1, self._launch_wizard) @@ -281,8 +281,8 @@ class MainWindow(QtGui.QMainWindow): def _launch_wizard(self): if self._wizard is None: - self._wizard = Wizard(self._checker_thread, - bypass_checks=self._bypass_checks) + self._wizard = Wizard(bypass_checks=self._bypass_checks) + self._wizard.accepted.connect(self._finish_init) self._wizard.exec_() self._wizard = None @@ -369,6 +369,7 @@ class MainWindow(QtGui.QMainWindow): msg) def _finish_init(self): + self.ui.cmbProviders.clear() self.ui.cmbProviders.addItems(self._configured_providers()) self._show_systray() self.show() @@ -425,6 +426,9 @@ class MainWindow(QtGui.QMainWindow): """ Sets up the systray icon """ + if self._systray is not None: + self._systray.setVisible(True) + return systrayMenu = QtGui.QMenu(self) systrayMenu.addAction(self._action_visible) systrayMenu.addAction(self.ui.action_sign_out) @@ -618,7 +622,6 @@ class MainWindow(QtGui.QMainWindow): provider = self.ui.cmbProviders.currentText() self._provider_bootstrapper.run_provider_select_checks( - self._checker_thread, provider, download_if_needed=True) @@ -643,7 +646,6 @@ class MainWindow(QtGui.QMainWindow): provider, "provider.json")): self._provider_bootstrapper.run_provider_setup_checks( - self._checker_thread, self._provider_config, download_if_needed=True) else: @@ -728,7 +730,7 @@ class MainWindow(QtGui.QMainWindow): auth_partial = partial(self._srp_auth.authenticate, username, password) - self._checker_thread.add_checks([auth_partial]) + threads.deferToThread(auth_partial) else: self._set_status(data[self._provider_bootstrapper.ERROR_KEY]) self._login_set_enabled(True) @@ -760,7 +762,6 @@ class MainWindow(QtGui.QMainWindow): self._systray.setIcon(self.LOGGED_IN_ICON) self._soledad_bootstrapper.run_soledad_setup_checks( - self._checker_thread, self._provider_config, self.ui.lnUser.text(), self.ui.lnPassword.text(), @@ -768,6 +769,22 @@ class MainWindow(QtGui.QMainWindow): self._download_eip_config() + def _soledad_intermediate_stage(self, data): + """ + SLOT + TRIGGERS: + 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 + they fail. + """ + passed = data[self._soledad_bootstrapper.PASSED_KEY] + if not passed: + # TODO: display in the GUI + logger.error("Soledad failed to start: %s" % + (data[self._soledad_bootstrapper.ERROR_KEY],)) + def _soledad_bootstrapped_stage(self, data): """ SLOT @@ -787,14 +804,24 @@ class MainWindow(QtGui.QMainWindow): else: logger.debug("Done bootstrapping Soledad") - self._soledad = data[self._soledad_bootstrapper.SOLEDAD_KEY] - self._keymanager = data[self._soledad_bootstrapper.KEYMANAGER_KEY] + self._soledad = self._soledad_bootstrapper.soledad + self._keymanager = self._soledad_bootstrapper.keymanager - self._smtp_bootstrapper.run_smtp_setup_checks( - self._checker_thread, - self._provider_config, - self._smtp_config, - True) + if self._provider_config.provides_mx() and \ + self._enabled_services.count(self.MX_SERVICE) > 0: + self._smtp_bootstrapper.run_smtp_setup_checks( + self._provider_config, + self._smtp_config, + True) + else: + if self._enabled_services.count(self.MX_SERVICE) > 0: + pass # TODO: show MX status + #self._set_eip_status(self.tr("%s does not support MX") % + # (self._provider_config.get_domain(),), + # error=True) + else: + pass # TODO: show MX status + #self._set_eip_status(self.tr("MX is disabled")) def _smtp_bootstrapped_stage(self, data): """ @@ -914,14 +941,13 @@ class MainWindow(QtGui.QMainWindow): self._set_eip_status(self.tr("Checking configuration, please wait...")) if self._provider_config.provides_eip() and \ - self._enabled_services.count("openvpn") > 0: + self._enabled_services.count(self.OPENVPN_SERVICE) > 0: self._vpn_systray.setVisible(True) self._eip_bootstrapper.run_eip_setup_checks( - self._checker_thread, self._provider_config, download_if_needed=True) else: - if self._enabled_services.count("openvpn") > 0: + if self._enabled_services.count(self.OPENVPN_SERVICE) > 0: self._set_eip_status(self.tr("%s does not support EIP") % (self._provider_config.get_domain(),), error=True) @@ -1035,7 +1061,9 @@ class MainWindow(QtGui.QMainWindow): """ self._set_eip_status_icon("error") self._set_eip_status(self.tr("Signing out...")) - self._checker_thread.add_checks([self._srp_auth.logout]) + # XXX: If other defers are doing authenticated stuff, this + # might conflict with those. CHECK! + threads.deferToThread(self._srp_auth.logout) def _done_logging_out(self, ok, message): """ @@ -1121,8 +1149,6 @@ class MainWindow(QtGui.QMainWindow): logger.debug('About to quit, doing cleanup...') self._vpn.set_should_quit() self._vpn.wait() - self._checker_thread.set_should_quit() - self._checker_thread.wait() self._cleanup_pidfiles() def quit(self): -- cgit v1.2.3 From 655cec1fec89eb30fc17bdc0a5f527e5a91ba5b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Tue, 4 Jun 2013 12:56:17 -0300 Subject: Remove CheckerThread from SRPAuth Also, some pep8 fixes --- src/leap/gui/mainwindow.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 25478aa1..89f06a1c 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -815,12 +815,12 @@ class MainWindow(QtGui.QMainWindow): True) else: if self._enabled_services.count(self.MX_SERVICE) > 0: - pass # TODO: show MX status + pass # TODO: show MX status #self._set_eip_status(self.tr("%s does not support MX") % - # (self._provider_config.get_domain(),), + # (self._provider_config.get_domain(),), # error=True) else: - pass # TODO: show MX status + pass # TODO: show MX status #self._set_eip_status(self.tr("MX is disabled")) def _smtp_bootstrapped_stage(self, data): -- cgit v1.2.3 From 5b5eef87e8eb41916f2f5657287ac1ad8f0bbfeb Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Wed, 5 Jun 2013 11:52:37 -0300 Subject: Select the configured domain in the providers box --- src/leap/gui/mainwindow.py | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 89f06a1c..f9e088a7 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -377,6 +377,12 @@ class MainWindow(QtGui.QMainWindow): if self._wizard: possible_username = self._wizard.get_username() possible_password = self._wizard.get_password() + + # select the configured provider in the combo box + domain = self._wizard.get_domain() + provider_index = self.ui.cmbProviders.findText(domain) + self.ui.cmbProviders.setCurrentIndex(provider_index) + self.ui.chkRemember.setChecked(self._wizard.get_remember()) self._enabled_services = list(self._wizard.get_services()) self._settings.set_enabled_services( -- cgit v1.2.3 From 40c1190ad556aee33d1b90a9c234b36ad0759861 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Thu, 6 Jun 2013 11:39:57 -0300 Subject: Make the login process more granular with defers --- src/leap/gui/mainwindow.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index f9e088a7..c892cadd 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -259,6 +259,8 @@ class MainWindow(QtGui.QMainWindow): self._soledad = None self._keymanager = None + self._login_defer = None + self._smtp_config = SMTPConfig() if self._first_run(): @@ -733,10 +735,7 @@ class MainWindow(QtGui.QMainWindow): self._srp_auth.logout_finished.connect( self._done_logging_out) - auth_partial = partial(self._srp_auth.authenticate, - username, - password) - threads.deferToThread(auth_partial) + self._login_defer = self._srp_auth.authenticate(username,password) else: self._set_status(data[self._provider_bootstrapper.ERROR_KEY]) self._login_set_enabled(True) @@ -756,6 +755,7 @@ class MainWindow(QtGui.QMainWindow): # "Succeeded" message and then we switch to the EIP status # panel QtCore.QTimer.singleShot(1000, self._switch_to_status) + self._login_defer = None else: self._login_set_enabled(True) @@ -1172,6 +1172,9 @@ class MainWindow(QtGui.QMainWindow): self.close() + if self._login_defer: + self._login_defer.cancel() + if self._quit_callback: self._quit_callback() logger.debug('Bye.') -- cgit v1.2.3 From 3e4ccef05a02c7b717b392acbb6201b2f8858a91 Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Fri, 7 Jun 2013 12:10:08 -0300 Subject: Remember provider along with username and password --- src/leap/gui/mainwindow.py | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index f9e088a7..96c50201 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -405,8 +405,21 @@ class MainWindow(QtGui.QMainWindow): saved_user = self._settings.get_user() auto_login = self._settings.get_autologin() + try: + username, domain = saved_user.split('@') + except (ValueError, AttributeError) as e: + # if the saved_user does not contain an '@' or its None + logger.error('Username@provider malformed. %r' % (e, )) + saved_user = None + if saved_user is not None: - self.ui.lnUser.setText(saved_user) + # fill the username + self.ui.lnUser.setText(username) + + # select the configured provider in the combo box + provider_index = self.ui.cmbProviders.findText(domain) + self.ui.cmbProviders.setCurrentIndex(provider_index) + self.ui.chkRemember.setChecked(True) self.ui.chkAutoLogin.setEnabled(self.ui.chkRemember .isEnabled()) @@ -699,13 +712,16 @@ class MainWindow(QtGui.QMainWindow): self._login_set_enabled(False) if self.ui.chkRemember.isChecked(): + # in the keyring and in the settings + # we store the value 'usename@provider' + username_domain = (username + '@' + provider).encode("utf8") try: keyring.set_password(self.KEYRING_KEY, - username.encode("utf8"), + username_domain, password.encode("utf8")) # Only save the username if it was saved correctly in # the keyring - self._settings.set_user(username) + self._settings.set_user(username_domain) except Exception as e: logger.error("Problem saving data to keyring. %r" % (e,)) -- cgit v1.2.3 From 20c78001df4cabccd062004e1a6a4f323ca594b8 Mon Sep 17 00:00:00 2001 From: kali Date: Tue, 11 Jun 2013 01:17:13 +0900 Subject: pep8 --- src/leap/gui/mainwindow.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index c892cadd..f8175b7f 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -735,7 +735,7 @@ class MainWindow(QtGui.QMainWindow): self._srp_auth.logout_finished.connect( self._done_logging_out) - self._login_defer = self._srp_auth.authenticate(username,password) + self._login_defer = self._srp_auth.authenticate(username, password) else: self._set_status(data[self._provider_bootstrapper.ERROR_KEY]) self._login_set_enabled(True) -- cgit v1.2.3 From 029b4c2ac07fab41dbed9ab90e04e477938c3c05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Tue, 11 Jun 2013 12:09:30 -0300 Subject: Merge systray icons Also, catch a possible problem with the login answer from the webapp and display a proper message --- src/leap/gui/mainwindow.py | 38 ++++++++++++++------------------------ 1 file changed, 14 insertions(+), 24 deletions(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index f9e088a7..fa49c55d 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -217,12 +217,11 @@ class MainWindow(QtGui.QMainWindow): self._really_quit = False self._systray = None - self._vpn_systray = None - self._action_eip_status = QtGui.QAction(self.tr("Encryption is OFF"), + self._action_eip_status = QtGui.QAction(self.tr("Encrypted internet is OFF"), self) self._action_eip_status.setEnabled(False) - self._action_eip_startstop = QtGui.QAction(self.tr("Stop"), self) + self._action_eip_startstop = QtGui.QAction(self.tr("Turn encryption ON"), self) self._action_eip_startstop.triggered.connect( self._stop_eip) self._action_eip_write = QtGui.QAction( @@ -234,7 +233,7 @@ class MainWindow(QtGui.QMainWindow): "%12.2f Kb" % (0.0,), self) self._action_eip_read.setEnabled(False) - self._action_visible = QtGui.QAction(self.tr("Hide"), self) + self._action_visible = QtGui.QAction(self.tr("Hide Main Window"), self) self._action_visible.triggered.connect(self._toggle_visible) self._enabled_services = [] @@ -440,22 +439,15 @@ class MainWindow(QtGui.QMainWindow): systrayMenu.addAction(self.ui.action_sign_out) systrayMenu.addSeparator() systrayMenu.addAction(self.ui.action_quit) + systrayMenu.addSeparator() + systrayMenu.addAction(self._action_eip_status) + systrayMenu.addAction(self._action_eip_startstop) self._systray = QtGui.QSystemTrayIcon(self) self._systray.setContextMenu(systrayMenu) - self._systray.setIcon(QtGui.QIcon(self.LOGGED_OUT_ICON)) + self._systray.setIcon(QtGui.QIcon(self.ERROR_ICON)) self._systray.setVisible(True) self._systray.activated.connect(self._toggle_visible) - vpn_systrayMenu = QtGui.QMenu(self) - vpn_systrayMenu.addAction(self._action_eip_status) - vpn_systrayMenu.addAction(self._action_eip_startstop) - vpn_systrayMenu.addAction(self._action_eip_read) - vpn_systrayMenu.addAction(self._action_eip_write) - self._vpn_systray = QtGui.QSystemTrayIcon(self) - self._vpn_systray.setContextMenu(vpn_systrayMenu) - self._vpn_systray.setIcon(QtGui.QIcon(self.ERROR_ICON)) - self._vpn_systray.setVisible(False) - def _toggle_visible(self, reason=None): """ SLOT @@ -599,7 +591,7 @@ class MainWindow(QtGui.QMainWindow): :param status: status message :type status: str """ - self._vpn_systray.setToolTip(status) + self._systray.setToolTip(status) if error: status = "%s" % (status,) self.ui.lblEIPStatus.setText(status) @@ -765,7 +757,6 @@ class MainWindow(QtGui.QMainWindow): triggers the eip bootstrapping """ self.ui.stackedWidget.setCurrentIndex(self.EIP_STATUS_INDEX) - self._systray.setIcon(self.LOGGED_IN_ICON) self._soledad_bootstrapper.run_soledad_setup_checks( self._provider_config, @@ -895,11 +886,11 @@ class MainWindow(QtGui.QMainWindow): providerconfig=self._provider_config, socket_host=host, socket_port=port) - self.ui.btnEipStartStop.setText(self.tr("Stop EIP")) + self.ui.btnEipStartStop.setText(self.tr("Turn Encryption OFF")) self.ui.btnEipStartStop.disconnect(self) self.ui.btnEipStartStop.clicked.connect( self._stop_eip) - self._action_eip_startstop.setText(self.tr("Stop")) + self._action_eip_startstop.setText(self.tr("Turn Encryption OFF")) self._action_eip_startstop.disconnect(self) self._action_eip_startstop.triggered.connect( self._stop_eip) @@ -928,11 +919,11 @@ class MainWindow(QtGui.QMainWindow): self._vpn.set_should_quit() self._set_eip_status(self.tr("EIP has stopped")) self._set_eip_status_icon("error") - self.ui.btnEipStartStop.setText(self.tr("Start EIP")) + self.ui.btnEipStartStop.setText(self.tr("Turn Encryption ON")) self.ui.btnEipStartStop.disconnect(self) self.ui.btnEipStartStop.clicked.connect( self._start_eip) - self._action_eip_startstop.setText(self.tr("Start")) + self._action_eip_startstop.setText(self.tr("Turn Encryption ON")) self._action_eip_startstop.disconnect(self) self._action_eip_startstop.triggered.connect( self._start_eip) @@ -948,7 +939,6 @@ class MainWindow(QtGui.QMainWindow): if self._provider_config.provides_eip() and \ self._enabled_services.count(self.OPENVPN_SERVICE) > 0: - self._vpn_systray.setVisible(True) self._eip_bootstrapper.run_eip_setup_checks( self._provider_config, download_if_needed=True) @@ -973,12 +963,13 @@ class MainWindow(QtGui.QMainWindow): if status in ("WAIT", "AUTH", "GET_CONFIG", "RECONNECTING", "ASSIGN_IP"): selected_pixmap = self.CONNECTING_ICON + tray_message = self.tr("Turning Encryption ON") elif status in ("CONNECTED"): tray_message = self.tr("Encryption is ON") selected_pixmap = self.CONNECTED_ICON self.ui.lblVPNStatusIcon.setPixmap(selected_pixmap) - self._vpn_systray.setIcon(QtGui.QIcon(selected_pixmap)) + self._systray.setIcon(QtGui.QIcon(selected_pixmap)) self._action_eip_status.setText(tray_message) def _update_vpn_state(self, data): @@ -1079,7 +1070,6 @@ class MainWindow(QtGui.QMainWindow): Switches the stackedWidget back to the login stage after logging out """ - self._systray.setIcon(self.LOGGED_OUT_ICON) self.ui.action_sign_out.setEnabled(False) self.ui.stackedWidget.setCurrentIndex(self.LOGIN_INDEX) self.ui.lnPassword.setText("") -- cgit v1.2.3 From 56f90d03b40e2a138a8b653de408f207ad562a09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Tue, 11 Jun 2013 12:37:29 -0300 Subject: Save the provider used for EIP as the default provider. --- src/leap/gui/mainwindow.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index f9e088a7..fdcacb56 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -889,12 +889,24 @@ class MainWindow(QtGui.QMainWindow): return host, port def _start_eip(self): + """ + SLOT + TRIGGERS: + self.ui.btnEipStartStop.clicked + self._action_eip_startstop.triggered + or called from _finish_eip_bootstrap + + Starts EIP + """ try: host, port = self._get_socket_host() self._vpn.start(eipconfig=self._eip_config, providerconfig=self._provider_config, socket_host=host, socket_port=port) + + self._settings.set_defaultprovider(self._provider_config.get_domain()) + self.ui.btnEipStartStop.setText(self.tr("Stop EIP")) self.ui.btnEipStartStop.disconnect(self) self.ui.btnEipStartStop.clicked.connect( -- cgit v1.2.3 From dbb873016042b213dd9cd84a59aec0c0a2383691 Mon Sep 17 00:00:00 2001 From: kali Date: Wed, 5 Jun 2013 05:18:39 +0900 Subject: use twisted processProtocol instead of QProcess to drive openvpn --- src/leap/gui/mainwindow.py | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 89f06a1c..2cad6df3 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -44,7 +44,8 @@ from leap.services.soledad.soledadbootstrapper import SoledadBootstrapper from leap.services.mail.smtpbootstrapper import SMTPBootstrapper from leap.platform_init import IS_MAC, IS_WIN from leap.platform_init.initializers import init_platform -from leap.services.eip.vpn import VPN +from leap.services.eip.vpnprocess import VPN, VPNManager + from leap.services.eip.vpnlaunchers import (VPNLauncherException, OpenVPNNotFoundException, EIPNoPkexecAvailable, @@ -196,9 +197,9 @@ class MainWindow(QtGui.QMainWindow): self._smtp_bootstrapped_stage) self._vpn = VPN() - self._vpn.state_changed.connect(self._update_vpn_state) - self._vpn.status_changed.connect(self._update_vpn_status) - self._vpn.process_finished.connect( + self._vpn.qtsigs.state_changed.connect(self._update_vpn_state) + self._vpn.qtsigs.status_changed.connect(self._update_vpn_status) + self._vpn.qtsigs.process_finished.connect( self._eip_finished) self.ui.chkRemember.stateChanged.connect( @@ -816,8 +817,9 @@ class MainWindow(QtGui.QMainWindow): else: if self._enabled_services.count(self.MX_SERVICE) > 0: pass # TODO: show MX status - #self._set_eip_status(self.tr("%s does not support MX") % - # (self._provider_config.get_domain(),), + #self._set_eip_status( + # self.tr("%s does not support MX") % + # (self._provider_config.get_domain(),), # error=True) else: pass # TODO: show MX status @@ -852,8 +854,6 @@ class MainWindow(QtGui.QMainWindow): # TODO: pick local smtp port in a better way # TODO: Make the encrypted_only configurable - # TODO: Remove mocking!!! - self._keymanager.fetch_keys_from_server = Mock(return_value=[]) from leap.mail.smtp import setup_smtp_relay setup_smtp_relay(port=1234, keymanager=self._keymanager, @@ -919,7 +919,7 @@ class MainWindow(QtGui.QMainWindow): self.ui.btnEipStartStop.setEnabled(True) def _stop_eip(self): - self._vpn.set_should_quit() + self._vpn.terminate() self._set_eip_status(self.tr("EIP has stopped")) self._set_eip_status_icon("error") self.ui.btnEipStartStop.setText(self.tr("Start EIP")) @@ -983,7 +983,7 @@ class MainWindow(QtGui.QMainWindow): Updates the displayed VPN state based on the data provided by the VPN thread """ - status = data[self._vpn.STATUS_STEP_KEY] + status = data[VPNManager.STATUS_STEP_KEY] self._set_eip_status_icon(status) if status == "AUTH": self._set_eip_status(self.tr("VPN: Authenticating...")) @@ -1014,12 +1014,12 @@ class MainWindow(QtGui.QMainWindow): Updates the download/upload labels based on the data provided by the VPN thread """ - upload = float(data[self._vpn.TUNTAP_WRITE_KEY]) + upload = float(data[VPNManager.TUNTAP_WRITE_KEY]) upload = upload / 1000.0 upload_str = "%12.2f Kb" % (upload,) self.ui.lblUpload.setText(upload_str) self._action_eip_write.setText(upload_str) - download = float(data[self._vpn.TUNTAP_READ_KEY]) + download = float(data[VPNManager.TUNTAP_READ_KEY]) download = download / 1000.0 download_str = "%12.2f Kb" % (download,) self.ui.lblDownload.setText(download_str) @@ -1079,7 +1079,7 @@ class MainWindow(QtGui.QMainWindow): self.ui.lnPassword.setText("") self._login_set_enabled(True) self._set_status("") - self._vpn.set_should_quit() + self._vpn.terminate() def _intermediate_stage(self, data): """ @@ -1147,8 +1147,11 @@ class MainWindow(QtGui.QMainWindow): Should be called from the quit function. """ logger.debug('About to quit, doing cleanup...') - self._vpn.set_should_quit() - self._vpn.wait() + + logger.debug('Killing vpn') + self._vpn.terminate() + + logger.debug('Cleaning pidfiles') self._cleanup_pidfiles() def quit(self): -- cgit v1.2.3 From b2653dcf8f9619c73e4fc792a2d952dd2fdfd3b4 Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Tue, 11 Jun 2013 17:00:22 -0300 Subject: Remove lines disconnecting vpn on logout --- src/leap/gui/mainwindow.py | 3 --- 1 file changed, 3 deletions(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index a7d88aee..afa7e947 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -1084,8 +1084,6 @@ class MainWindow(QtGui.QMainWindow): Starts the logout sequence """ - self._set_eip_status_icon("error") - self._set_eip_status(self.tr("Signing out...")) # XXX: If other defers are doing authenticated stuff, this # might conflict with those. CHECK! threads.deferToThread(self._srp_auth.logout) @@ -1103,7 +1101,6 @@ class MainWindow(QtGui.QMainWindow): self.ui.lnPassword.setText("") self._login_set_enabled(True) self._set_status("") - self._vpn.terminate() def _intermediate_stage(self, data): """ -- cgit v1.2.3 From da018dfadc4f3c6cbd1613b45b339279aebb0589 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Wed, 12 Jun 2013 10:56:57 -0300 Subject: Autostart EIP whenever possible --- src/leap/gui/mainwindow.py | 94 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 79 insertions(+), 15 deletions(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index afa7e947..65f5fe3d 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -153,8 +153,12 @@ class MainWindow(QtGui.QMainWindow): EIPConfig.standalone = standalone self._standalone = standalone self._provider_config = ProviderConfig() + # Used for automatic start of EIP + self._provisional_provider_config = ProviderConfig() self._eip_config = EIPConfig() + self._already_started_eip = False + # This is created once we have a valid provider config self._srp_auth = None @@ -219,10 +223,11 @@ class MainWindow(QtGui.QMainWindow): self._systray = None - self._action_eip_status = QtGui.QAction(self.tr("Encrypted internet is OFF"), - self) + self._action_eip_status = QtGui.QAction( + self.tr("Encrypted internet is OFF"), self) self._action_eip_status.setEnabled(False) - self._action_eip_startstop = QtGui.QAction(self.tr("Turn encryption ON"), self) + self._action_eip_startstop = QtGui.QAction( + self.tr("Turn encryption ON"), self) self._action_eip_startstop.triggered.connect( self._stop_eip) self._action_eip_write = QtGui.QAction( @@ -400,6 +405,7 @@ class MainWindow(QtGui.QMainWindow): self._wizard = None self._settings.set_properprovider(True) else: + self._try_autostart_eip() if not self._settings.get_remember(): # nothing to do here return @@ -443,6 +449,31 @@ class MainWindow(QtGui.QMainWindow): if auto_login and saved_password: self._login() + def _try_autostart_eip(self): + """ + Tries to autostart EIP + """ + default_provider = self._settings.get_defaultprovider() + + if default_provider is None: + logger.info("Cannot autostart EIP because there's no default " + "provider configured") + return + + self._enabled_services = self._settings.get_enabled_services( + default_provider) + + if self._provisional_provider_config.load( + os.path.join("leap", + "providers", + default_provider, + "provider.json")): + self._download_eip_config() + else: + # XXX: Display a proper message to the user + logger.error("Unable to load %s config, cannot autostart." % + (default_provider,)) + def _show_systray(self): """ Sets up the systray icon @@ -744,6 +775,7 @@ class MainWindow(QtGui.QMainWindow): self._srp_auth.logout_finished.connect( self._done_logging_out) + # TODO: Add errback! self._login_defer = self._srp_auth.authenticate(username, password) else: self._set_status(data[self._provider_bootstrapper.ERROR_KEY]) @@ -905,15 +937,17 @@ class MainWindow(QtGui.QMainWindow): Starts EIP """ + provider_config = self._get_best_provider_config() + try: host, port = self._get_socket_host() self._vpn.start(eipconfig=self._eip_config, - providerconfig=self._provider_config, + providerconfig=provider_config, socket_host=host, socket_port=port) self._settings.set_defaultprovider( - self._provider_config.get_domain()) + provider_config.get_domain()) self.ui.btnEipStartStop.setText(self.tr("Turn Encryption OFF")) self.ui.btnEipStartStop.disconnect(self) self.ui.btnEipStartStop.clicked.connect( @@ -955,25 +989,53 @@ class MainWindow(QtGui.QMainWindow): self._action_eip_startstop.disconnect(self) self._action_eip_startstop.triggered.connect( self._start_eip) + self._already_started_eip = False + + 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 + """ + 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 couldn't find any usable ProviderConfig") + + return provider_config def _download_eip_config(self): """ Starts the EIP bootstrapping sequence """ leap_assert(self._eip_bootstrapper, "We need an eip bootstrapper!") - leap_assert(self._provider_config, "We need a provider config") - self._set_eip_status(self.tr("Checking configuration, please wait...")) + provider_config = self._get_best_provider_config() - if self._provider_config.provides_eip() and \ - self._enabled_services.count(self.OPENVPN_SERVICE) > 0: + if provider_config.provides_eip() and \ + self._enabled_services.count(self.OPENVPN_SERVICE) > 0 and \ + not self._already_started_eip: + + self._set_eip_status( + self.tr("Checking configuration, please wait...")) self._eip_bootstrapper.run_eip_setup_checks( - self._provider_config, + provider_config, download_if_needed=True) - else: + self._already_started_eip = True + elif not self._already_started_eip: if self._enabled_services.count(self.OPENVPN_SERVICE) > 0: self._set_eip_status(self.tr("%s does not support EIP") % - (self._provider_config.get_domain(),), + (provider_config.get_domain(),), error=True) else: self._set_eip_status(self.tr("EIP is disabled")) @@ -1059,14 +1121,16 @@ class MainWindow(QtGui.QMainWindow): loaded """ leap_assert(self._eip_config, "We need an eip config!") - leap_assert(self._provider_config, "We need a provider config!") + + provider_config = self._get_best_provider_config() + + domain = provider_config.get_domain() if data[self._eip_bootstrapper.PASSED_KEY] and \ (self._eip_config.loaded() or self._eip_config.load(os.path.join("leap", "providers", - self._provider_config - .get_domain(), + domain, "eip-service.json"))): self._start_eip() else: -- cgit v1.2.3 From 521c4b41515fa9491f744274548e1714eb8695f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Wed, 12 Jun 2013 21:31:32 -0300 Subject: Display the default provider in the systray menu --- src/leap/gui/mainwindow.py | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 65f5fe3d..ddcf1a4c 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -223,6 +223,9 @@ class MainWindow(QtGui.QMainWindow): self._systray = None + self._action_eip_provider = QtGui.QAction( + self.tr("No default provider"), self) + self._action_eip_provider.setEnabled(False) self._action_eip_status = QtGui.QAction( self.tr("Encrypted internet is OFF"), self) self._action_eip_status.setEnabled(False) @@ -460,6 +463,8 @@ class MainWindow(QtGui.QMainWindow): "provider configured") return + self._action_eip_provider.setText(default_provider) + self._enabled_services = self._settings.get_enabled_services( default_provider) @@ -487,6 +492,7 @@ class MainWindow(QtGui.QMainWindow): systrayMenu.addSeparator() systrayMenu.addAction(self.ui.action_quit) systrayMenu.addSeparator() + systrayMenu.addAction(self._action_eip_provider) systrayMenu.addAction(self._action_eip_status) systrayMenu.addAction(self._action_eip_startstop) self._systray = QtGui.QSystemTrayIcon(self) @@ -948,6 +954,7 @@ class MainWindow(QtGui.QMainWindow): self._settings.set_defaultprovider( provider_config.get_domain()) + self._action_eip_provider.setText(provider_config.get_domain()) self.ui.btnEipStartStop.setText(self.tr("Turn Encryption OFF")) self.ui.btnEipStartStop.disconnect(self) self.ui.btnEipStartStop.clicked.connect( -- cgit v1.2.3 From cd11784b8fdf0cb45783e8d6a8e9b5288f34820d Mon Sep 17 00:00:00 2001 From: kali Date: Thu, 13 Jun 2013 22:48:29 +0900 Subject: pep8 --- src/leap/gui/mainwindow.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index afa7e947..23084102 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -219,10 +219,12 @@ class MainWindow(QtGui.QMainWindow): self._systray = None - self._action_eip_status = QtGui.QAction(self.tr("Encrypted internet is OFF"), - self) + self._action_eip_status = QtGui.QAction( + self.tr("Encrypted internet is OFF"), + self) self._action_eip_status.setEnabled(False) - self._action_eip_startstop = QtGui.QAction(self.tr("Turn encryption ON"), self) + self._action_eip_startstop = QtGui.QAction( + self.tr("Turn encryption ON"), self) self._action_eip_startstop.triggered.connect( self._stop_eip) self._action_eip_write = QtGui.QAction( -- cgit v1.2.3 From 09f1399db76a5c64cc38d45510b18cecd3a3d457 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Thu, 13 Jun 2013 10:49:21 -0300 Subject: If eip fails to autostart, mark it as such --- src/leap/gui/mainwindow.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 65f5fe3d..752f5ef1 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -186,7 +186,7 @@ class MainWindow(QtGui.QMainWindow): self._eip_bootstrapper = EIPBootstrapper() self._eip_bootstrapper.download_config.connect( - self._intermediate_stage) + self._eip_intermediate_stage) self._eip_bootstrapper.download_client_certificate.connect( self._finish_eip_bootstrap) @@ -1140,6 +1140,7 @@ class MainWindow(QtGui.QMainWindow): else: self._set_eip_status(data[self._eip_bootstrapper.ERROR_KEY], error=True) + self._already_started_eip = False def _logout(self): """ @@ -1184,6 +1185,21 @@ class MainWindow(QtGui.QMainWindow): self._login_set_enabled(True) self._set_status(data[self._provider_bootstrapper.ERROR_KEY]) + def _eip_intermediate_stage(self, data): + """ + SLOT + TRIGGERS: + self._eip_bootstrapper.download_config + + If there was a problem, displays it, otherwise it does nothing. + This is used for intermediate bootstrapping stages, in case + they fail. + """ + passed = data[self._provider_bootstrapper.PASSED_KEY] + if not passed: + self._set_status(data[self._provider_bootstrapper.ERROR_KEY]) + self._already_started_eip = False + def _eip_finished(self, exitCode): """ SLOT -- cgit v1.2.3 From b2f2831d6fc090a508437a073267d5a9e2bd5e14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Wed, 12 Jun 2013 14:22:16 -0300 Subject: Refactor login to its own widget and remove Utils menu --- src/leap/gui/mainwindow.py | 199 ++++++++++++++++++++++----------------------- 1 file changed, 98 insertions(+), 101 deletions(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 0e388e64..61eb8ca4 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -37,6 +37,7 @@ from leap.config.providerconfig import ProviderConfig from leap.crypto.srpauth import SRPAuth from leap.gui.loggerwindow import LoggerWindow from leap.gui.wizard import Wizard +from leap.gui.login import LoginWidget from leap.services.eip.eipbootstrapper import EIPBootstrapper from leap.services.eip.eipconfig import EIPConfig from leap.services.eip.providerbootstrapper import ProviderBootstrapper @@ -135,11 +136,18 @@ class MainWindow(QtGui.QMainWindow): self.ui = Ui_MainWindow() self.ui.setupUi(self) - self.ui.lnPassword.setEchoMode(QtGui.QLineEdit.Password) + self._settings = LeapSettings(standalone) + + self._login_widget = LoginWidget( + self._settings, + self.ui.stackedWidget.widget(self.LOGIN_INDEX)) + self.ui.loginLayout.addWidget(self._login_widget) + + self._login_widget.login.connect(self._login) + self._login_widget.show_wizard.connect( + self._launch_wizard) - self.ui.btnLogin.clicked.connect(self._login) - self.ui.lnUser.returnPressed.connect(self._focus_password) - self.ui.lnPassword.returnPressed.connect(self._login) + self.ui.btnShowLog.clicked.connect(self._show_logger_window) self.ui.stackedWidget.setCurrentIndex(self.LOGIN_INDEX) @@ -206,10 +214,6 @@ class MainWindow(QtGui.QMainWindow): self._vpn.qtsigs.process_finished.connect( self._eip_finished) - self.ui.chkRemember.stateChanged.connect( - self._remember_state_changed) - self.ui.chkRemember.setEnabled(keyring.get_keyring() is not None) - self.ui.action_sign_out.setEnabled(False) self.ui.action_sign_out.triggered.connect(self._logout) self.ui.action_about_leap.triggered.connect(self._about) @@ -244,7 +248,6 @@ class MainWindow(QtGui.QMainWindow): self._action_visible.triggered.connect(self._toggle_visible) self._enabled_services = [] - self._settings = LeapSettings(standalone) self._center_window() @@ -281,6 +284,13 @@ class MainWindow(QtGui.QMainWindow): self._finish_init() def _rejected_wizard(self): + """ + SLOT + TRIGGERS: self._wizard.rejected + + Called if the wizard has been cancelled or closed before + finishing. + """ if self._wizard_firstrun: self._settings.set_properprovider(False) self.quit() @@ -288,11 +298,24 @@ class MainWindow(QtGui.QMainWindow): self._finish_init() def _launch_wizard(self): + """ + SLOT + TRIGGERS: + self._login_widget.show_wizard + self.ui.action_wizard.triggered + + Also called in first run. + + Launches the wizard, creating the object itself if not already + there. + """ if self._wizard is None: self._wizard = Wizard(bypass_checks=self._bypass_checks) self._wizard.accepted.connect(self._finish_init) + self.setVisible(False) self._wizard.exec_() self._wizard = None + self.setVisible(True) def _get_leap_logging_handler(self): """ @@ -310,6 +333,11 @@ class MainWindow(QtGui.QMainWindow): def _show_logger_window(self): """ + SLOT + TRIGGERS: + self.ui.action_show_logs.triggered + self.ui.btnShowLog.clicked + Displays the window with the history of messages logged until now and displays the new ones on arrival. """ @@ -319,14 +347,11 @@ class MainWindow(QtGui.QMainWindow): logger.error('Leap logger handler not found') else: self._logger_window = LoggerWindow(handler=leap_log_handler) - self._logger_window.show() + self._logger_window.setVisible(not self._logger_window.isVisible()) + self.ui.btnShowLog.setChecked(self._logger_window.isVisible()) else: - self._logger_window.show() - - def _remember_state_changed(self, state): - enable = True if state == QtCore.Qt.Checked else False - self.ui.chkAutoLogin.setEnabled(enable) - self._settings.set_remember(enable) + self._logger_window.setVisible(not self._logger_window.isVisible()) + self.ui.btnShowLog.setChecked(self._logger_window.isVisible()) def _new_updates_available(self, req): """ @@ -377,8 +402,21 @@ class MainWindow(QtGui.QMainWindow): msg) def _finish_init(self): - self.ui.cmbProviders.clear() - self.ui.cmbProviders.addItems(self._configured_providers()) + """ + SLOT + TRIGGERS: + self._wizard.accepted + + Also called at the end of the constructor if not first run, + and after _rejected_wizard if not first run. + + Implements the behavior after either constructing the + mainwindow object, loading the saved user/password, or after + the wizard has been executed. + """ + # XXX: May be this can be divided into two methods? + + self._login_widget.set_providers(self._configured_providers()) self._show_systray() self.show() @@ -388,20 +426,18 @@ class MainWindow(QtGui.QMainWindow): # select the configured provider in the combo box domain = self._wizard.get_domain() - provider_index = self.ui.cmbProviders.findText(domain) - self.ui.cmbProviders.setCurrentIndex(provider_index) + self._login_widget.select_provider_by_name(domain) - self.ui.chkRemember.setChecked(self._wizard.get_remember()) + self._login_widget.set_remember(self._wizard.get_remember()) self._enabled_services = list(self._wizard.get_services()) self._settings.set_enabled_services( - self.ui.cmbProviders.currentText(), + self._login_widget.get_selected_provider(), self._enabled_services) if possible_username is not None: - self.ui.lnUser.setText(possible_username) - self._focus_password() + self._login_widget.set_user(possible_username) if possible_password is not None: - self.ui.lnPassword.setText(possible_password) - self.ui.chkRemember.setChecked(True) + self._login_widget.set_password(possible_password) + self._login_widget.set_remember(True) self._login() self._wizard = None self._settings.set_properprovider(True) @@ -412,7 +448,6 @@ class MainWindow(QtGui.QMainWindow): return saved_user = self._settings.get_user() - auto_login = self._settings.get_autologin() try: username, domain = saved_user.split('@') @@ -423,15 +458,12 @@ class MainWindow(QtGui.QMainWindow): if saved_user is not None: # fill the username - self.ui.lnUser.setText(username) + self._login_widget.set_user(username) # select the configured provider in the combo box - provider_index = self.ui.cmbProviders.findText(domain) - self.ui.cmbProviders.setCurrentIndex(provider_index) + self._login_widget.select_provider_by_name(domain) - self.ui.chkRemember.setChecked(True) - self.ui.chkAutoLogin.setEnabled(self.ui.chkRemember - .isEnabled()) + self._login_widget.set_remember(True) saved_password = None try: @@ -442,12 +474,7 @@ class MainWindow(QtGui.QMainWindow): logger.debug("Incorrect Password. %r." % (e,)) if saved_password is not None: - self.ui.lnPassword.setText(saved_password.decode("utf8")) - - # Only automatically login if there is a saved user - # and the password was retrieved right - self.ui.chkAutoLogin.setChecked(auto_login) - if auto_login and saved_password: + self._login_widget.set_password(saved_password.decode("utf8")) self._login() def _try_autostart_eip(self): @@ -543,6 +570,9 @@ class MainWindow(QtGui.QMainWindow): def _about(self): """ + SLOT + TRIGGERS: self.ui.action_about_leap.triggered + Display the About LEAP dialog """ QtGui.QMessageBox.about( @@ -580,7 +610,6 @@ class MainWindow(QtGui.QMainWindow): self._settings.set_geometry(self.saveGeometry()) self._settings.set_windowstate(self.saveState()) - self._settings.set_autologin(self.ui.chkAutoLogin.isChecked()) QtGui.QMainWindow.closeEvent(self, e) @@ -615,23 +644,6 @@ class MainWindow(QtGui.QMainWindow): is_proper_provider = self._settings.get_properprovider() return not (has_provider_on_disk and is_proper_provider) - def _focus_password(self): - """ - Focuses in the password lineedit - """ - self.ui.lnPassword.setFocus() - - def _set_status(self, status, error=True): - """ - Sets the status label at the login stage to status - - :param status: status message - :type status: str - """ - if error: - status = "%s" % (status,) - self.ui.lblStatus.setText(status) - def _set_eip_status(self, status, error=False): """ Sets the status label at the VPN stage to status @@ -644,28 +656,13 @@ class MainWindow(QtGui.QMainWindow): status = "%s" % (status,) self.ui.lblEIPStatus.setText(status) - def _login_set_enabled(self, enabled=False): - """ - Enables or disables all the login widgets - - :param enabled: wether they should be enabled or not - :type enabled: bool - """ - self.ui.lnUser.setEnabled(enabled) - self.ui.lnPassword.setEnabled(enabled) - self.ui.btnLogin.setEnabled(enabled) - self.ui.chkRemember.setEnabled(enabled) - if not enabled: - self.ui.chkAutoLogin.setEnabled(False) - self.ui.cmbProviders.setEnabled(enabled) - def _download_provider_config(self): """ Starts the bootstrapping sequence. It will download the provider configuration if it's not present, otherwise will emit the corresponding signals inmediately """ - provider = self.ui.cmbProviders.currentText() + provider = self._login_widget.get_selected_provider() self._provider_bootstrapper.run_provider_select_checks( provider, @@ -685,7 +682,7 @@ class MainWindow(QtGui.QMainWindow): :type data: dict """ if data[self._provider_bootstrapper.PASSED_KEY]: - provider = self.ui.cmbProviders.currentText() + provider = self._login_widget.get_selected_provider() if self._provider_config.loaded() or \ self._provider_config.load(os.path.join("leap", "providers", @@ -695,12 +692,12 @@ class MainWindow(QtGui.QMainWindow): self._provider_config, download_if_needed=True) else: - self._set_status( + self._login_widget.set_status( self.tr("Could not load provider configuration")) - self._login_set_enabled(True) + self._login_widget.set_enabled(True) else: - self._set_status(data[self._provider_bootstrapper.ERROR_KEY]) - self._login_set_enabled(True) + self._login_widget.set_status(data[self._provider_bootstrapper.ERROR_KEY]) + self._login_widget.set_enabled(True) def _login(self): """ @@ -716,29 +713,29 @@ class MainWindow(QtGui.QMainWindow): """ leap_assert(self._provider_config, "We need a provider config") - username = self.ui.lnUser.text() - password = self.ui.lnPassword.text() - provider = self.ui.cmbProviders.currentText() + username = self._login_widget.get_user() + password = self._login_widget.get_password() + provider = self._login_widget.get_selected_provider() self._enabled_services = self._settings.get_enabled_services( - self.ui.cmbProviders.currentText()) + self._login_widget.get_selected_provider()) if len(provider) == 0: - self._set_status(self.tr("Please select a valid provider")) + self._login_widget.set_status(self.tr("Please select a valid provider")) return if len(username) == 0: - self._set_status(self.tr("Please provide a valid username")) + self._login_widget.set_status(self.tr("Please provide a valid username")) return if len(password) == 0: - self._set_status(self.tr("Please provide a valid Password")) + self._login_widget.set_status(self.tr("Please provide a valid Password")) return - self._set_status(self.tr("Logging in..."), error=False) - self._login_set_enabled(False) + self._login_widget.set_status(self.tr("Logging in..."), error=False) + self._login_widget.set_enabled(False) - if self.ui.chkRemember.isChecked(): + if self._login_widget.get_remember(): # in the keyring and in the settings # we store the value 'usename@provider' username_domain = (username + '@' + provider).encode("utf8") @@ -766,8 +763,8 @@ class MainWindow(QtGui.QMainWindow): leap_assert(self._provider_config, "We need a provider config!") if data[self._provider_bootstrapper.PASSED_KEY]: - username = self.ui.lnUser.text().encode("utf8") - password = self.ui.lnPassword.text().encode("utf8") + username = self._login_widget.get_user().encode("utf8") + password = self._login_widget.get_password().encode("utf8") if self._srp_auth is None: self._srp_auth = SRPAuth(self._provider_config) @@ -779,8 +776,8 @@ class MainWindow(QtGui.QMainWindow): # TODO: Add errback! self._login_defer = self._srp_auth.authenticate(username, password) else: - self._set_status(data[self._provider_bootstrapper.ERROR_KEY]) - self._login_set_enabled(True) + self._login_widget.set_status(data[self._provider_bootstrapper.ERROR_KEY]) + self._login_widget.set_enabled(True) def _authentication_finished(self, ok, message): """ @@ -790,7 +787,7 @@ class MainWindow(QtGui.QMainWindow): Once the user is properly authenticated, try starting the EIP service """ - self._set_status(message, error=not ok) + self._login_widget.set_status(message, error=not ok) if ok: self.ui.action_sign_out.setEnabled(True) # We leave a bit of room for the user to see the @@ -799,7 +796,7 @@ class MainWindow(QtGui.QMainWindow): QtCore.QTimer.singleShot(1000, self._switch_to_status) self._login_defer = None else: - self._login_set_enabled(True) + self._login_widget.set_enabled(True) def _switch_to_status(self): """ @@ -810,8 +807,8 @@ class MainWindow(QtGui.QMainWindow): self._soledad_bootstrapper.run_soledad_setup_checks( self._provider_config, - self.ui.lnUser.text(), - self.ui.lnPassword.text(), + self._login_widget.get_user(), + self._login_widget.get_password(), download_if_needed=True) self._download_eip_config() @@ -1163,9 +1160,9 @@ class MainWindow(QtGui.QMainWindow): """ self.ui.action_sign_out.setEnabled(False) self.ui.stackedWidget.setCurrentIndex(self.LOGIN_INDEX) - self.ui.lnPassword.setText("") - self._login_set_enabled(True) - self._set_status("") + self._login_widget.set_password("") + self._login_widget.set_enabled(True) + self._login_widget.set_status("") def _intermediate_stage(self, data): """ @@ -1182,8 +1179,8 @@ class MainWindow(QtGui.QMainWindow): """ passed = data[self._provider_bootstrapper.PASSED_KEY] if not passed: - self._login_set_enabled(True) - self._set_status(data[self._provider_bootstrapper.ERROR_KEY]) + self._login_widget.set_enabled(True) + self._login_widget.set_status(data[self._provider_bootstrapper.ERROR_KEY]) def _eip_finished(self, exitCode): """ -- cgit v1.2.3 From 5e8feb737d0a0fb8065cda583c88498385ff7b9f Mon Sep 17 00:00:00 2001 From: kali Date: Thu, 13 Jun 2013 23:37:13 +0900 Subject: pep8 --- src/leap/gui/mainwindow.py | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 61eb8ca4..01707554 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -347,7 +347,8 @@ class MainWindow(QtGui.QMainWindow): logger.error('Leap logger handler not found') else: self._logger_window = LoggerWindow(handler=leap_log_handler) - self._logger_window.setVisible(not self._logger_window.isVisible()) + self._logger_window.setVisible( + not self._logger_window.isVisible()) self.ui.btnShowLog.setChecked(self._logger_window.isVisible()) else: self._logger_window.setVisible(not self._logger_window.isVisible()) @@ -474,7 +475,8 @@ class MainWindow(QtGui.QMainWindow): logger.debug("Incorrect Password. %r." % (e,)) if saved_password is not None: - self._login_widget.set_password(saved_password.decode("utf8")) + self._login_widget.set_password( + saved_password.decode("utf8")) self._login() def _try_autostart_eip(self): @@ -696,7 +698,8 @@ class MainWindow(QtGui.QMainWindow): self.tr("Could not load provider configuration")) self._login_widget.set_enabled(True) else: - self._login_widget.set_status(data[self._provider_bootstrapper.ERROR_KEY]) + self._login_widget.set_status( + data[self._provider_bootstrapper.ERROR_KEY]) self._login_widget.set_enabled(True) def _login(self): @@ -721,15 +724,18 @@ class MainWindow(QtGui.QMainWindow): self._login_widget.get_selected_provider()) if len(provider) == 0: - self._login_widget.set_status(self.tr("Please select a valid provider")) + self._login_widget.set_status( + self.tr("Please select a valid provider")) return if len(username) == 0: - self._login_widget.set_status(self.tr("Please provide a valid username")) + self._login_widget.set_status( + self.tr("Please provide a valid username")) return if len(password) == 0: - self._login_widget.set_status(self.tr("Please provide a valid Password")) + self._login_widget.set_status( + self.tr("Please provide a valid Password")) return self._login_widget.set_status(self.tr("Logging in..."), error=False) @@ -776,7 +782,8 @@ class MainWindow(QtGui.QMainWindow): # TODO: Add errback! self._login_defer = self._srp_auth.authenticate(username, password) else: - self._login_widget.set_status(data[self._provider_bootstrapper.ERROR_KEY]) + self._login_widget.set_status( + data[self._provider_bootstrapper.ERROR_KEY]) self._login_widget.set_enabled(True) def _authentication_finished(self, ok, message): @@ -1180,7 +1187,8 @@ class MainWindow(QtGui.QMainWindow): passed = data[self._provider_bootstrapper.PASSED_KEY] if not passed: self._login_widget.set_enabled(True) - self._login_widget.set_status(data[self._provider_bootstrapper.ERROR_KEY]) + self._login_widget.set_status( + data[self._provider_bootstrapper.ERROR_KEY]) def _eip_finished(self, exitCode): """ -- cgit v1.2.3 From b8a83ca21a0a44487097dbf41735e3bad176d5e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Wed, 12 Jun 2013 11:22:08 -0300 Subject: Always show context menu when clicking the systray --- src/leap/gui/mainwindow.py | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 01707554..3c6c579c 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -523,31 +523,41 @@ class MainWindow(QtGui.QMainWindow): self._systray.setContextMenu(systrayMenu) self._systray.setIcon(QtGui.QIcon(self.ERROR_ICON)) self._systray.setVisible(True) - self._systray.activated.connect(self._toggle_visible) + self._systray.activated.connect(self._tray_activated) - def _toggle_visible(self, reason=None): + def _tray_activated(self, reason=None): """ SLOT TRIGGER: self._systray.activated - Toggles the window visibility + Displays the context menu from the tray icon """ get_action = lambda visible: ( - self.tr("Show"), - self.tr("Hide"))[int(visible)] - - minimized = self.isMinimized() + self.tr("Show Main Window"), + self.tr("Hide Main Window"))[int(visible)] if reason != QtGui.QSystemTrayIcon.Context: - # do show - if minimized: - self.showNormal() - self.setVisible(not self.isVisible()) - # set labels visible = self.isVisible() self._action_visible.setText(get_action(visible)) + context_menu = self._systray.contextMenu() + # for some reason, context_menu.show() + # is failing in a way beyond my understanding. + # (not working the first time it's clicked). + # this works however. + # XXX in osx it shows some glitches. + context_menu.exec_(self._systray.geometry().center()) + + def _toggle_visible(self): + """ + SLOT + TRIGGER: self._action_visible.triggered + + Toggles the window visibility + """ + self.setVisible(not self.isVisible()) + def _center_window(self): """ Centers the mainwindow based on the desktop geometry -- cgit v1.2.3 From c3fa54bc8628ba1618aba7b09a0daf458e798d3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Thu, 13 Jun 2013 15:39:21 -0300 Subject: Don't autostart EIP if the user explicitly stops the service --- src/leap/gui/mainwindow.py | 1 + 1 file changed, 1 insertion(+) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index e135c798..381dbf19 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -1012,6 +1012,7 @@ class MainWindow(QtGui.QMainWindow): self._action_eip_startstop.triggered.connect( self._start_eip) self._already_started_eip = False + self._settings.set_defaultprovider(None) def _get_best_provider_config(self): """ -- cgit v1.2.3 From cfd60d6e47a351e1ce52709a497e5a0b03319dcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Thu, 13 Jun 2013 15:14:15 -0300 Subject: Refactor the status bits out of the MainWindow to StatusPanelWidget --- src/leap/gui/mainwindow.py | 238 +++++++++++++++------------------------------ 1 file changed, 81 insertions(+), 157 deletions(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index e135c798..67fe34e3 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -38,14 +38,15 @@ from leap.crypto.srpauth import SRPAuth from leap.gui.loggerwindow import LoggerWindow from leap.gui.wizard import Wizard from leap.gui.login import LoginWidget +from leap.gui.statuspanel import StatusPanelWidget from leap.services.eip.eipbootstrapper import EIPBootstrapper from leap.services.eip.eipconfig import EIPConfig from leap.services.eip.providerbootstrapper import ProviderBootstrapper from leap.services.soledad.soledadbootstrapper import SoledadBootstrapper from leap.services.mail.smtpbootstrapper import SMTPBootstrapper -from leap.platform_init import IS_MAC, IS_WIN +from leap.platform_init import IS_WIN from leap.platform_init.initializers import init_platform -from leap.services.eip.vpnprocess import VPN, VPNManager +from leap.services.eip.vpnprocess import VPN from leap.services.eip.vpnlaunchers import (VPNLauncherException, OpenVPNNotFoundException, @@ -115,24 +116,6 @@ class MainWindow(QtGui.QMainWindow): self._updates_content = "" - if IS_MAC: - EIP_ICONS = ( - ":/images/conn_connecting-light.png", - ":/images/conn_connected-light.png", - ":/images/conn_error-light.png") - else: - EIP_ICONS = ( - ":/images/conn_connecting.png", - ":/images/conn_connected.png", - ":/images/conn_error.png") - - self.CONNECTING_ICON = QtGui.QPixmap(EIP_ICONS[0]) - self.CONNECTED_ICON = QtGui.QPixmap(EIP_ICONS[1]) - self.ERROR_ICON = QtGui.QPixmap(EIP_ICONS[2]) - - self.LOGGED_OUT_ICON = QtGui.QPixmap(":/images/leap-gray-big.png") - self.LOGGED_IN_ICON = QtGui.QPixmap(":/images/leap-color-big.png") - self.ui = Ui_MainWindow() self.ui.setupUi(self) @@ -149,11 +132,14 @@ class MainWindow(QtGui.QMainWindow): self.ui.btnShowLog.clicked.connect(self._show_logger_window) + self._status_panel = StatusPanelWidget( + self.ui.stackedWidget.widget(self.EIP_STATUS_INDEX)) + self.ui.statusLayout.addWidget(self._status_panel) + self.ui.stackedWidget.setCurrentIndex(self.LOGIN_INDEX) - self.ui.btnEipStartStop.setEnabled(False) - self.ui.btnEipStartStop.clicked.connect( - self._start_eip) + self._status_panel.start_eip.connect(self._start_eip) + self._status_panel.stop_eip.connect(self._stop_eip) # This is loaded only once, there's a bug when doing that more # than once @@ -169,6 +155,7 @@ class MainWindow(QtGui.QMainWindow): # This is created once we have a valid provider config self._srp_auth = None + self._logged_user = None # This thread is always running, although it's quite # lightweight when it's done setting up provider @@ -209,8 +196,10 @@ class MainWindow(QtGui.QMainWindow): self._smtp_bootstrapped_stage) self._vpn = VPN() - self._vpn.qtsigs.state_changed.connect(self._update_vpn_state) - self._vpn.qtsigs.status_changed.connect(self._update_vpn_status) + self._vpn.qtsigs.state_changed.connect( + self._status_panel.update_vpn_state) + self._vpn.qtsigs.status_changed.connect( + self._status_panel.update_vpn_status) self._vpn.qtsigs.process_finished.connect( self._eip_finished) @@ -234,18 +223,14 @@ class MainWindow(QtGui.QMainWindow): self.tr("Encrypted internet is OFF"), self) self._action_eip_status.setEnabled(False) + + self._status_panel.set_action_eip_status( + self._action_eip_status) + self._action_eip_startstop = QtGui.QAction( - self.tr("Turn encryption ON"), self) + self.tr("Turn ON"), self) self._action_eip_startstop.triggered.connect( self._stop_eip) - self._action_eip_write = QtGui.QAction( - QtGui.QIcon(":/images/Arrow-Up-32.png"), - "%12.2f Kb" % (0.0,), self) - self._action_eip_write.setEnabled(False) - self._action_eip_read = QtGui.QAction( - QtGui.QIcon(":/images/Arrow-Down-32.png"), - "%12.2f Kb" % (0.0,), self) - self._action_eip_read.setEnabled(False) self._action_visible = QtGui.QAction(self.tr("Hide Main Window"), self) self._action_visible.triggered.connect(self._toggle_visible) @@ -527,10 +512,12 @@ class MainWindow(QtGui.QMainWindow): systrayMenu.addAction(self._action_eip_startstop) self._systray = QtGui.QSystemTrayIcon(self) self._systray.setContextMenu(systrayMenu) - self._systray.setIcon(QtGui.QIcon(self.ERROR_ICON)) + self._systray.setIcon(self._status_panel.ERROR_ICON) self._systray.setVisible(True) self._systray.activated.connect(self._tray_activated) + self._status_panel.set_systray(self._systray) + def _tray_activated(self, reason=None): """ SLOT @@ -662,18 +649,6 @@ class MainWindow(QtGui.QMainWindow): is_proper_provider = self._settings.get_properprovider() return not (has_provider_on_disk and is_proper_provider) - def _set_eip_status(self, status, error=False): - """ - Sets the status label at the VPN stage to status - - :param status: status message - :type status: str - """ - self._systray.setToolTip(status) - if error: - status = "%s" % (status,) - self.ui.lblEIPStatus.setText(status) - def _download_provider_config(self): """ Starts the bootstrapping sequence. It will download the @@ -812,6 +787,7 @@ class MainWindow(QtGui.QMainWindow): """ self._login_widget.set_status(message, error=not ok) if ok: + self._logged_user = self._login_widget.get_user() self.ui.action_sign_out.setEnabled(True) # We leave a bit of room for the user to see the # "Succeeded" message and then we switch to the EIP status @@ -826,6 +802,11 @@ class MainWindow(QtGui.QMainWindow): Changes the stackedWidget index to the EIP status one and triggers the eip bootstrapping """ + if not self._already_started_eip: + self._status_panel.set_provider( + "%s@%s" % (self._login_widget.get_user(), + self._provider_config.get_domain())) + self.ui.stackedWidget.setCurrentIndex(self.EIP_STATUS_INDEX) self._soledad_bootstrapper.run_soledad_setup_checks( @@ -883,13 +864,14 @@ class MainWindow(QtGui.QMainWindow): else: if self._enabled_services.count(self.MX_SERVICE) > 0: pass # TODO: show MX status - #self._set_eip_status( + #self._status_panel.set_eip_status( # self.tr("%s does not support MX") % # (self._provider_config.get_domain(),), # error=True) else: pass # TODO: show MX status - #self._set_eip_status(self.tr("MX is disabled")) + #self._status_panel.set_eip_status( + # self.tr("MX is disabled")) def _smtp_bootstrapped_stage(self, data): """ @@ -969,45 +951,55 @@ class MainWindow(QtGui.QMainWindow): self._settings.set_defaultprovider( provider_config.get_domain()) + + provider = self._provider_config.get_domain() + if self._logged_user is not None: + provider = "%s@%s" % (self._logged_user, provider) + + self._status_panel.set_provider(provider) + self._action_eip_provider.setText(provider_config.get_domain()) - self.ui.btnEipStartStop.setText(self.tr("Turn Encryption OFF")) - self.ui.btnEipStartStop.disconnect(self) - self.ui.btnEipStartStop.clicked.connect( - self._stop_eip) - self._action_eip_startstop.setText(self.tr("Turn Encryption OFF")) + + self._status_panel.eip_started() + + self._action_eip_startstop.setText(self.tr("Turn OFF")) self._action_eip_startstop.disconnect(self) self._action_eip_startstop.triggered.connect( self._stop_eip) except EIPNoPolkitAuthAgentAvailable: - self._set_eip_status(self.tr("We could not find any " - "authentication " - "agent in your system.
" - "Make sure you have " - "polkit-gnome-authentication-" - "agent-1 " - "running and try again."), - error=True) + self._status_panel.set_eip_status( + self.tr("We could not find any " + "authentication " + "agent in your system.
" + "Make sure you have " + "polkit-gnome-authentication-" + "agent-1 " + "running and try again."), + error=True) except EIPNoPkexecAvailable: - self._set_eip_status(self.tr("We could not find pkexec " - "in your system."), - error=True) + self._status_panel.set_eip_status( + self.tr("We could not find pkexec " + "in your system."), + error=True) except OpenVPNNotFoundException: - self._set_eip_status(self.tr("We couldn't find openvpn"), - error=True) + self._status_panel.set_eip_status( + self.tr("We couldn't find openvpn"), + error=True) except VPNLauncherException as e: - self._set_eip_status("%s" % (e,), error=True) + self._status_panel.set_eip_status("%s" % (e,), error=True) + else: + self._already_started_eip = True - self.ui.btnEipStartStop.setEnabled(True) + self._status_panel.set_startstop_enabled(True) def _stop_eip(self): self._vpn.terminate() - self._set_eip_status(self.tr("EIP has stopped")) - self._set_eip_status_icon("error") - self.ui.btnEipStartStop.setText(self.tr("Turn Encryption ON")) - self.ui.btnEipStartStop.disconnect(self) - self.ui.btnEipStartStop.clicked.connect( - self._start_eip) - self._action_eip_startstop.setText(self.tr("Turn Encryption ON")) + self._status_panel.set_eip_status(self.tr("Off")) + self._status_panel.set_eip_status_icon("error") + + self._status_panel.eip_stopped() + + self._action_eip_startstop.setText(self.tr("Turn ON")) self._action_eip_startstop.disconnect(self) self._action_eip_startstop.triggered.connect( self._start_eip) @@ -1048,92 +1040,21 @@ class MainWindow(QtGui.QMainWindow): self._enabled_services.count(self.OPENVPN_SERVICE) > 0 and \ not self._already_started_eip: - self._set_eip_status( - self.tr("Checking configuration, please wait...")) + self._status_panel.set_eip_status( + self.tr("Starting...")) self._eip_bootstrapper.run_eip_setup_checks( provider_config, download_if_needed=True) self._already_started_eip = True elif not self._already_started_eip: if self._enabled_services.count(self.OPENVPN_SERVICE) > 0: - self._set_eip_status(self.tr("%s does not support EIP") % - (provider_config.get_domain(),), - error=True) + self._status_panel.set_eip_status( + self.tr("Not supported"), + error=True) else: - self._set_eip_status(self.tr("EIP is disabled")) + self._status_panel.set_eip_status(self.tr("Disabled")) self.ui.btnEipStartStop.setEnabled(False) - def _set_eip_status_icon(self, status): - """ - Given a status step from the VPN thread, set the icon properly - - :param status: status step - :type status: str - """ - selected_pixmap = self.ERROR_ICON - tray_message = self.tr("Encryption is OFF") - if status in ("WAIT", "AUTH", "GET_CONFIG", - "RECONNECTING", "ASSIGN_IP"): - selected_pixmap = self.CONNECTING_ICON - tray_message = self.tr("Turning Encryption ON") - elif status in ("CONNECTED"): - tray_message = self.tr("Encryption is ON") - selected_pixmap = self.CONNECTED_ICON - - self.ui.lblVPNStatusIcon.setPixmap(selected_pixmap) - self._systray.setIcon(QtGui.QIcon(selected_pixmap)) - self._action_eip_status.setText(tray_message) - - def _update_vpn_state(self, data): - """ - SLOT - TRIGGER: self._vpn.state_changed - - Updates the displayed VPN state based on the data provided by - the VPN thread - """ - status = data[VPNManager.STATUS_STEP_KEY] - self._set_eip_status_icon(status) - if status == "AUTH": - self._set_eip_status(self.tr("VPN: Authenticating...")) - elif status == "GET_CONFIG": - self._set_eip_status(self.tr("VPN: Retrieving configuration...")) - elif status == "CONNECTED": - self._set_eip_status(self.tr("VPN: Connected!")) - elif status == "WAIT": - self._set_eip_status(self.tr("VPN: Waiting to start...")) - elif status == "ASSIGN_IP": - self._set_eip_status(self.tr("VPN: Assigning IP")) - elif status == "ALREADYRUNNING": - # Put the following calls in Qt's event queue, otherwise - # the UI won't update properly - QtCore.QTimer.singleShot(0, self._stop_eip) - QtCore.QTimer.singleShot(0, partial(self._set_eip_status, - self.tr("Unable to start VPN, " - "it's already " - "running."))) - else: - self._set_eip_status(status) - - def _update_vpn_status(self, data): - """ - SLOT - TRIGGER: self._vpn.status_changed - - Updates the download/upload labels based on the data provided - by the VPN thread - """ - upload = float(data[VPNManager.TUNTAP_WRITE_KEY]) - upload = upload / 1000.0 - upload_str = "%12.2f Kb" % (upload,) - self.ui.lblUpload.setText(upload_str) - self._action_eip_write.setText(upload_str) - download = float(data[VPNManager.TUNTAP_READ_KEY]) - download = download / 1000.0 - download_str = "%12.2f Kb" % (download,) - self.ui.lblDownload.setText(download_str) - self._action_eip_read.setText(download_str) - def _finish_eip_bootstrap(self, data): """ SLOT @@ -1157,11 +1078,13 @@ class MainWindow(QtGui.QMainWindow): self._start_eip() else: if data[self._eip_bootstrapper.PASSED_KEY]: - self._set_eip_status(self.tr("Could not load EIP " - "Configuration"), error=True) + self._status_panel.set_eip_status( + self.tr("Could not load EIP Configuration"), + error=True) else: - self._set_eip_status(data[self._eip_bootstrapper.ERROR_KEY], - error=True) + self._status_panel.set_eip_status( + data[self._eip_bootstrapper.ERROR_KEY], + error=True) self._already_started_eip = False def _logout(self): @@ -1183,6 +1106,7 @@ class MainWindow(QtGui.QMainWindow): Switches the stackedWidget back to the login stage after logging out """ + self._logged_user = None self.ui.action_sign_out.setEnabled(False) self.ui.stackedWidget.setCurrentIndex(self.LOGIN_INDEX) self._login_widget.set_password("") -- cgit v1.2.3 From c752f90f2e242b96a6a63aa56466d22d8db8ceb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Thu, 13 Jun 2013 16:16:47 -0300 Subject: Always use best provider config Also, set the expected user@provider after stopping EIP, in case it was automatically started with another provider --- src/leap/gui/mainwindow.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 67fe34e3..aa9154e2 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -805,7 +805,7 @@ class MainWindow(QtGui.QMainWindow): if not self._already_started_eip: self._status_panel.set_provider( "%s@%s" % (self._login_widget.get_user(), - self._provider_config.get_domain())) + self._get_best_provider_config().get_domain())) self.ui.stackedWidget.setCurrentIndex(self.EIP_STATUS_INDEX) @@ -952,7 +952,7 @@ class MainWindow(QtGui.QMainWindow): self._settings.set_defaultprovider( provider_config.get_domain()) - provider = self._provider_config.get_domain() + provider = provider_config.get_domain() if self._logged_user is not None: provider = "%s@%s" % (self._logged_user, provider) @@ -1005,6 +1005,11 @@ class MainWindow(QtGui.QMainWindow): self._start_eip) self._already_started_eip = False + if self._logged_user: + self._status_panel.set_provider( + "%s@%s" % (self._logged_user, + self._get_best_provider_config().get_domain())) + def _get_best_provider_config(self): """ Returns the best ProviderConfig to use at a moment. We may -- cgit v1.2.3 From d8ccb2845ec34d0d00ef5c1799822da7c1281bea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Fri, 14 Jun 2013 10:49:41 -0300 Subject: Fix wrong set_status call after refactor --- src/leap/gui/mainwindow.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 90e74823..a5905679 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -1150,7 +1150,8 @@ class MainWindow(QtGui.QMainWindow): """ passed = data[self._provider_bootstrapper.PASSED_KEY] if not passed: - self._set_status(data[self._provider_bootstrapper.ERROR_KEY]) + self._login_widget.set_status( + data[self._provider_bootstrapper.ERROR_KEY]) self._already_started_eip = False def _eip_finished(self, exitCode): -- cgit v1.2.3 From 699eb99b1092335ee681dacdc06e6bf9c89827ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Fri, 14 Jun 2013 11:19:50 -0300 Subject: Make both clicks behave the same in the systray --- src/leap/gui/mainwindow.py | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 90e74823..c58cd4e3 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -529,18 +529,17 @@ class MainWindow(QtGui.QMainWindow): self.tr("Show Main Window"), self.tr("Hide Main Window"))[int(visible)] - if reason != QtGui.QSystemTrayIcon.Context: - # set labels - visible = self.isVisible() - self._action_visible.setText(get_action(visible)) - - context_menu = self._systray.contextMenu() - # for some reason, context_menu.show() - # is failing in a way beyond my understanding. - # (not working the first time it's clicked). - # this works however. - # XXX in osx it shows some glitches. - context_menu.exec_(self._systray.geometry().center()) + # set labels + visible = self.isVisible() + self._action_visible.setText(get_action(visible)) + + context_menu = self._systray.contextMenu() + # for some reason, context_menu.show() + # is failing in a way beyond my understanding. + # (not working the first time it's clicked). + # this works however. + # XXX in osx it shows some glitches. + context_menu.exec_(self._systray.geometry().center()) def _toggle_visible(self): """ -- cgit v1.2.3 From 4494b396385d1f9f84a43201cf25c3afd87a823d Mon Sep 17 00:00:00 2001 From: kali Date: Fri, 14 Jun 2013 04:06:43 +0900 Subject: disable soledad bootstrapper --- src/leap/gui/mainwindow.py | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index a5905679..42148836 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -185,11 +185,11 @@ class MainWindow(QtGui.QMainWindow): self._eip_bootstrapper.download_client_certificate.connect( self._finish_eip_bootstrap) - self._soledad_bootstrapper = SoledadBootstrapper() - self._soledad_bootstrapper.download_config.connect( - self._soledad_intermediate_stage) - self._soledad_bootstrapper.gen_key.connect( - self._soledad_bootstrapped_stage) + #self._soledad_bootstrapper = SoledadBootstrapper() + #self._soledad_bootstrapper.download_config.connect( + #self._soledad_intermediate_stage) + #self._soledad_bootstrapper.gen_key.connect( + #self._soledad_bootstrapped_stage) self._smtp_bootstrapper = SMTPBootstrapper() self._smtp_bootstrapper.download_config.connect( @@ -809,11 +809,12 @@ class MainWindow(QtGui.QMainWindow): self.ui.stackedWidget.setCurrentIndex(self.EIP_STATUS_INDEX) - self._soledad_bootstrapper.run_soledad_setup_checks( - self._provider_config, - self._login_widget.get_user(), - self._login_widget.get_password(), - download_if_needed=True) + # XXX disabling soledad for now + #self._soledad_bootstrapper.run_soledad_setup_checks( + #self._provider_config, + #self._login_widget.get_user(), + #self._login_widget.get_password(), + #download_if_needed=True) self._download_eip_config() -- cgit v1.2.3 From fdda95c92d22b4ede61bfb7587320ddb36da5cd7 Mon Sep 17 00:00:00 2001 From: kali Date: Sat, 15 Jun 2013 01:17:35 +0900 Subject: working openvpn termination: SIGTERM, then SIGKILL. Closes: #2753 --- src/leap/gui/mainwindow.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 42148836..dd9fb148 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -994,19 +994,21 @@ class MainWindow(QtGui.QMainWindow): self._status_panel.set_startstop_enabled(True) def _stop_eip(self): + """ + Stops vpn process and makes gui adjustments to reflect + the change of state. + """ self._vpn.terminate() + self._status_panel.set_eip_status(self.tr("Off")) self._status_panel.set_eip_status_icon("error") - self._status_panel.eip_stopped() - self._action_eip_startstop.setText(self.tr("Turn ON")) self._action_eip_startstop.disconnect(self) self._action_eip_startstop.triggered.connect( self._start_eip) self._already_started_eip = False self._settings.set_defaultprovider(None) - if self._logged_user: self._status_panel.set_provider( "%s@%s" % (self._logged_user, @@ -1204,12 +1206,12 @@ class MainWindow(QtGui.QMainWindow): """ logger.debug('About to quit, doing cleanup...') - logger.debug('Killing vpn') - self._vpn.terminate() - logger.debug('Cleaning pidfiles') self._cleanup_pidfiles() + logger.debug('Terminating vpn') + self._vpn.terminate() + def quit(self): """ Cleanup and tidely close the main window before quitting. @@ -1223,13 +1225,14 @@ class MainWindow(QtGui.QMainWindow): if self._logger_window: self._logger_window.close() - self.close() - if self._login_defer: self._login_defer.cancel() + self.close() + if self._quit_callback: self._quit_callback() + logger.debug('Bye.') -- cgit v1.2.3 From 0f43f3db34dd0262e298dd4431b1e971c77dfbdd Mon Sep 17 00:00:00 2001 From: kali Date: Mon, 17 Jun 2013 05:37:04 +0900 Subject: Remove temporal folder during shutdown Closes: #2891 This is the temporal folder that is used under osx and linux for the unix socket to connect to the management interface. --- src/leap/gui/mainwindow.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 51b96463..9fd543bf 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -1209,7 +1209,7 @@ class MainWindow(QtGui.QMainWindow): self._cleanup_pidfiles() logger.debug('Terminating vpn') - self._vpn.terminate() + self._vpn.terminate(shutdown=True) def quit(self): """ -- cgit v1.2.3 From 1d23bb2d8f5715031bc45f506ac32ce2afa5bfce Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Tue, 18 Jun 2013 13:03:10 -0300 Subject: Close the app on rejected wizard. Closes bug #2905 --- src/leap/gui/mainwindow.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 51b96463..bf6aefe9 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -299,9 +299,12 @@ class MainWindow(QtGui.QMainWindow): """ if self._wizard is None: self._wizard = Wizard(bypass_checks=self._bypass_checks) - self._wizard.accepted.connect(self._finish_init) + self._wizard.accepted.connect(self._finish_init) + self.setVisible(False) self._wizard.exec_() + # We need this to process any wizard related event + QtCore.QCoreApplication.processEvents() self._wizard = None self.setVisible(True) -- cgit v1.2.3 From 22afa7da7befa83f23eb039418edb39b0f5c2856 Mon Sep 17 00:00:00 2001 From: kali Date: Sat, 15 Jun 2013 23:43:50 +0900 Subject: Improve labels in the app * Clarify use of EIP * Closes #2695 --- src/leap/gui/mainwindow.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 51b96463..d5979395 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -474,8 +474,8 @@ class MainWindow(QtGui.QMainWindow): default_provider = self._settings.get_defaultprovider() if default_provider is None: - logger.info("Cannot autostart EIP because there's no default " - "provider configured") + logger.info("Cannot autostart Encrypted Internet because there is " + "no default provider configured") return self._action_eip_provider.setText(default_provider) @@ -983,7 +983,7 @@ class MainWindow(QtGui.QMainWindow): error=True) except OpenVPNNotFoundException: self._status_panel.set_eip_status( - self.tr("We couldn't find openvpn"), + self.tr("We couldn't find openvpn binary"), error=True) except VPNLauncherException as e: self._status_panel.set_eip_status("%s" % (e,), error=True) @@ -1087,7 +1087,7 @@ class MainWindow(QtGui.QMainWindow): else: if data[self._eip_bootstrapper.PASSED_KEY]: self._status_panel.set_eip_status( - self.tr("Could not load EIP Configuration"), + self.tr("Could not load Encrypted Internet Configuration"), error=True) else: self._status_panel.set_eip_status( -- cgit v1.2.3 From e699db4377d1b79c0c48eb3c753d373e44cceb13 Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Wed, 19 Jun 2013 14:53:00 -0300 Subject: Comment out soledad temporarily. Closes #2932. --- src/leap/gui/mainwindow.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index cf20c6eb..a5d022e9 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -42,7 +42,8 @@ from leap.gui.statuspanel import StatusPanelWidget from leap.services.eip.eipbootstrapper import EIPBootstrapper from leap.services.eip.eipconfig import EIPConfig from leap.services.eip.providerbootstrapper import ProviderBootstrapper -from leap.services.soledad.soledadbootstrapper import SoledadBootstrapper +# XXX: comment out soledad temporarily to avoid problem in Windows, issue #2932 +# from leap.services.soledad.soledadbootstrapper import SoledadBootstrapper from leap.services.mail.smtpbootstrapper import SMTPBootstrapper from leap.platform_init import IS_WIN from leap.platform_init.initializers import init_platform -- cgit v1.2.3 From 6cb47a3627286dc64f781b5412ec66b6ab92560c Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Thu, 20 Jun 2013 07:57:51 +0900 Subject: do not apply systray menu workaround for osx Closes: #2920 --- src/leap/gui/mainwindow.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index a5d022e9..a3c601c5 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -39,6 +39,7 @@ from leap.gui.loggerwindow import LoggerWindow from leap.gui.wizard import Wizard from leap.gui.login import LoginWidget from leap.gui.statuspanel import StatusPanelWidget +from leap.platform_init import IS_MAC from leap.services.eip.eipbootstrapper import EIPBootstrapper from leap.services.eip.eipconfig import EIPConfig from leap.services.eip.providerbootstrapper import ProviderBootstrapper @@ -538,12 +539,12 @@ class MainWindow(QtGui.QMainWindow): self._action_visible.setText(get_action(visible)) context_menu = self._systray.contextMenu() - # for some reason, context_menu.show() - # is failing in a way beyond my understanding. - # (not working the first time it's clicked). - # this works however. - # XXX in osx it shows some glitches. - context_menu.exec_(self._systray.geometry().center()) + if not IS_MAC: + # for some reason, context_menu.show() + # is failing in a way beyond my understanding. + # (not working the first time it's clicked). + # this works however. + context_menu.exec_(self._systray.geometry().center()) def _toggle_visible(self): """ -- cgit v1.2.3 From 4a422c92ae83453807074afca6c2f038823e296f Mon Sep 17 00:00:00 2001 From: kali Date: Thu, 20 Jun 2013 10:26:46 +0900 Subject: hide mx until we integrate it Closes: #2938 --- src/leap/gui/mainwindow.py | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index a5d022e9..42ee5418 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -109,10 +109,14 @@ class MainWindow(QtGui.QMainWindow): QtGui.QMainWindow.__init__(self) # register leap events + + # XXX ------- this is blocking ----------- register(signal=proto.UPDATER_NEW_UPDATES, callback=self._new_updates_available) register(signal=proto.RAISE_WINDOW, callback=self._on_raise_window_event) + # XXX ------- this is blocking ----------- + self._quit_callback = quit_callback self._updates_content = "" -- cgit v1.2.3 From 440f2036e36985e9536644b28af0e62cea8704eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Fri, 21 Jun 2013 15:31:24 -0300 Subject: Disable remembering when not using a proper keyring backend --- src/leap/gui/mainwindow.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 2ed01917..9dc1e006 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -55,6 +55,7 @@ from leap.services.eip.vpnlaunchers import (VPNLauncherException, EIPNoPkexecAvailable, EIPNoPolkitAuthAgentAvailable) from leap.util import __version__ as VERSION +from leap.util.keyring_helpers import has_keyring from leap.services.mail.smtpconfig import SMTPConfig @@ -435,7 +436,7 @@ class MainWindow(QtGui.QMainWindow): self._login_widget.set_user(possible_username) if possible_password is not None: self._login_widget.set_password(possible_password) - self._login_widget.set_remember(True) + self._login_widget.set_remember(has_keyring()) self._login() self._wizard = None self._settings.set_properprovider(True) @@ -454,7 +455,7 @@ class MainWindow(QtGui.QMainWindow): logger.error('Username@provider malformed. %r' % (e, )) saved_user = None - if saved_user is not None: + if saved_user is not None and has_keyring(): # fill the username self._login_widget.set_user(username) @@ -740,7 +741,7 @@ class MainWindow(QtGui.QMainWindow): self._login_widget.set_status(self.tr("Logging in..."), error=False) self._login_widget.set_enabled(False) - if self._login_widget.get_remember(): + if self._login_widget.get_remember() and has_keyring(): # in the keyring and in the settings # we store the value 'usename@provider' username_domain = (username + '@' + provider).encode("utf8") -- cgit v1.2.3 From 63bc283c90a80ddc030e24fcc38c533b1e7c551d Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Mon, 24 Jun 2013 02:21:34 +0900 Subject: let errors go in their own panel --- src/leap/gui/mainwindow.py | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 9dc1e006..b0bf8a44 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -695,7 +695,7 @@ class MainWindow(QtGui.QMainWindow): download_if_needed=True) else: self._login_widget.set_status( - self.tr("Could not load provider configuration")) + self.tr("Could not load provider configuration.")) self._login_widget.set_enabled(True) else: self._login_widget.set_status( @@ -950,6 +950,7 @@ class MainWindow(QtGui.QMainWindow): Starts EIP """ + self._status_panel.eip_pre_up() provider_config = self._get_best_provider_config() try: @@ -977,7 +978,9 @@ class MainWindow(QtGui.QMainWindow): self._action_eip_startstop.triggered.connect( self._stop_eip) except EIPNoPolkitAuthAgentAvailable: - self._status_panel.set_eip_status( + self._status_panel.set_global_status( + # XXX this should change to polkit-kde where + # applicable. self.tr("We could not find any " "authentication " "agent in your system.
" @@ -986,20 +989,31 @@ class MainWindow(QtGui.QMainWindow): "agent-1 " "running and try again."), error=True) + self._set_eipstatus_off() except EIPNoPkexecAvailable: - self._status_panel.set_eip_status( + self._status_panel.set_global_status( self.tr("We could not find pkexec " "in your system."), error=True) + self._set_eipstatus_off() except OpenVPNNotFoundException: - self._status_panel.set_eip_status( - self.tr("We couldn't find openvpn binary"), + self._status_panel.set_global_status( + self.tr("We could not find openvpn binary."), error=True) + self._set_eipstatus_off() except VPNLauncherException as e: - self._status_panel.set_eip_status("%s" % (e,), error=True) + self._status_panel.set_gloal_status("%s" % (e,), error=True) + self._set_eipstatus_off() else: self._already_started_eip = True + #self._status_panel.set_startstop_enabled(True) + + def _set_eipstatus_off(self): + """ + Sets eip status to off + """ + self._status_panel.set_eip_status(self.tr("OFF"), error=True) self._status_panel.set_startstop_enabled(True) def _stop_eip(self): @@ -1009,7 +1023,7 @@ class MainWindow(QtGui.QMainWindow): """ self._vpn.terminate() - self._status_panel.set_eip_status(self.tr("Off")) + self._status_panel.set_eip_status(self.tr("OFF")) self._status_panel.set_eip_status_icon("error") self._status_panel.eip_stopped() self._action_eip_startstop.setText(self.tr("Turn ON")) @@ -1042,7 +1056,7 @@ class MainWindow(QtGui.QMainWindow): elif self._provisional_provider_config.loaded(): provider_config = self._provisional_provider_config else: - leap_assert(False, "We couldn't find any usable ProviderConfig") + leap_assert(False, "We could not find any usable ProviderConfig.") return provider_config @@ -1097,7 +1111,8 @@ class MainWindow(QtGui.QMainWindow): else: if data[self._eip_bootstrapper.PASSED_KEY]: self._status_panel.set_eip_status( - self.tr("Could not load Encrypted Internet Configuration"), + self.tr("Could not load Encrypted Internet " + "Configuration."), error=True) else: self._status_panel.set_eip_status( -- cgit v1.2.3 From 19c90e02a65d1d6fe30e6915cd2a9440878aef83 Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Mon, 24 Jun 2013 02:57:26 +0900 Subject: Improve OpenVPN Process Control * Disable toggle button until we get "connected" status. #2956 * Catch abnormal termination and update UI accordingly. #2890 --- src/leap/gui/mainwindow.py | 54 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 48 insertions(+), 6 deletions(-) (limited to 'src/leap/gui/mainwindow.py') diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index b0bf8a44..94343292 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -90,6 +90,9 @@ class MainWindow(QtGui.QMainWindow): new_updates = QtCore.Signal(object) raise_window = QtCore.Signal([]) + # We use this flag to detect abnormal terminations + user_stopped_eip = False + def __init__(self, quit_callback, standalone=False, bypass_checks=False): """ @@ -951,6 +954,7 @@ class MainWindow(QtGui.QMainWindow): Starts EIP """ self._status_panel.eip_pre_up() + self.user_stopped_eip = False provider_config = self._get_best_provider_config() try: @@ -1007,8 +1011,6 @@ class MainWindow(QtGui.QMainWindow): else: self._already_started_eip = True - #self._status_panel.set_startstop_enabled(True) - def _set_eipstatus_off(self): """ Sets eip status to off @@ -1016,11 +1018,16 @@ class MainWindow(QtGui.QMainWindow): self._status_panel.set_eip_status(self.tr("OFF"), error=True) self._status_panel.set_startstop_enabled(True) - def _stop_eip(self): + def _stop_eip(self, abnormal=False): """ Stops vpn process and makes gui adjustments to reflect the change of state. + + :param abnormal: whether this was an abnormal termination. + :type abnormal: bool + "" """ + self.user_stopped_eip = True self._vpn.terminate() self._status_panel.set_eip_status(self.tr("OFF")) @@ -1036,6 +1043,8 @@ class MainWindow(QtGui.QMainWindow): self._status_panel.set_provider( "%s@%s" % (self._logged_user, self._get_best_provider_config().get_domain())) + if abnormal: + self._status_panel.set_startstop_enabled(True) def _get_best_provider_config(self): """ @@ -1188,10 +1197,43 @@ class MainWindow(QtGui.QMainWindow): self._vpn.process_finished Triggered when the EIP/VPN process finishes to set the UI - accordingly + accordingly. """ - logger.debug("Finished VPN with exitCode %s" % (exitCode,)) - self._stop_eip() + logger.info("VPN process finished with exitCode %s..." + % (exitCode,)) + + # Ideally we would have the right exit code here, + # but the use of different wrappers (pkexec, cocoasudo) swallows + # the openvpn exit code so we get zero exit in some cases where we + # shouldn't. As a workaround we just use a flag to indicate + # a purposeful switch off, and mark everything else as unexpected. + + # In the near future we should trigger a native notification from here, + # since the user really really wants to know she is unprotected asap. + # And the right thing to do will be to fail-close. + + # TODO we should have a way of parsing the latest lines in the vpn + # log buffer so we can have a more precise idea of which type + # of error did we have (server side, local problem, etc) + abnormal = True + + # XXX check if these exitCodes are pkexec/cocoasudo specific + if exitCode in (126, 127): + self._status_panel.set_global_status( + self.tr("Encrypted Internet could not be launched " + "because you did not authenticate properly."), + error=True) + self._vpn.killit() + elif exitCode != 0 or not self.user_stopped_eip: + self._status_panel.set_global_status( + self.tr("Encrypted Internet finished in an " + "unexpected manner!"), error=True) + else: + abnormal = False + if exitCode == 0: + # XXX remove this warning after I fix cocoasudo. + logger.warning("The above exit code MIGHT BE WRONG.") + self._stop_eip(abnormal) def _on_raise_window_event(self, req): """ -- cgit v1.2.3