From a3164642064c49b1a5b62775c5d782062e770c57 Mon Sep 17 00:00:00 2001 From: Serghei Mihai Date: Fri, 21 Apr 2017 11:43:59 +0200 Subject: [PATCH] provisionning agent (#12910) --- corbo/hobo_agent/__init__.py | 0 corbo/hobo_agent/management/__init__.py | 0 corbo/hobo_agent/management/commands/__init__.py | 0 .../hobo_agent/management/commands/hobo_notify.py | 51 +++++++++++++ debian/debian_config.py | 2 + tests/conftest.py | 85 ++++++++++++++++++++++ tests/settings.py | 2 + tests/test_notify.py | 72 ++++++++++++++++++ tox.ini | 2 + 9 files changed, 214 insertions(+) create mode 100644 corbo/hobo_agent/__init__.py create mode 100644 corbo/hobo_agent/management/__init__.py create mode 100644 corbo/hobo_agent/management/commands/__init__.py create mode 100644 corbo/hobo_agent/management/commands/hobo_notify.py create mode 100644 tests/settings.py create mode 100644 tests/test_notify.py diff --git a/corbo/hobo_agent/__init__.py b/corbo/hobo_agent/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/corbo/hobo_agent/management/__init__.py b/corbo/hobo_agent/management/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/corbo/hobo_agent/management/commands/__init__.py b/corbo/hobo_agent/management/commands/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/corbo/hobo_agent/management/commands/hobo_notify.py b/corbo/hobo_agent/management/commands/hobo_notify.py new file mode 100644 index 0000000..e123f9a --- /dev/null +++ b/corbo/hobo_agent/management/commands/hobo_notify.py @@ -0,0 +1,51 @@ +# corbo - Announces Manager +# Copyright (C) 2017 Entr'ouvert +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +from hobo.agent.common.management.commands import hobo_notify + +from corbo.models import Subscription + +class Command(hobo_notify.Command): + + def process_notification(self, tenant, notification): + super(Command, self).process_notification(tenant, notification) + object_type = notification['objects']['@type'] + if object_type != 'user': + return + users = notification['objects']['data'] + action = notification['@type'] + if notification.get('full'): + uuids = [user['uuid'] for user in users] + Subscription.objects.filter(uuid__isnull=False).filter(uuid='').exclude(uuid__in=uuids).delete() + + for user in users: + for subscription in Subscription.objects.filter(uuid=user['uuid']): + if action == 'provision': + if subscription.identifier.startswith('mailto:'): + if user.get('email'): + subscription.identifier = 'mailto:%s' % user['email'] + else: + subscription.delete() + continue + elif subscription.identifier.startswith('sms:'): + if user.get('mobile'): + subscription.identifier = 'sms:%s' % user['mobile'] + else: + subscription.delete() + continue + subscription.save() + elif action == 'deprovision': + subscription.delete() diff --git a/debian/debian_config.py b/debian/debian_config.py index 743e9ca..fe2d43d 100644 --- a/debian/debian_config.py +++ b/debian/debian_config.py @@ -12,6 +12,8 @@ INSTALLED_APPS += ('mellon',) # execfile('/usr/lib/hobo/debian_config_common.py') +INSTALLED_APPS = ('corbo.hobo_agent', ) + INSTALLED_APPS + # # local settings # diff --git a/tests/conftest.py b/tests/conftest.py index 9623903..334c6c5 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,9 +1,22 @@ import pytest import django_webtest import copy +import tempfile +import os +import json +import shutil import django.core.mail.backends.locmem from django.core.mail.backends.locmem import EmailBackend as DjangoEmailBackend +from django.utils.text import slugify + +from corbo.models import Category, Announce, Broadcast, Subscription + +CATEGORIES = ('Alerts', 'News') + +SUBSCRIBERS = [{'uuid': 'uuid1', 'email': 'foo@example.net', 'mobile': '0102030405'}, + {'uuid': 'uuid2', 'email': 'bar@example.net', 'mobile': '0607080900'}, + {'uuid': '', 'email': 'john@example.net', 'mobile': '0304050607'}] class MockedEmailBackend(object): @@ -42,3 +55,75 @@ def app(request): wtm._patch_settings() request.addfinalizer(wtm._unpatch_settings) return django_webtest.DjangoTestApp() + + +@pytest.fixture +def categories(): + categories = [] + for category in CATEGORIES: + c, created = Category.objects.get_or_create(name=category, slug=slugify(category)) + categories.append(c) + return categories + + +@pytest.fixture +def subscriptions(categories): + subscriptions = [] + for category in categories: + for subscriber in SUBSCRIBERS: + uuid = subscriber['uuid'] + subscriptions.append(Subscription.objects.create(category=category, uuid=uuid, + identifier='mailto:%(email)s' % subscriber)) + subscriptions.append(Subscription.objects.create(category=category, uuid=uuid, + identifier='sms:%(mobile)s' % subscriber)) + return subscriptions + + +@pytest.fixture +def tenant_base(request, settings): + base = tempfile.mkdtemp('corbo-tenant-base') + settings.TENANT_BASE = base + + def fin(): + shutil.rmtree(base) + request.addfinalizer(fin) + return base + + +@pytest.fixture(scope='function') +def tenant(transactional_db, request, tenant_base): + from hobo.multitenant.models import Tenant + base = tenant_base + + @pytest.mark.django_db + def make_tenant(name): + tenant_dir = os.path.join(base, name) + os.mkdir(tenant_dir) + with open(os.path.join(tenant_dir, 'hobo.json'), 'w') as fd: + json.dump({ + 'variables': { + 'hobo_test_variable': True, + 'other_variable': 'foo', + }, + 'services': [ + {'slug': 'test', + 'service-id': 'corbo', + 'title': 'Test', + 'this': True, + 'secret_key': '12345', + 'base_url': 'http://%s' % name, + 'saml-sp-metadata-url': 'http://%s/metadata/' % name, + 'variables': { + 'other_variable': 'bar', + } + }, + {'slug': 'passerelle', + 'title': 'Webserivces', + 'service-id': 'passerelle', + 'secret_key': 'abcdef', + 'base_url': 'http://passerelle.example.net', + 'saml-sp-metadata-url': 'http://passerelle.example.net/metadata/' }, + ]}, fd) + return Tenant(domain_url=name, + schema_name=name.replace('-', '_').replace('.', '_')) + return make_tenant('corbo.example.net') diff --git a/tests/settings.py b/tests/settings.py new file mode 100644 index 0000000..56fc458 --- /dev/null +++ b/tests/settings.py @@ -0,0 +1,2 @@ +# Add corbo hobo agent +INSTALLED_APPS = ('corbo.hobo_agent', ) + INSTALLED_APPS diff --git a/tests/test_notify.py b/tests/test_notify.py new file mode 100644 index 0000000..9bc1994 --- /dev/null +++ b/tests/test_notify.py @@ -0,0 +1,72 @@ +import pytest +from copy import deepcopy +import json + +from corbo.models import Subscription +from corbo.hobo_agent.management.commands.hobo_notify import Command +from django.core.management import call_command + +NOTIFICATION = {'@type': 'provision', + 'objects': {'@type': 'user', + 'data': [ + {'uuid': 'uuid1', 'email': 'foo1@example.net', 'mobile': '0504030201'}, + {'uuid': 'uuid2', 'email': 'bar1@example.net', 'mobile': '0009080706'}, + ]}, + 'audience': [], + 'full': False +} + + +def test_notify_provision(tenant, subscriptions): + command = Command() + command.process_notification(tenant, NOTIFICATION) + assert Subscription.objects.count() == len(subscriptions) + for user in NOTIFICATION['objects']['data']: + assert Subscription.objects.filter(uuid=user['uuid'], identifier='mailto:%(email)s' % user).exists() + assert Subscription.objects.filter(uuid=user['uuid'], identifier='sms:%(mobile)s' % user).exists() + + +def test_notify_other_provision(tenant, subscriptions): + role_notification = deepcopy(NOTIFICATION) + role_notification['objects']['@type'] = 'role' + command = Command() + command.process_notification(tenant, role_notification) + assert Subscription.objects.count() == len(subscriptions) + for subscription in subscriptions: + assert Subscription.objects.filter(uuid=subscription.uuid, identifier=subscription.identifier) + + +def test_notify_deprovision(tenant, subscriptions): + deprovision_notification = deepcopy(NOTIFICATION) + deprovision_notification['@type'] = 'deprovision' + command = Command() + command.process_notification(tenant, deprovision_notification) + assert Subscription.objects.filter(uuid__isnull=True).count() == 0 + + +def test_notify_full(tenant, subscriptions): + full_notification = deepcopy(NOTIFICATION) + full_notification['full'] = True + command = Command() + command.process_notification(tenant, full_notification) + assert Subscription.objects.count() == 8 + + +def test_notify_emails_only(tenant, subscriptions): + email_notification = deepcopy(NOTIFICATION) + for user in email_notification['objects']['data']: + user['mobile'] = None + user['email'] = 'new-%(email)s' % user + command = Command() + command.process_notification(tenant, email_notification) + assert Subscription.objects.exclude(identifier__startswith='sms:').exists() + + +def test_notify_mobiles_only(tenant, subscriptions): + mobile_notification = deepcopy(NOTIFICATION) + for user in mobile_notification['objects']['data']: + user['email'] = None + user['mobile'] = '0(mobile)s' % user + command = Command() + command.process_notification(tenant, mobile_notification) + assert Subscription.objects.exclude(identifier__startswith='mailto:').exists() diff --git a/tox.ini b/tox.ini index 1c63b4e..8ef71bf 100644 --- a/tox.ini +++ b/tox.ini @@ -6,9 +6,11 @@ usedevelop = coverage: True setenv = DJANGO_SETTINGS_MODULE=corbo.settings + CORBO_SETTINGS_FILE=tests/settings.py coverage: COVERAGE=--junitxml=test_results.xml --cov-report xml --cov=corbo/ --cov-config .coveragerc deps = django18: django>=1.8,<1.9 + http://git.entrouvert.org/hobo.git/snapshot/hobo-master.tar.gz pytest-cov pytest-django>=3.1.1 pytest>=3.0.4 -- 2.11.0