summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/leap/bitmask/backend.py161
-rw-r--r--src/leap/bitmask/config/providerconfig.py64
-rw-r--r--src/leap/bitmask/gui/mainwindow.py207
-rw-r--r--src/leap/bitmask/gui/preferenceswindow.py114
-rw-r--r--src/leap/bitmask/gui/wizard.py73
-rw-r--r--src/leap/bitmask/services/soledad/soledadbootstrapper.py3
6 files changed, 360 insertions, 262 deletions
diff --git a/src/leap/bitmask/backend.py b/src/leap/bitmask/backend.py
index d6d5004f..e8bf0482 100644
--- a/src/leap/bitmask/backend.py
+++ b/src/leap/bitmask/backend.py
@@ -37,8 +37,8 @@ from leap.bitmask.config.providerconfig import ProviderConfig
from leap.bitmask.crypto.srpauth import SRPAuth
from leap.bitmask.crypto.srpregister import SRPRegister
from leap.bitmask.platform_init import IS_LINUX
-from leap.bitmask.provider import get_provider_path
from leap.bitmask.provider.providerbootstrapper import ProviderBootstrapper
+from leap.bitmask.services import get_supported
from leap.bitmask.services.eip import eipconfig
from leap.bitmask.services.eip import get_openvpn_management
from leap.bitmask.services.eip.eipbootstrapper import EIPBootstrapper
@@ -64,26 +64,6 @@ from PySide import QtCore
logger = logging.getLogger(__name__)
-def get_provider_config(config, domain):
- """
- Return the ProviderConfig object for the given domain.
- If it is already loaded in `config`, then don't reload.
-
- :param config: a ProviderConfig object
- :type conig: ProviderConfig
- :param domain: the domain which config is required.
- :type domain: unicode
-
- :returns: True if the config was loaded successfully, False otherwise.
- :rtype: bool
- """
- # TODO: see ProviderConfig.get_provider_config
- if (not config.loaded() or config.get_domain() != domain):
- config.load(get_provider_path(domain))
-
- return config.loaded()
-
-
class ILEAPComponent(zope.interface.Interface):
"""
Interface that every component for the backend should comply to
@@ -167,6 +147,7 @@ class Provider(object):
:type bypass_checks: bool
"""
self.key = "provider"
+ self._signaler = signaler
self._provider_bootstrapper = ProviderBootstrapper(signaler,
bypass_checks)
self._download_provider_defer = None
@@ -208,13 +189,9 @@ class Provider(object):
"""
d = None
- # TODO: use this commented code when we don't need the provider config
- # in the maiwindow.
- # config = ProviderConfig.get_provider_config(provider)
- # self._provider_config = config
- # if config is not None:
- config = self._provider_config
- if get_provider_config(config, provider):
+ config = ProviderConfig.get_provider_config(provider)
+ self._provider_config = config
+ if config is not None:
d = self._provider_bootstrapper.run_provider_setup_checks(
config, download_if_needed=True)
else:
@@ -228,6 +205,73 @@ class Provider(object):
d = defer.Deferred()
return d
+ def _get_services(self, domain):
+ """
+ Returns a list of services provided by the given provider.
+
+ :param domain: the provider to get the services from.
+ :type domain: str
+
+ :rtype: list of str
+ """
+ services = []
+ provider_config = ProviderConfig.get_provider_config(domain)
+ if provider_config is not None:
+ services = provider_config.get_services()
+
+ return services
+
+ def get_supported_services(self, domain):
+ """
+ Signal a list of supported services provided by the given provider.
+
+ :param domain: the provider to get the services from.
+ :type domain: str
+
+ Signals:
+ prov_get_supported_services -> list of unicode
+ """
+ services = get_supported(self._get_services(domain))
+
+ self._signaler.signal(
+ self._signaler.PROV_GET_SUPPORTED_SERVICES, services)
+
+ def get_all_services(self, providers):
+ """
+ Signal a list of services provided by all the configured providers.
+
+ :param providers: the list of providers to get the services.
+ :type providers: list
+
+ Signals:
+ prov_get_all_services -> list of unicode
+ """
+ services_all = set()
+
+ for domain in providers:
+ services = self._get_services(domain)
+ services_all = services_all.union(set(services))
+
+ self._signaler.signal(
+ self._signaler.PROV_GET_ALL_SERVICES, services_all)
+
+ def get_details(self, domain, lang=None):
+ """
+ Signal a ProviderConfigLight object with the current ProviderConfig
+ settings.
+
+ :param domain: the domain name of the provider.
+ :type domain: str
+ :param lang: the language to use for localized strings.
+ :type lang: str
+
+ Signals:
+ prov_get_details -> ProviderConfigLight
+ """
+ self._signaler.signal(
+ self._signaler.PROV_GET_DETAILS,
+ self._provider_config.get_light_config(domain, lang))
+
class Register(object):
"""
@@ -926,6 +970,10 @@ class Signaler(QtCore.QObject):
prov_unsupported_client = QtCore.Signal(object)
prov_unsupported_api = QtCore.Signal(object)
+ prov_get_all_services = QtCore.Signal(object)
+ prov_get_supported_services = QtCore.Signal(object)
+ prov_get_details = QtCore.Signal(object)
+
prov_cancelled_setup = QtCore.Signal(object)
# Signals for SRPRegister
@@ -1021,6 +1069,9 @@ class Signaler(QtCore.QObject):
PROV_UNSUPPORTED_CLIENT = "prov_unsupported_client"
PROV_UNSUPPORTED_API = "prov_unsupported_api"
PROV_CANCELLED_SETUP = "prov_cancelled_setup"
+ PROV_GET_ALL_SERVICES = "prov_get_all_services"
+ PROV_GET_SUPPORTED_SERVICES = "prov_get_supported_services"
+ PROV_GET_DETAILS = "prov_get_details"
SRP_REGISTRATION_FINISHED = "srp_registration_finished"
SRP_REGISTRATION_FAILED = "srp_registration_failed"
@@ -1106,6 +1157,9 @@ class Signaler(QtCore.QObject):
self.PROV_UNSUPPORTED_CLIENT,
self.PROV_UNSUPPORTED_API,
self.PROV_CANCELLED_SETUP,
+ self.PROV_GET_ALL_SERVICES,
+ self.PROV_GET_SUPPORTED_SERVICES,
+ self.PROV_GET_DETAILS,
self.SRP_REGISTRATION_FINISHED,
self.SRP_REGISTRATION_FAILED,
@@ -1393,6 +1447,47 @@ class Backend(object):
"""
self._call_queue.put(("provider", "bootstrap", None, provider))
+ def provider_get_supported_services(self, domain):
+ """
+ Signal a list of supported services provided by the given provider.
+
+ :param domain: the provider to get the services from.
+ :type domain: str
+
+ Signals:
+ prov_get_supported_services -> list of unicode
+ """
+ self._call_queue.put(("provider", "get_supported_services", None,
+ domain))
+
+ def provider_get_all_services(self, providers):
+ """
+ Signal a list of services provided by all the configured providers.
+
+ :param providers: the list of providers to get the services.
+ :type providers: list
+
+ Signals:
+ prov_get_all_services -> list of unicode
+ """
+ self._call_queue.put(("provider", "get_all_services", None,
+ providers))
+
+ def provider_get_details(self, domain, lang):
+ """
+ Signal a ProviderConfigLight object with the current ProviderConfig
+ settings.
+
+ :param domain: the domain name of the provider.
+ :type domain: str
+ :param lang: the language to use for localized strings.
+ :type lang: str
+
+ Signals:
+ prov_get_details -> ProviderConfigLight
+ """
+ self._call_queue.put(("provider", "get_details", None, domain, lang))
+
def user_register(self, provider, username, password):
"""
Register a user using the domain and password given as parameters.
@@ -1698,16 +1793,6 @@ class Backend(object):
# XXX HACK: this section is meant to be a place to hold methods and
# variables needed in the meantime while we migrate all to the backend.
- def get_provider_config(self):
- # TODO: refactor the provider config into a singleton/global loading it
- # every time from the file.
- provider_config = self._components["provider"]._provider_config
- return provider_config
-
- def get_soledad(self):
- soledad = self._components["soledad"]._soledad_bootstrapper._soledad
- return soledad
-
def get_keymanager(self):
km = self._components["soledad"]._soledad_bootstrapper._keymanager
return km
diff --git a/src/leap/bitmask/config/providerconfig.py b/src/leap/bitmask/config/providerconfig.py
index b411c6f3..cf31b3b2 100644
--- a/src/leap/bitmask/config/providerconfig.py
+++ b/src/leap/bitmask/config/providerconfig.py
@@ -38,6 +38,35 @@ class MissingCACert(Exception):
pass
+class ProviderConfigLight(object):
+ """
+ A light config object to hold some provider settings needed by the GUI.
+ """
+ def __init__(self):
+ """
+ Define the public attributes.
+ """
+ self.domain = ""
+ self.name = ""
+ self.description = ""
+ self.enrollment_policy = ""
+ self.services = []
+
+ @property
+ def services_string(self):
+ """
+ Return a comma separated list of serices provided by this provider.
+
+ :rtype: str
+ """
+ services = []
+ for service in self.services:
+ services.append(get_service_display_name(service))
+
+ services_str = ", ".join(services)
+ return services_str
+
+
class ProviderConfig(BaseConfig):
"""
Provider configuration abstraction class
@@ -45,6 +74,29 @@ class ProviderConfig(BaseConfig):
def __init__(self):
BaseConfig.__init__(self)
+ def get_light_config(self, domain, lang=None):
+ """
+ Return a ProviderConfigLight object with the data for the loaded
+ object.
+
+ :param domain: the domain name of the provider.
+ :type domain: str
+ :param lang: the language to use for localized strings.
+ :type lang: str
+
+ :rtype: ProviderConfigLight or None if the ProviderConfig isn't loaded.
+ """
+ config = self.get_provider_config(domain)
+ details = ProviderConfigLight()
+
+ details.domain = config.get_domain()
+ details.name = config.get_name(lang=lang)
+ details.description = config.get_description(lang=lang)
+ details.enrollment_policy = config.get_enrollment_policy()
+ details.services = config.get_services()
+
+ return details
+
@classmethod
def get_provider_config(self, domain):
"""
@@ -144,18 +196,6 @@ class ProviderConfig(BaseConfig):
services = self._safe_get_value("services")
return services
- def get_services_string(self):
- """
- Returns a string with the available services in the current
- provider, ready to be shown to the user.
- """
- 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):
"""
Returns the path to the certificate for the current provider.
diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py
index 201a24ec..4d79305e 100644
--- a/src/leap/bitmask/gui/mainwindow.py
+++ b/src/leap/bitmask/gui/mainwindow.py
@@ -30,7 +30,6 @@ from leap.bitmask import __version__ as VERSION
from leap.bitmask import __version_hash__ as VERSION_HASH
from leap.bitmask.config import flags
from leap.bitmask.config.leapsettings import LeapSettings
-from leap.bitmask.config.providerconfig import ProviderConfig
from leap.bitmask.gui import statemachines
from leap.bitmask.gui.advanced_key_management import AdvancedKeyManagement
@@ -43,7 +42,6 @@ from leap.bitmask.gui.preferenceswindow import PreferencesWindow
from leap.bitmask.gui.systray import SysTray
from leap.bitmask.gui.wizard import Wizard
-from leap.bitmask import provider
from leap.bitmask.platform_init import IS_WIN, IS_MAC, IS_LINUX
from leap.bitmask.platform_init.initializers import init_platform
@@ -64,7 +62,6 @@ if IS_WIN:
from leap.bitmask.platform_init.locks import WindowsLock
from leap.bitmask.platform_init.locks import raise_window_ack
-from leap.common.check import leap_assert
from leap.common.events import register
from leap.common.events import events_pb2 as proto
@@ -178,15 +175,6 @@ class MainWindow(QtGui.QMainWindow):
self._trying_to_start_eip = False
- # This is loaded only once, there's a bug when doing that more
- # than once
- # XXX HACK!! But we need it as long as we are using
- # provider_config in here
- self._provider_config = self._backend.get_provider_config()
-
- # Used for automatic start of EIP
- self._provisional_provider_config = ProviderConfig()
-
self._already_started_eip = False
self._soledad_started = False
@@ -247,6 +235,8 @@ class MainWindow(QtGui.QMainWindow):
self._ui_mx_visible = True
self._ui_eip_visible = True
+ self._provider_details = None
+
# last minute UI manipulations
self._center_window()
@@ -383,6 +373,9 @@ class MainWindow(QtGui.QMainWindow):
self._connect_and_track(sig.prov_cancelled_setup,
self._set_login_cancelled)
+ self._connect_and_track(sig.prov_get_details,
+ self._provider_get_details)
+
# Login signals
self._connect_and_track(sig.srp_auth_ok, self._authentication_finished)
@@ -430,9 +423,14 @@ class MainWindow(QtGui.QMainWindow):
sig.backend_bad_call.connect(self._backend_bad_call)
+ sig.prov_check_api_certificate.connect(self._get_provider_details)
+
sig.prov_unsupported_client.connect(self._needs_update)
sig.prov_unsupported_api.connect(self._incompatible_api)
+ sig.prov_get_all_services.connect(
+ self._provider_get_all_services)
+
# EIP start signals
sig.eip_openvpn_already_running.connect(
self._on_eip_openvpn_already_running)
@@ -597,12 +595,13 @@ class MainWindow(QtGui.QMainWindow):
domain = self._login_widget.get_selected_provider()
logged_user = "{0}@{1}".format(self._logged_user, domain)
- has_mx = True
- if self._logged_user is not None:
- provider_config = self._get_best_provider_config()
- has_mx = provider_config.provides_mx()
+ details = self._provider_details
+ mx_provided = False
+ if details is not None:
+ mx_provided = MX_SERVICE in details
- akm = AdvancedKeyManagement(self, has_mx, logged_user,
+ # XXX: handle differently not logged in user?
+ akm = AdvancedKeyManagement(self, mx_provided, logged_user,
self._keymanager, self._soledad_started)
akm.show()
@@ -618,8 +617,7 @@ class MainWindow(QtGui.QMainWindow):
user = self._login_widget.get_user()
prov = self._login_widget.get_selected_provider()
preferences = PreferencesWindow(
- self, self._backend, self._provider_config,
- self._soledad_started, user, prov)
+ self, self._backend, self._soledad_started, user, prov)
self.soledad_ready.connect(preferences.set_soledad_ready)
preferences.show()
@@ -857,16 +855,9 @@ class MainWindow(QtGui.QMainWindow):
"""
providers = self._settings.get_configured_providers()
- services = set()
-
- for prov in providers:
- provider_config = ProviderConfig()
- loaded = provider_config.load(
- provider.get_provider_path(prov))
- if loaded:
- for service in provider_config.get_services():
- services.add(service)
+ self._backend.provider_get_all_services(providers)
+ def _provider_get_all_services(self, services):
self._set_eip_visible(EIP_SERVICE in services)
self._set_mx_visible(MX_SERVICE in services)
@@ -904,14 +895,11 @@ class MainWindow(QtGui.QMainWindow):
"""
Set the login label to reflect offline status.
"""
- if self._logged_in_offline:
- provider = ""
- else:
+ provider = ""
+ if not self._logged_in_offline:
provider = self.ui.lblLoginProvider.text()
- self.ui.lblLoginProvider.setText(
- provider +
- self.tr(" (offline mode)"))
+ self.ui.lblLoginProvider.setText(provider + self.tr(" (offline mode)"))
#
# systray
@@ -1165,9 +1153,8 @@ class MainWindow(QtGui.QMainWindow):
provider configuration if it's not present, otherwise will
emit the corresponding signals inmediately
"""
- # XXX should rename this provider, name clash.
- provider = self._login_widget.get_selected_provider()
- self._backend.provider_setup(provider)
+ domain = self._login_widget.get_selected_provider()
+ self._backend.provider_setup(domain)
@QtCore.Slot(dict)
def _load_provider_config(self, data):
@@ -1175,12 +1162,11 @@ class MainWindow(QtGui.QMainWindow):
TRIGGERS:
self._backend.signaler.prov_download_provider_info
- Once the provider config has been downloaded, this loads the
- self._provider_config instance with it and starts the second
- part of the bootstrapping sequence
+ Once the provider config has been downloaded, start the second
+ part of the bootstrapping sequence.
:param data: result from the last stage of the
- run_provider_select_checks
+ backend.provider_setup()
:type data: dict
"""
if data[self._backend.PASSED_KEY]:
@@ -1222,7 +1208,6 @@ class MainWindow(QtGui.QMainWindow):
self._set_label_offline()
self.offline_mode_bypass_login.emit()
else:
- leap_assert(self._provider_config, "We need a provider config")
self.ui.action_create_new_account.setEnabled(False)
if self._login_widget.start_login():
self._download_provider_config()
@@ -1290,15 +1275,13 @@ class MainWindow(QtGui.QMainWindow):
Once the provider configuration is loaded, this starts the SRP
authentication
"""
- leap_assert(self._provider_config, "We need a provider config!")
-
if data[self._backend.PASSED_KEY]:
username = self._login_widget.get_user()
password = self._login_widget.get_password()
self._show_hide_unsupported_services()
- domain = self._provider_config.get_domain()
+ domain = self._login_widget.get_selected_provider()
self._backend.user_login(domain, username, password)
else:
logger.error(data[self._backend.ERROR_KEY])
@@ -1317,7 +1300,7 @@ class MainWindow(QtGui.QMainWindow):
self._logged_user = self._login_widget.get_user()
user = self._logged_user
- domain = self._provider_config.get_domain()
+ domain = self._login_widget.get_selected_provider()
full_user_id = make_address(user, domain)
self._mail_conductor.userid = full_user_id
self._start_eip_bootstrap()
@@ -1331,7 +1314,7 @@ class MainWindow(QtGui.QMainWindow):
sig.soledad_bootstrap_failed.connect(lambda: btn_enabled(True))
sig.soledad_bootstrap_finished.connect(lambda: btn_enabled(True))
- if not self._get_best_provider_config().provides_mx():
+ if not MX_SERVICE in self._provider_details.services:
self._set_mx_visible(False)
def _start_eip_bootstrap(self):
@@ -1341,11 +1324,10 @@ class MainWindow(QtGui.QMainWindow):
"""
self._login_widget.logged_in()
- provider = self._provider_config.get_domain()
- self.ui.lblLoginProvider.setText(provider)
+ domain = self._login_widget.get_selected_provider()
+ self.ui.lblLoginProvider.setText(domain)
- self._enabled_services = self._settings.get_enabled_services(
- self._provider_config.get_domain())
+ self._enabled_services = self._settings.get_enabled_services(domain)
# TODO separate UI from logic.
if self._provides_mx_and_enabled():
@@ -1355,6 +1337,30 @@ class MainWindow(QtGui.QMainWindow):
self._maybe_start_eip()
+ @QtCore.Slot()
+ def _get_provider_details(self):
+ """
+ TRIGGERS:
+ prov_check_api_certificate
+
+ Set the attributes to know if the EIP and MX services are supported
+ and enabled.
+ This is triggered right after the provider has been set up.
+ """
+ domain = self._login_widget.get_selected_provider()
+ lang = QtCore.QLocale.system().name()
+ self._backend.provider_get_details(domain, lang)
+
+ @QtCore.Slot()
+ def _provider_get_details(self, details):
+ """
+ Set the details for the just downloaded provider.
+
+ :param details: the details of the provider.
+ :type details: ProviderConfigLight
+ """
+ self._provider_details = details
+
def _provides_mx_and_enabled(self):
"""
Defines if the current provider provides mx and if we have it enabled.
@@ -1362,9 +1368,15 @@ class MainWindow(QtGui.QMainWindow):
:returns: True if provides and is enabled, False otherwise
:rtype: bool
"""
- provider_config = self._get_best_provider_config()
- return (provider_config.provides_mx() and
- MX_SERVICE in self._enabled_services)
+ domain = self._login_widget.get_selected_provider()
+ enabled_services = self._settings.get_enabled_services(domain)
+
+ mx_enabled = MX_SERVICE in enabled_services
+ mx_provided = False
+ if self._provider_details is not None:
+ mx_provided = MX_SERVICE in self._provider_details.services
+
+ return mx_enabled and mx_provided
def _provides_eip_and_enabled(self):
"""
@@ -1373,16 +1385,23 @@ class MainWindow(QtGui.QMainWindow):
:returns: True if provides and is enabled, False otherwise
:rtype: bool
"""
- provider_config = self._get_best_provider_config()
- return (provider_config.provides_eip() and
- EIP_SERVICE in self._enabled_services)
+ domain = self._login_widget.get_selected_provider()
+ enabled_services = self._settings.get_enabled_services(domain)
+
+ eip_enabled = EIP_SERVICE in enabled_services
+ eip_provided = False
+ if self._provider_details is not None:
+ eip_provided = EIP_SERVICE in self._provider_details.services
+
+ return eip_enabled and eip_provided
def _maybe_run_soledad_setup_checks(self):
"""
Conditionally start Soledad.
"""
# TODO split.
- if not self._provides_mx_and_enabled():
+ if not self._provides_mx_and_enabled() and not flags.OFFLINE:
+ logger.debug("Does not provides and enabled MX")
return
username = self._login_widget.get_user()
@@ -1390,9 +1409,6 @@ class MainWindow(QtGui.QMainWindow):
provider_domain = self._login_widget.get_selected_provider()
if flags.OFFLINE:
- self._provisional_provider_config.load(
- provider.get_provider_path(provider_domain))
-
full_user_id = make_address(username, provider_domain)
uuid = self._settings.get_uuid(full_user_id)
self._mail_conductor.userid = full_user_id
@@ -1405,7 +1421,7 @@ class MainWindow(QtGui.QMainWindow):
self._backend.soledad_load_offline(full_user_id, password, uuid)
else:
if self._logged_user is not None:
- domain = self._provider_config.get_domain()
+ domain = self._login_widget.get_selected_provider()
self._backend.soledad_bootstrap(username, domain, password)
###################################################################
@@ -1457,19 +1473,8 @@ class MainWindow(QtGui.QMainWindow):
# TODO in the OFFLINE mode we should also modify the rules
# in the mail state machine so it shows that imap is active
# (but not smtp since it's not yet ready for offline use)
- start_fun = self._mail_conductor.start_imap_service
- if flags.OFFLINE:
- provider_domain = self._login_widget.get_selected_provider()
- self._provider_config.load(
- provider.get_provider_path(provider_domain))
- provides_mx = self._provider_config.provides_mx()
-
- if flags.OFFLINE and provides_mx:
- start_fun()
- return
-
- if self._provides_mx_and_enabled():
- start_fun()
+ if self._provides_mx_and_enabled() or flags.OFFLINE:
+ self._mail_conductor.start_imap_service()
# end service control methods (imap)
@@ -1519,9 +1524,7 @@ class MainWindow(QtGui.QMainWindow):
"""
self._eip_connection.qtsigs.connected_signal.emit()
- provider_config = self._get_best_provider_config()
- domain = provider_config.get_domain()
-
+ domain = self._login_widget.get_selected_provider()
self._eip_status.set_provider(domain)
self._settings.set_defaultprovider(domain)
self._already_started_eip = True
@@ -1582,19 +1585,8 @@ class MainWindow(QtGui.QMainWindow):
self._enabled_services = settings.get_enabled_services(
default_provider)
- loaded = self._provisional_provider_config.load(
- provider.get_provider_path(default_provider))
- if loaded and settings.get_autostart_eip():
- # 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,
- # or we can try only if it fails.
+ if settings.get_autostart_eip():
self._maybe_start_eip()
- elif settings.get_autostart_eip():
- # XXX: Display a proper message to the user
- self.eip_needs_login.emit()
- logger.error("Unable to load %s config, cannot autostart." %
- (default_provider,))
@QtCore.Slot()
def _start_EIP(self):
@@ -1700,11 +1692,12 @@ class MainWindow(QtGui.QMainWindow):
logger.debug('Setting autostart to: False')
self._settings.set_autostart_eip(False)
- if self._logged_user:
- self._eip_status.set_provider(
- make_address(
- self._logged_user,
- self._get_best_provider_config().get_domain()))
+ user = self._logged_user
+ if user:
+ domain = self._login_widget.get_selected_provider()
+ full_user_id = make_address(user, domain)
+ self._eip_status.set_provider(full_user_id)
+
self._eip_status.eip_stopped()
@QtCore.Slot()
@@ -1874,30 +1867,6 @@ class MainWindow(QtGui.QMainWindow):
# end of EIP methods ---------------------------------------------
- def _get_best_provider_config(self):
- """
- Returns the best ProviderConfig to use at a moment. We may
- have to use self._provider_config or
- self._provisional_provider_config depending on the start
- status.
-
- :rtype: ProviderConfig
- """
- # TODO move this out of gui.
- leap_assert(self._provider_config is not None or
- self._provisional_provider_config is not None,
- "We need a provider config")
-
- provider_config = None
- if self._provider_config.loaded():
- provider_config = self._provider_config
- elif self._provisional_provider_config.loaded():
- provider_config = self._provisional_provider_config
- else:
- leap_assert(False, "We could not find any usable ProviderConfig.")
-
- return provider_config
-
@QtCore.Slot()
def _logout(self):
"""
diff --git a/src/leap/bitmask/gui/preferenceswindow.py b/src/leap/bitmask/gui/preferenceswindow.py
index 0a4c7f56..c67052f3 100644
--- a/src/leap/bitmask/gui/preferenceswindow.py
+++ b/src/leap/bitmask/gui/preferenceswindow.py
@@ -24,12 +24,9 @@ from functools import partial
from PySide import QtCore, QtGui
-from leap.bitmask.provider import get_provider_path
from leap.bitmask.config.leapsettings import LeapSettings
from leap.bitmask.gui.ui_preferences import Ui_Preferences
from leap.bitmask.util.credentials import 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, MX_SERVICE
logger = logging.getLogger(__name__)
@@ -41,15 +38,12 @@ class PreferencesWindow(QtGui.QDialog):
"""
preferences_saved = QtCore.Signal()
- def __init__(self, parent, backend, provider_config, soledad_started,
- username, domain):
+ def __init__(self, parent, backend, soledad_started, username, domain):
"""
:param parent: parent object of the PreferencesWindow.
:parent type: QWidget
:param backend: Backend being used
:type backend: Backend
- :param provider_config: ProviderConfig object.
- :type provider_config: ProviderConfig
:param soledad_started: whether soledad has started or not
:type soledad_started: bool
:param username: the user set in the login widget
@@ -62,7 +56,6 @@ class PreferencesWindow(QtGui.QDialog):
self._backend = backend
self._settings = LeapSettings()
- self._provider_config = provider_config
self._soledad_started = soledad_started
self._username = username
self._domain = domain
@@ -99,31 +92,7 @@ class PreferencesWindow(QtGui.QDialog):
Actions to perform is the user is logged in.
"""
- settings = self._settings
- pw_enabled = True
-
- # check if provider has 'mx' ...
- # TODO: we should move this to the backend.
- if self._provider_config.provides_mx():
- enabled_services = settings.get_enabled_services(self._domain)
- mx_name = get_service_display_name(MX_SERVICE)
-
- # ... and if the user have it enabled
- if MX_SERVICE not in enabled_services:
- msg = self.tr("You need to enable {0} in order to change "
- "the password.".format(mx_name))
- self._set_password_change_status(msg, error=True)
- pw_enabled = False
- else:
- # check if Soledad is bootstrapped
- if not self._soledad_started:
- msg = self.tr(
- "You need to wait until {0} is ready in "
- "order to change the password.".format(mx_name))
- self._set_password_change_status(msg)
- pw_enabled = False
-
- self.ui.gbPasswordChange.setEnabled(pw_enabled)
+ self._backend.provider_provides_mx()
@QtCore.Slot()
def _not_logged_in(self):
@@ -139,6 +108,44 @@ class PreferencesWindow(QtGui.QDialog):
self.ui.gbPasswordChange.setEnabled(False)
@QtCore.Slot()
+ def _provides_mx(self):
+ """
+ TRIGGERS:
+ Signaler.prov_provides_mx
+
+ Actions to perform if the provider provides MX.
+ """
+ pw_enabled = True
+ enabled_services = self._settings.get_enabled_services(self._domain)
+ mx_name = get_service_display_name(MX_SERVICE)
+
+ if MX_SERVICE not in enabled_services:
+ msg = self.tr("You need to enable {0} in order to change "
+ "the password.".format(mx_name))
+ self._set_password_change_status(msg, error=True)
+ pw_enabled = False
+ else:
+ # check if Soledad is bootstrapped
+ if not self._soledad_started:
+ msg = self.tr(
+ "You need to wait until {0} is ready in "
+ "order to change the password.".format(mx_name))
+ self._set_password_change_status(msg)
+ pw_enabled = False
+
+ self.ui.gbPasswordChange.setEnabled(pw_enabled)
+
+ @QtCore.Slot()
+ def _not_provides_mx(self):
+ """
+ TRIGGERS:
+ Signaler.prov_not_provides_mx
+
+ Actions to perform if the provider does not provides MX.
+ """
+ self.ui.gbPasswordChange.setEnabled(False)
+
+ @QtCore.Slot()
def set_soledad_ready(self):
"""
TRIGGERS:
@@ -339,8 +346,7 @@ class PreferencesWindow(QtGui.QDialog):
TRIGGERS:
self.ui.cbProvidersServices.currentIndexChanged[unicode]
- Loads the services that the provider provides into the UI for
- the user to enable or disable.
+ Fill the services list with the selected provider's services.
:param domain: the domain of the provider to load services from.
:type domain: str
@@ -351,10 +357,6 @@ class PreferencesWindow(QtGui.QDialog):
if not domain:
return
- provider_config = self._get_provider_config(domain)
- if provider_config is None:
- return
-
# set the proper connection for the 'save' button
try:
self.ui.pbSaveServices.clicked.disconnect()
@@ -364,7 +366,21 @@ class PreferencesWindow(QtGui.QDialog):
save_services = partial(self._save_enabled_services, domain)
self.ui.pbSaveServices.clicked.connect(save_services)
- services = get_supported(provider_config.get_services())
+ self._backend.provider_get_supported_services(domain)
+
+ @QtCore.Slot(str)
+ def _load_services(self, services):
+ """
+ TRIGGERS:
+ self.ui.cbProvidersServices.currentIndexChanged[unicode]
+
+ 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
+ """
+ domain = self.ui.cbProvidersServices.currentText()
services_conf = self._settings.get_enabled_services(domain)
# discard changes if other provider is selected
@@ -412,27 +428,15 @@ class PreferencesWindow(QtGui.QDialog):
self._set_providers_services_status(msg, success=True)
self.preferences_saved.emit()
- 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()
- if not provider_config.load(get_provider_path(domain)):
- provider_config = None
-
- return provider_config
-
def _backend_connect(self):
"""
Helper to connect to backend signals
"""
sig = self._backend.signaler
+ sig.prov_provides_mx.connect(self._provides_mx)
+ sig.prov_get_supported_services.connect(self._load_services)
+
sig.srp_status_logged_in.connect(self._is_logged_in)
sig.srp_status_not_logged_in.connect(self._not_logged_in)
diff --git a/src/leap/bitmask/gui/wizard.py b/src/leap/bitmask/gui/wizard.py
index ce45b431..4d774907 100644
--- a/src/leap/bitmask/gui/wizard.py
+++ b/src/leap/bitmask/gui/wizard.py
@@ -26,8 +26,6 @@ from PySide import QtCore, QtGui
from leap.bitmask.config import flags
from leap.bitmask.config.leapsettings import LeapSettings
-from leap.bitmask.config.providerconfig import ProviderConfig
-from leap.bitmask.provider import get_provider_path
from leap.bitmask.services import get_service_display_name, get_supported
from leap.bitmask.util.credentials import password_checks, username_checks
from leap.bitmask.util.credentials import USERNAME_REGEX
@@ -88,10 +86,9 @@ class Wizard(QtGui.QWizard):
self._backend_connect()
self._domain = None
- # HACK!! We need provider_config for the time being, it'll be
- # removed
- self._provider_config = (
- self._backend._components["provider"]._provider_config)
+
+ # this details are set when the provider download is complete.
+ self._provider_details = None
# We will store a reference to the defers for eventual use
# (eg, to cancel them) but not doing anything with them right now.
@@ -513,10 +510,12 @@ class Wizard(QtGui.QWizard):
check. Since this check is the last of this set, it also
completes the page if passed
"""
- if self._provider_config.load(get_provider_path(self._domain)):
+ if data[self._backend.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)
else:
new_data = {
self._backend.PASSED_KEY: False,
@@ -538,6 +537,16 @@ class Wizard(QtGui.QWizard):
else:
self.ui.cbProviders.setEnabled(True)
+ @QtCore.Slot()
+ def _provider_get_details(self, details):
+ """
+ Set the details for the just downloaded provider.
+
+ :param details: the details of the provider.
+ :type details: ProviderConfigLight
+ """
+ self._provider_details = details
+
@QtCore.Slot(dict)
def _download_ca_cert(self, data):
"""
@@ -605,11 +614,9 @@ class Wizard(QtGui.QWizard):
the user to enable or disable.
"""
self.ui.grpServices.setTitle(
- self.tr("Services by %s") %
- (self._provider_config.get_name(),))
+ self.tr("Services by {0}").format(self._provider_details.name))
- services = get_supported(
- self._provider_config.get_services())
+ services = get_supported(self._provider_details.services)
for service in services:
try:
@@ -652,38 +659,31 @@ class Wizard(QtGui.QWizard):
if not self._provider_setup_ok:
self._reset_provider_setup()
sub_title = self.tr("Gathering configuration options for {0}")
- sub_title = sub_title.format(self._provider_config.get_name())
+ sub_title = sub_title.format(self._provider_details.name)
self.page(pageId).setSubTitle(sub_title)
self.ui.lblDownloadCaCert.setPixmap(self.QUESTION_ICON)
self._provider_setup_defer = self._backend.\
provider_bootstrap(self._domain)
if pageId == self.PRESENT_PROVIDER_PAGE:
- self.page(pageId).setSubTitle(self.tr("Description of services "
- "offered by %s") %
- (self._provider_config
- .get_name(),))
-
- lang = QtCore.QLocale.system().name()
- self.ui.lblProviderName.setText(
- "<b>%s</b>" %
- (self._provider_config.get_name(lang=lang),))
- self.ui.lblProviderURL.setText(
- "https://%s" % (self._provider_config.get_domain(),))
- self.ui.lblProviderDesc.setText(
- "<i>%s</i>" %
- (self._provider_config.get_description(lang=lang),))
-
- self.ui.lblServicesOffered.setText(self._provider_config
- .get_services_string())
- self.ui.lblProviderPolicy.setText(self._provider_config
- .get_enrollment_policy())
+ sub_title = self.tr("Description of services offered by {0}")
+ sub_title = sub_title.format(self._provider_details.name)
+ self.page(pageId).setSubTitle(sub_title)
+
+ details = self._provider_details
+ name = "<b>{0}</b>".format(details.name)
+ domain = "https://{0}".format(details.domain)
+ description = "<i>{0}</i>".format(details.description)
+ self.ui.lblProviderName.setText(name)
+ self.ui.lblProviderURL.setText(domain)
+ self.ui.lblProviderDesc.setText(description)
+ self.ui.lblServicesOffered.setText(details.services_string)
+ self.ui.lblProviderPolicy.setText(details.enrollment_policy)
if pageId == self.REGISTER_USER_PAGE:
- self.page(pageId).setSubTitle(self.tr("Register a new user with "
- "%s") %
- (self._provider_config
- .get_name(),))
+ sub_title = self.tr("Register a new user with {0}")
+ sub_title = sub_title.format(self._provider_details.name)
+ self.page(pageId).setSubTitle(sub_title)
self.ui.chkRemember.setVisible(False)
if pageId == self.SERVICES_PAGE:
@@ -706,8 +706,6 @@ class Wizard(QtGui.QWizard):
if self.currentPage() == self.page(self.SELECT_PROVIDER_PAGE):
if self._use_existing_provider:
self._domain = self.ui.cbProviders.currentText()
- self._provider_config = ProviderConfig.get_provider_config(
- self._domain)
if self._show_register:
return self.REGISTER_USER_PAGE
else:
@@ -732,6 +730,7 @@ class Wizard(QtGui.QWizard):
sig.prov_name_resolution.connect(self._name_resolution)
sig.prov_https_connection.connect(self._https_connection)
sig.prov_download_provider_info.connect(self._download_provider_info)
+ sig.prov_get_details.connect(self._provider_get_details)
sig.prov_download_ca_cert.connect(self._download_ca_cert)
sig.prov_check_ca_fingerprint.connect(self._check_ca_fingerprint)
diff --git a/src/leap/bitmask/services/soledad/soledadbootstrapper.py b/src/leap/bitmask/services/soledad/soledadbootstrapper.py
index 2bdad7e2..db12fd80 100644
--- a/src/leap/bitmask/services/soledad/soledadbootstrapper.py
+++ b/src/leap/bitmask/services/soledad/soledadbootstrapper.py
@@ -188,8 +188,9 @@ class SoledadBootstrapper(AbstractBootstrapper):
try:
self.load_and_sync_soledad(uuid, offline=True)
self._signaler.signal(self._signaler.SOLEDAD_OFFLINE_FINISHED)
- except Exception:
+ except Exception as e:
# TODO: we should handle more specific exceptions in here
+ logger.exception(e)
self._signaler.signal(self._signaler.SOLEDAD_OFFLINE_FAILED)
def _get_soledad_local_params(self, uuid, offline=False):