summaryrefslogtreecommitdiff
path: root/src/leap/bitmask/gui
diff options
context:
space:
mode:
Diffstat (limited to 'src/leap/bitmask/gui')
-rw-r--r--src/leap/bitmask/gui/__init__.py7
-rw-r--r--src/leap/bitmask/gui/eip_preferenceswindow.py11
-rw-r--r--src/leap/bitmask/gui/eip_status.py32
-rw-r--r--src/leap/bitmask/gui/mail_status.py2
-rw-r--r--src/leap/bitmask/gui/mainwindow.py148
-rw-r--r--src/leap/bitmask/gui/preferenceswindow.py13
-rw-r--r--src/leap/bitmask/gui/statemachines.py11
-rw-r--r--src/leap/bitmask/gui/twisted_main.py43
-rw-r--r--src/leap/bitmask/gui/wizard.py115
9 files changed, 215 insertions, 167 deletions
diff --git a/src/leap/bitmask/gui/__init__.py b/src/leap/bitmask/gui/__init__.py
index 4b289442..bba02061 100644
--- a/src/leap/bitmask/gui/__init__.py
+++ b/src/leap/bitmask/gui/__init__.py
@@ -17,5 +17,8 @@
"""
init file for leap.gui
"""
-app = __import__("app", globals(), locals(), [], 2)
-__all__ = [app]
+# This was added for coverage and testing, but when doing the osx
+# bundle with py2app it fails because of this, so commenting for now
+# Also creates conflicts with the new frontend/backend separation.
+# app = __import__("app", globals(), locals(), [], 2)
+# __all__ = [app]
diff --git a/src/leap/bitmask/gui/eip_preferenceswindow.py b/src/leap/bitmask/gui/eip_preferenceswindow.py
index 530cd38d..0f63972f 100644
--- a/src/leap/bitmask/gui/eip_preferenceswindow.py
+++ b/src/leap/bitmask/gui/eip_preferenceswindow.py
@@ -33,7 +33,7 @@ class EIPPreferencesWindow(QtGui.QDialog):
"""
Window that displays the EIP preferences.
"""
- def __init__(self, parent, domain, backend):
+ def __init__(self, parent, domain, backend, leap_signaler):
"""
:param parent: parent object of the EIPPreferencesWindow.
:type parent: QWidget
@@ -46,6 +46,7 @@ class EIPPreferencesWindow(QtGui.QDialog):
self.AUTOMATIC_GATEWAY_LABEL = self.tr("Automatic")
self._settings = LeapSettings()
+ self._leap_signaler = leap_signaler
self._backend = backend
# Load UI
@@ -96,7 +97,7 @@ class EIPPreferencesWindow(QtGui.QDialog):
if not providers:
return
- self._backend.eip_get_initialized_providers(providers)
+ self._backend.eip_get_initialized_providers(domains=providers)
@QtCore.Slot(list)
def _load_providers_in_combo(self, providers):
@@ -148,6 +149,8 @@ class EIPPreferencesWindow(QtGui.QDialog):
gateway = self.ui.cbGateways.itemData(idx)
self._settings.set_selected_gateway(provider, gateway)
+ self._backend.settings_set_selected_gateway(provider=provider,
+ gateway=gateway)
msg = self.tr(
"Gateway settings for provider '{0}' saved.").format(provider)
@@ -174,7 +177,7 @@ class EIPPreferencesWindow(QtGui.QDialog):
domain = self.ui.cbProvidersGateway.itemData(domain_idx)
self._selected_domain = domain
- self._backend.eip_get_gateways_list(domain)
+ self._backend.eip_get_gateways_list(domain=domain)
@QtCore.Slot(list)
def _update_gateways_list(self, gateways):
@@ -248,7 +251,7 @@ class EIPPreferencesWindow(QtGui.QDialog):
self.ui.cbGateways.setEnabled(False)
def _backend_connect(self):
- sig = self._backend.signaler
+ sig = self._leap_signaler
sig.eip_get_gateways_list.connect(self._update_gateways_list)
sig.eip_get_gateways_list_error.connect(self._gateways_list_error)
sig.eip_uninitialized_provider.connect(
diff --git a/src/leap/bitmask/gui/eip_status.py b/src/leap/bitmask/gui/eip_status.py
index bd569343..a707050a 100644
--- a/src/leap/bitmask/gui/eip_status.py
+++ b/src/leap/bitmask/gui/eip_status.py
@@ -24,7 +24,6 @@ from functools import partial
from PySide import QtCore, QtGui
-from leap.bitmask.config import flags
from leap.bitmask.services import get_service_display_name, EIP_SERVICE
from leap.bitmask.platform_init import IS_LINUX
from leap.bitmask.util.averages import RateMovingAverage
@@ -44,7 +43,7 @@ class EIPStatusWidget(QtGui.QWidget):
RATE_STR = "%1.2f KB/s"
TOTAL_STR = "%1.2f Kb"
- def __init__(self, parent=None, eip_conductor=None):
+ def __init__(self, parent, eip_conductor, leap_signaler):
"""
:param parent: the parent of the widget.
:type parent: QObject
@@ -60,6 +59,8 @@ class EIPStatusWidget(QtGui.QWidget):
self.ui = Ui_EIPStatus()
self.ui.setupUi(self)
+ self._leap_signaler = leap_signaler
+
self.eip_conductor = eip_conductor
self.eipconnection = eip_conductor.eip_connection
@@ -98,7 +99,7 @@ class EIPStatusWidget(QtGui.QWidget):
"""
Connect backend signals.
"""
- signaler = self.eip_conductor._backend.signaler
+ signaler = self._leap_signaler
signaler.eip_openvpn_already_running.connect(
self._on_eip_openvpn_already_running)
@@ -121,8 +122,8 @@ class EIPStatusWidget(QtGui.QWidget):
# XXX we cannot connect this signal now because
# it interferes with the proper notifications during restarts
# without available network.
- #signaler.eip_network_unreachable.connect(
- #self._on_eip_network_unreachable)
+ # signaler.eip_network_unreachable.connect(
+ # self._on_eip_network_unreachable)
def _make_status_clickable(self):
"""
@@ -324,7 +325,7 @@ class EIPStatusWidget(QtGui.QWidget):
Triggered after a successful login.
Enables the start button.
"""
- #logger.debug('Showing EIP start button')
+ # logger.debug('Showing EIP start button')
self.eip_button.show()
# Restore the eip action menu
@@ -543,7 +544,7 @@ class EIPStatusWidget(QtGui.QWidget):
elif vpn_state == "ALREADYRUNNING":
# Put the following calls in Qt's event queue, otherwise
# the UI won't update properly
- #self.send_disconnect_signal()
+ # self.send_disconnect_signal()
QtDelayedCall(
0, self.eipconnection.qtsigns.do_disconnect_signal.emit)
msg = self.tr("Unable to start VPN, it's already running.")
@@ -587,16 +588,23 @@ class EIPStatusWidget(QtGui.QWidget):
self._systray.setIcon(QtGui.QIcon(selected_pixmap_tray))
self._eip_status_menu.setTitle(tray_message)
- def set_provider(self, provider):
+ def set_provider(self, provider, country_code):
+ """
+ Set the provider used right now, name and flag (if available).
+
+ :param provider: the provider in use.
+ :type provider: str
+ :param country_code: the country code of the gateway in use.
+ :type country_code: str
+ """
self._provider = provider
self.ui.lblEIPMessage.setText(
self.tr("Routing traffic through: <b>{0}</b>").format(
provider))
- ccode = flags.CURRENT_VPN_COUNTRY
- if ccode is not None:
- self.set_country_code(ccode)
+ if country_code is not None:
+ self.set_country_code(country_code)
def set_country_code(self, code):
"""
@@ -729,7 +737,7 @@ class EIPStatusWidget(QtGui.QWidget):
self.set_eip_status_icon("error")
def set_eipstatus_off(self, error=True):
- # XXX this should be handled by the state machine.
+ # XXX this should be handled by the state machine.
"""
Sets eip status to off
"""
diff --git a/src/leap/bitmask/gui/mail_status.py b/src/leap/bitmask/gui/mail_status.py
index 5caef745..bb755b5c 100644
--- a/src/leap/bitmask/gui/mail_status.py
+++ b/src/leap/bitmask/gui/mail_status.py
@@ -304,7 +304,7 @@ class MailStatusWidget(QtGui.QWidget):
ext_status = ""
if req.event == proto.KEYMANAGER_LOOKING_FOR_KEY:
- ext_status = self.tr("Looking for key for this user")
+ ext_status = self.tr("Initial sync in progress, please wait...")
elif req.event == proto.KEYMANAGER_KEY_FOUND:
ext_status = self.tr("Found key! Starting mail...")
# elif req.event == proto.KEYMANAGER_KEY_NOT_FOUND:
diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py
index 53a7d95a..6959650b 100644
--- a/src/leap/bitmask/gui/mainwindow.py
+++ b/src/leap/bitmask/gui/mainwindow.py
@@ -18,6 +18,7 @@
Main window for Bitmask.
"""
import logging
+import time
from datetime import datetime
@@ -25,6 +26,11 @@ from PySide import QtCore, QtGui
from leap.bitmask import __version__ as VERSION
from leap.bitmask import __version_hash__ as VERSION_HASH
+
+# TODO: we should use a more granular signaling instead of passing error/ok as
+# a result.
+from leap.bitmask.backend.leapbackend import ERROR_KEY, PASSED_KEY
+
from leap.bitmask.config import flags
from leap.bitmask.config.leapsettings import LeapSettings
@@ -37,13 +43,13 @@ from leap.bitmask.gui.mail_status import MailStatusWidget
from leap.bitmask.gui.preferenceswindow import PreferencesWindow
from leap.bitmask.gui.systray import SysTray
from leap.bitmask.gui.wizard import Wizard
-from leap.bitmask.gui import twisted_main
from leap.bitmask.platform_init import IS_WIN, IS_MAC, IS_LINUX
from leap.bitmask.platform_init.initializers import init_platform
from leap.bitmask.platform_init.initializers import init_signals
-from leap.bitmask.backend import leapbackend
+from leap.bitmask.backend.backend_proxy import BackendProxy
+from leap.bitmask.backend.leapsignaler import LeapSignaler
from leap.bitmask.services.eip import conductor as eip_conductor
from leap.bitmask.services.mail import conductor as mail_conductor
@@ -91,13 +97,10 @@ class MainWindow(QtGui.QMainWindow):
# We give the services some time to a halt before forcing quit.
SERVICES_STOP_TIMEOUT = 20000 # in milliseconds
- def __init__(self, bypass_checks=False, start_hidden=False):
+ def __init__(self, start_hidden=False):
"""
Constructor for the client main window
- :param bypass_checks: Set to true if the app should bypass first round
- of checks for CA certificates at bootstrap
- :type bypass_checks: bool
:param start_hidden: Set to true if the app should not show the window
but just the tray.
:type start_hidden: bool
@@ -119,15 +122,18 @@ class MainWindow(QtGui.QMainWindow):
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.menuBar().setNativeMenuBar(not IS_LINUX)
- self._backend = leapbackend.Backend(bypass_checks)
- self._backend.start()
+
+ self._backend = BackendProxy()
+
+ self._leap_signaler = LeapSignaler()
+ self._leap_signaler.start()
self._settings = LeapSettings()
+ # gateway = self._settings.get_selected_gateway(provider)
+ # self._backend.settings_set_selected_gateway(provider, gateway)
# Login Widget
- self._login_widget = LoginWidget(
- self._settings,
- self)
+ self._login_widget = LoginWidget(self._settings, self)
self.ui.loginLayout.addWidget(self._login_widget)
# Mail Widget
@@ -144,8 +150,9 @@ class MainWindow(QtGui.QMainWindow):
# EIP Control redux #########################################
self._eip_conductor = eip_conductor.EIPConductor(
- self._settings, self._backend)
- self._eip_status = EIPStatusWidget(self, self._eip_conductor)
+ self._settings, self._backend, self._leap_signaler)
+ self._eip_status = EIPStatusWidget(self, self._eip_conductor,
+ self._leap_signaler)
init_signals.eip_missing_helpers.connect(
self._disable_eip_missing_helpers)
@@ -180,6 +187,7 @@ class MainWindow(QtGui.QMainWindow):
self._services_being_stopped = {}
# used to know if we are in the final steps of quitting
+ self._quitting = False
self._finally_quitting = False
self._backend_connected_signals = []
@@ -249,7 +257,7 @@ class MainWindow(QtGui.QMainWindow):
# XXX should connect to mail_conductor.start_mail_service instead
self.soledad_ready.connect(self._start_smtp_bootstrapping)
self.soledad_ready.connect(self._start_imap_service)
- ################################# end Qt Signals connection ########
+ # ################################ end Qt Signals connection ########
init_platform()
@@ -258,7 +266,6 @@ class MainWindow(QtGui.QMainWindow):
self._logger_window = None
- self._bypass_checks = bypass_checks
self._start_hidden = start_hidden
self._mail_conductor = mail_conductor.MailConductor(self._backend)
@@ -283,7 +290,7 @@ class MainWindow(QtGui.QMainWindow):
self._wizard_firstrun = True
self._disconnect_and_untrack()
self._wizard = Wizard(backend=self._backend,
- bypass_checks=bypass_checks)
+ leap_signaler=self._leap_signaler)
# Give this window time to finish init and then show the wizard
QtDelayedCall(1, self._launch_wizard)
self._wizard.accepted.connect(self._finish_init)
@@ -342,7 +349,7 @@ class MainWindow(QtGui.QMainWindow):
that we are tracking to disconnect later.
:type only_tracked: bool
"""
- sig = self._backend.signaler
+ sig = self._leap_signaler
conntrack = self._connect_and_track
auth_err = self._authentication_error
@@ -407,6 +414,9 @@ class MainWindow(QtGui.QMainWindow):
sig.eip_dns_error.connect(self._eip_dns_error)
+ sig.eip_get_gateway_country_code.connect(self._set_eip_provider)
+ sig.eip_no_gateway.connect(self._set_eip_provider)
+
# ==================================================================
# Soledad signals
@@ -480,7 +490,7 @@ class MainWindow(QtGui.QMainWindow):
if self._wizard is None:
self._disconnect_and_untrack()
self._wizard = Wizard(backend=self._backend,
- bypass_checks=self._bypass_checks)
+ leap_signaler=self._leap_signaler)
self._wizard.accepted.connect(self._finish_init)
self._wizard.rejected.connect(self._rejected_wizard)
@@ -575,7 +585,8 @@ class MainWindow(QtGui.QMainWindow):
if self._provider_details is not None:
mx_provided = MX_SERVICE in self._provider_details['services']
preferences = PreferencesWindow(self, user, domain, self._backend,
- self._soledad_started, mx_provided)
+ self._soledad_started, mx_provided,
+ self._leap_signaler)
self.soledad_ready.connect(preferences.set_soledad_ready)
preferences.show()
@@ -604,12 +615,13 @@ class MainWindow(QtGui.QMainWindow):
return
self._trying_to_start_eip = settings.get_autostart_eip()
- self._backend.eip_can_start(default_provider)
+ self._backend.eip_can_start(domain=default_provider)
# If we don't want to start eip, we leave everything
# initialized to quickly start it
if not self._trying_to_start_eip:
- self._backend.eip_setup(default_provider, skip_network=True)
+ self._backend.eip_setup(provider=default_provider,
+ skip_network=True)
def _backend_can_start_eip(self):
"""
@@ -686,7 +698,9 @@ class MainWindow(QtGui.QMainWindow):
Displays the EIP preferences window.
"""
domain = self._login_widget.get_selected_provider()
- EIPPreferencesWindow(self, domain, self._backend).show()
+ pref = EIPPreferencesWindow(self, domain,
+ self._backend, self._leap_signaler)
+ pref.show()
#
# updates
@@ -821,7 +835,7 @@ class MainWindow(QtGui.QMainWindow):
"""
providers = self._settings.get_configured_providers()
- self._backend.provider_get_all_services(providers)
+ self._backend.provider_get_all_services(providers=providers)
def _provider_get_all_services(self, services):
self._set_eip_visible(EIP_SERVICE in services)
@@ -1121,7 +1135,7 @@ class MainWindow(QtGui.QMainWindow):
emit the corresponding signals inmediately
"""
domain = self._login_widget.get_selected_provider()
- self._backend.provider_setup(domain)
+ self._backend.provider_setup(provider=domain)
@QtCore.Slot(dict)
def _load_provider_config(self, data):
@@ -1136,11 +1150,11 @@ class MainWindow(QtGui.QMainWindow):
backend.provider_setup()
:type data: dict
"""
- if data[self._backend.PASSED_KEY]:
+ if data[PASSED_KEY]:
selected_provider = self._login_widget.get_selected_provider()
- self._backend.provider_bootstrap(selected_provider)
+ self._backend.provider_bootstrap(provider=selected_provider)
else:
- logger.error(data[self._backend.ERROR_KEY])
+ logger.error(data[ERROR_KEY])
self._login_problem_provider()
@QtCore.Slot()
@@ -1242,16 +1256,17 @@ class MainWindow(QtGui.QMainWindow):
Once the provider configuration is loaded, this starts the SRP
authentication
"""
- if data[self._backend.PASSED_KEY]:
+ if data[PASSED_KEY]:
username = self._login_widget.get_user()
password = self._login_widget.get_password()
self._show_hide_unsupported_services()
domain = self._login_widget.get_selected_provider()
- self._backend.user_login(domain, username, password)
+ self._backend.user_login(provider=domain,
+ username=username, password=password)
else:
- logger.error(data[self._backend.ERROR_KEY])
+ logger.error(data[ERROR_KEY])
self._login_problem_provider()
@QtCore.Slot()
@@ -1277,11 +1292,11 @@ class MainWindow(QtGui.QMainWindow):
if MX_SERVICE in self._enabled_services:
btn_enabled = self._login_widget.set_logout_btn_enabled
btn_enabled(False)
- sig = self._backend.signaler
+ sig = self._leap_signaler
sig.soledad_bootstrap_failed.connect(lambda: btn_enabled(True))
sig.soledad_bootstrap_finished.connect(lambda: btn_enabled(True))
- if not MX_SERVICE in self._provider_details['services']:
+ if MX_SERVICE not in self._provider_details['services']:
self._set_mx_visible(False)
def _start_eip_bootstrap(self):
@@ -1316,7 +1331,7 @@ class MainWindow(QtGui.QMainWindow):
"""
domain = self._login_widget.get_selected_provider()
lang = QtCore.QLocale.system().name()
- self._backend.provider_get_details(domain, lang)
+ self._backend.provider_get_details(domain=domain, lang=lang)
@QtCore.Slot()
def _provider_get_details(self, details):
@@ -1385,11 +1400,14 @@ class MainWindow(QtGui.QMainWindow):
# this is mostly for internal use/debug for now.
logger.warning("Sorry! Log-in at least one time.")
return
- self._backend.soledad_load_offline(full_user_id, password, uuid)
+ self._backend.soledad_load_offline(username=full_user_id,
+ password=password, uuid=uuid)
else:
if self._logged_user is not None:
domain = self._login_widget.get_selected_provider()
- self._backend.soledad_bootstrap(username, domain, password)
+ self._backend.soledad_bootstrap(username=username,
+ domain=domain,
+ password=password)
###################################################################
# Service control methods: soledad
@@ -1468,14 +1486,27 @@ class MainWindow(QtGui.QMainWindow):
signal that currently is beeing processed under status_panel.
After the refactor to EIPConductor this should not be necessary.
"""
- domain = self._login_widget.get_selected_provider()
+ self._already_started_eip = True
- self._eip_status.set_provider(domain)
+ domain = self._login_widget.get_selected_provider()
self._settings.set_defaultprovider(domain)
- self._already_started_eip = True
+
+ self._backend.eip_get_gateway_country_code(domain=domain)
# check for connectivity
- self._backend.eip_check_dns(domain)
+ self._backend.eip_check_dns(domain=domain)
+
+ @QtCore.Slot()
+ def _set_eip_provider(self, country_code=None):
+ """
+ TRIGGERS:
+ Signaler.eip_get_gateway_country_code
+ Signaler.eip_no_gateway
+
+ Set the current provider and country code in the eip status widget.
+ """
+ domain = self._login_widget.get_selected_provider()
+ self._eip_status.set_provider(domain, country_code)
@QtCore.Slot()
def _eip_dns_error(self):
@@ -1539,7 +1570,7 @@ class MainWindow(QtGui.QMainWindow):
self._eip_status.eip_button.setEnabled(False)
domain = self._login_widget.get_selected_provider()
- self._backend.eip_setup(domain)
+ self._backend.eip_setup(provider=domain)
self._already_started_eip = True
# we want to start soledad anyway after a certain timeout if eip
@@ -1571,12 +1602,12 @@ class MainWindow(QtGui.QMainWindow):
Start the VPN thread if the eip configuration is properly
loaded.
"""
- passed = data[self._backend.PASSED_KEY]
+ passed = data[PASSED_KEY]
if not passed:
error_msg = self.tr("There was a problem with the provider")
self._eip_status.set_eip_status(error_msg, error=True)
- logger.error(data[self._backend.ERROR_KEY])
+ logger.error(data[ERROR_KEY])
self._already_started_eip = False
return
@@ -1594,11 +1625,11 @@ class MainWindow(QtGui.QMainWindow):
This is used for intermediate bootstrapping stages, in case
they fail.
"""
- passed = data[self._backend.PASSED_KEY]
+ passed = data[PASSED_KEY]
if not passed:
self._login_widget.set_status(
self.tr("Unable to connect: Problem with provider"))
- logger.error(data[self._backend.ERROR_KEY])
+ logger.error(data[ERROR_KEY])
self._already_started_eip = False
self._eip_status.aborted()
@@ -1663,9 +1694,9 @@ class MainWindow(QtGui.QMainWindow):
This is used for intermediate bootstrapping stages, in case
they fail.
"""
- passed = data[self._backend.PASSED_KEY]
+ passed = data[PASSED_KEY]
if not passed:
- logger.error(data[self._backend.ERROR_KEY])
+ logger.error(data[ERROR_KEY])
self._login_problem_provider()
#
@@ -1708,13 +1739,13 @@ class MainWindow(QtGui.QMainWindow):
self._cancel_ongoing_defers()
- self._services_being_stopped = {'imap', 'eip'}
+ self._services_being_stopped = set(('imap', 'eip'))
imap_stopped = lambda: self._remove_service('imap')
- self._backend.signaler.imap_stopped.connect(imap_stopped)
+ self._leap_signaler.imap_stopped.connect(imap_stopped)
eip_stopped = lambda: self._remove_service('eip')
- self._backend.signaler.eip_stopped.connect(eip_stopped)
+ self._leap_signaler.eip_stopped.connect(eip_stopped)
logger.debug('Stopping mail services')
self._backend.imap_stop_service()
@@ -1732,8 +1763,10 @@ class MainWindow(QtGui.QMainWindow):
Start the quit sequence and wait for services to finish.
Cleanup and close the main window before quitting.
"""
- # TODO separate the shutting down of services from the
- # UI stuff.
+ if self._quitting:
+ return
+
+ self._quitting = True
# first thing to do quitting, hide the mainwindow and show tooltip.
self.hide()
@@ -1786,8 +1819,6 @@ class MainWindow(QtGui.QMainWindow):
Final steps to quit the app, starting from here we don't care about
running services or user interaction, just quitting.
"""
- logger.debug('Final quit...')
-
# We can reach here because all the services are stopped or because a
# timeout was triggered. Since we want to run this only once, we exit
# if this is called twice.
@@ -1796,12 +1827,17 @@ class MainWindow(QtGui.QMainWindow):
self._finally_quitting = True
+ logger.debug('Closing soledad...')
+ self._backend.soledad_close()
+ logger.debug('Final quit...')
+
+ self._leap_signaler.stop()
+ self._backend.stop()
+ time.sleep(0.05) # give the thread a little time to finish.
+
# Remove lockfiles on a clean shutdown.
logger.debug('Cleaning pidfiles')
if IS_WIN:
WindowsLock.release_all_locks()
- self._backend.stop()
self.close()
-
- QtDelayedCall(100, twisted_main.quit)
diff --git a/src/leap/bitmask/gui/preferenceswindow.py b/src/leap/bitmask/gui/preferenceswindow.py
index a3b81d38..3c9cd5d0 100644
--- a/src/leap/bitmask/gui/preferenceswindow.py
+++ b/src/leap/bitmask/gui/preferenceswindow.py
@@ -38,7 +38,8 @@ class PreferencesWindow(QtGui.QDialog):
"""
preferences_saved = QtCore.Signal()
- def __init__(self, parent, username, domain, backend, soledad_started, mx):
+ def __init__(self, parent, username, domain, backend, soledad_started, mx,
+ leap_signaler):
"""
:param parent: parent object of the PreferencesWindow.
:parent type: QWidget
@@ -58,6 +59,7 @@ class PreferencesWindow(QtGui.QDialog):
self._username = username
self._domain = domain
+ self._leap_signaler = leap_signaler
self._backend = backend
self._soledad_started = soledad_started
self._mx_provided = mx
@@ -194,7 +196,8 @@ class PreferencesWindow(QtGui.QDialog):
return
self._set_changing_password(True)
- self._backend.user_change_password(current_password, new_password)
+ self._backend.user_change_password(current_password=current_password,
+ new_password=new_password)
@QtCore.Slot()
def _srp_change_password_ok(self):
@@ -208,7 +211,7 @@ class PreferencesWindow(QtGui.QDialog):
logger.debug("SRP password changed successfully.")
if self._mx_provided:
- self._backend.soledad_change_password(new_password)
+ self._backend.soledad_change_password(new_password=new_password)
else:
self._change_password_success()
@@ -357,7 +360,7 @@ class PreferencesWindow(QtGui.QDialog):
save_services = partial(self._save_enabled_services, domain)
self.ui.pbSaveServices.clicked.connect(save_services)
- self._backend.provider_get_supported_services(domain)
+ self._backend.provider_get_supported_services(domain=domain)
@QtCore.Slot(str)
def _load_services(self, services):
@@ -423,7 +426,7 @@ class PreferencesWindow(QtGui.QDialog):
"""
Helper to connect to backend signals
"""
- sig = self._backend.signaler
+ sig = self._leap_signaler
sig.prov_get_supported_services.connect(self._load_services)
diff --git a/src/leap/bitmask/gui/statemachines.py b/src/leap/bitmask/gui/statemachines.py
index 00a1387e..91f1f605 100644
--- a/src/leap/bitmask/gui/statemachines.py
+++ b/src/leap/bitmask/gui/statemachines.py
@@ -240,9 +240,9 @@ class CompositeMachine(QStateMachine):
c2.qtsigs.disconnected_signal.connect(self.off_ev2_slot)
# XXX why is this getting deletec in c++?
- #Traceback (most recent call last):
- #self.postEvent(self.events.on_ev2)
- #RuntimeError: Internal C++ object (ConnectedEvent2) already deleted.
+ # Traceback (most recent call last):
+ # self.postEvent(self.events.on_ev2)
+ # RuntimeError: Internal C++ object (ConnectedEvent2) already deleted.
# XXX trying the following workaround, since
# I cannot find why in the world this is getting deleted :(
# XXX refactor!
@@ -318,9 +318,8 @@ class ConnectionMachineBuilder(object):
components = self._conn.components
if components is None:
- # simple case: connection definition inherits directly from
- # the abstract connection.
-
+ # simple case: connection definition inherits directly from
+ # the abstract connection.
leap_assert_type(self._conn, connections.AbstractLEAPConnection)
return self._make_simple_machine(self._conn, **kwargs)
diff --git a/src/leap/bitmask/gui/twisted_main.py b/src/leap/bitmask/gui/twisted_main.py
deleted file mode 100644
index b1ce0ead..00000000
--- a/src/leap/bitmask/gui/twisted_main.py
+++ /dev/null
@@ -1,43 +0,0 @@
-# -*- coding: utf-8 -*-
-# twisted_main.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/>.
-"""
-Main functions for integration of twisted reactor
-"""
-import logging
-
-from twisted.internet import error, reactor
-from PySide import QtCore
-
-logger = logging.getLogger(__name__)
-
-
-def stop():
- QtCore.QCoreApplication.sendPostedEvents()
- QtCore.QCoreApplication.flush()
- try:
- reactor.stop()
- logger.debug('Twisted reactor stopped')
- except error.ReactorNotRunning:
- logger.debug('Twisted reactor not running')
- logger.debug("Done stopping all the things.")
-
-
-def quit():
- """
- Stop the mainloop.
- """
- reactor.callLater(0, stop)
diff --git a/src/leap/bitmask/gui/wizard.py b/src/leap/bitmask/gui/wizard.py
index f66c553d..be5bde52 100644
--- a/src/leap/bitmask/gui/wizard.py
+++ b/src/leap/bitmask/gui/wizard.py
@@ -24,6 +24,10 @@ from functools import partial
from PySide import QtCore, QtGui
+# TODO: we should use a more granular signaling instead of passing error/ok as
+# a result.
+from leap.bitmask.backend.leapbackend import ERROR_KEY, PASSED_KEY
+
from leap.bitmask.config import flags
from leap.bitmask.config.leapsettings import LeapSettings
from leap.bitmask.services import get_service_display_name, get_supported
@@ -49,16 +53,12 @@ class Wizard(QtGui.QWizard):
REGISTER_USER_PAGE = 4
SERVICES_PAGE = 5
- def __init__(self, backend, bypass_checks=False):
+ def __init__(self, backend, leap_signaler):
"""
Constructor for the main Wizard.
:param backend: Backend being used
:type backend: Backend
- :param bypass_checks: Set to true if the app should bypass
- first round of checks for CA
- certificates at bootstrap
- :type bypass_checks: bool
"""
QtGui.QWizard.__init__(self)
@@ -83,7 +83,10 @@ class Wizard(QtGui.QWizard):
self.ui.grpCheckProvider.setVisible(False)
self._connect_and_track(self.ui.btnCheck.clicked, self._check_provider)
- self._connect_and_track(self.ui.lnProvider.returnPressed, self._check_provider)
+ self._connect_and_track(self.ui.lnProvider.returnPressed,
+ self._check_provider)
+
+ self._leap_signaler = leap_signaler
self._backend = backend
self._backend_connect()
@@ -98,22 +101,24 @@ class Wizard(QtGui.QWizard):
self._provider_select_defer = None
self._provider_setup_defer = None
- self._connect_and_track(self.currentIdChanged, self._current_id_changed)
+ self._connect_and_track(self.currentIdChanged,
+ self._current_id_changed)
- self._connect_and_track(self.ui.lnProvider.textChanged, self._enable_check)
+ self._connect_and_track(self.ui.lnProvider.textChanged,
+ self._enable_check)
self._connect_and_track(self.ui.rbNewProvider.toggled,
- lambda x: self._enable_check())
+ lambda x: self._enable_check())
self._connect_and_track(self.ui.cbProviders.currentIndexChanged[int],
- self._reset_provider_check)
+ self._reset_provider_check)
self._connect_and_track(self.ui.lblUser.returnPressed,
- self._focus_password)
+ self._focus_password)
self._connect_and_track(self.ui.lblPassword.returnPressed,
- self._focus_second_password)
+ self._focus_second_password)
self._connect_and_track(self.ui.lblPassword2.returnPressed,
- self._register)
+ self._register)
self._connect_and_track(self.ui.btnRegister.clicked,
- self._register)
+ self._register)
self._connect_and_track(self.ui.rbExistingProvider.toggled,
self._skip_provider_checks)
@@ -184,21 +189,55 @@ class Wizard(QtGui.QWizard):
:param pinned: list of pinned providers
:type pinned: list of str
+
+
+ How the combobox items are arranged:
+ -----------------------------------
+
+ First run:
+
+ demo.bitmask.net
+ --
+ pinned2.org
+ pinned1.org
+ pinned3.org
+
+ After some usage:
+
+ added-by-user.org
+ pinned-but-then-used.org
+ ---
+ demo.bitmask.net
+ pinned1.org
+ pinned3.org
+ pinned2.org
+
+ In other words:
+ * There are two sections.
+ * Section one consists of all the providers that the user has used.
+ If this is empty, than use demo.bitmask.net for this section.
+ This list is sorted alphabetically.
+ * Section two consists of all the pinned or 'pre seeded' providers,
+ minus any providers that are now in section one. This last list
+ is in random order.
"""
ls = LeapSettings()
- providers = ls.get_configured_providers()
- if not providers and not pinned:
+ user_added = ls.get_configured_providers()
+ if not user_added and not pinned:
self.ui.rbExistingProvider.setEnabled(False)
self.ui.label_8.setEnabled(False) # 'https://' label
self.ui.cbProviders.setEnabled(False)
return
- user_added = []
+ user_added.sort()
+
+ if not user_added:
+ user_added = [pinned.pop(0)]
- # separate pinned providers from user added ones
- for p in providers:
- if p not in pinned:
- user_added.append(p)
+ # separate unused pinned providers from user added ones
+ for p in user_added:
+ if p in pinned:
+ pinned.remove(p)
if user_added:
self.ui.cbProviders.addItems(user_added)
@@ -288,7 +327,8 @@ class Wizard(QtGui.QWizard):
if user_ok and pass_ok:
self._set_register_status(self.tr("Starting registration..."))
- self._backend.user_register(self._domain, username, password)
+ self._backend.user_register(provider=self._domain,
+ username=username, password=password)
self._username = username
self._password = password
else:
@@ -440,7 +480,7 @@ class Wizard(QtGui.QWizard):
self.ui.lblNameResolution.setPixmap(self.QUESTION_ICON)
self._provider_select_defer = self._backend.\
- provider_setup(self._domain)
+ provider_setup(provider=self._domain)
@QtCore.Slot(bool)
def _skip_provider_checks(self, skip):
@@ -475,8 +515,8 @@ class Wizard(QtGui.QWizard):
:param complete_page: page id to complete
:type complete_page: int
"""
- passed = data[self._backend.PASSED_KEY]
- error = data[self._backend.ERROR_KEY]
+ passed = data[PASSED_KEY]
+ error = data[ERROR_KEY]
if passed:
label.setPixmap(self.OK_ICON)
if complete:
@@ -496,7 +536,7 @@ class Wizard(QtGui.QWizard):
"""
self._complete_task(data, self.ui.lblNameResolution)
status = ""
- passed = data[self._backend.PASSED_KEY]
+ passed = data[PASSED_KEY]
if not passed:
status = self.tr("<font color='red'><b>Non-existent "
"provider</b></font>")
@@ -516,10 +556,10 @@ class Wizard(QtGui.QWizard):
"""
self._complete_task(data, self.ui.lblHTTPS)
status = ""
- passed = data[self._backend.PASSED_KEY]
+ passed = data[PASSED_KEY]
if not passed:
status = self.tr("<font color='red'><b>%s</b></font>") \
- % (data[self._backend.ERROR_KEY])
+ % (data[ERROR_KEY])
self.ui.lblProviderSelectStatus.setText(status)
else:
self.ui.lblProviderInfo.setPixmap(self.QUESTION_ICON)
@@ -536,22 +576,21 @@ class Wizard(QtGui.QWizard):
check. Since this check is the last of this set, it also
completes the page if passed
"""
- if data[self._backend.PASSED_KEY]:
+ if data[PASSED_KEY]:
self._complete_task(data, self.ui.lblProviderInfo,
True, self.SELECT_PROVIDER_PAGE)
self._provider_checks_ok = True
lang = QtCore.QLocale.system().name()
- self._backend.provider_get_details(self._domain, lang)
+ self._backend.provider_get_details(domain=self._domain, lang=lang)
else:
new_data = {
- self._backend.PASSED_KEY: False,
- self._backend.ERROR_KEY:
- self.tr("Unable to load provider configuration")
+ PASSED_KEY: False,
+ ERROR_KEY: self.tr("Unable to load provider configuration")
}
self._complete_task(new_data, self.ui.lblProviderInfo)
status = ""
- if not data[self._backend.PASSED_KEY]:
+ if not data[PASSED_KEY]:
status = self.tr("<font color='red'><b>Not a valid provider"
"</b></font>")
self.ui.lblProviderSelectStatus.setText(status)
@@ -582,7 +621,7 @@ class Wizard(QtGui.QWizard):
Sets the status for the download of the CA certificate check
"""
self._complete_task(data, self.ui.lblDownloadCaCert)
- passed = data[self._backend.PASSED_KEY]
+ passed = data[PASSED_KEY]
if passed:
self.ui.lblCheckCaFpr.setPixmap(self.QUESTION_ICON)
@@ -595,7 +634,7 @@ class Wizard(QtGui.QWizard):
Sets the status for the CA fingerprint check
"""
self._complete_task(data, self.ui.lblCheckCaFpr)
- passed = data[self._backend.PASSED_KEY]
+ passed = data[PASSED_KEY]
if passed:
self.ui.lblCheckApiCert.setPixmap(self.QUESTION_ICON)
@@ -689,7 +728,7 @@ class Wizard(QtGui.QWizard):
self.page(pageId).setSubTitle(sub_title)
self.ui.lblDownloadCaCert.setPixmap(self.QUESTION_ICON)
self._provider_setup_defer = self._backend.\
- provider_bootstrap(self._domain)
+ provider_bootstrap(provider=self._domain)
if pageId == self.PRESENT_PROVIDER_PAGE:
sub_title = self.tr("Description of services offered by {0}")
@@ -752,7 +791,7 @@ class Wizard(QtGui.QWizard):
"""
Connects all the backend signals with the wizard.
"""
- sig = self._backend.signaler
+ sig = self._leap_signaler
conntrack = self._connect_and_track
conntrack(sig.prov_name_resolution, self._name_resolution)
conntrack(sig.prov_https_connection, self._https_connection)