summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKali Kaneko <kali@leap.se>2013-10-01 17:34:24 -0400
committerKali Kaneko <kali@leap.se>2013-10-03 13:14:34 -0400
commit689c716b831047c8fe18945956e809b74e4250a3 (patch)
treec1f3b1f82abe2d29a6232f6b4bda1d4404a44555
parente9c84a3d2d9fd3a0457f256a908cb5bce9351682 (diff)
Disable EIP on/off button and action when login required.
Also adds an explicit should_autostart flag in config.
-rw-r--r--changes/bug_3927_fix-eip-turn-on-button-action2
-rw-r--r--src/leap/bitmask/config/__init__.py0
-rw-r--r--src/leap/bitmask/config/leapsettings.py19
-rw-r--r--src/leap/bitmask/gui/eip_status.py26
-rw-r--r--src/leap/bitmask/gui/login.py4
-rw-r--r--src/leap/bitmask/gui/mainwindow.py118
-rw-r--r--src/leap/bitmask/provider/__init__.py34
-rw-r--r--src/leap/bitmask/services/eip/eipconfig.py40
8 files changed, 206 insertions, 37 deletions
diff --git a/changes/bug_3927_fix-eip-turn-on-button-action b/changes/bug_3927_fix-eip-turn-on-button-action
new file mode 100644
index 00000000..53e9b133
--- /dev/null
+++ b/changes/bug_3927_fix-eip-turn-on-button-action
@@ -0,0 +1,2 @@
+ o Avoids errors due to the EIP switch button and action being enabled
+ when we do not have a configured provider. Closes: #3927
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):