diff options
| author | Kali Kaneko <kali@leap.se> | 2013-10-01 17:34:24 -0400 | 
|---|---|---|
| committer | Kali Kaneko <kali@leap.se> | 2013-10-03 13:14:34 -0400 | 
| commit | 689c716b831047c8fe18945956e809b74e4250a3 (patch) | |
| tree | c1f3b1f82abe2d29a6232f6b4bda1d4404a44555 /src | |
| parent | e9c84a3d2d9fd3a0457f256a908cb5bce9351682 (diff) | |
Disable EIP on/off button and action when login required.
Also adds an explicit should_autostart flag in config.
Diffstat (limited to 'src')
| -rw-r--r-- | src/leap/bitmask/config/__init__.py | 0 | ||||
| -rw-r--r-- | src/leap/bitmask/config/leapsettings.py | 19 | ||||
| -rw-r--r-- | src/leap/bitmask/gui/eip_status.py | 26 | ||||
| -rw-r--r-- | src/leap/bitmask/gui/login.py | 4 | ||||
| -rw-r--r-- | src/leap/bitmask/gui/mainwindow.py | 118 | ||||
| -rw-r--r-- | src/leap/bitmask/provider/__init__.py | 34 | ||||
| -rw-r--r-- | src/leap/bitmask/services/eip/eipconfig.py | 40 | 
7 files changed, 204 insertions, 37 deletions
| diff --git a/src/leap/bitmask/config/__init__.py b/src/leap/bitmask/config/__init__.py deleted file mode 100644 index e69de29b..00000000 --- a/src/leap/bitmask/config/__init__.py +++ /dev/null diff --git a/src/leap/bitmask/config/leapsettings.py b/src/leap/bitmask/config/leapsettings.py index 338fa475..dc1af899 100644 --- a/src/leap/bitmask/config/leapsettings.py +++ b/src/leap/bitmask/config/leapsettings.py @@ -65,6 +65,7 @@ class LeapSettings(object):      PROPERPROVIDER_KEY = "ProperProvider"      REMEMBER_KEY = "RememberUserAndPass"      DEFAULTPROVIDER_KEY = "DefaultProvider" +    AUTOSTARTEIP_KEY = "AutoStartEIP"      ALERTMISSING_KEY = "AlertMissingScripts"      GATEWAY_KEY = "Gateway" @@ -285,6 +286,24 @@ class LeapSettings(object):          else:              self._settings.setValue(self.DEFAULTPROVIDER_KEY, provider) +    def get_autostart_eip(self): +        """ +        Gets whether the app should autostart EIP. + +        :rtype: bool +        """ +        return to_bool(self._settings.value(self.AUTOSTARTEIP_KEY, False)) + +    def set_autostart_eip(self, autostart): +        """ +        Sets whether the app should autostart EIP. + +        :param autostart: True if we should try to autostart EIP. +        :type autostart: bool +        """ +        leap_assert_type(autostart, bool) +        self._settings.setValue(self.AUTOSTARTEIP_KEY, autostart) +      def get_alert_missing_scripts(self):          """          Returns the setting for alerting of missing up/down scripts. diff --git a/src/leap/bitmask/gui/eip_status.py b/src/leap/bitmask/gui/eip_status.py index 6b1235a6..946eaa4e 100644 --- a/src/leap/bitmask/gui/eip_status.py +++ b/src/leap/bitmask/gui/eip_status.py @@ -233,6 +233,30 @@ class EIPStatusWidget(QtGui.QWidget):          """          self.set_startstop_enabled(False) +    @QtCore.Slot() +    def disable_eip_start(self): +        """ +        Triggered when a default provider_config has not been found. +        Disables the start button and adds instructions to the user. +        """ +        logger.debug('Hiding EIP start button') +        # you might be tempted to change this for a .setEnabled(False). +        # it won't work. it's under the claws of the state machine. +        # probably the best thing would be to make a transitional +        # transition there, but that's more involved. +        self.eip_button.hide() +        msg = self.tr("You must login to use Encrypted Internet") +        self.eip_label.setText(msg) + +    @QtCore.Slot() +    def enable_eip_start(self): +        """ +        Triggered after a successful login. +        Enables the start button. +        """ +        logger.debug('Showing EIP start button') +        self.eip_button.show() +      # XXX disable (later) --------------------------      def set_eip_status(self, status, error=False):          """ @@ -261,6 +285,8 @@ class EIPStatusWidget(QtGui.QWidget):          :param value: True for enabled, False otherwise          :type value: bool          """ +        # TODO use disable_eip_start instead +        # this should be handled by the state machine          leap_assert_type(value, bool)          self.ui.btnEipStartStop.setEnabled(value)          self._action_eip_startstop.setEnabled(value) diff --git a/src/leap/bitmask/gui/login.py b/src/leap/bitmask/gui/login.py index c635081c..582f26be 100644 --- a/src/leap/bitmask/gui/login.py +++ b/src/leap/bitmask/gui/login.py @@ -14,7 +14,6 @@  #  # You should have received a copy of the GNU General Public License  # along with this program.  If not, see <http://www.gnu.org/licenses/>. -  """  Login widget implementation  """ @@ -36,9 +35,9 @@ class LoginWidget(QtGui.QWidget):      Login widget that emits signals to display the wizard or to      perform login.      """ -      # Emitted when the login button is clicked      login = QtCore.Signal() +    logged_in_signal = QtCore.Signal()      cancel_login = QtCore.Signal()      logout = QtCore.Signal() @@ -320,6 +319,7 @@ class LoginWidget(QtGui.QWidget):          self.ui.lblUser.setText("%s@%s" % (self.get_user(),                                             self.get_selected_provider()))          self.set_login_status("") +        self.logged_in_signal.emit()      def logged_out(self):          """ diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py index 58ed3eb3..7129b670 100644 --- a/src/leap/bitmask/gui/mainwindow.py +++ b/src/leap/bitmask/gui/mainwindow.py @@ -38,9 +38,10 @@ from leap.bitmask.gui.eip_status import EIPStatusWidget  from leap.bitmask.gui.mail_status import MailStatusWidget  from leap.bitmask.gui.wizard import Wizard +from leap.bitmask import provider  from leap.bitmask.provider.providerbootstrapper import ProviderBootstrapper  from leap.bitmask.services.eip.eipbootstrapper import EIPBootstrapper -from leap.bitmask.services.eip.eipconfig import EIPConfig +from leap.bitmask.services.eip import eipconfig  # XXX: Soledad might not work out of the box in Windows, issue #2932  from leap.bitmask.services.soledad.soledadbootstrapper import \      SoledadBootstrapper @@ -100,6 +101,7 @@ class MainWindow(QtGui.QMainWindow):      MX_SERVICE = "mx"      # Signals +    eip_needs_login = QtCore.Signal([])      new_updates = QtCore.Signal(object)      raise_window = QtCore.Signal([])      soledad_ready = QtCore.Signal([]) @@ -162,6 +164,10 @@ class MainWindow(QtGui.QMainWindow):          self._eip_status = EIPStatusWidget(self)          self.ui.eipLayout.addWidget(self._eip_status) +        self._login_widget.logged_in_signal.connect( +            self._eip_status.enable_eip_start) +        self._login_widget.logged_in_signal.connect( +            self._enable_eip_start_action)          self._mail_status = MailStatusWidget(self)          self.ui.mailLayout.addWidget(self._mail_status) @@ -174,13 +180,17 @@ class MainWindow(QtGui.QMainWindow):              self._stop_eip)          self._eip_status.eip_connection_connected.connect(              self._on_eip_connected) +        self.eip_needs_login.connect( +            self._eip_status.disable_eip_start) +        self.eip_needs_login.connect( +            self._disable_eip_start_action)          # This is loaded only once, there's a bug when doing that more          # than once          self._provider_config = ProviderConfig()          # Used for automatic start of EIP          self._provisional_provider_config = ProviderConfig() -        self._eip_config = EIPConfig() +        self._eip_config = eipconfig.EIPConfig()          self._already_started_eip = False @@ -309,27 +319,29 @@ class MainWindow(QtGui.QMainWindow):          self._smtp_config = SMTPConfig() -        if self._first_run(): -            self._wizard_firstrun = True -            self._wizard = Wizard(bypass_checks=bypass_checks) -            # Give this window time to finish init and then show the wizard -            QtCore.QTimer.singleShot(1, self._launch_wizard) -            self._wizard.accepted.connect(self._finish_init) -            self._wizard.rejected.connect(self._rejected_wizard) -        else: -            self._finish_init() -          # Eip machine is a public attribute where the state machine for          # the eip connection will be available to the different components.          # Remember that this will not live in the  +1600LOC mainwindow for          # all the eternity, so at some point we will be moving this to          # the EIPConductor or some other clever component that we will          # instantiate from here. -        self.eip_machine = None +        self.eip_machine = None          # start event machines          self.start_eip_machine() +        if self._first_run(): +            self._wizard_firstrun = True +            self._wizard = Wizard(bypass_checks=bypass_checks) +            # Give this window time to finish init and then show the wizard +            QtCore.QTimer.singleShot(1, self._launch_wizard) +            self._wizard.accepted.connect(self._finish_init) +            self._wizard.rejected.connect(self._rejected_wizard) +        else: +            # during finish_init, we disable the eip start button +            # so this has to be done after eip_machine is started +            self._finish_init() +      def _rejected_wizard(self):          """          SLOT @@ -582,21 +594,29 @@ class MainWindow(QtGui.QMainWindow):          """          Tries to autostart EIP          """ -        default_provider = self._settings.get_defaultprovider() +        settings = self._settings + +        should_autostart = settings.get_autostart_eip() +        if not should_autostart: +            logger.debug('Will not autostart EIP since it is setup ' +                         'to not to do it') +            self.eip_needs_login.emit() +            return + +        default_provider = settings.get_defaultprovider()          if default_provider is None:              logger.info("Cannot autostart Encrypted Internet because there is "                          "no default provider configured") +            self.eip_needs_login.emit()              return -        self._enabled_services = self._settings.get_enabled_services( +        self._enabled_services = settings.get_enabled_services(              default_provider) -        if self._provisional_provider_config.load( -            os.path.join("leap", -                         "providers", -                         default_provider, -                         "provider.json")): +        loaded = self._provisional_provider_config.load( +            provider.get_provider_path(default_provider)) +        if loaded:              # XXX I think we should not try to re-download config every time,              # it adds some delay.              # Maybe if it's the first run in a session, @@ -604,6 +624,7 @@ class MainWindow(QtGui.QMainWindow):              self._download_eip_config()          else:              # XXX: Display a proper message to the user +            self.eip_needs_login.emit()              logger.error("Unable to load %s config, cannot autostart." %                           (default_provider,)) @@ -1165,6 +1186,21 @@ class MainWindow(QtGui.QMainWindow):                                             label=label)          self.eip_machine = eip_machine          self.eip_machine.start() +        logger.debug('eip machine started') + +    @QtCore.Slot() +    def _disable_eip_start_action(self): +        """ +        Disables the EIP start action in the systray menu. +        """ +        self._action_eip_startstop.setEnabled(False) + +    @QtCore.Slot() +    def _enable_eip_start_action(self): +        """ +        Enables the EIP start action in the systray menu. +        """ +        self._action_eip_startstop.setEnabled(True)      @QtCore.Slot()      def _on_eip_connected(self): @@ -1197,6 +1233,27 @@ class MainWindow(QtGui.QMainWindow):          self._eip_status.eip_pre_up()          self.user_stopped_eip = False +        # until we set an option in the preferences window, +        # we'll assume that by default we try to autostart. +        # If we switch it off manually, it won't try the next +        # time. +        self._settings.set_autostart_eip(True) + +        loaded = eipconfig.load_eipconfig_if_needed( +            provider_config, self._eip_config, provider) + +        if not loaded: +            self._eip_status.set_eip_status( +                self.tr("Could not load Encrypted Internet " +                        "Configuration."), +                error=True) +            # signal connection aborted to state machine +            qtsigs = self._eip_connection.qtsigs +            qtsigs.connection_aborted_signal.emit() +            logger.error("Tried to start EIP but cannot find any " +                         "available provider!") +            return +          try:              # XXX move this to EIPConductor              host, port = get_openvpn_management() @@ -1263,7 +1320,7 @@ class MainWindow(QtGui.QMainWindow):              self._already_started_eip = True      @QtCore.Slot() -    def _stop_eip(self, abnormal=False): +    def _stop_eip(self):          """          SLOT          TRIGGERS: @@ -1277,18 +1334,15 @@ class MainWindow(QtGui.QMainWindow):          :param abnormal: whether this was an abnormal termination.          :type abnormal: bool          """ -        if abnormal: -            logger.warning("Abnormal EIP termination.") -          self.user_stopped_eip = True          self._vpn.terminate()          self._set_eipstatus_off(False) -          self._already_started_eip = False -        # XXX do via signal -        self._settings.set_defaultprovider(None) +        logger.debug('Setting autostart to: False') +        self._settings.set_autostart_eip(False) +          if self._logged_user:              self._eip_status.set_provider(                  "%s@%s" % (self._logged_user, @@ -1351,13 +1405,9 @@ class MainWindow(QtGui.QMainWindow):          provider_config = self._get_best_provider_config()          domain = provider_config.get_domain() -        loaded = self._eip_config.loaded() -        if not loaded: -            eip_config_path = os.path.join("leap", "providers", -                                           domain, "eip-service.json") -            api_version = provider_config.get_api_version() -            self._eip_config.set_api_version(api_version) -            loaded = self._eip_config.load(eip_config_path) +        # XXX  move check to _start_eip ? +        loaded = eipconfig.load_eipconfig_if_needed( +            provider_config, self._eip_config, domain)          if loaded:              # DO START EIP Connection! diff --git a/src/leap/bitmask/provider/__init__.py b/src/leap/bitmask/provider/__init__.py index e69de29b..53587d65 100644 --- a/src/leap/bitmask/provider/__init__.py +++ b/src/leap/bitmask/provider/__init__.py @@ -0,0 +1,34 @@ +# -*- 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 <http://www.gnu.org/licenses/>. +""" +Module initialization for leap.bitmask.provider +""" +import os +from leap.common.check import leap_assert + + +def get_provider_path(domain): +    """ +    Returns relative path for provider config. + +    :param domain: the domain to which this providerconfig belongs to. +    :type domain: str +    :returns: the path +    :rtype: str +    """ +    leap_assert(domain is not None, "get_provider_path: We need a domain") +    return os.path.join("leap", "providers", domain, "provider.json") diff --git a/src/leap/bitmask/services/eip/eipconfig.py b/src/leap/bitmask/services/eip/eipconfig.py index 7d8995b4..16ed4cc0 100644 --- a/src/leap/bitmask/services/eip/eipconfig.py +++ b/src/leap/bitmask/services/eip/eipconfig.py @@ -33,6 +33,45 @@ from leap.common.check import leap_assert, leap_assert_type  logger = logging.getLogger(__name__) +def get_eipconfig_path(domain): +    """ +    Returns relative path for EIP config. + +    :param domain: the domain to which this eipconfig belongs to. +    :type domain: str +    :returns: the path +    :rtype: str +    """ +    leap_assert(domain is not None, "get_eipconfig_path: We need a domain") +    return os.path.join("leap", "providers", domain, "eip-service.json") + + +def load_eipconfig_if_needed(provider_config, eip_config, domain): +    """ +    Utility function to prime a eip_config object from a loaded +    provider_config and the chosen provider domain. + +    :param provider_config: a loaded instance of ProviderConfig +    :type provider_config: ProviderConfig + +    :param eip_config: the eipconfig object to be primed. +    :type eip_config: EIPConfig + +    :param domain: the chosen provider domain +    :type domain: str + +    :returns: Whether the eip_config object has been succesfully loaded +    :rtype: bool +    """ +    loaded = eip_config.loaded() +    if not loaded: +        eip_config_path = get_eipconfig_path(domain) +        api_version = provider_config.get_api_version() +        eip_config.set_api_version(api_version) +        loaded = eip_config.load(eip_config_path) +    return loaded + +  class VPNGatewaySelector(object):      """      VPN Gateway selector. @@ -59,7 +98,6 @@ class VPNGatewaySelector(object):              tz_offset = self.equivalent_timezones[tz_offset]          self._local_offset = tz_offset -          self._eipconfig = eipconfig      def get_gateways_list(self): | 
