summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/leap/bitmask/backend.py11
-rw-r--r--src/leap/bitmask/gui/mainwindow.py15
-rw-r--r--src/leap/bitmask/provider/__init__.py22
-rw-r--r--src/leap/bitmask/provider/providerbootstrapper.py17
4 files changed, 64 insertions, 1 deletions
diff --git a/src/leap/bitmask/backend.py b/src/leap/bitmask/backend.py
index 8a289a79..705a85be 100644
--- a/src/leap/bitmask/backend.py
+++ b/src/leap/bitmask/backend.py
@@ -194,6 +194,8 @@ class Signaler(QtCore.QObject):
prov_problem_with_provider = QtCore.Signal(object)
+ prov_unsupported_client = QtCore.Signal(object)
+
# These will exist both in the backend and the front end.
# The frontend might choose to not "interpret" all the signals
# from the backend, but the backend needs to have all the signals
@@ -205,6 +207,7 @@ class Signaler(QtCore.QObject):
PROV_CHECK_CA_FINGERPRINT_KEY = "prov_check_ca_fingerprint"
PROV_CHECK_API_CERTIFICATE_KEY = "prov_check_api_certificate"
PROV_PROV_PROBLEM_WITH_PROVIER_KEY = "prov_problem_with_provider"
+ PROV_UNSUPPORTED_CLIENT = "prov_unsupported_client"
def __init__(self):
"""
@@ -220,7 +223,8 @@ class Signaler(QtCore.QObject):
self.PROV_DOWNLOAD_CA_CERT_KEY,
self.PROV_CHECK_CA_FINGERPRINT_KEY,
self.PROV_CHECK_API_CERTIFICATE_KEY,
- self.PROV_PROV_PROBLEM_WITH_PROVIER_KEY
+ self.PROV_PROV_PROBLEM_WITH_PROVIER_KEY,
+ self.PROV_UNSUPPORTED_CLIENT
]
for sig in signals:
@@ -243,6 +247,11 @@ class Signaler(QtCore.QObject):
# will do zmq.send_multipart, and the frontend version will be
# similar to this
log.msg("Signaling %s :: %s" % (key, data))
+
+ # for some reason emitting 'None' gives a segmentation fault.
+ if data is None:
+ data = ''
+
try:
self._signals[key].emit(data)
except KeyError:
diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py
index f954006d..69cb4169 100644
--- a/src/leap/bitmask/gui/mainwindow.py
+++ b/src/leap/bitmask/gui/mainwindow.py
@@ -380,6 +380,9 @@ class MainWindow(QtGui.QMainWindow):
partial(self._login_widget.set_status,
self.tr("Unable to login: Problem with provider")))
+ self._backend.signaler.prov_unsupported_client.connect(
+ self._needs_update)
+
def _backend_disconnect(self):
"""
Helper to disconnect from backend signals.
@@ -856,6 +859,18 @@ class MainWindow(QtGui.QMainWindow):
"<a href='https://leap.se'>More about LEAP"
"</a>") % (VERSION, VERSION_HASH[:10], greet))
+ def _needs_update(self):
+ """
+ Display a warning dialog to inform the user that the app needs update.
+ """
+ url = "https://dl.bitmask.net/"
+ msg = self.tr(
+ "The current client version is not supported "
+ "by this provider.<br>"
+ "Please update to latest version.<br><br>"
+ "You can get the latest version from {0}").format(url)
+ QtGui.QMessageBox.warning(self, self.tr("Update Needed"), msg)
+
def changeEvent(self, e):
"""
Reimplements the changeEvent method to minimize to tray
diff --git a/src/leap/bitmask/provider/__init__.py b/src/leap/bitmask/provider/__init__.py
index 53587d65..68f3ded0 100644
--- a/src/leap/bitmask/provider/__init__.py
+++ b/src/leap/bitmask/provider/__init__.py
@@ -18,6 +18,10 @@
Module initialization for leap.bitmask.provider
"""
import os
+
+from distutils.version import LooseVersion
+
+from leap.bitmask import __version__ as BITMASK_VERSION
from leap.common.check import leap_assert
@@ -32,3 +36,21 @@ def get_provider_path(domain):
"""
leap_assert(domain is not None, "get_provider_path: We need a domain")
return os.path.join("leap", "providers", domain, "provider.json")
+
+
+class SupportedClient(object):
+ """
+ Class responsible of checking for client compatibility.
+ """
+
+ @classmethod
+ def supports(self, minimum_version):
+ """
+ :param minimum_version: the version number of the client that
+ we need to check.
+ :type minimum_version: str
+
+ :returns: True if that version is supported or False otherwise.
+ :return type: bool
+ """
+ return LooseVersion(minimum_version) <= LooseVersion(BITMASK_VERSION)
diff --git a/src/leap/bitmask/provider/providerbootstrapper.py b/src/leap/bitmask/provider/providerbootstrapper.py
index 947ba0c9..695b1593 100644
--- a/src/leap/bitmask/provider/providerbootstrapper.py
+++ b/src/leap/bitmask/provider/providerbootstrapper.py
@@ -30,6 +30,7 @@ from leap.bitmask import util
from leap.bitmask.util.constants import REQUEST_TIMEOUT
from leap.bitmask.services.abstractbootstrapper import AbstractBootstrapper
from leap.bitmask.provider.supportedapis import SupportedAPIs
+from leap.bitmask.provider import SupportedClient
from leap.common import ca_bundle
from leap.common.certs import get_digest
from leap.common.files import check_and_fix_urw_only, get_mtime, mkdir_p
@@ -45,6 +46,14 @@ class UnsupportedProviderAPI(Exception):
pass
+class UnsupportedClientVersionError(Exception):
+ """
+ Raised when attempting to use a provider with an older
+ client than supported.
+ """
+ pass
+
+
class WrongFingerprint(Exception):
"""
Raised when a fingerprint comparison does not match.
@@ -59,6 +68,8 @@ class ProviderBootstrapper(AbstractBootstrapper):
If a check fails, the subsequent checks are not executed
"""
+ MIN_CLIENT_VERSION = 'x-minimum-client-version'
+
def __init__(self, signaler=None, bypass_checks=False):
"""
Constructor for provider bootstrapper object
@@ -187,6 +198,8 @@ class ProviderBootstrapper(AbstractBootstrapper):
res.raise_for_status()
logger.debug("Request status code: {0}".format(res.status_code))
+ min_client_version = res.headers.get(self.MIN_CLIENT_VERSION, '0')
+
# Not modified
if res.status_code == 304:
logger.debug("Provider definition has not been modified")
@@ -194,6 +207,10 @@ class ProviderBootstrapper(AbstractBootstrapper):
# end refactor, more or less...
# XXX Watch out, have to check the supported api yet.
else:
+ if not SupportedClient.supports(min_client_version):
+ self._signaler.signal(self._signaler.PROV_UNSUPPORTED_CLIENT)
+ raise UnsupportedClientVersionError()
+
provider_definition, mtime = get_content(res)
provider_config = ProviderConfig()