From 8cce83844448a83ab03cb8a3a04320547e024d06 Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Tue, 27 Aug 2013 09:52:53 -0300 Subject: Move configured providers getter to LeapSettings. --- src/leap/bitmask/config/leapsettings.py | 29 ++++++++++++++++++++++++----- src/leap/bitmask/gui/mainwindow.py | 27 ++++----------------------- 2 files changed, 28 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/leap/bitmask/config/leapsettings.py b/src/leap/bitmask/config/leapsettings.py index 35010280..6aab84e4 100644 --- a/src/leap/bitmask/config/leapsettings.py +++ b/src/leap/bitmask/config/leapsettings.py @@ -75,11 +75,10 @@ class LeapSettings(object): the config :type standalone: bool """ - - settings_path = os.path.join(get_platform_prefixer() - .get_path_prefix(standalone=standalone), - "leap", - self.CONFIG_NAME) + self._path_prefix = get_platform_prefixer().get_path_prefix( + standalone=standalone) + settings_path = os.path.join( + self._path_prefix, "leap", self.CONFIG_NAME) self._settings = QtCore.QSettings(settings_path, QtCore.QSettings.IniFormat) @@ -119,6 +118,26 @@ class LeapSettings(object): leap_assert(windowstate, "We need a window state") self._settings.setValue(self.WINDOWSTATE_KEY, windowstate) + def get_configured_providers(self): + """ + Returns the configured providers based on the file structure in the + settings directory. + + :rtype: list of str + """ + # TODO: check which providers have a valid certificate among + # other things, not just the directories + providers = [] + try: + providers_path = os.path.join( + self._path_prefix, "leap", "providers") + providers = os.listdir(providers_path) + except Exception as e: + logger.debug("Error listing providers, assume there are none. %r" + % (e,)) + + return providers + def get_enabled_services(self, provider): """ Returns a list of enabled services for the given provider diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py index c832887a..7b9d492e 100644 --- a/src/leap/bitmask/gui/mainwindow.py +++ b/src/leap/bitmask/gui/mainwindow.py @@ -491,7 +491,8 @@ class MainWindow(QtGui.QMainWindow): """ # XXX: May be this can be divided into two methods? - self._login_widget.set_providers(self._configured_providers()) + providers = self._settings.get_configured_providers() + self._login_widget.set_providers(providers) self._show_systray() self.show() if IS_MAC: @@ -736,34 +737,14 @@ class MainWindow(QtGui.QMainWindow): QtGui.QMainWindow.closeEvent(self, e) - def _configured_providers(self): - """ - Returns the available providers based on the file structure - - :rtype: list - """ - - # TODO: check which providers have a valid certificate among - # other things, not just the directories - 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): """ Returns True if there are no configured providers. False otherwise :rtype: bool """ - has_provider_on_disk = len(self._configured_providers()) != 0 + providers = self._settings.get_configured_providers() + has_provider_on_disk = len(providers) != 0 is_proper_provider = self._settings.get_properprovider() return not (has_provider_on_disk and is_proper_provider) -- cgit v1.2.3 From 956330af5a67922e7710e7c4817de8fc15fab5ac Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Tue, 27 Aug 2013 11:05:00 -0300 Subject: Remove key for a provider with no enabled services --- src/leap/bitmask/config/leapsettings.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/leap/bitmask/config/leapsettings.py b/src/leap/bitmask/config/leapsettings.py index 6aab84e4..c1fabd9c 100644 --- a/src/leap/bitmask/config/leapsettings.py +++ b/src/leap/bitmask/config/leapsettings.py @@ -170,8 +170,12 @@ class LeapSettings(object): leap_assert(len(provider) > 0, "We need a nonempty provider") leap_assert_type(services, list) - self._settings.setValue("%s/Services" % (provider,), - services) + key = "{0}/Services".format(provider) + if not services: + # if there are no enabled services we don't need that key + self._settings.remove(key) + else: + self._settings.setValue(key, services) def get_user(self): """ -- cgit v1.2.3 From 45796e0256e3a57e506d6db8c2bde62a510ae6ae Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Mon, 26 Aug 2013 17:47:01 -0300 Subject: Preferences: select enabled services for providers --- src/leap/bitmask/gui/mainwindow.py | 11 +- src/leap/bitmask/gui/preferenceswindow.py | 165 +++++++++++++++++++++++++++++- src/leap/bitmask/gui/ui/mainwindow.ui | 2 +- src/leap/bitmask/gui/ui/preferences.ui | 78 ++++++++++++-- 4 files changed, 236 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py index 7b9d492e..34451928 100644 --- a/src/leap/bitmask/gui/mainwindow.py +++ b/src/leap/bitmask/gui/mainwindow.py @@ -288,17 +288,12 @@ class MainWindow(QtGui.QMainWindow): ################################# end Qt Signals connection ######## - # Enable the password change when soledad is ready - self.soledad_ready.connect( - partial(self.ui.btnPreferences.setEnabled, True)) - init_platform() self._wizard = None self._wizard_firstrun = False self._logger_window = None - self._preferences_window = None self._bypass_checks = bypass_checks @@ -419,7 +414,11 @@ class MainWindow(QtGui.QMainWindow): Displays the preferences window. """ - PreferencesWindow(self, self._srp_auth, self._soledad).show() + preferences_window = PreferencesWindow( + self, self._srp_auth, self._soledad, + self._settings, self._standalone) + + preferences_window.show() def _uncheck_logger_button(self): """ diff --git a/src/leap/bitmask/gui/preferenceswindow.py b/src/leap/bitmask/gui/preferenceswindow.py index a8220e86..f580e703 100644 --- a/src/leap/bitmask/gui/preferenceswindow.py +++ b/src/leap/bitmask/gui/preferenceswindow.py @@ -18,15 +18,18 @@ """ Preferences window """ +import os import logging from functools import partial -from PySide import QtGui +from PySide import QtCore, QtGui from leap.bitmask.gui.ui_preferences import Ui_Preferences from leap.soledad.client import NoStorageSecret from leap.bitmask.crypto.srpauth import SRPAuthBadPassword from leap.bitmask.util.password import basic_password_checks +from leap.bitmask.services import get_supported +from leap.bitmask.config.providerconfig import ProviderConfig logger = logging.getLogger(__name__) @@ -38,7 +41,7 @@ class PreferencesWindow(QtGui.QDialog): WEAK_PASSWORDS = ("123456", "qweasd", "qwerty", "password") - def __init__(self, parent, srp_auth, soledad): + def __init__(self, parent, srp_auth, soledad, leap_settings): """ :param parent: parent object of the PreferencesWindow. :parent type: QWidget @@ -51,14 +54,51 @@ class PreferencesWindow(QtGui.QDialog): self._srp_auth = srp_auth self._soledad = soledad + self._settings = leap_settings # Load UI self.ui = Ui_Preferences() self.ui.setupUi(self) self.ui.lblPasswordChangeStatus.setVisible(False) + self.ui.lblProvidersServicesStatus.setVisible(False) + + # Correspondence for services and their name to display + EIP_LABEL = self.tr("Encrypted Internet") + MX_LABEL = self.tr("Encrypted Mail") + + self.SERVICE_DISPLAY = [ + EIP_LABEL, + MX_LABEL + ] + self.SERVICE_CONFIG = [ + "openvpn", + "mx" + ] + + self._selected_services = set() + self._provider_config = ProviderConfig() # Connections self.ui.pbChangePassword.clicked.connect(self._change_password) + self.ui.cbProvidersServices.currentIndexChanged[unicode].connect( + self._populate_services) + + parent.soledad_ready.connect(self._soledad_ready) + + if not self._settings.get_configured_providers(): + self.ui.gbEnabledServices.setEnabled(False) + else: + self._add_configured_providers() + + def _soledad_ready(self): + """ + SLOT + TRIGGERS: + parent.soledad_ready + It sets the soledad object as ready to use. + """ + self._soledad_ready = True + self.ui.gbPasswordChange.setEnabled(True) def _set_password_change_status(self, status, error=False, success=False): """ @@ -134,7 +174,7 @@ class PreferencesWindow(QtGui.QDialog): self._set_password_change_status( self.tr("Password changed successfully."), success=True) - self._clear_inputs() + self._clear_password_inputs() self._set_changing_password(False) def _change_password_problem(self, failure): @@ -156,10 +196,127 @@ class PreferencesWindow(QtGui.QDialog): self._set_changing_password(False) failure.trap(Exception) - def _clear_inputs(self): + def _clear_password_inputs(self): """ Clear the contents of the inputs. """ self.ui.leCurrentPassword.setText("") self.ui.leNewPassword.setText("") self.ui.leNewPassword2.setText("") + + def _set_providers_services_status(self, status, success=False): + """ + Sets the status label for the password change. + + :param status: status message to display, can be HTML + :type status: str + """ + if success: + status = "%s" % (status,) + + self.ui.lblProvidersServicesStatus.setVisible(True) + self.ui.lblProvidersServicesStatus.setText(status) + + def _add_configured_providers(self): + """ + Add the client's configured providers to the providers combo boxes. + """ + self.ui.cbProvidersServices.clear() + self.ui.cbProvidersGateway.clear() + for provider in self._settings.get_configured_providers(): + self.ui.cbProvidersServices.addItem(provider) + self.ui.cbProvidersGateway.addItem(provider) + + def _service_selection_changed(self, service, state): + """ + SLOT + TRIGGER: service_checkbox.stateChanged + Adds the service to the state if the state is checked, removes + it otherwise + + :param service: service to handle + :type service: str + :param state: state of the checkbox + :type state: int + """ + if state == QtCore.Qt.Checked: + self._selected_services = \ + self._selected_services.union(set([service])) + else: + self._selected_services = \ + self._selected_services.difference(set([service])) + + # We hide the maybe-visible status label after a change + self.ui.lblProvidersServicesStatus.setVisible(False) + + def _populate_services(self, domain): + """ + SLOT + TRIGGERS: + self.ui.cbProvidersServices.clicked + + Loads the services that the provider provides into the UI for + the user to enable or disable. + + :param domain: the domain of the provider to load services from. + :type domain: str + """ + # We hide the maybe-visible status label after a change + self.ui.lblProvidersServicesStatus.setVisible(False) + + provider_config_path = os.path.join( + "leap", "providers", domain, "provider.json") + + if not domain or not self._provider_config.load(provider_config_path): + return + + # set the proper connection for the 'save' button + try: + self.ui.pbSaveServices.clicked.disconnect() + except RuntimeError: + pass # Signal was not connected + + save_services = partial(self._save_enabled_services, domain) + self.ui.pbSaveServices.clicked.connect(save_services) + + services = get_supported(self._provider_config.get_services()) + services_conf = self._settings.get_enabled_services(domain) + + # discard changes if other provider is selected + self._selected_services = set() + + # from: http://stackoverflow.com/a/13103617/687989 + # remove existing checkboxes + layout = self.ui.vlServices + for i in reversed(range(layout.count())): + layout.itemAt(i).widget().setParent(None) + + # add one checkbox per service and set the current configured value + for service in services: + try: + checkbox = QtGui.QCheckBox(self) + service_index = self.SERVICE_CONFIG.index(service) + checkbox.setText(self.SERVICE_DISPLAY[service_index]) + self.ui.vlServices.addWidget(checkbox) + checkbox.stateChanged.connect( + partial(self._service_selection_changed, service)) + + checkbox.setChecked(service in services_conf) + except ValueError: + logger.error("Something went wrong while trying to " + "load service %s" % (service,)) + + def _save_enabled_services(self, provider): + """ + Saves the new settings to the configuration file. + + :param provider: the provider config that we need to save. + :type provider: str + """ + services = list(self._selected_services) + self._settings.set_enabled_services(provider, services) + + msg = self.tr( + "Services settings for provider '{0}' saved.".format(provider)) + logger.debug(msg) + self._set_providers_services_status(msg, success=True) diff --git a/src/leap/bitmask/gui/ui/mainwindow.ui b/src/leap/bitmask/gui/ui/mainwindow.ui index 834a562e..17837642 100644 --- a/src/leap/bitmask/gui/ui/mainwindow.ui +++ b/src/leap/bitmask/gui/ui/mainwindow.ui @@ -217,7 +217,7 @@ - false + true Preferences diff --git a/src/leap/bitmask/gui/ui/preferences.ui b/src/leap/bitmask/gui/ui/preferences.ui index 8c63ccad..b59990b1 100644 --- a/src/leap/bitmask/gui/ui/preferences.ui +++ b/src/leap/bitmask/gui/ui/preferences.ui @@ -6,8 +6,8 @@ 0 0 - 451 - 267 + 453 + 463 @@ -17,9 +17,12 @@ :/images/mask-icon.png:/images/mask-icon.png - - + + + + false + Password Change @@ -98,7 +101,64 @@ - + + + + Enabled services + + + + + + Save this provider settings + + + + + + + Services + + + false + + + + + + + + + + + + + <Select provider> + + + + + + + + Select provider: + + + + + + + < Providers Services Status > + + + Qt::AlignCenter + + + + + + + false @@ -116,12 +176,12 @@ &Select provider: - cbProviders + cbProvidersGateway - + <Select provider> @@ -137,7 +197,7 @@ - + Automatic @@ -148,7 +208,7 @@ - + Qt::Vertical -- cgit v1.2.3 From 39395c6c9ac3bc7011f5ac3fbe5da9605f36ed18 Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Tue, 27 Aug 2013 17:52:40 -0300 Subject: Refactor services display names out. Closes #3578. --- src/leap/bitmask/gui/preferenceswindow.py | 27 ++++++++++-------------- src/leap/bitmask/gui/wizard.py | 25 +++++----------------- src/leap/bitmask/services/__init__.py | 35 +++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 36 deletions(-) (limited to 'src') diff --git a/src/leap/bitmask/gui/preferenceswindow.py b/src/leap/bitmask/gui/preferenceswindow.py index f580e703..05f616b0 100644 --- a/src/leap/bitmask/gui/preferenceswindow.py +++ b/src/leap/bitmask/gui/preferenceswindow.py @@ -30,6 +30,7 @@ from leap.bitmask.crypto.srpauth import SRPAuthBadPassword from leap.bitmask.util.password import basic_password_checks from leap.bitmask.services import get_supported from leap.bitmask.config.providerconfig import ProviderConfig +from leap.bitmask.services import get_service_display_name logger = logging.getLogger(__name__) @@ -41,7 +42,7 @@ class PreferencesWindow(QtGui.QDialog): WEAK_PASSWORDS = ("123456", "qweasd", "qwerty", "password") - def __init__(self, parent, srp_auth, soledad, leap_settings): + def __init__(self, parent, srp_auth, soledad, leap_settings, standalone): """ :param parent: parent object of the PreferencesWindow. :parent type: QWidget @@ -49,12 +50,17 @@ class PreferencesWindow(QtGui.QDialog): :type srp_auth: SRPAuth :param soledad: Soledad object configured in the main app. :type soledad: Soledad + :param standalone: If True, the application is running as standalone + and the preferences dialog should display some + messages according to this. + :type standalone: bool """ QtGui.QDialog.__init__(self, parent) self._srp_auth = srp_auth self._soledad = soledad self._settings = leap_settings + self._standalone = standalone # Load UI self.ui = Ui_Preferences() @@ -62,19 +68,6 @@ class PreferencesWindow(QtGui.QDialog): self.ui.lblPasswordChangeStatus.setVisible(False) self.ui.lblProvidersServicesStatus.setVisible(False) - # Correspondence for services and their name to display - EIP_LABEL = self.tr("Encrypted Internet") - MX_LABEL = self.tr("Encrypted Mail") - - self.SERVICE_DISPLAY = [ - EIP_LABEL, - MX_LABEL - ] - self.SERVICE_CONFIG = [ - "openvpn", - "mx" - ] - self._selected_services = set() self._provider_config = ProviderConfig() @@ -295,8 +288,10 @@ class PreferencesWindow(QtGui.QDialog): for service in services: try: checkbox = QtGui.QCheckBox(self) - service_index = self.SERVICE_CONFIG.index(service) - checkbox.setText(self.SERVICE_DISPLAY[service_index]) + service_label = get_service_display_name( + service, self._standalone) + checkbox.setText(service_label) + self.ui.vlServices.addWidget(checkbox) checkbox.stateChanged.connect( partial(self._service_selection_changed, service)) diff --git a/src/leap/bitmask/gui/wizard.py b/src/leap/bitmask/gui/wizard.py index e3f0085b..ac0f032f 100644 --- a/src/leap/bitmask/gui/wizard.py +++ b/src/leap/bitmask/gui/wizard.py @@ -34,7 +34,7 @@ from leap.bitmask.util.request_helpers import get_content from leap.bitmask.util.keyring_helpers import has_keyring from leap.bitmask.util.password import basic_password_checks from leap.bitmask.services.eip.providerbootstrapper import ProviderBootstrapper -from leap.bitmask.services import get_supported +from leap.bitmask.services import get_service_display_name, get_supported from ui_wizard import Ui_Wizard @@ -84,23 +84,6 @@ class Wizard(QtGui.QWizard): self.ERROR_ICON = QtGui.QPixmap(":/images/Dialog-error.png") self.OK_ICON = QtGui.QPixmap(":/images/Dialog-accept.png") - # Correspondence for services and their name to display - EIP_LABEL = self.tr("Encrypted Internet") - MX_LABEL = self.tr("Encrypted Mail") - - if self._is_need_eip_password_warning(): - EIP_LABEL += " " + self.tr( - "(will need admin password to start)") - - self.SERVICE_DISPLAY = [ - EIP_LABEL, - MX_LABEL - ] - self.SERVICE_CONFIG = [ - "openvpn", - "mx" - ] - self._selected_services = set() self._shown_services = set() @@ -507,8 +490,10 @@ class Wizard(QtGui.QWizard): try: if service not in self._shown_services: checkbox = QtGui.QCheckBox(self) - service_index = self.SERVICE_CONFIG.index(service) - checkbox.setText(self.SERVICE_DISPLAY[service_index]) + service_label = get_service_display_name( + service, self.standalone) + checkbox.setText(service_label) + self.ui.serviceListLayout.addWidget(checkbox) checkbox.stateChanged.connect( partial(self._service_selection_changed, service)) diff --git a/src/leap/bitmask/services/__init__.py b/src/leap/bitmask/services/__init__.py index 253359cd..924ca547 100644 --- a/src/leap/bitmask/services/__init__.py +++ b/src/leap/bitmask/services/__init__.py @@ -17,9 +17,44 @@ """ Services module. """ +from PySide import QtCore +from leap.bitmask.util.privilege_policies import is_missing_policy_permissions + DEPLOYED = ["openvpn", "mx"] +def get_service_display_name(service, standalone=False): + """ + Returns the name to display of the given service. + + :param service: the 'machine' service name + :type service: str + :param standalone: True if the app is running in a standalone mode, used + to display messages according that. + :type standalone: bool + + :rtype: str + """ + # qt translator method helper + _tr = QtCore.QObject().tr + + # Correspondence for services and their name to display + EIP_LABEL = _tr("Encrypted Internet") + MX_LABEL = _tr("Encrypted Mail") + + service_display = [EIP_LABEL, MX_LABEL] + service_config = ["openvpn", "mx"] + + # If we need to add a warning about eip needing + # administrative permissions to start. That can be either + # because we are running in standalone mode, or because we could + # not find the needed privilege escalation mechanisms being operative. + if standalone or is_missing_policy_permissions(): + EIP_LABEL += " " + _tr("(will need admin password to start)") + + return service_display[service_config.index(service)] + + def get_supported(services): """ Returns a list of the available services. -- cgit v1.2.3 From 3b12583c01976025a18caef8ef4bdccae9e92549 Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Wed, 28 Aug 2013 15:34:38 -0300 Subject: Use dirspec instead of plain xdg. Closes #3574. --- src/leap/bitmask/config/leapsettings.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/leap/bitmask/config/leapsettings.py b/src/leap/bitmask/config/leapsettings.py index 35010280..4929ab41 100644 --- a/src/leap/bitmask/config/leapsettings.py +++ b/src/leap/bitmask/config/leapsettings.py @@ -24,7 +24,7 @@ import logging from PySide import QtCore from leap.common.check import leap_assert, leap_assert_type -from leap.common.config.prefixers import get_platform_prefixer +from leap.common.config import get_path_prefix logger = logging.getLogger(__name__) @@ -76,10 +76,9 @@ class LeapSettings(object): :type standalone: bool """ - settings_path = os.path.join(get_platform_prefixer() - .get_path_prefix(standalone=standalone), - "leap", - self.CONFIG_NAME) + settings_path = os.path.join( + get_path_prefix(standalone=standalone), "leap", self.CONFIG_NAME) + self._settings = QtCore.QSettings(settings_path, QtCore.QSettings.IniFormat) -- cgit v1.2.3 From b27fcd2a41fec9c642207488489f0d13cc04f6db Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Wed, 28 Aug 2013 16:03:58 -0300 Subject: Replace old path_prefix with new method. --- src/leap/bitmask/config/leapsettings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/leap/bitmask/config/leapsettings.py b/src/leap/bitmask/config/leapsettings.py index 4604b807..ca94129e 100644 --- a/src/leap/bitmask/config/leapsettings.py +++ b/src/leap/bitmask/config/leapsettings.py @@ -129,7 +129,7 @@ class LeapSettings(object): providers = [] try: providers_path = os.path.join( - self._path_prefix, "leap", "providers") + get_path_prefix(), "leap", "providers") providers = os.listdir(providers_path) except Exception as e: logger.debug("Error listing providers, assume there are none. %r" -- cgit v1.2.3 From c43193f36b69620a5f88ec67c515975819c6b542 Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Thu, 29 Aug 2013 17:19:02 -0300 Subject: Enable password change when soledad is ready. Closes #3610. --- src/leap/bitmask/gui/mainwindow.py | 21 +++++++++++++++++++-- src/leap/bitmask/gui/preferenceswindow.py | 20 ++++++++++++-------- 2 files changed, 31 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py index 34451928..6d612d4e 100644 --- a/src/leap/bitmask/gui/mainwindow.py +++ b/src/leap/bitmask/gui/mainwindow.py @@ -284,6 +284,7 @@ class MainWindow(QtGui.QMainWindow): # Services signals/slots connection self.new_updates.connect(self._react_to_new_updates) self.soledad_ready.connect(self._start_imap_service) + self.soledad_ready.connect(self._set_soledad_ready) self.mail_client_logged_in.connect(self._fetch_incoming_mail) ################################# end Qt Signals connection ######## @@ -298,6 +299,7 @@ class MainWindow(QtGui.QMainWindow): self._bypass_checks = bypass_checks self._soledad = None + self._soledad_ready = False self._keymanager = None self._imap_service = None @@ -415,11 +417,26 @@ class MainWindow(QtGui.QMainWindow): Displays the preferences window. """ preferences_window = PreferencesWindow( - self, self._srp_auth, self._soledad, - self._settings, self._standalone) + self, self._srp_auth, self._settings, self._standalone) + + if self._soledad_ready: + preferences_window.set_soledad_ready(self._soledad) + else: + self.soledad_ready.connect( + lambda: preferences_window.set_soledad_ready(self._soledad)) preferences_window.show() + def _set_soledad_ready(self): + """ + SLOT + TRIGGERS: + self.soledad_ready + + It sets the soledad object as ready to use. + """ + self._soledad_ready = True + def _uncheck_logger_button(self): """ SLOT diff --git a/src/leap/bitmask/gui/preferenceswindow.py b/src/leap/bitmask/gui/preferenceswindow.py index 05f616b0..17e12304 100644 --- a/src/leap/bitmask/gui/preferenceswindow.py +++ b/src/leap/bitmask/gui/preferenceswindow.py @@ -42,14 +42,12 @@ class PreferencesWindow(QtGui.QDialog): WEAK_PASSWORDS = ("123456", "qweasd", "qwerty", "password") - def __init__(self, parent, srp_auth, soledad, leap_settings, standalone): + def __init__(self, parent, srp_auth, leap_settings, standalone): """ :param parent: parent object of the PreferencesWindow. :parent type: QWidget :param srp_auth: SRPAuth object configured in the main app. :type srp_auth: SRPAuth - :param soledad: Soledad object configured in the main app. - :type soledad: Soledad :param standalone: If True, the application is running as standalone and the preferences dialog should display some messages according to this. @@ -58,9 +56,9 @@ class PreferencesWindow(QtGui.QDialog): QtGui.QDialog.__init__(self, parent) self._srp_auth = srp_auth - self._soledad = soledad self._settings = leap_settings self._standalone = standalone + self._soledad = None # Load UI self.ui = Ui_Preferences() @@ -76,21 +74,23 @@ class PreferencesWindow(QtGui.QDialog): self.ui.cbProvidersServices.currentIndexChanged[unicode].connect( self._populate_services) - parent.soledad_ready.connect(self._soledad_ready) - if not self._settings.get_configured_providers(): self.ui.gbEnabledServices.setEnabled(False) else: self._add_configured_providers() - def _soledad_ready(self): + def set_soledad_ready(self, soledad): """ SLOT TRIGGERS: parent.soledad_ready + It sets the soledad object as ready to use. + + :param soledad: Soledad object configured in the main app. + :type soledad: Soledad """ - self._soledad_ready = True + self._soledad = soledad self.ui.gbPasswordChange.setEnabled(True) def _set_password_change_status(self, status, error=False, success=False): @@ -128,6 +128,10 @@ class PreferencesWindow(QtGui.QDialog): def _change_password(self): """ + SLOT + TRIGGERS: + self.ui.pbChangePassword.clicked + Changes the user's password if the inputboxes are correctly filled. """ username = self._srp_auth.get_username() -- cgit v1.2.3 From cd9eb81ab722bcaf77995cd308fcb8c70cba02cb Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Fri, 30 Aug 2013 20:36:52 +0200 Subject: s/bitmask/leap.bitmask in package name ...And this should be fixed forever and ever now. or until we change namespaces/package names again :) --- src/leap/bitmask/util/requirement_checker.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/leap/bitmask/util/requirement_checker.py b/src/leap/bitmask/util/requirement_checker.py index bd3c1412..37e8e693 100644 --- a/src/leap/bitmask/util/requirement_checker.py +++ b/src/leap/bitmask/util/requirement_checker.py @@ -53,7 +53,7 @@ def get_requirements(): if not develop: requires_file_name = os.path.join( 'leap', 'bitmask', 'util', 'reqs.txt') - dist_name = Requirement.parse('bitmask') + dist_name = Requirement.parse('leap.bitmask') try: with resource_stream(dist_name, requires_file_name) as stream: -- cgit v1.2.3 From 2026a2a331edfed91ca66686776cd9d26c2ac58d Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Fri, 30 Aug 2013 16:12:52 -0300 Subject: Update preferences ui to select and save gateway. --- src/leap/bitmask/gui/ui/preferences.ui | 199 ++++++++++++++++++--------------- 1 file changed, 108 insertions(+), 91 deletions(-) (limited to 'src') diff --git a/src/leap/bitmask/gui/ui/preferences.ui b/src/leap/bitmask/gui/ui/preferences.ui index b59990b1..e66a2d68 100644 --- a/src/leap/bitmask/gui/ui/preferences.ui +++ b/src/leap/bitmask/gui/ui/preferences.ui @@ -6,8 +6,8 @@ 0 0 - 453 - 463 + 503 + 529 @@ -18,80 +18,77 @@ :/images/mask-icon.png:/images/mask-icon.png - - + + + + Qt::Vertical + + + + 20 + 40 + + + + + + - false + true - Password Change + Select gateway for provider - - - QFormLayout::ExpandingFieldsGrow - - - - - &Current password: - - - leCurrentPassword - - - - - - - QLineEdit::Password - + + false + + + + + + + <Select provider> + + - - + + - &New password: + &Select provider: - leNewPassword - - - - - - - QLineEdit::Password + cbProvidersGateway - - + + - &Re-enter new password: - - - leNewPassword2 + Select gateway: - - - - QLineEdit::Password - + + + + + Automatic + + - - + + - Change + Save this provider settings - - + + - <Password change status> + < Providers Gateway Status > Qt::AlignCenter @@ -101,7 +98,7 @@ - + Enabled services @@ -158,69 +155,89 @@ - - + + false - Select gateway for provider - - - false + Password Change - + + + QFormLayout::ExpandingFieldsGrow + - + - &Select provider: + &Current password: - cbProvidersGateway + leCurrentPassword - - - - <Select provider> - - + + + QLineEdit::Password + - + - Select gateway: + &New password: + + + leNewPassword - - - - Automatic - - + + + QLineEdit::Password + + + + + + + &Re-enter new password: + + + leNewPassword2 + + + + + + + QLineEdit::Password + + + + + + + Change + + + + + + + <Password change status> + + + Qt::AlignCenter + - - - - Qt::Vertical - - - - 20 - 40 - - - - -- cgit v1.2.3 From f29133e7e2244ef7181685af7d93653cb54562e8 Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Fri, 30 Aug 2013 16:14:06 -0300 Subject: Add config option to set & get preferred gateway. --- src/leap/bitmask/config/leapsettings.py | 36 +++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'src') diff --git a/src/leap/bitmask/config/leapsettings.py b/src/leap/bitmask/config/leapsettings.py index ca94129e..ad67b29e 100644 --- a/src/leap/bitmask/config/leapsettings.py +++ b/src/leap/bitmask/config/leapsettings.py @@ -66,6 +66,10 @@ class LeapSettings(object): REMEMBER_KEY = "RememberUserAndPass" DEFAULTPROVIDER_KEY = "DefaultProvider" ALERTMISSING_KEY = "AlertMissingScripts" + GATEWAY_KEY = "Gateway" + + # values + GATEWAY_AUTOMATIC = "Automatic" def __init__(self, standalone=False): """ @@ -137,6 +141,38 @@ class LeapSettings(object): return providers + def get_selected_gateway(self, provider): + """ + Returns the configured gateway for the given provider. + + :param provider: provider domain + :type provider: str + + :rtype: str + """ + leap_assert(len(provider) > 0, "We need a nonempty provider") + gateway_key = "{0}/{1}".format(provider, self.GATEWAY_KEY) + gateway = self._settings.value(gateway_key, self.GATEWAY_AUTOMATIC) + + return gateway + + def set_selected_gateway(self, provider, gateway): + """ + Saves the configured gateway for the given provider + + :param provider: provider domain + :type provider: str + + :param gateway: gateway to use as default + :type gateway: str + """ + + leap_assert(len(provider) > 0, "We need a nonempty provider") + leap_assert_type(gateway, (str, unicode)) + + gateway_key = "{0}/{1}".format(provider, self.GATEWAY_KEY) + self._settings.setValue(gateway_key, gateway) + def get_enabled_services(self, provider): """ Returns a list of enabled services for the given provider -- cgit v1.2.3 From 3edf686a911f9fd58a0d66dcc7f2d798f5ab88f7 Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Fri, 30 Aug 2013 16:16:13 -0300 Subject: Add method to return gateways with their names. Also the test code in the bottom was updated to work. --- src/leap/bitmask/services/eip/eipconfig.py | 41 +++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/leap/bitmask/services/eip/eipconfig.py b/src/leap/bitmask/services/eip/eipconfig.py index 843e7397..1f49f9cd 100644 --- a/src/leap/bitmask/services/eip/eipconfig.py +++ b/src/leap/bitmask/services/eip/eipconfig.py @@ -62,11 +62,12 @@ class VPNGatewaySelector(object): self._eipconfig = eipconfig - def get_gateways(self): + def get_gateways_list(self): """ - Returns the 4 best gateways, sorted by timezone proximity. + Returns the existing gateways, sorted by timezone proximity. - :rtype: list of IPv4Address or IPv6Address object. + :rtype: list of tuples (location, ip) + (str, IPv4Address or IPv6Address object) """ gateways_timezones = [] locations = self._eipconfig.get_locations() @@ -77,19 +78,35 @@ class VPNGatewaySelector(object): gateway_distance = 99 # if hasn't location -> should go last if gateway_location is not None: - gw_offset = int(locations[gateway['location']]['timezone']) + timezone = locations[gateway['location']]['timezone'] + gateway_name = locations[gateway['location']].get('name', None) + if gateway_name is not None: + gateway_location = gateway_name + + gw_offset = int(timezone) if gw_offset in self.equivalent_timezones: gw_offset = self.equivalent_timezones[gw_offset] gateway_distance = self._get_timezone_distance(gw_offset) ip = self._eipconfig.get_gateway_ip(idx) - gateways_timezones.append((ip, gateway_distance)) + gateways_timezones.append((ip, gateway_distance, gateway_location)) - gateways_timezones = sorted(gateways_timezones, - key=lambda gw: gw[1])[:4] + gateways_timezones = sorted(gateways_timezones, key=lambda gw: gw[1]) + + gateways = [] + for ip, distance, location in gateways_timezones: + gateways.append((location, ip)) + + return gateways - gateways = [ip for ip, dist in gateways_timezones] + def get_gateways(self): + """ + Returns the 4 best gateways, sorted by timezone proximity. + + :rtype: list of IPv4Address or IPv6Address object. + """ + gateways = [ip for location, ip in self.get_gateways_list()][:4] return gateways def _get_timezone_distance(self, offset): @@ -246,7 +263,8 @@ if __name__ == "__main__": console.setFormatter(formatter) logger.addHandler(console) - eipconfig = EIPConfig('1') + eipconfig = EIPConfig() + eipconfig.set_api_version('1') try: eipconfig.get_clusters() @@ -255,9 +273,14 @@ if __name__ == "__main__": print "Safe value getting is working" if eipconfig.load("leap/providers/bitmask.net/eip-service.json"): + print "EIPConfig methods" print eipconfig.get_clusters() print eipconfig.get_gateways() print eipconfig.get_locations() print eipconfig.get_openvpn_configuration() print eipconfig.get_serial() print eipconfig.get_version() + print "VPNGatewaySelector methods" + gws = VPNGatewaySelector(eipconfig) + print gws.get_gateways() + print gws.get_gateways_list() -- cgit v1.2.3 From 89e89d5f1bada3dfc65ce44c76b4250ed561d6ab Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Fri, 30 Aug 2013 16:31:32 -0300 Subject: Add gateway selection feature to the preferences. --- src/leap/bitmask/gui/preferenceswindow.py | 156 ++++++++++++++++++++++++++++-- 1 file changed, 149 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/leap/bitmask/gui/preferenceswindow.py b/src/leap/bitmask/gui/preferenceswindow.py index 17e12304..c3c3490b 100644 --- a/src/leap/bitmask/gui/preferenceswindow.py +++ b/src/leap/bitmask/gui/preferenceswindow.py @@ -30,6 +30,7 @@ from leap.bitmask.crypto.srpauth import SRPAuthBadPassword from leap.bitmask.util.password import basic_password_checks from leap.bitmask.services import get_supported from leap.bitmask.config.providerconfig import ProviderConfig +from leap.bitmask.services.eip.eipconfig import EIPConfig, VPNGatewaySelector from leap.bitmask.services import get_service_display_name logger = logging.getLogger(__name__) @@ -54,6 +55,7 @@ class PreferencesWindow(QtGui.QDialog): :type standalone: bool """ QtGui.QDialog.__init__(self, parent) + self.AUTOMATIC_GATEWAY_LABEL = self.tr("Automatic") self._srp_auth = srp_auth self._settings = leap_settings @@ -65,14 +67,19 @@ class PreferencesWindow(QtGui.QDialog): self.ui.setupUi(self) self.ui.lblPasswordChangeStatus.setVisible(False) self.ui.lblProvidersServicesStatus.setVisible(False) + self.ui.lblProvidersGatewayStatus.setVisible(False) self._selected_services = set() - self._provider_config = ProviderConfig() # Connections self.ui.pbChangePassword.clicked.connect(self._change_password) self.ui.cbProvidersServices.currentIndexChanged[unicode].connect( self._populate_services) + self.ui.cbProvidersGateway.currentIndexChanged[unicode].connect( + self._populate_gateways) + + self.ui.cbGateways.currentIndexChanged[unicode].connect( + lambda x: self.ui.lblProvidersGatewayStatus.setVisible(False)) if not self._settings.get_configured_providers(): self.ui.gbEnabledServices.setEnabled(False) @@ -207,6 +214,9 @@ class PreferencesWindow(QtGui.QDialog): :param status: status message to display, can be HTML :type status: str + :param success: is set to True if we should display the + message as green + :type success: bool """ if success: status = "%s" % (status,) @@ -214,6 +224,28 @@ class PreferencesWindow(QtGui.QDialog): self.ui.lblProvidersServicesStatus.setVisible(True) self.ui.lblProvidersServicesStatus.setText(status) + def _set_providers_gateway_status(self, status, success=False, + error=False): + """ + Sets the status label for the gateway change. + + :param status: status message to display, can be HTML + :type status: str + :param success: is set to True if we should display the + message as green + :type success: bool + :param error: is set to True if we should display the + message as red + :type error: bool + """ + if success: + status = "%s" % (status,) + elif error: + status = "%s" % (status,) + + self.ui.lblProvidersGatewayStatus.setVisible(True) + self.ui.lblProvidersGatewayStatus.setText(status) + def _add_configured_providers(self): """ Add the client's configured providers to the providers combo boxes. @@ -250,7 +282,7 @@ class PreferencesWindow(QtGui.QDialog): """ SLOT TRIGGERS: - self.ui.cbProvidersServices.clicked + self.ui.cbProvidersServices.currentIndexChanged[unicode] Loads the services that the provider provides into the UI for the user to enable or disable. @@ -261,10 +293,11 @@ class PreferencesWindow(QtGui.QDialog): # We hide the maybe-visible status label after a change self.ui.lblProvidersServicesStatus.setVisible(False) - provider_config_path = os.path.join( - "leap", "providers", domain, "provider.json") + if not domain: + return - if not domain or not self._provider_config.load(provider_config_path): + provider_config = self._get_provider_config(domain) + if provider_config is None: return # set the proper connection for the 'save' button @@ -276,7 +309,7 @@ class PreferencesWindow(QtGui.QDialog): save_services = partial(self._save_enabled_services, domain) self.ui.pbSaveServices.clicked.connect(save_services) - services = get_supported(self._provider_config.get_services()) + services = get_supported(provider_config.get_services()) services_conf = self._settings.get_enabled_services(domain) # discard changes if other provider is selected @@ -307,7 +340,11 @@ class PreferencesWindow(QtGui.QDialog): def _save_enabled_services(self, provider): """ - Saves the new settings to the configuration file. + SLOT + TRIGGERS: + self.ui.pbSaveServices.clicked + + Saves the new enabled services settings to the configuration file. :param provider: the provider config that we need to save. :type provider: str @@ -319,3 +356,108 @@ class PreferencesWindow(QtGui.QDialog): "Services settings for provider '{0}' saved.".format(provider)) logger.debug(msg) self._set_providers_services_status(msg, success=True) + + def _get_provider_config(self, domain): + """ + Helper to return a valid Provider Config from the domain name. + + :param domain: the domain name of the provider. + :type domain: str + + :rtype: ProviderConfig or None if there is a problem loading the config + """ + provider_config = ProviderConfig() + provider_config_path = os.path.join( + "leap", "providers", domain, "provider.json") + + if not provider_config.load(provider_config_path): + provider_config = None + + return provider_config + + def _save_selected_gateway(self, provider): + """ + SLOT + TRIGGERS: + self.ui.pbSaveGateway.clicked + + Saves the new gateway setting to the configuration file. + + :param provider: the provider config that we need to save. + :type provider: str + """ + gateway = self.ui.cbGateways.currentText() + + if gateway == self.AUTOMATIC_GATEWAY_LABEL: + gateway = self._settings.GATEWAY_AUTOMATIC + else: + idx = self.ui.cbGateways.currentIndex() + gateway = self.ui.cbGateways.itemData(idx) + + self._settings.set_selected_gateway(provider, gateway) + + msg = self.tr( + "Gateway settings for provider '{0}' saved.".format(provider)) + logger.debug(msg) + self._set_providers_gateway_status(msg, success=True) + + def _populate_gateways(self, domain): + """ + SLOT + TRIGGERS: + self.ui.cbProvidersGateway.currentIndexChanged[unicode] + + Loads the gateways that the provider provides into the UI for + the user to select. + + :param domain: the domain of the provider to load gateways from. + :type domain: str + """ + # We hide the maybe-visible status label after a change + self.ui.lblProvidersGatewayStatus.setVisible(False) + + if not domain: + return + + try: + # disconnect prevoiusly connected save method + self.ui.pbSaveGateway.clicked.disconnect() + except RuntimeError: + pass # Signal was not connected + + # set the proper connection for the 'save' button + save_gateway = partial(self._save_selected_gateway, domain) + self.ui.pbSaveGateway.clicked.connect(save_gateway) + + eip_config = EIPConfig() + provider_config = self._get_provider_config(domain) + + eip_config_path = os.path.join("leap", "providers", + domain, "eip-service.json") + api_version = provider_config.get_api_version() + eip_config.set_api_version(api_version) + eip_loaded = eip_config.load(eip_config_path) + + if not eip_loaded or provider_config is None: + self._set_providers_gateway_status( + self.tr("There was a problem with configuration files."), + error=True) + return + + gateways = VPNGatewaySelector(eip_config).get_gateways_list() + logger.debug(gateways) + + self.ui.cbGateways.clear() + self.ui.cbGateways.addItem(self.AUTOMATIC_GATEWAY_LABEL) + + # Add the available gateways and + # select the one stored in configuration file. + selected_gateway = self._settings.get_selected_gateway(domain) + index = 0 + for idx, (gw_name, gw_ip) in enumerate(gateways): + gateway = "{0} ({1})".format(gw_name, gw_ip) + self.ui.cbGateways.addItem(gateway, gw_ip) + if gw_ip == selected_gateway: + index = idx + 1 + + self.ui.cbGateways.setCurrentIndex(index) -- cgit v1.2.3 From 07da9729f4cb3d62361c226e772aa077bf07cfa7 Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Fri, 30 Aug 2013 16:20:34 -0300 Subject: Start the vpn with the user configured gateway. --- src/leap/bitmask/services/eip/vpnlaunchers.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/leap/bitmask/services/eip/vpnlaunchers.py b/src/leap/bitmask/services/eip/vpnlaunchers.py index f8c51ad8..15221c48 100644 --- a/src/leap/bitmask/services/eip/vpnlaunchers.py +++ b/src/leap/bitmask/services/eip/vpnlaunchers.py @@ -33,6 +33,7 @@ except ImportError: from abc import ABCMeta, abstractmethod from functools import partial +from leap.bitmask.config.leapsettings import LeapSettings from leap.bitmask.config.providerconfig import ProviderConfig from leap.bitmask.services.eip.eipconfig import EIPConfig, VPNGatewaySelector from leap.bitmask.util import first @@ -414,8 +415,15 @@ class LinuxVPNLauncher(VPNLauncher): if openvpn_verb is not None: args += ['--verb', '%d' % (openvpn_verb,)] - gateway_selector = VPNGatewaySelector(eipconfig) - gateways = gateway_selector.get_gateways() + gateways = [] + leap_settings = LeapSettings(ProviderConfig.standalone) + gateway_conf = leap_settings.get_selected_gateway() + + if gateway_conf == leap_settings.GATEWAY_AUTOMATIC: + gateway_selector = VPNGatewaySelector(eipconfig) + gateways = gateway_selector.get_gateways() + else: + gateways = [gateway_conf] if not gateways: logger.error('No gateway was found!') -- cgit v1.2.3 From 8df63e671ee971e5f987320482f020ad7ceeeb6b Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Fri, 30 Aug 2013 21:50:35 +0200 Subject: remove reqs from vcs --- src/leap/bitmask/util/reqs.txt | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 src/leap/bitmask/util/reqs.txt (limited to 'src') diff --git a/src/leap/bitmask/util/reqs.txt b/src/leap/bitmask/util/reqs.txt deleted file mode 100644 index 0bcf85dc..00000000 --- a/src/leap/bitmask/util/reqs.txt +++ /dev/null @@ -1,14 +0,0 @@ -requests -srp>=1.0.2 -pyopenssl -keyring -python-dateutil -psutil -ipaddr -twisted -qt4reactor -python-gnupg -leap.common>=0.2.5 -leap.soledad>=0.1.0 -mock -oauth \ No newline at end of file -- cgit v1.2.3 From 68f9095533af0623a3e2555fe860a60667351a6d Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Fri, 30 Aug 2013 18:06:19 -0300 Subject: Fix, method name bug. --- src/leap/bitmask/gui/preferenceswindow.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/leap/bitmask/gui/preferenceswindow.py b/src/leap/bitmask/gui/preferenceswindow.py index c3c3490b..1becfb18 100644 --- a/src/leap/bitmask/gui/preferenceswindow.py +++ b/src/leap/bitmask/gui/preferenceswindow.py @@ -126,7 +126,7 @@ class PreferencesWindow(QtGui.QDialog): :type disable: bool """ if disable: - self._set_password_change_disable(self.tr("Changing password...")) + self._set_password_change_status(self.tr("Changing password...")) self.ui.leCurrentPassword.setEnabled(not disable) self.ui.leNewPassword.setEnabled(not disable) -- cgit v1.2.3 From 579f06a924767962aac7d23df21d0cf2aa43a7bd Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Sun, 1 Sep 2013 19:21:57 +0200 Subject: Fix arguments passed to get_selected_gateway() Closes: #3658 --- src/leap/bitmask/services/eip/vpnlaunchers.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/leap/bitmask/services/eip/vpnlaunchers.py b/src/leap/bitmask/services/eip/vpnlaunchers.py index 15221c48..5921882b 100644 --- a/src/leap/bitmask/services/eip/vpnlaunchers.py +++ b/src/leap/bitmask/services/eip/vpnlaunchers.py @@ -417,7 +417,8 @@ class LinuxVPNLauncher(VPNLauncher): gateways = [] leap_settings = LeapSettings(ProviderConfig.standalone) - gateway_conf = leap_settings.get_selected_gateway() + domain = providerconfig.get_domain() + gateway_conf = leap_settings.get_selected_gateway(domain) if gateway_conf == leap_settings.GATEWAY_AUTOMATIC: gateway_selector = VPNGatewaySelector(eipconfig) -- cgit v1.2.3 From 2085475e3b5ac44b82d8bf7d98b30a67e5c42a61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Sun, 1 Sep 2013 16:10:04 -0300 Subject: Improve mail UI until we have a proper state machine --- src/leap/bitmask/gui/statuspanel.py | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/leap/bitmask/gui/statuspanel.py b/src/leap/bitmask/gui/statuspanel.py index 9352eb04..49d7e24a 100644 --- a/src/leap/bitmask/gui/statuspanel.py +++ b/src/leap/bitmask/gui/statuspanel.py @@ -591,6 +591,11 @@ class StatusPanelWidget(QtGui.QWidget): :param req: Request type :type req: leap.common.events.events_pb2.SignalRequest """ + # We want to ignore this kind of events once everything has + # started + if self._smtp_started and self._imap_started: + return + self.ui.lblMailStatus.setText(self.tr("Starting...")) ext_status = "" -- cgit v1.2.3 From 8856f3fd19fa1617b716ce1c8b9d3a3281a8398d Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Mon, 2 Sep 2013 11:42:01 -0300 Subject: Fix typo, closes #3615. --- src/leap/bitmask/gui/ui/wizard.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/leap/bitmask/gui/ui/wizard.ui b/src/leap/bitmask/gui/ui/wizard.ui index 3b8f1215..570c01a9 100644 --- a/src/leap/bitmask/gui/ui/wizard.ui +++ b/src/leap/bitmask/gui/ui/wizard.ui @@ -183,7 +183,7 @@ - Can we stablish a secure connection? + Can we establish a secure connection? -- cgit v1.2.3 From eb01c527bcfa3152eab6601fde88236f7866c2f1 Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Mon, 2 Sep 2013 11:32:13 -0300 Subject: Use configured gateway in all platforms. Also use python 2.6 compatible str.format. --- src/leap/bitmask/services/eip/vpnlaunchers.py | 39 +++++++++++++++++++++------ 1 file changed, 31 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/leap/bitmask/services/eip/vpnlaunchers.py b/src/leap/bitmask/services/eip/vpnlaunchers.py index 5921882b..a9213a9a 100644 --- a/src/leap/bitmask/services/eip/vpnlaunchers.py +++ b/src/leap/bitmask/services/eip/vpnlaunchers.py @@ -430,7 +430,7 @@ class LinuxVPNLauncher(VPNLauncher): logger.error('No gateway was found!') raise VPNLauncherException(self.tr('No gateway was found!')) - logger.debug("Using gateways ips: {}".format(', '.join(gateways))) + logger.debug("Using gateways ips: {0}".format(', '.join(gateways))) for gw in gateways: args += ['--remote', gw, '1194', 'udp'] @@ -678,11 +678,22 @@ class DarwinVPNLauncher(VPNLauncher): if openvpn_verb is not None: args += ['--verb', '%d' % (openvpn_verb,)] - gateway_selector = VPNGatewaySelector(eipconfig) - gateways = gateway_selector.get_gateways() + gateways = [] + leap_settings = LeapSettings(ProviderConfig.standalone) + domain = providerconfig.get_domain() + gateway_conf = leap_settings.get_selected_gateway(domain) + + if gateway_conf == leap_settings.GATEWAY_AUTOMATIC: + gateway_selector = VPNGatewaySelector(eipconfig) + gateways = gateway_selector.get_gateways() + else: + gateways = [gateway_conf] + + if not gateways: + logger.error('No gateway was found!') + raise VPNLauncherException(self.tr('No gateway was found!')) - logger.debug("Using gateways ips: {gw}".format( - gw=', '.join(gateways))) + logger.debug("Using gateways ips: {0}".format(', '.join(gateways))) for gw in gateways: args += ['--remote', gw, '1194', 'udp'] @@ -850,10 +861,22 @@ class WindowsVPNLauncher(VPNLauncher): if openvpn_verb is not None: args += ['--verb', '%d' % (openvpn_verb,)] - gateway_selector = VPNGatewaySelector(eipconfig) - gateways = gateway_selector.get_gateways() + gateways = [] + leap_settings = LeapSettings(ProviderConfig.standalone) + domain = providerconfig.get_domain() + gateway_conf = leap_settings.get_selected_gateway(domain) + + if gateway_conf == leap_settings.GATEWAY_AUTOMATIC: + gateway_selector = VPNGatewaySelector(eipconfig) + gateways = gateway_selector.get_gateways() + else: + gateways = [gateway_conf] + + if not gateways: + logger.error('No gateway was found!') + raise VPNLauncherException(self.tr('No gateway was found!')) - logger.debug("Using gateways ips: {}".format(', '.join(gateways))) + logger.debug("Using gateways ips: {0}".format(', '.join(gateways))) for gw in gateways: args += ['--remote', gw, '1194', 'udp'] -- cgit v1.2.3 From c6baec1cc4e5b5aea2690569cb1be64b983d6986 Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Mon, 2 Sep 2013 01:07:22 +0200 Subject: emit failed for all kinds of socket error --- src/leap/bitmask/services/soledad/soledadbootstrapper.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/leap/bitmask/services/soledad/soledadbootstrapper.py b/src/leap/bitmask/services/soledad/soledadbootstrapper.py index 2419fc0d..3bbfea85 100644 --- a/src/leap/bitmask/services/soledad/soledadbootstrapper.py +++ b/src/leap/bitmask/services/soledad/soledadbootstrapper.py @@ -159,8 +159,7 @@ class SoledadBootstrapper(AbstractBootstrapper): self.soledad_timeout.emit() except socket.error as exc: logger.error("Socket error while initializing soledad") - if exc.errno in (111, ): - self.soledad_failed.emit() + self.soledad_failed.emit() except u1db_errors.Unauthorized: logger.error("Error while initializing soledad " "(unauthorized).") -- cgit v1.2.3 From 4b3f00962cbce75f5120c0d370e03c3007dfe92d Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Mon, 2 Sep 2013 13:40:17 +0200 Subject: Add a selective filter for leap logs. Closes: #3504 --- src/leap/bitmask/app.py | 11 +++- src/leap/bitmask/util/leap_log_handler.py | 3 + src/leap/bitmask/util/log_silencer.py | 95 +++++++++++++++++++++++++++++++ 3 files changed, 107 insertions(+), 2 deletions(-) create mode 100644 src/leap/bitmask/util/log_silencer.py (limited to 'src') diff --git a/src/leap/bitmask/app.py b/src/leap/bitmask/app.py index 6ffa1d25..0dce5e61 100644 --- a/src/leap/bitmask/app.py +++ b/src/leap/bitmask/app.py @@ -25,6 +25,7 @@ from functools import partial from PySide import QtCore, QtGui from leap.bitmask.util import leap_argparse +from leap.bitmask.util import log_silencer from leap.bitmask.util.leap_log_handler import LeapLogHandler from leap.bitmask.util.streamtologger import StreamToLogger from leap.common.events import server as event_server @@ -51,7 +52,7 @@ def install_qtreactor(logger): logger.debug("Qt4 reactor installed") -def add_logger_handlers(debug=False, logfile=None): +def add_logger_handlers(debug=False, logfile=None, standalone=False): """ Create the logger and attach the handlers. @@ -71,6 +72,7 @@ def add_logger_handlers(debug=False, logfile=None): # Create logger and formatter logger = logging.getLogger(name='leap') logger.setLevel(level) + log_format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s' formatter = logging.Formatter(log_format) @@ -78,12 +80,16 @@ def add_logger_handlers(debug=False, logfile=None): console = logging.StreamHandler() console.setLevel(level) console.setFormatter(formatter) + + silencer = log_silencer.SelectiveSilencerFilter(standalone=standalone) + console.addFilter(silencer) logger.addHandler(console) logger.debug('Console handler plugged!') # LEAP custom handler leap_handler = LeapLogHandler() leap_handler.setLevel(level) + leap_handler.addFilter(silencer) logger.addHandler(leap_handler) logger.debug('Leap handler plugged!') @@ -93,6 +99,7 @@ def add_logger_handlers(debug=False, logfile=None): fileh = logging.FileHandler(logfile) fileh.setLevel(logging.DEBUG) fileh.setFormatter(formatter) + fileh.addFilter(silencer) logger.addHandler(fileh) logger.debug('File handler plugged!') @@ -155,7 +162,7 @@ def main(): # pylint: avoid unused import assert(locale_rc) - logger = add_logger_handlers(debug, logfile) + logger = add_logger_handlers(debug, logfile, standalone) replace_stdout_stderr_with_logging(logger) if not we_are_the_one_and_only(): diff --git a/src/leap/bitmask/util/leap_log_handler.py b/src/leap/bitmask/util/leap_log_handler.py index 9adb21a5..98924c12 100644 --- a/src/leap/bitmask/util/leap_log_handler.py +++ b/src/leap/bitmask/util/leap_log_handler.py @@ -90,6 +90,9 @@ class HandlerAdapter(object): def setLevel(self, *args, **kwargs): return self._handler.setLevel(*args, **kwargs) + def addFilter(self, *args, **kwargs): + return self._handler.addFilter(*args, **kwargs) + def handle(self, *args, **kwargs): return self._handler.handle(*args, **kwargs) diff --git a/src/leap/bitmask/util/log_silencer.py b/src/leap/bitmask/util/log_silencer.py new file mode 100644 index 00000000..09aa2cff --- /dev/null +++ b/src/leap/bitmask/util/log_silencer.py @@ -0,0 +1,95 @@ +# -*- coding: utf-8 -*- +# log_silencer.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 . +""" +Filter for leap logs. +""" +import logging +import os +import re + +from leap.common.config import get_path_prefix + + +class SelectiveSilencerFilter(logging.Filter): + """ + Configurable filter for root leap logger. + + If you want to ignore components from the logging, just add them, + one by line, to ~/.config/leap/leap.dev.conf + """ + # TODO we can augment this by properly parsing the log-silencer file + # and having different sections: ignore, levels, ... + + # TODO use ConfigParser to unify sections [log-ignore] [log-debug] etc + + CONFIG_NAME = "leap.dev.conf" + + # Components to be completely silenced in the main bitmask logs. + # You probably should think twice before adding a component to + # the tuple below. Only very well tested components should go here, and + # only in those cases in which we gain more from silencing them than from + # having their logs into the main log file that the user will likely send + # to us. + SILENCER_RULES = ( + 'leap.common.events', + ) + + def __init__(self, standalone=False): + """ + Tries to load silencer rules from the default path, + or load from the SILENCER_RULES tuple if not found. + """ + self.standalone = standalone + self.rules = None + if os.path.isfile(self._rules_path): + self.rules = self._load_rules() + if not self.rules: + self.rules = self.SILENCER_RULES + + @property + def _rules_path(self): + """ + The configuration file for custom ignore rules. + """ + return os.path.join( + get_path_prefix(standalone=self.standalone), + "leap", self.CONFIG_NAME) + + def _load_rules(self): + """ + Loads a list of paths to be ignored from the logging. + """ + lines = open(self._rules_path).readlines() + return map(lambda line: re.sub('\s', '', line), + lines) + + def filter(self, record): + """ + Implements the filter functionality for this Filter + + :param record: the record to be examined + :type record: logging.LogRecord + :returns: a bool indicating whether the record should be logged or not. + :rtype: bool + """ + if not self.rules: + return True + logger_path = record.name + for path in self.rules: + if logger_path.startswith(path): + return False + return True -- cgit v1.2.3 From 0cacbe7c8dae97a04654c2cca5e928dfa9e3741d Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Mon, 2 Sep 2013 14:46:38 -0300 Subject: Fix local offset calculation. Closes #3595. Python returns the timezone with the opposed sign to the standard notation. --- src/leap/bitmask/services/eip/eipconfig.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/leap/bitmask/services/eip/eipconfig.py b/src/leap/bitmask/services/eip/eipconfig.py index 1f49f9cd..1cb7419e 100644 --- a/src/leap/bitmask/services/eip/eipconfig.py +++ b/src/leap/bitmask/services/eip/eipconfig.py @@ -141,7 +141,7 @@ class VPNGatewaySelector(object): if time.daylight: local_offset = time.altzone - return local_offset / 3600 + return -local_offset / 3600 class EIPConfig(BaseConfig): -- cgit v1.2.3 From e4e79e29c01e6389d37d12ed72b0ba9f972d2ede Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Mon, 2 Sep 2013 15:06:01 -0300 Subject: Display correct service name in wizard. --- src/leap/bitmask/config/providerconfig.py | 10 +++++++--- src/leap/bitmask/services/__init__.py | 10 +++++++--- 2 files changed, 14 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/leap/bitmask/config/providerconfig.py b/src/leap/bitmask/config/providerconfig.py index c65932be..a7808399 100644 --- a/src/leap/bitmask/config/providerconfig.py +++ b/src/leap/bitmask/config/providerconfig.py @@ -24,6 +24,7 @@ import os from leap.bitmask.config.provider_spec import leap_provider_spec from leap.common.check import leap_check from leap.common.config.baseconfig import BaseConfig, LocalizedKey +from leap.bitmask.services import get_service_display_name logger = logging.getLogger(__name__) @@ -130,9 +131,11 @@ class ProviderConfig(BaseConfig): Returns a string with the available services in the current provider, ready to be shown to the user. """ - services_str = ", ".join(self.get_services()) - services_str = services_str.replace( - "openvpn", "Encrypted Internet") + services = [] + for service in self.get_services(): + services.append(get_service_display_name(service)) + + services_str = ", ".join(services) return services_str def get_ca_cert_path(self, about_to_download=False): @@ -216,3 +219,4 @@ if __name__ == "__main__": print provider.get_languages() print provider.get_name() print provider.get_services() + print provider.get_services_string() diff --git a/src/leap/bitmask/services/__init__.py b/src/leap/bitmask/services/__init__.py index 924ca547..339f9cc6 100644 --- a/src/leap/bitmask/services/__init__.py +++ b/src/leap/bitmask/services/__init__.py @@ -26,6 +26,8 @@ DEPLOYED = ["openvpn", "mx"] def get_service_display_name(service, standalone=False): """ Returns the name to display of the given service. + If there is no configured name for that service, then returns the same + parameter :param service: the 'machine' service name :type service: str @@ -42,8 +44,10 @@ def get_service_display_name(service, standalone=False): EIP_LABEL = _tr("Encrypted Internet") MX_LABEL = _tr("Encrypted Mail") - service_display = [EIP_LABEL, MX_LABEL] - service_config = ["openvpn", "mx"] + service_display = { + "openvpn": EIP_LABEL, + "mx": MX_LABEL + } # If we need to add a warning about eip needing # administrative permissions to start. That can be either @@ -52,7 +56,7 @@ def get_service_display_name(service, standalone=False): if standalone or is_missing_policy_permissions(): EIP_LABEL += " " + _tr("(will need admin password to start)") - return service_display[service_config.index(service)] + return service_display.get(service, service) def get_supported(services): -- cgit v1.2.3 From 99667150fc48841742f97de83c11bb97b0e8882a Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Tue, 3 Sep 2013 11:13:47 +0200 Subject: Logout stops mail services. Closes: #3553 --- src/leap/bitmask/gui/mainwindow.py | 88 ++++++++++++++++++++++++-------------- 1 file changed, 57 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py index 6d612d4e..7a94fd0f 100644 --- a/src/leap/bitmask/gui/mainwindow.py +++ b/src/leap/bitmask/gui/mainwindow.py @@ -14,9 +14,8 @@ # # 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 +Main window for Bitmask. """ import logging import os @@ -102,6 +101,7 @@ class MainWindow(QtGui.QMainWindow): raise_window = QtCore.Signal([]) soledad_ready = QtCore.Signal([]) mail_client_logged_in = QtCore.Signal([]) + logout = QtCore.Signal([]) # We use this flag to detect abnormal terminations user_stopped_eip = False @@ -286,6 +286,8 @@ class MainWindow(QtGui.QMainWindow): self.soledad_ready.connect(self._start_imap_service) self.soledad_ready.connect(self._set_soledad_ready) self.mail_client_logged_in.connect(self._fetch_incoming_mail) + self.logout.connect(self._stop_imap_service) + self.logout.connect(self._stop_smtp_service) ################################# end Qt Signals connection ######## @@ -301,6 +303,7 @@ class MainWindow(QtGui.QMainWindow): self._soledad = None self._soledad_ready = False self._keymanager = None + self._smtp_service = None self._imap_service = None self._login_defer = None @@ -909,7 +912,7 @@ class MainWindow(QtGui.QMainWindow): self._srp_auth.logout_finished.connect( self._done_logging_out) - # TODO: Add errback! + # TODO Add errback! self._login_defer = self._srp_auth.authenticate(username, password) else: self._login_widget.set_status( @@ -976,7 +979,7 @@ class MainWindow(QtGui.QMainWindow): """ passed = data[self._soledad_bootstrapper.PASSED_KEY] if not passed: - # TODO: display in the GUI: + # TODO display in the GUI: # should pass signal to a slot in status_panel # that sets the global status logger.error("Soledad failed to start: %s" % @@ -1037,13 +1040,13 @@ 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._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 + pass # TODO show MX status #self._status_panel.set_eip_status( # self.tr("MX is disabled")) @@ -1070,25 +1073,43 @@ class MainWindow(QtGui.QMainWindow): logger.debug("Done bootstrapping SMTP") hosts = self._smtp_config.get_hosts() - # TODO: handle more than one host and define how to choose + # 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 move the start to _start_smtp_service + + # TODO Make the encrypted_only configurable + # TODO pick local smtp port in a better way + # TODO remove hard-coded port and let leap.mail set + # the specific default. from leap.mail.smtp import setup_smtp_relay client_cert = self._eip_config.get_client_cert_path( self._provider_config) - setup_smtp_relay(port=2013, - keymanager=self._keymanager, - smtp_host=host, - smtp_port=port, - smtp_cert=client_cert, - smtp_key=client_cert, - encrypted_only=False) + self._smtp_service = setup_smtp_relay( + port=2013, + keymanager=self._keymanager, + smtp_host=host, + smtp_port=port, + smtp_cert=client_cert, + smtp_key=client_cert, + encrypted_only=False) + + def _stop_smtp_service(self): + """ + SLOT + TRIGGERS: + self.logout + """ + # There is a subtle difference here: + # we are stopping the factory for the smtp service here, + # but in the imap case we are just stopping the fetcher. + if self._smtp_service is not None: + logger.debug('Stopping smtp service.') + self._smtp_service.doStop() ################################################################### # Service control methods: imap @@ -1097,7 +1118,7 @@ class MainWindow(QtGui.QMainWindow): """ SLOT TRIGGERS: - soledad_ready + self.soledad_ready """ if self._provider_config.provides_mx() and \ self._enabled_services.count(self.MX_SERVICE) > 0: @@ -1106,17 +1127,6 @@ class MainWindow(QtGui.QMainWindow): self._imap_service = imap.start_imap_service( self._soledad, self._keymanager) - else: - if self._enabled_services.count(self.MX_SERVICE) > 0: - pass # TODO: show MX 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._status_panel.set_eip_status( - # self.tr("MX is disabled")) def _on_mail_client_logged_in(self, req): """ @@ -1128,13 +1138,27 @@ class MainWindow(QtGui.QMainWindow): """ SLOT TRIGGERS: - mail_client_logged_in + self.mail_client_logged_in """ # TODO have a mutex over fetch operation. if self._imap_service: logger.debug('Client connected, fetching mail...') self._imap_service.fetch() + def _stop_imap_service(self): + """ + SLOT + TRIGGERS: + self.logout + """ + # There is a subtle difference here: + # we are just stopping the fetcher here, + # but in the smtp case we are stopping the factory. + # We should homogenize both services. + if self._imap_service is not None: + logger.debug('Stopping imap service.') + self._imap_service.stop() + # end service control methods (imap) ################################################################### @@ -1146,7 +1170,8 @@ class MainWindow(QtGui.QMainWindow): :rtype: tuple (str, str) (host, port) """ - # TODO: make this properly multiplatform + # TODO make this properly multiplatform + # TODO get this out of gui/ if platform.system() == "Windows": host = "localhost" @@ -1399,6 +1424,7 @@ class MainWindow(QtGui.QMainWindow): # XXX: If other defers are doing authenticated stuff, this # might conflict with those. CHECK! threads.deferToThread(self._srp_auth.logout) + self.logout.emit() def _done_logging_out(self, ok, message): """ @@ -1573,7 +1599,7 @@ class MainWindow(QtGui.QMainWindow): """ Cleanup and tidely close the main window before quitting. """ - # TODO: separate the shutting down of services from the + # TODO separate the shutting down of services from the # UI stuff. self._cleanup_and_quit() -- cgit v1.2.3 From 7511d3ffe98602c979a80972e0ba67b2a0e54310 Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Tue, 3 Sep 2013 15:30:53 -0300 Subject: Remove last page from wizard. Also remove the globe image because is no longer needed. --- src/leap/bitmask/gui/ui/wizard.ui | 91 --------------------------------------- src/leap/bitmask/gui/wizard.py | 3 +- 2 files changed, 1 insertion(+), 93 deletions(-) (limited to 'src') diff --git a/src/leap/bitmask/gui/ui/wizard.ui b/src/leap/bitmask/gui/ui/wizard.ui index 570c01a9..2a412784 100644 --- a/src/leap/bitmask/gui/ui/wizard.ui +++ b/src/leap/bitmask/gui/ui/wizard.ui @@ -740,97 +740,6 @@ - - - Congratulations! - - - You have successfully configured Bitmask. - - - 6 - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - :/images/mask-icon.png - - - - - - - - 0 - 0 - - - - - - - :/images/Globe.png - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - diff --git a/src/leap/bitmask/gui/wizard.py b/src/leap/bitmask/gui/wizard.py index ac0f032f..e004e6cf 100644 --- a/src/leap/bitmask/gui/wizard.py +++ b/src/leap/bitmask/gui/wizard.py @@ -52,7 +52,6 @@ class Wizard(QtGui.QWizard): SETUP_PROVIDER_PAGE = 3 REGISTER_USER_PAGE = 4 SERVICES_PAGE = 5 - FINISH_PAGE = 6 WEAK_PASSWORDS = ("123456", "qweasd", "qwerty", "password") @@ -144,7 +143,7 @@ class Wizard(QtGui.QWizard): self.page(self.REGISTER_USER_PAGE).setButtonText( QtGui.QWizard.CommitButton, self.tr("&Next >")) - self.page(self.FINISH_PAGE).setButtonText( + self.page(self.SERVICES_PAGE).setButtonText( QtGui.QWizard.FinishButton, self.tr("Connect")) # XXX: Temporary removal for enrollment policy -- cgit v1.2.3 From d315312740333abf8450e4e0b004d219a0936488 Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Wed, 28 Aug 2013 19:44:27 +0200 Subject: Properly daemonize the call to polkit gnome authentication agent. Closes: #3554 --- src/leap/bitmask/services/eip/vpnlaunchers.py | 25 ++++++------- src/leap/bitmask/util/polkit_agent.py | 52 +++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 12 deletions(-) create mode 100644 src/leap/bitmask/util/polkit_agent.py (limited to 'src') diff --git a/src/leap/bitmask/services/eip/vpnlaunchers.py b/src/leap/bitmask/services/eip/vpnlaunchers.py index 5921882b..7ee54342 100644 --- a/src/leap/bitmask/services/eip/vpnlaunchers.py +++ b/src/leap/bitmask/services/eip/vpnlaunchers.py @@ -23,8 +23,8 @@ import logging import getpass import os import platform -import subprocess import stat +import subprocess try: import grp except ImportError: @@ -34,6 +34,7 @@ from abc import ABCMeta, abstractmethod from functools import partial from leap.bitmask.config.leapsettings import LeapSettings + from leap.bitmask.config.providerconfig import ProviderConfig from leap.bitmask.services.eip.eipconfig import EIPConfig, VPNGatewaySelector from leap.bitmask.util import first @@ -218,19 +219,19 @@ def _is_auth_agent_running(): return any(is_running) -def _try_to_launch_agent(): +def _try_to_launch_agent(standalone=False): """ Tries to launch a polkit daemon. """ - opts = [ - "/usr/lib/policykit-1-gnome/polkit-gnome-authentication-agent-1", - # XXX add kde thing here - ] - for cmd in opts: - try: - subprocess.Popen([cmd], shell=True) - except: - pass + env = None + if standalone is True: + env = { + "PYTHONPATH": os.path.abspath('../../../../lib/')} + try: + subprocess.call(["python", "-m", "leap.bitmask.util.polkit_agent"], + shell=True, env=env) + except Exception as exc: + logger.exception(exc) class LinuxVPNLauncher(VPNLauncher): @@ -314,7 +315,7 @@ class LinuxVPNLauncher(VPNLauncher): """ if _is_pkexec_in_system(): if not _is_auth_agent_running(): - _try_to_launch_agent() + _try_to_launch_agent(ProviderConfig.standalone) if _is_auth_agent_running(): pkexec_possibilities = which(kls.PKEXEC_BIN) leap_assert(len(pkexec_possibilities) > 0, diff --git a/src/leap/bitmask/util/polkit_agent.py b/src/leap/bitmask/util/polkit_agent.py new file mode 100644 index 00000000..a4650273 --- /dev/null +++ b/src/leap/bitmask/util/polkit_agent.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# polkit_agent.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 . +""" +Daemonizes polkit authentication agent. +""" +import logging +import subprocess + +import daemon + +logger = logging.getLogger(__name__) + +BASE_PATH = "/usr/lib/policykit-1-gnome/"\ + + "polkit-%s-authentication-agent-1" + +GNOME_PATH = BASE_PATH % ("gnome",) +KDE_PATH = BASE_PATH % ("kde",) + + +def _launch_agent(): + logger.debug('Launching polkit auth agent') + print "launching polkit" + try: + subprocess.call(GNOME_PATH) + except Exception as exc: + try: + subprocess.call(KDE_PATH) + except Exception as exc: + logger.error('Exception while running polkit authentication agent ' + '%s' % (exc,)) + + +def launch(): + with daemon.DaemonContext(): + _launch_agent() + +if __name__ == "__main__": + launch() -- cgit v1.2.3 From aae5eb050d6c5f8f4559ee33e231382421d1a569 Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Wed, 4 Sep 2013 11:27:07 -0300 Subject: Set appropiate error on login cancel. Closes #3582 --- src/leap/bitmask/gui/mainwindow.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py index 7a94fd0f..759a591b 100644 --- a/src/leap/bitmask/gui/mainwindow.py +++ b/src/leap/bitmask/gui/mainwindow.py @@ -891,6 +891,8 @@ class MainWindow(QtGui.QMainWindow): logger.debug("Cancelling login defer.") self._login_defer.cancel() + self._login_widget.set_status(self.tr("Log in cancelled by the user.")) + def _provider_config_loaded(self, data): """ SLOT -- cgit v1.2.3 From 1d9199849f889f244da113dd8e73fca02aa1d40e Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Wed, 4 Sep 2013 12:18:33 -0300 Subject: Enable preferences option in systray. Closes #3717 --- src/leap/bitmask/gui/mainwindow.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py index 759a591b..1fdd0792 100644 --- a/src/leap/bitmask/gui/mainwindow.py +++ b/src/leap/bitmask/gui/mainwindow.py @@ -270,6 +270,9 @@ class MainWindow(QtGui.QMainWindow): self._status_panel.set_action_eip_startstop( self._action_eip_startstop) + self._action_preferences = QtGui.QAction(self.tr("Preferences"), self) + self._action_preferences.triggered.connect(self._show_preferences) + self._action_visible = QtGui.QAction(self.tr("Hide Main Window"), self) self._action_visible.triggered.connect(self._toggle_visible) @@ -609,10 +612,8 @@ class MainWindow(QtGui.QMainWindow): self._systray.setVisible(True) return - # Placeholder actions - # They are temporary to display the tray as designed - preferences_action = QtGui.QAction(self.tr("Preferences"), self) - preferences_action.setEnabled(False) + # Placeholder action + # It is temporary to display the tray as designed help_action = QtGui.QAction(self.tr("Help"), self) help_action.setEnabled(False) @@ -623,7 +624,7 @@ class MainWindow(QtGui.QMainWindow): systrayMenu.addAction(self._action_eip_status) systrayMenu.addAction(self._action_eip_startstop) systrayMenu.addSeparator() - systrayMenu.addAction(preferences_action) + systrayMenu.addAction(self._action_preferences) systrayMenu.addAction(help_action) systrayMenu.addSeparator() systrayMenu.addAction(self.ui.action_log_out) -- cgit v1.2.3 From 845d70c8efb70478cb19fcc88e0c7958ee75370c Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Mon, 2 Sep 2013 17:39:22 -0300 Subject: Fix save log dialog freezing. Closes #3675. Avoid using native dialog seems to solve the QFileDialog freezing when qtreactor is used. See more at: http://www.code-corner.de/?p=171 --- src/leap/bitmask/gui/loggerwindow.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/leap/bitmask/gui/loggerwindow.py b/src/leap/bitmask/gui/loggerwindow.py index 9b4ba55d..ece4cad6 100644 --- a/src/leap/bitmask/gui/loggerwindow.py +++ b/src/leap/bitmask/gui/loggerwindow.py @@ -146,7 +146,8 @@ class LoggerWindow(QtGui.QDialog): Lets the user save the current log to a file """ fileName, filtr = QtGui.QFileDialog.getSaveFileName( - self, self.tr("Save As")) + self, self.tr("Save As"), + options=QtGui.QFileDialog.DontUseNativeDialog) if fileName: try: -- cgit v1.2.3 From 4a6acd4ed143d6d43ad9a70c13694dbae0cbaf49 Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Wed, 4 Sep 2013 20:05:57 +0200 Subject: Update version --- src/leap/bitmask/__init__.py | 75 ++++++++++++++++++++++++++++++++++ src/leap/bitmask/util/__init__.py | 50 +---------------------- src/leap/bitmask/util/leap_argparse.py | 6 ++- 3 files changed, 80 insertions(+), 51 deletions(-) (limited to 'src') diff --git a/src/leap/bitmask/__init__.py b/src/leap/bitmask/__init__.py index e69de29b..ebdd53c4 100644 --- a/src/leap/bitmask/__init__.py +++ b/src/leap/bitmask/__init__.py @@ -0,0 +1,75 @@ +# -*- coding: utf-8 -*- +# __init__.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 . +""" +Init file for leap.bitmask + +Initializes version and app info. +""" +import re + +from pkg_resources import parse_version + +from leap.bitmask.util import first + + +def _is_release_version(version): + """ + Helper to determine whether a version is a final release or not. + The release needs to be of the form: w.x.y.z containing only numbers + and dots. + + :param version: the version string + :type version: str + :returns: if the version is a release version or not. + :rtype: bool + """ + parsed_version = parse_version(version) + not_number = 0 + for x in parsed_version: + try: + int(x) + except: + not_number += 1 + + return not_number == 1 + + +__version__ = "unknown" +IS_RELEASE_VERSION = False + +__short_version__ = "unknown" + +try: + from leap.bitmask._version import get_versions + __version__ = get_versions()['version'] + IS_RELEASE_VERSION = _is_release_version(__version__) + del get_versions +except ImportError: + #running on a tree that has not run + #the setup.py setver + pass + +__appname__ = "unknown" +try: + from leap._appname import __appname__ +except ImportError: + #running on a tree that has not run + #the setup.py setver + pass + +__short_version__ = first(re.findall('\d\.\d\.\d', __version__)) +__full_version__ = __appname__ + '/' + str(__version__) diff --git a/src/leap/bitmask/util/__init__.py b/src/leap/bitmask/util/__init__.py index ce8323cd..6dd18bcf 100644 --- a/src/leap/bitmask/util/__init__.py +++ b/src/leap/bitmask/util/__init__.py @@ -15,59 +15,11 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . """ -Initializes version and app info, plus some small and handy functions. +Some small and handy functions. """ import datetime import os -from pkg_resources import parse_version - - -def _is_release_version(version): - """ - Helper to determine whether a version is a final release or not. - The release needs to be of the form: w.x.y.z containing only numbers - and dots. - - :param version: the version string - :type version: str - :returns: if the version is a release version or not. - :rtype: bool - """ - parsed_version = parse_version(version) - not_number = 0 - for x in parsed_version: - try: - int(x) - except: - not_number += 1 - - return not_number == 1 - - -__version__ = "unknown" -IS_RELEASE_VERSION = False - -try: - from leap.bitmask._version import get_versions - __version__ = get_versions()['version'] - IS_RELEASE_VERSION = _is_release_version(__version__) - del get_versions -except ImportError: - #running on a tree that has not run - #the setup.py setver - pass - -__appname__ = "unknown" -try: - from leap._appname import __appname__ -except ImportError: - #running on a tree that has not run - #the setup.py setver - pass - -__full_version__ = __appname__ + '/' + str(__version__) - def first(things): """ diff --git a/src/leap/bitmask/util/leap_argparse.py b/src/leap/bitmask/util/leap_argparse.py index 71f5163d..bc21a9cf 100644 --- a/src/leap/bitmask/util/leap_argparse.py +++ b/src/leap/bitmask/util/leap_argparse.py @@ -14,10 +14,12 @@ # # You should have received a copy of the GNU General Public License # along with this program. If not, see . - +""" +Parses the command line arguments passed to the application. +""" import argparse -from leap.bitmask.util import IS_RELEASE_VERSION +from leap.bitmask import IS_RELEASE_VERSION def build_parser(): -- cgit v1.2.3 From 6a4b2a00b59ac017b05e88812b2eb5ed8341bd66 Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Thu, 5 Sep 2013 14:34:47 -0300 Subject: Fix: Update version location. --- src/leap/bitmask/app.py | 2 +- src/leap/bitmask/gui/mainwindow.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/leap/bitmask/app.py b/src/leap/bitmask/app.py index 0dce5e61..158f1afe 100644 --- a/src/leap/bitmask/app.py +++ b/src/leap/bitmask/app.py @@ -156,7 +156,7 @@ def main(): from leap.bitmask.gui.mainwindow import MainWindow from leap.bitmask.platform_init import IS_MAC from leap.bitmask.platform_init.locks import we_are_the_one_and_only - from leap.bitmask.util import __version__ as VERSION + from leap.bitmask import __version__ as VERSION from leap.bitmask.util.requirement_checker import check_requirements # pylint: avoid unused import diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py index 1fdd0792..706b9c2a 100644 --- a/src/leap/bitmask/gui/mainwindow.py +++ b/src/leap/bitmask/gui/mainwindow.py @@ -58,7 +58,7 @@ from leap.bitmask.services.eip.vpnlaunchers import \ EIPNoPolkitAuthAgentAvailable from leap.bitmask.services.eip.vpnlaunchers import EIPNoTunKextLoaded -from leap.bitmask.util import __version__ as VERSION +from leap.bitmask import __version__ as VERSION from leap.bitmask.util.keyring_helpers import has_keyring from leap.bitmask.util.leap_log_handler import LeapLogHandler -- cgit v1.2.3 From ca1c9e01fecd74150399d5829d3255337be8f10a Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Wed, 4 Sep 2013 18:13:19 +0200 Subject: Fix invocation of the helper polkit-agent launcher. Otherwise, we are dumped into a nasty console. --- src/leap/bitmask/services/eip/vpnlaunchers.py | 8 +++++++- src/leap/bitmask/util/polkit_agent.py | 24 ++++++++++++------------ 2 files changed, 19 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/leap/bitmask/services/eip/vpnlaunchers.py b/src/leap/bitmask/services/eip/vpnlaunchers.py index 49edc8eb..a50da8b9 100644 --- a/src/leap/bitmask/services/eip/vpnlaunchers.py +++ b/src/leap/bitmask/services/eip/vpnlaunchers.py @@ -32,6 +32,7 @@ except ImportError: from abc import ABCMeta, abstractmethod from functools import partial +from time import sleep from leap.bitmask.config.leapsettings import LeapSettings @@ -228,7 +229,11 @@ def _try_to_launch_agent(standalone=False): env = { "PYTHONPATH": os.path.abspath('../../../../lib/')} try: - subprocess.call(["python", "-m", "leap.bitmask.util.polkit_agent"], + # We need to quote the command because subprocess call + # will do "sh -c 'foo'", so if we do not quoute it we'll end + # up with a invocation to the python interpreter. And that + # is bad. + subprocess.call(["python -m leap.bitmask.util.polkit_agent"], shell=True, env=env) except Exception as exc: logger.exception(exc) @@ -316,6 +321,7 @@ class LinuxVPNLauncher(VPNLauncher): if _is_pkexec_in_system(): if not _is_auth_agent_running(): _try_to_launch_agent(ProviderConfig.standalone) + sleep(0.5) if _is_auth_agent_running(): pkexec_possibilities = which(kls.PKEXEC_BIN) leap_assert(len(pkexec_possibilities) > 0, diff --git a/src/leap/bitmask/util/polkit_agent.py b/src/leap/bitmask/util/polkit_agent.py index a4650273..6fda2f88 100644 --- a/src/leap/bitmask/util/polkit_agent.py +++ b/src/leap/bitmask/util/polkit_agent.py @@ -24,24 +24,24 @@ import daemon logger = logging.getLogger(__name__) -BASE_PATH = "/usr/lib/policykit-1-gnome/"\ - + "polkit-%s-authentication-agent-1" - -GNOME_PATH = BASE_PATH % ("gnome",) -KDE_PATH = BASE_PATH % ("kde",) +AUTH_FILE = "polkit-%s-authentication-agent-1" +BASE_PATH_GNO = "/usr/lib/policykit-1-gnome/" +BASE_PATH_KDE = "/usr/lib/kde4/libexec/" +GNO_PATH = BASE_PATH_GNO + AUTH_FILE % ("gnome",) +KDE_PATH = BASE_PATH_KDE + AUTH_FILE % ("kde",) def _launch_agent(): logger.debug('Launching polkit auth agent') - print "launching polkit" try: - subprocess.call(GNOME_PATH) + subprocess.call(GNO_PATH) except Exception as exc: - try: - subprocess.call(KDE_PATH) - except Exception as exc: - logger.error('Exception while running polkit authentication agent ' - '%s' % (exc,)) + logger.error('Exception while running polkit authentication agent ' + '%s' % (exc,)) + # XXX fix KDE launch. See: #3755 + #try: + #subprocess.call(KDE_PATH) + #except Exception as exc: def launch(): -- cgit v1.2.3 From 6d2c5a14f51363a791fbc264f7e8d6cb4b69b6d2 Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Thu, 5 Sep 2013 15:54:33 -0300 Subject: Fix test checking is_release_version helper. --- src/leap/bitmask/util/tests/test_is_release_version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/leap/bitmask/util/tests/test_is_release_version.py b/src/leap/bitmask/util/tests/test_is_release_version.py index 088ec66d..0a0093da 100644 --- a/src/leap/bitmask/util/tests/test_is_release_version.py +++ b/src/leap/bitmask/util/tests/test_is_release_version.py @@ -19,7 +19,7 @@ tests for _is_release_version function """ import unittest -from leap.bitmask.util import _is_release_version as is_release_version +from leap.bitmask import _is_release_version as is_release_version from leap.common.testing.basetest import BaseLeapTest -- cgit v1.2.3 From 58420cb3d10cd5eceacbd88a6bc7fdfdc4a85f88 Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Thu, 5 Sep 2013 16:34:20 -0300 Subject: Display the mx status in the system tray. --- src/leap/bitmask/gui/mainwindow.py | 9 ++++++- src/leap/bitmask/gui/statuspanel.py | 50 ++++++++++++++++++++++++++++--------- 2 files changed, 46 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py index 706b9c2a..0950462b 100644 --- a/src/leap/bitmask/gui/mainwindow.py +++ b/src/leap/bitmask/gui/mainwindow.py @@ -254,14 +254,20 @@ class MainWindow(QtGui.QMainWindow): 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) - self._status_panel.set_action_eip_status( self._action_eip_status) + self._action_mail_status = QtGui.QAction( + self.tr("Encrypted Mail is OFF"), self) + self._action_mail_status.setEnabled(False) + self._status_panel.set_action_mail_status( + self._action_mail_status) + self._action_eip_startstop = QtGui.QAction( self.tr("Turn OFF"), self) self._action_eip_startstop.triggered.connect( @@ -623,6 +629,7 @@ class MainWindow(QtGui.QMainWindow): systrayMenu.addAction(self._action_eip_provider) systrayMenu.addAction(self._action_eip_status) systrayMenu.addAction(self._action_eip_startstop) + systrayMenu.addAction(self._action_mail_status) systrayMenu.addSeparator() systrayMenu.addAction(self._action_preferences) systrayMenu.addAction(help_action) diff --git a/src/leap/bitmask/gui/statuspanel.py b/src/leap/bitmask/gui/statuspanel.py index 49d7e24a..3a91f08e 100644 --- a/src/leap/bitmask/gui/statuspanel.py +++ b/src/leap/bitmask/gui/statuspanel.py @@ -356,6 +356,16 @@ class StatusPanelWidget(QtGui.QWidget): leap_assert_type(action_eip_status, QtGui.QAction) self._action_eip_status = action_eip_status + def set_action_mail_status(self, action_mail_status): + """ + Sets the action_mail_status to use. + + :param action_mail_status: action_mail_status to be used + :type action_mail_status: QtGui.QAction + """ + leap_assert_type(action_mail_status, QtGui.QAction) + self._action_mail_status = action_mail_status + def set_global_status(self, status, error=False): """ Sets the global status label. @@ -538,6 +548,27 @@ class StatusPanelWidget(QtGui.QWidget): def set_provider(self, provider): self.ui.lblProvider.setText(provider) + def _set_mail_status(self, status, ready=False): + """ + Sets the Encrypted Mail status in the label and in the tray icon. + + :param status: the status text to display + :type status: unicode + :param ready: if mx is ready or not. + :type ready: bool + """ + self.ui.lblMailStatus.setText(status) + + tray_status = self.tr('Encrypted Mail is OFF') + + icon = QtGui.QPixmap(self.MAIL_OFF_ICON) + if ready: + icon = QtGui.QPixmap(self.MAIL_ON_ICON) + tray_status = self.tr('Encrypted Mail is ON') + + self.ui.lblMailIcon.setPixmap(icon) + self._action_mail_status.setText(tray_status) + def _mail_handle_soledad_events(self, req): """ Callback for ... @@ -557,7 +588,7 @@ class StatusPanelWidget(QtGui.QWidget): :param req: Request type :type req: leap.common.events.events_pb2.SignalRequest """ - self.ui.lblMailStatus.setText(self.tr("Starting...")) + self._set_mail_status(self.tr("Starting...")) ext_status = "" @@ -596,7 +627,7 @@ class StatusPanelWidget(QtGui.QWidget): if self._smtp_started and self._imap_started: return - self.ui.lblMailStatus.setText(self.tr("Starting...")) + self._set_mail_status(self.tr("Starting...")) ext_status = "" @@ -644,14 +675,11 @@ class StatusPanelWidget(QtGui.QWidget): ext_status = self.tr("SMTP has started...") self._smtp_started = True if self._smtp_started and self._imap_started: - self.ui.lblMailStatus.setText(self.tr("ON")) - self.ui.lblMailIcon.setPixmap(QtGui.QPixmap(self.MAIL_ON_ICON)) - self.ui.lblMailIcon.setPixmap( - QtGui.QPixmap(":/images/mail-locked.png")) + self._set_mail_status(self.tr("ON"), ready=True) ext_status = "" elif req.event == proto.SMTP_SERVICE_FAILED_TO_START: ext_status = self.tr("SMTP failed to start, check the logs.") - self.ui.lblMailStatus.setText(self.tr("Failed")) + self._set_mail_status(self.tr("Failed")) else: leap_assert(False, "Don't know how to handle this state: %s" @@ -684,19 +712,17 @@ class StatusPanelWidget(QtGui.QWidget): ext_status = self.tr("IMAP has started...") self._imap_started = True if self._smtp_started and self._imap_started: - self.ui.lblMailStatus.setText(self.tr("ON")) - self.ui.lblMailIcon.setPixmap(QtGui.QPixmap(self.MAIL_ON_ICON)) + self._set_mail_status(self.tr("ON"), ready=True) ext_status = "" elif req.event == proto.IMAP_SERVICE_FAILED_TO_START: ext_status = self.tr("IMAP failed to start, check the logs.") - self.ui.lblMailStatus.setText(self.tr("Failed")) + self._set_mail_status(self.tr("Failed")) elif req.event == proto.IMAP_UNREAD_MAIL: if self._smtp_started and self._imap_started: self.ui.lblUnread.setText( self.tr("%s Unread Emails") % (req.content)) self.ui.lblUnread.setVisible(req.content != "0") - self.ui.lblMailStatus.setText(self.tr("ON")) - self.ui.lblMailIcon.setPixmap(QtGui.QPixmap(self.MAIL_ON_ICON)) + self._set_mail_status(self.tr("ON"), ready=True) else: leap_assert(False, "Don't know how to handle this state: %s" -- cgit v1.2.3 From 6df266025131673a91ff40bbb715e836aaf1b49a Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Mon, 9 Sep 2013 09:13:30 -0300 Subject: Fix path prefix helper for bundle and add test. --- src/leap/bitmask/config/leapsettings.py | 12 ++-- src/leap/bitmask/config/tests/test_leapsettings.py | 71 ++++++++++++++++++++++ 2 files changed, 77 insertions(+), 6 deletions(-) create mode 100644 src/leap/bitmask/config/tests/test_leapsettings.py (limited to 'src') diff --git a/src/leap/bitmask/config/leapsettings.py b/src/leap/bitmask/config/leapsettings.py index ad67b29e..7d8b5977 100644 --- a/src/leap/bitmask/config/leapsettings.py +++ b/src/leap/bitmask/config/leapsettings.py @@ -75,12 +75,12 @@ class LeapSettings(object): """ Constructor - :param standalone: parameter used to define the location of - the config + :param standalone: parameter used to define the location of the config. :type standalone: bool """ - settings_path = os.path.join( - get_path_prefix(standalone=standalone), "leap", self.CONFIG_NAME) + self._path_prefix = get_path_prefix(standalone=standalone) + settings_path = os.path.join(self._path_prefix, + "leap", self.CONFIG_NAME) self._settings = QtCore.QSettings(settings_path, QtCore.QSettings.IniFormat) @@ -132,8 +132,8 @@ class LeapSettings(object): # other things, not just the directories providers = [] try: - providers_path = os.path.join( - get_path_prefix(), "leap", "providers") + providers_path = os.path.join(self._path_prefix, + "leap", "providers") providers = os.listdir(providers_path) except Exception as e: logger.debug("Error listing providers, assume there are none. %r" diff --git a/src/leap/bitmask/config/tests/test_leapsettings.py b/src/leap/bitmask/config/tests/test_leapsettings.py new file mode 100644 index 00000000..18166923 --- /dev/null +++ b/src/leap/bitmask/config/tests/test_leapsettings.py @@ -0,0 +1,71 @@ +# -*- coding: utf-8 -*- +# test_leapsettings.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 . + +""" +Tests for leapsettings module. +""" + +try: + import unittest2 as unittest +except ImportError: + import unittest + +import os +import mock + +from leap.common.testing.basetest import BaseLeapTest +from leap.bitmask.config.leapsettings import LeapSettings + + +class LeapSettingsTest(BaseLeapTest): + """Tests for LeapSettings""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def test_get_configured_providers(self): + """ + Test that the config file IS NOT stored under the CWD. + """ + self._leapsettings = LeapSettings() + with mock.patch('os.listdir') as os_listdir: + # use this method only to spy where LeapSettings is looking for + self._leapsettings.get_configured_providers() + args, kwargs = os_listdir.call_args + config_dir = args[0] + self.assertFalse(config_dir.startswith(os.getcwd())) + self.assertFalse(config_dir.endswith('config')) + + def test_get_configured_providers_in_bundle(self): + """ + Test that the config file IS stored under the CWD. + """ + self._leapsettings = LeapSettings(standalone=True) + with mock.patch('os.listdir') as os_listdir: + # use this method only to spy where LeapSettings is looking for + self._leapsettings.get_configured_providers() + args, kwargs = os_listdir.call_args + config_dir = args[0] + self.assertTrue(config_dir.startswith(os.getcwd())) + self.assertFalse(config_dir.endswith('config')) + + +if __name__ == "__main__": + unittest.main() -- cgit v1.2.3 From f72e3c5d02b5d8c2272359b2bd6cd4963ddfe9cb Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Wed, 11 Sep 2013 12:41:51 +0200 Subject: catch indexerror on first utility --- src/leap/bitmask/util/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/leap/bitmask/util/__init__.py b/src/leap/bitmask/util/__init__.py index 6dd18bcf..78efcb6e 100644 --- a/src/leap/bitmask/util/__init__.py +++ b/src/leap/bitmask/util/__init__.py @@ -27,7 +27,7 @@ def first(things): """ try: return things[0] - except TypeError: + except (IndexError, TypeError): return None -- cgit v1.2.3