From 1f8a89adeaa5fc551810551e81cf6315a618f85a Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Thu, 12 Nov 2015 12:59:48 +0100 Subject: [PATCH 3/3] passerelle: use shared_secret for ApiUser.key (fixes #8580) --- .../passerelle/management/commands/hobo_deploy.py | 14 +++++- jenkins.sh | 20 ++++++-- tests_passerelle/conftest.py | 15 ++++++ tests_passerelle/settings.py | 25 ++++++++++ tests_passerelle/test_deploy.py | 57 ++++++++++++++++++++++ 5 files changed, 125 insertions(+), 6 deletions(-) create mode 100644 tests_passerelle/conftest.py create mode 100644 tests_passerelle/settings.py create mode 100644 tests_passerelle/test_deploy.py diff --git a/hobo/agent/passerelle/management/commands/hobo_deploy.py b/hobo/agent/passerelle/management/commands/hobo_deploy.py index b488ec8..b74f712 100644 --- a/hobo/agent/passerelle/management/commands/hobo_deploy.py +++ b/hobo/agent/passerelle/management/commands/hobo_deploy.py @@ -2,6 +2,7 @@ import urlparse from tenant_schemas.utils import tenant_context from hobo.agent.common.management.commands import hobo_deploy +from hobo.multitenant.settings_loaders import KnownServices from passerelle.base.models import ApiUser @@ -12,12 +13,21 @@ class Command(hobo_deploy.Command): def deploy_specifics(self, hobo_environment, tenant): super(Command, self).deploy_specifics(hobo_environment, tenant) with tenant_context(tenant): - for service in hobo_environment.get('services'): + services = hobo_environment.get('services') + for service in services: + if service.get('this'): + this = service + break + else: + raise RuntimeError('unable to find this service') + our_key = this['secret_key'] + for service in services: if service.get('this') or not service.get('secret_key'): continue domain = urlparse.urlparse(service.get('base_url')).netloc.split(':')[0] obj, created = ApiUser.objects.get_or_create(username=domain, keytype='SIGN') obj.fullname = service.get('title') - obj.key = service.get('secret_key') + their_key = service.get('secret_key') + obj.key = KnownServices.shared_secret(our_key, their_key) obj.save() diff --git a/jenkins.sh b/jenkins.sh index 695e60e..145a332 100755 --- a/jenkins.sh +++ b/jenkins.sh @@ -1,5 +1,7 @@ #!/bin/sh +set -e # prevent hiding of errors + rm -f *coverage.xml rm -f *test_results.xml @@ -13,21 +15,31 @@ pip install --upgrade -r requirements.txt pip install --upgrade mock pip install --upgrade raven pip install http://git.entrouvert.org/authentic.git/snapshot/authentic-master.tar.gz +pip install http://git.entrouvert.org/passerelle.git/snapshot/passerelle-master.tar.gz + -DJANGO_SETTINGS_MODULE=hobo.settings \ -HOBO_SETTINGS_FILE=tests/settings.py \ -py.test --junitxml=hobo_server_test_results.xml --cov-report xml --cov=hobo/ --cov-config .coveragerc tests/ +# Base tests +DJANGO_SETTINGS_MODULE=hobo.settings HOBO_SETTINGS_FILE=tests/settings.py py.test --junitxml=hobo_server_test_results.xml --cov-report xml --cov=hobo/ --cov-config .coveragerc tests/ mv coverage.xml hobo_server_coverage.xml +# Multitenant PYTHONPATH=tests_multitenant DJANGO_SETTINGS_MODULE=settings py.test --junitxml=multitenant_test_results.xml --cov-report xml --cov=../hobo/ --cov-config .coveragerc tests_multitenant/ mv coverage.xml multitenant_coverage.xml + +# Authentic agent DEBIAN_CONFIG_COMMON=debian/debian_config_common.py DJANGO_SETTINGS_MODULE=authentic2.settings AUTHENTIC2_SETTINGS_FILE=tests_authentic/settings.py py.test --junitxml=authentic2_agent_test_results.xml --cov-report xml --cov=hobo/ --cov-config .coveragerc --nomigration tests_authentic/ mv coverage.xml authentic2_agent_coverage.xml -./merge-junit-results.py hobo_server_test_results.xml multitenant_test_results.xml authentic2_agent_test_results.xml >test_results.xml +# Passerelle agent +DEBIAN_CONFIG_COMMON=debian/debian_config_common.py DJANGO_SETTINGS_MODULE=passerelle.settings PASSERELLE_SETTINGS_FILE=tests_passerelle/settings.py py.test --junitxml=passerelle_agent_test_results.xml --cov-report xml --cov=hobo/ --cov-config .coveragerc --nomigration tests_passerelle/ +mv coverage.xml passerelle_agent_coverage.xml + +./merge-junit-results.py hobo_server_test_results.xml multitenant_test_results.xml authentic2_agent_test_results.xml passerelle_agent_test_results.xml >test_results.xml ./merge-coverage.py -o coverage.xml *_coverage.xml test -f pylint.out && cp pylint.out pylint.out.prev (pylint -f parseable --rcfile /var/lib/jenkins/pylint.django.rc hobo | tee pylint.out) || /bin/true test -f pylint.out.prev && (diff pylint.out.prev pylint.out | grep '^[><]' | grep .py) || /bin/true + +echo OK diff --git a/tests_passerelle/conftest.py b/tests_passerelle/conftest.py new file mode 100644 index 0000000..998f75c --- /dev/null +++ b/tests_passerelle/conftest.py @@ -0,0 +1,15 @@ +import os +import tempfile +import shutil +import json + +import pytest + +@pytest.fixture +def tenant_base(request, settings): + base = tempfile.mkdtemp('passerelle-tenant-base') + settings.TENANT_BASE = base + def fin(): + shutil.rmtree(base) + request.addfinalizer(fin) + return tenant_base diff --git a/tests_passerelle/settings.py b/tests_passerelle/settings.py new file mode 100644 index 0000000..4c1dec4 --- /dev/null +++ b/tests_passerelle/settings.py @@ -0,0 +1,25 @@ +import os.path +import __builtin__ as builtin +from mock import mock_open, patch +import os + +# Debian defaults +DEBUG = False + +PROJECT_NAME = 'passerelle' + +# +# hobotization (multitenant) +# +with patch.object(builtin, 'file', mock_open(read_data='xxx')): + execfile(os.environ['DEBIAN_CONFIG_COMMON']) + +# suds logs are buggy +LOGGING['loggers']['suds'] = { + 'level': 'ERROR', + 'handlers': ['mail_admins', 'sentry'], + 'propagate': True, +} + +# Add passerelle hobo agent +INSTALLED_APPS = ('hobo.agent.passerelle',) + INSTALLED_APPS diff --git a/tests_passerelle/test_deploy.py b/tests_passerelle/test_deploy.py new file mode 100644 index 0000000..01d8df2 --- /dev/null +++ b/tests_passerelle/test_deploy.py @@ -0,0 +1,57 @@ +import json +import sys +import time + +from tenant_schemas.utils import tenant_context +from hobo.multitenant.middleware import TenantMiddleware +from django.core.management import call_command +import StringIO + + +def test_deploy_specifics(db, tenant_base): + from django.conf import settings + from passerelle.base.models import ApiUser + + hobo_json = { + 'variables': { + 'hobo_test_variable': True, + 'other_variable': 'foo', + }, + 'services': [ + { + 'slug': 'test', + 'title': 'Test', + 'service-id': 'welco', + 'this': True, + 'secret_key': '12345', + 'base_url': 'http://passerelle.example.net', + 'saml-sp-metadata-url': 'http://passerelle.example.net/saml/metadata', + 'variables': { + 'other_variable': 'bar', + } + }, + { + 'slug': 'other', + 'title': 'Other', + 'secret_key': 'abcde', + 'service-id': 'wcs', + 'base_url': 'http://wcs.example.net' + }, + ] + } + old_stdin = sys.stdin + sys.stdin = StringIO.StringIO(json.dumps(hobo_json)) + try: + call_command('hobo_deploy', 'http://passerelle.example.net', '-') + finally: + sys.stdin = old_stdin + + assert len(list(TenantMiddleware.get_tenants())) == 1 + tenant = next(TenantMiddleware.get_tenants()) + with tenant_context(tenant): + # There is a 3 seconds cache now, hobo.json could be outdated + settings.clear_tenants_settings() + other = settings.KNOWN_SERVICES['wcs']['other'] + secret = other['secret'] + assert ApiUser.objects.filter(username=other['verif_orig'], keytype='SIGN', + key=secret).count() == 1 -- 2.1.4