From 74397ee78ab7f01cb622b0e06b3de901a3604f0b Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Tue, 7 Jan 2014 18:25:21 -0300 Subject: Warn the user if is using an old app version. [Closes #4636] --- src/leap/bitmask/provider/__init__.py | 22 ++++++++++++++++++++++ src/leap/bitmask/provider/providerbootstrapper.py | 17 +++++++++++++++++ 2 files changed, 39 insertions(+) (limited to 'src/leap/bitmask/provider') 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() -- cgit v1.2.3 From 504936617069b7dcba497ba6daf630769c36d4fd Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Tue, 7 Jan 2014 18:47:26 -0300 Subject: Move a provider problem to a separate signal. - Some code cleanup - Fix typos --- src/leap/bitmask/provider/providerbootstrapper.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/leap/bitmask/provider') diff --git a/src/leap/bitmask/provider/providerbootstrapper.py b/src/leap/bitmask/provider/providerbootstrapper.py index 695b1593..c02b4a05 100644 --- a/src/leap/bitmask/provider/providerbootstrapper.py +++ b/src/leap/bitmask/provider/providerbootstrapper.py @@ -228,6 +228,8 @@ class ProviderBootstrapper(AbstractBootstrapper): 'Found: {1}.').format(api_supported, api_version) logger.error(error) + self._signaler.signal( + self._signaler.PROV_PROBLEM_WITH_PROVIDER_KEY) raise UnsupportedProviderAPI(error) def run_provider_select_checks(self, domain, download_if_needed=False): -- cgit v1.2.3 From fc0663054c4f76c1103291c334bb60c0dff1280b Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Tue, 7 Jan 2014 18:58:06 -0300 Subject: Refactor provider utilities. --- src/leap/bitmask/provider/__init__.py | 37 +++++++++++++-------- src/leap/bitmask/provider/providerbootstrapper.py | 9 +++-- src/leap/bitmask/provider/supportedapis.py | 38 ---------------------- .../provider/tests/test_providerbootstrapper.py | 10 +++--- 4 files changed, 32 insertions(+), 62 deletions(-) delete mode 100644 src/leap/bitmask/provider/supportedapis.py (limited to 'src/leap/bitmask/provider') diff --git a/src/leap/bitmask/provider/__init__.py b/src/leap/bitmask/provider/__init__.py index 68f3ded0..ca6426f4 100644 --- a/src/leap/bitmask/provider/__init__.py +++ b/src/leap/bitmask/provider/__init__.py @@ -15,7 +15,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . """ -Module initialization for leap.bitmask.provider +Provider utilities. """ import os @@ -25,6 +25,10 @@ from leap.bitmask import __version__ as BITMASK_VERSION from leap.common.check import leap_assert +# The currently supported API versions by the client. +SUPPORTED_APIS = ["1"] + + def get_provider_path(domain): """ Returns relative path for provider config. @@ -38,19 +42,24 @@ def get_provider_path(domain): return os.path.join("leap", "providers", domain, "provider.json") -class SupportedClient(object): +def supports_api(api_version): """ - Class responsible of checking for client compatibility. + :param api_version: the version number of the api that we need to check + :type api_version: str + + :returns: if that version is supported or not. + :return type: bool """ + return api_version in SUPPORTED_APIS + - @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) +def supports_client(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 c02b4a05..e00dd646 100644 --- a/src/leap/bitmask/provider/providerbootstrapper.py +++ b/src/leap/bitmask/provider/providerbootstrapper.py @@ -29,8 +29,7 @@ from leap.bitmask.util.request_helpers import get_content 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.bitmask import provider 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 @@ -207,7 +206,7 @@ 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): + if not provider.supports_client(min_client_version): self._signaler.signal(self._signaler.PROV_UNSUPPORTED_CLIENT) raise UnsupportedClientVersionError() @@ -219,10 +218,10 @@ class ProviderBootstrapper(AbstractBootstrapper): domain, "provider.json"]) api_version = provider_config.get_api_version() - if SupportedAPIs.supports(api_version): + if provider.supports_api(api_version): logger.debug("Provider definition has been modified") else: - api_supported = ', '.join(SupportedAPIs.SUPPORTED_APIS) + api_supported = ', '.join(provider.SUPPORTED_APIS) error = ('Unsupported provider API version. ' 'Supported versions are: {0}. ' 'Found: {1}.').format(api_supported, api_version) diff --git a/src/leap/bitmask/provider/supportedapis.py b/src/leap/bitmask/provider/supportedapis.py deleted file mode 100644 index 3e650ba2..00000000 --- a/src/leap/bitmask/provider/supportedapis.py +++ /dev/null @@ -1,38 +0,0 @@ -# -*- coding: utf-8 -*- -# supportedapis.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 . - -""" -API Support check. -""" - - -class SupportedAPIs(object): - """ - Class responsible of checking for API compatibility. - """ - SUPPORTED_APIS = ["1"] - - @classmethod - def supports(self, api_version): - """ - :param api_version: the version number of the api that we need to check - :type api_version: str - - :returns: if that version is supported or not. - :return type: bool - """ - return api_version in self.SUPPORTED_APIS diff --git a/src/leap/bitmask/provider/tests/test_providerbootstrapper.py b/src/leap/bitmask/provider/tests/test_providerbootstrapper.py index d8336fec..6cf3e469 100644 --- a/src/leap/bitmask/provider/tests/test_providerbootstrapper.py +++ b/src/leap/bitmask/provider/tests/test_providerbootstrapper.py @@ -36,17 +36,17 @@ from nose.twistedtools import deferred, reactor from twisted.internet import threads from requests.models import Response +from leap.bitmask import provider +from leap.bitmask import util +from leap.bitmask.backend import Signaler from leap.bitmask.config.providerconfig import ProviderConfig from leap.bitmask.crypto.tests import fake_provider from leap.bitmask.provider.providerbootstrapper import ProviderBootstrapper from leap.bitmask.provider.providerbootstrapper import UnsupportedProviderAPI from leap.bitmask.provider.providerbootstrapper import WrongFingerprint -from leap.bitmask.provider.supportedapis import SupportedAPIs -from leap.bitmask.backend import Signaler -from leap.bitmask import util from leap.common.files import mkdir_p -from leap.common.testing.https_server import where from leap.common.testing.basetest import BaseLeapTest +from leap.common.testing.https_server import where class ProviderBootstrapperTest(BaseLeapTest): @@ -489,7 +489,7 @@ class ProviderBootstrapperActiveTest(unittest.TestCase): 'leap.bitmask.config.providerconfig.ProviderConfig.get_ca_cert_path', lambda x: where('cacert.pem')) def test_download_provider_info_unsupported_api(self): - self._setup_provider_config_with(SupportedAPIs.SUPPORTED_APIS[0], + self._setup_provider_config_with(provider.SUPPORTED_APIS[0], tempfile.mkdtemp()) self._setup_providerbootstrapper(False) self._produce_dummy_provider_json() -- cgit v1.2.3 From f4a0747e216fb651628490f7849d2e4c9c6d8092 Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Tue, 7 Jan 2014 19:06:49 -0300 Subject: Warn the user on incompatible api error. - Add a proper signal for the incompatible api error. - Warn the user of an incompatible api. --- src/leap/bitmask/provider/providerbootstrapper.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/leap/bitmask/provider') diff --git a/src/leap/bitmask/provider/providerbootstrapper.py b/src/leap/bitmask/provider/providerbootstrapper.py index e00dd646..52ebacd2 100644 --- a/src/leap/bitmask/provider/providerbootstrapper.py +++ b/src/leap/bitmask/provider/providerbootstrapper.py @@ -227,8 +227,7 @@ class ProviderBootstrapper(AbstractBootstrapper): 'Found: {1}.').format(api_supported, api_version) logger.error(error) - self._signaler.signal( - self._signaler.PROV_PROBLEM_WITH_PROVIDER_KEY) + self._signaler.signal(self._signaler.PROV_UNSUPPORTED_API) raise UnsupportedProviderAPI(error) def run_provider_select_checks(self, domain, download_if_needed=False): -- cgit v1.2.3 From caeb3f95236005ffd1260394688344459208e9a6 Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Wed, 8 Jan 2014 13:35:35 -0300 Subject: Replace version check with a better one. --- src/leap/bitmask/provider/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/leap/bitmask/provider') diff --git a/src/leap/bitmask/provider/__init__.py b/src/leap/bitmask/provider/__init__.py index ca6426f4..87f9a8b7 100644 --- a/src/leap/bitmask/provider/__init__.py +++ b/src/leap/bitmask/provider/__init__.py @@ -19,7 +19,7 @@ Provider utilities. """ import os -from distutils.version import LooseVersion +from pkg_resources import parse_version from leap.bitmask import __version__ as BITMASK_VERSION from leap.common.check import leap_assert @@ -62,4 +62,4 @@ def supports_client(minimum_version): :returns: True if that version is supported or False otherwise. :return type: bool """ - return LooseVersion(minimum_version) <= LooseVersion(BITMASK_VERSION) + return parse_version(minimum_version) <= parse_version(BITMASK_VERSION) -- cgit v1.2.3 From c9644f1bdbd26e3c54d8849433d8cfb9fc05a3e7 Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Wed, 8 Jan 2014 18:22:21 -0300 Subject: Use short version since we don't care of suffix. This way we support client '0.5.0-rc3' if the provider supports '0.5.0'. --- src/leap/bitmask/provider/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/leap/bitmask/provider') diff --git a/src/leap/bitmask/provider/__init__.py b/src/leap/bitmask/provider/__init__.py index 87f9a8b7..89ff5d95 100644 --- a/src/leap/bitmask/provider/__init__.py +++ b/src/leap/bitmask/provider/__init__.py @@ -21,7 +21,7 @@ import os from pkg_resources import parse_version -from leap.bitmask import __version__ as BITMASK_VERSION +from leap.bitmask import __short_version__ as BITMASK_VERSION from leap.common.check import leap_assert -- cgit v1.2.3 From 785380dfa7b3f6205b52be2a90afa9b0afa04c5e Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Thu, 9 Jan 2014 14:24:33 -0300 Subject: Add flag to disable version check. --- src/leap/bitmask/provider/providerbootstrapper.py | 34 +++++++++++++---------- 1 file changed, 19 insertions(+), 15 deletions(-) (limited to 'src/leap/bitmask/provider') diff --git a/src/leap/bitmask/provider/providerbootstrapper.py b/src/leap/bitmask/provider/providerbootstrapper.py index 52ebacd2..531d255e 100644 --- a/src/leap/bitmask/provider/providerbootstrapper.py +++ b/src/leap/bitmask/provider/providerbootstrapper.py @@ -24,6 +24,7 @@ import sys import requests +from leap.bitmask.config import flags from leap.bitmask.config.providerconfig import ProviderConfig, MissingCACert from leap.bitmask.util.request_helpers import get_content from leap.bitmask import util @@ -206,9 +207,11 @@ class ProviderBootstrapper(AbstractBootstrapper): # end refactor, more or less... # XXX Watch out, have to check the supported api yet. else: - if not provider.supports_client(min_client_version): - self._signaler.signal(self._signaler.PROV_UNSUPPORTED_CLIENT) - raise UnsupportedClientVersionError() + if flags.APP_VERSION_CHECK: + if not provider.supports_client(min_client_version): + self._signaler.signal( + self._signaler.PROV_UNSUPPORTED_CLIENT) + raise UnsupportedClientVersionError() provider_definition, mtime = get_content(res) @@ -217,18 +220,19 @@ class ProviderBootstrapper(AbstractBootstrapper): provider_config.save(["leap", "providers", domain, "provider.json"]) - api_version = provider_config.get_api_version() - if provider.supports_api(api_version): - logger.debug("Provider definition has been modified") - else: - api_supported = ', '.join(provider.SUPPORTED_APIS) - error = ('Unsupported provider API version. ' - 'Supported versions are: {0}. ' - 'Found: {1}.').format(api_supported, api_version) - - logger.error(error) - self._signaler.signal(self._signaler.PROV_UNSUPPORTED_API) - raise UnsupportedProviderAPI(error) + if flags.API_VERSION_CHECK: + api_version = provider_config.get_api_version() + if provider.supports_api(api_version): + logger.debug("Provider definition has been modified") + else: + api_supported = ', '.join(provider.SUPPORTED_APIS) + error = ('Unsupported provider API version. ' + 'Supported versions are: {0}. ' + 'Found: {1}.').format(api_supported, api_version) + + logger.error(error) + self._signaler.signal(self._signaler.PROV_UNSUPPORTED_API) + raise UnsupportedProviderAPI(error) def run_provider_select_checks(self, domain, download_if_needed=False): """ -- cgit v1.2.3