From 1263cd7a3cfca81ae3e6976a489e2d3d4013d64b Mon Sep 17 00:00:00 2001 From: kali Date: Thu, 30 Aug 2012 00:36:50 +0900 Subject: add lazy evaluation to config specs now callables are allowed in specs *only at one level depth* to allow for last-minute evaluation on context-sensitive data, like paths affected by os.environ also some minor modifications to make check tests pass after putting the new jsonconfig-based eipconfig in place. aaaaaall green again :) --- src/leap/base/config.py | 7 ++++++ src/leap/eip/checks.py | 15 +++++++----- src/leap/eip/config.py | 2 ++ src/leap/eip/constants.py | 50 +-------------------------------------- src/leap/eip/specs.py | 14 ++++++----- src/leap/eip/tests/__init__.py | 0 src/leap/eip/tests/data.py | 50 +++++++++++++++++++++++++++++++++++++++ src/leap/eip/tests/test_checks.py | 42 +++++++++++++++++++------------- 8 files changed, 102 insertions(+), 78 deletions(-) create mode 100644 src/leap/eip/tests/__init__.py create mode 100644 src/leap/eip/tests/data.py (limited to 'src') diff --git a/src/leap/base/config.py b/src/leap/base/config.py index 465016db..c7871f22 100644 --- a/src/leap/base/config.py +++ b/src/leap/base/config.py @@ -111,6 +111,13 @@ class JSONLeapConfig(BaseLeapConfig): folder, filename = os.path.split(to) if folder and not os.path.isdir(folder): mkdir_p(folder) + # lazy evaluation until first level nest + # to allow lambdas with context-dependant info + # like os.path.expanduser + config = self.get_config() + for k, v in config.iteritems(): + if callable(v): + config[k] = v() self._config.serialize(to) def load(self, fromfile=None): diff --git a/src/leap/eip/checks.py b/src/leap/eip/checks.py index e5b8e971..b92ea706 100644 --- a/src/leap/eip/checks.py +++ b/src/leap/eip/checks.py @@ -52,7 +52,7 @@ class EIPConfigChecker(object): self.config = None self.fetcher = fetcher - #self.eipconfig = eipconfig.EIPConfig() + self.eipconfig = eipconfig.EIPConfig() def run_all(self, checker=None, skip_download=False): """ @@ -211,14 +211,17 @@ class EIPConfigChecker(object): def _is_there_default_eipconfig(self): #XXX - #self.eipconfig.exists() - return os.path.isfile( - self._get_default_eipconfig_path()) + return self.eipconfig.exists() + #return os.path.isfile( + #self._get_default_eipconfig_path()) def _dump_default_eipconfig(self): #XXX self.eipconfig.save() - eipconfig.dump_default_eipconfig( - self._get_default_eipconfig_path()) + logger.debug('saving eipconfig') + #import ipdb;ipdb.set_trace() + self.eipconfig.save() + #eipconfig.dump_default_eipconfig( + #self._get_default_eipconfig_path()) def _get_provider_definition_uri(self, domain=None, path=None): if domain is None: diff --git a/src/leap/eip/config.py b/src/leap/eip/config.py index 34f05070..a7b24f9b 100644 --- a/src/leap/eip/config.py +++ b/src/leap/eip/config.py @@ -15,6 +15,7 @@ from leap.eip import exceptions as eip_exceptions from leap.eip import constants as eipconstants from leap.eip import specs as eipspecs +logging.basicConfig() logger = logging.getLogger(name=__name__) logger.setLevel('DEBUG') @@ -262,6 +263,7 @@ def build_ovpn_command(config, debug=False, do_pkexec_check=True): return [command[0], command[1:]] +# XXX deprecate def get_sensible_defaults(): """ gathers a dict of sensible defaults, diff --git a/src/leap/eip/constants.py b/src/leap/eip/constants.py index 31974926..ce50f5e0 100644 --- a/src/leap/eip/constants.py +++ b/src/leap/eip/constants.py @@ -1,51 +1,3 @@ +# not used anymore with the new JSONConfig.slug EIP_CONFIG = "eip.json" - -# XXX deprecate. EIPConfig used instead -# can move for testing purposes. - -EIP_SAMPLE_JSON = { - "provider": "testprovider.example.org", - "transport": "openvpn", - "openvpn_protocol": "tcp", - "openvpn_port": "80", - "openvpn_ca_certificate": "~/.config/leap/providers/" - "testprovider.example.org/" - "keys/ca/testprovider-ca-cert-" - "2013-01-01.pem", - "openvpn_client_certificate": "~/.config/leap/providers/" - "testprovider.example.org/" - "keys/client/openvpn-2012-09-31.pem", - "connect_on_login": True, - "block_cleartext_traffic": True, - "primary_gateway": "usa_west", - "secondary_gateway": "france", - "management_password": "oph7Que1othahwiech6J" -} - EIP_SERVICE_EXPECTED_PATH = "eip-service.json" - -EIP_SAMPLE_SERVICE = { - "serial": 1, - "version": "0.1.0", - "capabilities": { - "transport": ["openvpn"], - "ports": ["80", "53"], - "protocols": ["udp", "tcp"], - "static_ips": True, - "adblock": True - }, - "gateways": [ - {"country_code": "us", - "label": {"en":"west"}, - "capabilities": {}, - "hosts": ["1.2.3.4", "1.2.3.5"]}, - {"country_code": "us", - "label": {"en":"east"}, - "capabilities": {}, - "hosts": ["1.2.3.4", "1.2.3.5"]}, - {"country_code": "fr", - "label": {}, - "capabilities": {}, - "hosts": ["1.2.3.4", "1.2.3.5"]} - ] -} diff --git a/src/leap/eip/specs.py b/src/leap/eip/specs.py index 572177dd..a39e5979 100644 --- a/src/leap/eip/specs.py +++ b/src/leap/eip/specs.py @@ -1,19 +1,21 @@ +from __future__ import (unicode_literals) import os from leap.base import config as baseconfig -provider_ca_path = os.path.join( +provider_ca_path = lambda: unicode(os.path.join( baseconfig.get_default_provider_path(), 'keys', 'ca', 'testprovider-ca-cert.pem' -) +)) -client_cert_path = os.path.join( + +client_cert_path = lambda: unicode(os.path.join( baseconfig.get_default_provider_path(), 'keys', 'client', 'openvpn.pem' -) +)) eipconfig_spec = { 'provider': { @@ -33,7 +35,7 @@ eipconfig_spec = { 'type': int, 'default': 80 }, - 'oepnvpn_ca_certificate': { + 'openvpn_ca_certificate': { 'type': unicode, # path 'default': provider_ca_path }, @@ -45,7 +47,7 @@ eipconfig_spec = { 'type': bool, 'default': True }, - 'block_cleartext_tr affic': { + 'block_cleartext_traffic': { 'type': bool, 'default': True }, diff --git a/src/leap/eip/tests/__init__.py b/src/leap/eip/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/leap/eip/tests/data.py b/src/leap/eip/tests/data.py new file mode 100644 index 00000000..9067c270 --- /dev/null +++ b/src/leap/eip/tests/data.py @@ -0,0 +1,50 @@ +from __future__ import unicode_literals +import os + +# sample data used in tests + +EIP_SAMPLE_JSON = { + "provider": "testprovider.example.org", + "transport": "openvpn", + "openvpn_protocol": "tcp", + "openvpn_port": 80, + "openvpn_ca_certificate": os.path.expanduser( + "~/.config/leap/providers/" + "testprovider.example.org/" + "keys/ca/testprovider-ca-cert.pem"), + "openvpn_client_certificate": os.path.expanduser( + "~/.config/leap/providers/" + "testprovider.example.org/" + "keys/client/openvpn.pem"), + "connect_on_login": True, + "block_cleartext_traffic": True, + "primary_gateway": "usa_west", + "secondary_gateway": "france", + #"management_password": "oph7Que1othahwiech6J" +} + +EIP_SAMPLE_SERVICE = { + "serial": 1, + "version": "0.1.0", + "capabilities": { + "transport": ["openvpn"], + "ports": ["80", "53"], + "protocols": ["udp", "tcp"], + "static_ips": True, + "adblock": True + }, + "gateways": [ + {"country_code": "us", + "label": {"en":"west"}, + "capabilities": {}, + "hosts": ["1.2.3.4", "1.2.3.5"]}, + {"country_code": "us", + "label": {"en":"east"}, + "capabilities": {}, + "hosts": ["1.2.3.4", "1.2.3.5"]}, + {"country_code": "fr", + "label": {}, + "capabilities": {}, + "hosts": ["1.2.3.4", "1.2.3.5"]} + ] +} diff --git a/src/leap/eip/tests/test_checks.py b/src/leap/eip/tests/test_checks.py index 1c79ce0c..e53a2a1d 100644 --- a/src/leap/eip/tests/test_checks.py +++ b/src/leap/eip/tests/test_checks.py @@ -14,8 +14,9 @@ from leap.base import config as baseconfig from leap.base.constants import (DEFAULT_PROVIDER_DEFINITION, DEFINITION_EXPECTED_PATH) from leap.eip import checks as eipchecks -from leap.eip import constants as eipconstants +from leap.eip import specs as eipspecs from leap.eip import exceptions as eipexceptions +from leap.eip.tests import data as testdata from leap.testing.basetest import BaseLeapTest @@ -66,17 +67,24 @@ class EIPCheckTest(BaseLeapTest): def test_check_default_eipconfig(self): checker = eipchecks.EIPConfigChecker() # no eip config (empty home) - eipconfig = baseconfig.get_config_file(eipconstants.EIP_CONFIG) - self.assertFalse(os.path.isfile(eipconfig)) + eipconfig_path = checker.eipconfig.filename + self.assertFalse(os.path.isfile(eipconfig_path)) checker.check_default_eipconfig() # we've written one, so it should be there. - self.assertTrue(os.path.isfile(eipconfig)) - with open(eipconfig, 'rb') as fp: + self.assertTrue(os.path.isfile(eipconfig_path)) + with open(eipconfig_path, 'rb') as fp: deserialized = json.load(fp) - self.assertEqual(deserialized, - eipconstants.EIP_SAMPLE_JSON) - # TODO: when new JSONConfig class is in place, we shold - # run validation methods. + + # force re-evaluation of the paths + # small workaround for evaluating home dirs correctly + EIP_SAMPLE_JSON = copy.copy(testdata.EIP_SAMPLE_JSON) + EIP_SAMPLE_JSON['openvpn_client_certificate'] = \ + eipspecs.client_cert_path() + EIP_SAMPLE_JSON['openvpn_ca_certificate'] = \ + eipspecs.provider_ca_path() + self.assertEqual(deserialized, EIP_SAMPLE_JSON) + + # TODO: shold ALSO run validation methods. def test_check_is_there_default_provider(self): checker = eipchecks.EIPConfigChecker() @@ -85,7 +93,7 @@ class EIPCheckTest(BaseLeapTest): # This error will be possible catched in a different # place, when JSONConfig does validation of required fields. - sampleconfig = copy.copy(eipconstants.EIP_SAMPLE_JSON) + sampleconfig = copy.copy(testdata.EIP_SAMPLE_JSON) # blank out default_provider sampleconfig['provider'] = None eipcfg_path = checker._get_default_eipconfig_path() @@ -94,7 +102,7 @@ class EIPCheckTest(BaseLeapTest): with self.assertRaises(eipexceptions.EIPMissingDefaultProvider): checker.check_is_there_default_provider() - sampleconfig = eipconstants.EIP_SAMPLE_JSON + sampleconfig = testdata.EIP_SAMPLE_JSON eipcfg_path = checker._get_default_eipconfig_path() with open(eipcfg_path, 'w') as fp: json.dump(sampleconfig, fp) @@ -105,7 +113,7 @@ class EIPCheckTest(BaseLeapTest): mocked_get.return_value.status_code = 200 mocked_get.return_value.json = DEFAULT_PROVIDER_DEFINITION checker = eipchecks.EIPConfigChecker(fetcher=requests) - sampleconfig = eipconstants.EIP_SAMPLE_JSON + sampleconfig = testdata.EIP_SAMPLE_JSON checker.fetch_definition(config=sampleconfig) fn = os.path.join(baseconfig.get_default_provider_path(), @@ -121,24 +129,24 @@ class EIPCheckTest(BaseLeapTest): def test_fetch_eip_config(self): with patch.object(requests, "get") as mocked_get: mocked_get.return_value.status_code = 200 - mocked_get.return_value.json = eipconstants.EIP_SAMPLE_SERVICE + mocked_get.return_value.json = testdata.EIP_SAMPLE_SERVICE checker = eipchecks.EIPConfigChecker(fetcher=requests) - sampleconfig = eipconstants.EIP_SAMPLE_JSON + sampleconfig = testdata.EIP_SAMPLE_JSON checker.fetch_definition(config=sampleconfig) def test_check_complete_eip_config(self): checker = eipchecks.EIPConfigChecker() with self.assertRaises(eipexceptions.EIPConfigurationError): - sampleconfig = copy.copy(eipconstants.EIP_SAMPLE_JSON) + sampleconfig = copy.copy(testdata.EIP_SAMPLE_JSON) sampleconfig['provider'] = None checker.check_complete_eip_config(config=sampleconfig) with self.assertRaises(eipexceptions.EIPConfigurationError): - sampleconfig = copy.copy(eipconstants.EIP_SAMPLE_JSON) + sampleconfig = copy.copy(testdata.EIP_SAMPLE_JSON) del sampleconfig['provider'] checker.check_complete_eip_config(config=sampleconfig) # normal case - sampleconfig = copy.copy(eipconstants.EIP_SAMPLE_JSON) + sampleconfig = copy.copy(testdata.EIP_SAMPLE_JSON) checker.check_complete_eip_config(config=sampleconfig) if __name__ == "__main__": -- cgit v1.2.3