0001-provisionning-agent-12910.patch
corbo/hobo_agent/management/commands/hobo_notify.py | ||
---|---|---|
1 |
# corbo - Announces Manager |
|
2 |
# Copyright (C) 2017 Entr'ouvert |
|
3 |
# |
|
4 |
# This program is free software: you can redistribute it and/or modify it |
|
5 |
# under the terms of the GNU Affero General Public License as published |
|
6 |
# by the Free Software Foundation, either version 3 of the License, or |
|
7 |
# (at your option) any later version. |
|
8 |
# |
|
9 |
# This program is distributed in the hope that it will be useful, |
|
10 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
# GNU Affero General Public License for more details. |
|
13 |
# |
|
14 |
# You should have received a copy of the GNU Affero General Public License |
|
15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
16 | ||
17 |
from django.db.models import Q |
|
18 | ||
19 |
from hobo.agent.common.management.commands import hobo_notify |
|
20 | ||
21 |
from corbo.models import Subscription |
|
22 | ||
23 |
class Command(hobo_notify.Command): |
|
24 | ||
25 |
def process_notification(self, tenant, notification): |
|
26 |
super(Command, self).process_notification(tenant, notification) |
|
27 |
object_type = notification['objects']['@type'] |
|
28 |
if object_type != 'user': |
|
29 |
return |
|
30 |
users = notification['objects']['data'] |
|
31 |
action = notification['@type'] |
|
32 |
if notification.get('full'): |
|
33 |
uuids = [user['uuid'] for user in users] |
|
34 |
Subscription.objects.exclude(Q(uuid__in=uuids)|Q(uuid__isnull=True)|Q(uuid='')).delete() |
|
35 | ||
36 |
for user in users: |
|
37 |
for subscription in Subscription.objects.filter(uuid=user['uuid']): |
|
38 |
if action == 'provision': |
|
39 |
if subscription.identifier.startswith('mailto:'): |
|
40 |
if user.get('email'): |
|
41 |
subscription.identifier = 'mailto:%s' % user['email'] |
|
42 |
else: |
|
43 |
subscription.delete() |
|
44 |
continue |
|
45 |
elif subscription.identifier.startswith('sms:'): |
|
46 |
if user.get('mobile'): |
|
47 |
subscription.identifier = 'sms:%s' % user['mobile'] |
|
48 |
else: |
|
49 |
subscription.delete() |
|
50 |
continue |
|
51 |
subscription.save() |
|
52 |
elif action == 'deprovision': |
|
53 |
subscription.delete() |
debian/debian_config.py | ||
---|---|---|
12 | 12 |
# |
13 | 13 |
execfile('/usr/lib/hobo/debian_config_common.py') |
14 | 14 | |
15 |
INSTALLED_APPS = ('corbo.hobo_agent', ) + INSTALLED_APPS |
|
16 | ||
15 | 17 |
# |
16 | 18 |
# local settings |
17 | 19 |
# |
tests/conftest.py | ||
---|---|---|
1 | 1 |
import pytest |
2 | 2 |
import django_webtest |
3 | 3 |
import copy |
4 |
import tempfile |
|
5 |
import os |
|
6 |
import json |
|
7 |
import shutil |
|
4 | 8 | |
5 | 9 |
import django.core.mail.backends.locmem |
6 | 10 |
from django.core.mail.backends.locmem import EmailBackend as DjangoEmailBackend |
11 |
from django.utils.text import slugify |
|
12 | ||
13 |
from corbo.models import Category, Announce, Broadcast, Subscription |
|
14 | ||
15 |
CATEGORIES = ('Alerts', 'News') |
|
16 | ||
17 |
SUBSCRIBERS = [{'uuid': 'uuid1', 'email': 'foo@example.net', 'mobile': '0102030405'}, |
|
18 |
{'uuid': 'uuid2', 'email': 'bar@example.net', 'mobile': '0607080900'}, |
|
19 |
{'uuid': '', 'email': 'john@example.net', 'mobile': '0304050607'}, |
|
20 |
{'uuid': None, 'email': 'john2@example.net', 'mobile': '0405060708'}] |
|
21 | ||
7 | 22 | |
8 | 23 | |
9 | 24 |
class MockedEmailBackend(object): |
... | ... | |
42 | 57 |
wtm._patch_settings() |
43 | 58 |
request.addfinalizer(wtm._unpatch_settings) |
44 | 59 |
return django_webtest.DjangoTestApp() |
60 | ||
61 | ||
62 |
@pytest.fixture |
|
63 |
def categories(): |
|
64 |
categories = [] |
|
65 |
for category in CATEGORIES: |
|
66 |
c, created = Category.objects.get_or_create(name=category, slug=slugify(category)) |
|
67 |
categories.append(c) |
|
68 |
return categories |
|
69 | ||
70 | ||
71 |
@pytest.fixture |
|
72 |
def subscriptions(categories): |
|
73 |
subscriptions = [] |
|
74 |
for category in categories: |
|
75 |
for subscriber in SUBSCRIBERS: |
|
76 |
kwargs = {'category': category, 'identifier': 'mailto:%(email)s' % subscriber} |
|
77 |
uuid = subscriber['uuid'] |
|
78 |
if uuid is not None: |
|
79 |
kwargs['uuid'] = uuid |
|
80 |
subscriptions.append(Subscription.objects.create(**kwargs)) |
|
81 |
kwargs['identifier'] = 'sms:%(mobile)s' % subscriber |
|
82 |
subscriptions.append(Subscription.objects.create(**kwargs)) |
|
83 |
return subscriptions |
|
84 | ||
85 | ||
86 |
@pytest.fixture |
|
87 |
def tenant_base(request, settings): |
|
88 |
base = tempfile.mkdtemp('corbo-tenant-base') |
|
89 |
settings.TENANT_BASE = base |
|
90 | ||
91 |
def fin(): |
|
92 |
shutil.rmtree(base) |
|
93 |
request.addfinalizer(fin) |
|
94 |
return base |
|
95 | ||
96 | ||
97 |
@pytest.fixture(scope='function') |
|
98 |
def tenant(transactional_db, request, tenant_base): |
|
99 |
from hobo.multitenant.models import Tenant |
|
100 |
base = tenant_base |
|
101 | ||
102 |
@pytest.mark.django_db |
|
103 |
def make_tenant(name): |
|
104 |
tenant_dir = os.path.join(base, name) |
|
105 |
os.mkdir(tenant_dir) |
|
106 |
with open(os.path.join(tenant_dir, 'hobo.json'), 'w') as fd: |
|
107 |
json.dump({ |
|
108 |
'variables': { |
|
109 |
'hobo_test_variable': True, |
|
110 |
'other_variable': 'foo', |
|
111 |
}, |
|
112 |
'services': [ |
|
113 |
{'slug': 'test', |
|
114 |
'service-id': 'corbo', |
|
115 |
'title': 'Test', |
|
116 |
'this': True, |
|
117 |
'secret_key': '12345', |
|
118 |
'base_url': 'http://%s' % name, |
|
119 |
'saml-sp-metadata-url': 'http://%s/metadata/' % name, |
|
120 |
'variables': { |
|
121 |
'other_variable': 'bar', |
|
122 |
} |
|
123 |
}, |
|
124 |
{'slug': 'passerelle', |
|
125 |
'title': 'Webserivces', |
|
126 |
'service-id': 'passerelle', |
|
127 |
'secret_key': 'abcdef', |
|
128 |
'base_url': 'http://passerelle.example.net', |
|
129 |
'saml-sp-metadata-url': 'http://passerelle.example.net/metadata/' }, |
|
130 |
]}, fd) |
|
131 |
return Tenant(domain_url=name, |
|
132 |
schema_name=name.replace('-', '_').replace('.', '_')) |
|
133 |
return make_tenant('corbo.example.net') |
tests/settings.py | ||
---|---|---|
1 |
# Add corbo hobo agent |
|
2 |
INSTALLED_APPS = ('corbo.hobo_agent', ) + INSTALLED_APPS |
tests/test_notify.py | ||
---|---|---|
1 |
import pytest |
|
2 |
from copy import deepcopy |
|
3 |
import json |
|
4 | ||
5 |
from corbo.models import Subscription |
|
6 |
from corbo.hobo_agent.management.commands.hobo_notify import Command |
|
7 |
from django.core.management import call_command |
|
8 |
from django.db.models import Q |
|
9 | ||
10 |
NOTIFICATION = {'@type': 'provision', |
|
11 |
'objects': {'@type': 'user', |
|
12 |
'data': [ |
|
13 |
{'uuid': 'uuid1', 'email': 'foo1@example.net', 'mobile': '0504030201'}, |
|
14 |
{'uuid': 'uuid2', 'email': 'bar1@example.net', 'mobile': '0009080706'}, |
|
15 |
]}, |
|
16 |
'audience': [], |
|
17 |
'full': False |
|
18 |
} |
|
19 | ||
20 | ||
21 |
def test_notify_provision(tenant, subscriptions): |
|
22 |
command = Command() |
|
23 |
command.process_notification(tenant, NOTIFICATION) |
|
24 |
assert Subscription.objects.count() == len(subscriptions) |
|
25 |
for user in NOTIFICATION['objects']['data']: |
|
26 |
assert Subscription.objects.filter(uuid=user['uuid'], identifier='mailto:%(email)s' % user).exists() |
|
27 |
assert Subscription.objects.filter(uuid=user['uuid'], identifier='sms:%(mobile)s' % user).exists() |
|
28 | ||
29 | ||
30 |
def test_notify_other_provision(tenant, subscriptions): |
|
31 |
role_notification = deepcopy(NOTIFICATION) |
|
32 |
role_notification['objects']['@type'] = 'role' |
|
33 |
command = Command() |
|
34 |
command.process_notification(tenant, role_notification) |
|
35 |
assert Subscription.objects.count() == len(subscriptions) |
|
36 |
for subscription in subscriptions: |
|
37 |
assert Subscription.objects.filter(uuid=subscription.uuid, identifier=subscription.identifier) |
|
38 | ||
39 | ||
40 |
def test_notify_deprovision(tenant, subscriptions): |
|
41 |
deprovision_notification = deepcopy(NOTIFICATION) |
|
42 |
deprovision_notification['@type'] = 'deprovision' |
|
43 |
command = Command() |
|
44 |
command.process_notification(tenant, deprovision_notification) |
|
45 |
for user in deprovision_notification['objects']['data']: |
|
46 |
assert not Subscription.objects.filter(uuid=user['uuid']).exists() |
|
47 | ||
48 | ||
49 |
def test_notify_full(tenant, subscriptions): |
|
50 |
full_notification = deepcopy(NOTIFICATION) |
|
51 |
full_notification['full'] = True |
|
52 |
command = Command() |
|
53 |
command.process_notification(tenant, full_notification) |
|
54 |
# strings empty and null are the same for CharFields |
|
55 |
assert Subscription.objects.filter(Q(uuid='')|Q(uuid__isnull=True)).count() == 8 |
|
56 |
assert Subscription.objects.exclude(Q(uuid='')|Q(uuid__isnull=True)).count() == 8 |
|
57 |
full_notification['objects']['data'] = [] |
|
58 |
command.process_notification(tenant, full_notification) |
|
59 |
# check all remaining subscriptions have empty uuids |
|
60 |
for subscription in Subscription.objects.all(): |
|
61 |
assert not subscription.uuid |
|
62 | ||
63 | ||
64 |
def test_notify_emails_only(tenant, subscriptions): |
|
65 |
email_notification = deepcopy(NOTIFICATION) |
|
66 |
for user in email_notification['objects']['data']: |
|
67 |
user['mobile'] = None |
|
68 |
user['email'] = 'new-%(email)s' % user |
|
69 |
command = Command() |
|
70 |
command.process_notification(tenant, email_notification) |
|
71 |
for user in email_notification['objects']['data']: |
|
72 |
assert not Subscription.objects.filter(uuid=user['uuid'], identifier__startswith='sms:').exists() |
|
73 | ||
74 | ||
75 |
def test_notify_mobiles_only(tenant, subscriptions): |
|
76 |
mobile_notification = deepcopy(NOTIFICATION) |
|
77 |
for user in mobile_notification['objects']['data']: |
|
78 |
user['email'] = None |
|
79 |
user['mobile'] = '0%(mobile)s' % user |
|
80 |
command = Command() |
|
81 |
command.process_notification(tenant, mobile_notification) |
|
82 |
for user in mobile_notification['objects']['data']: |
|
83 |
assert not Subscription.objects.filter(uuid=user['uuid'], identifier__startswith='mailto:').exists() |
tox.ini | ||
---|---|---|
6 | 6 |
coverage: True |
7 | 7 |
setenv = |
8 | 8 |
DJANGO_SETTINGS_MODULE=corbo.settings |
9 |
CORBO_SETTINGS_FILE=tests/settings.py |
|
9 | 10 |
coverage: COVERAGE=--junitxml=test_results.xml --cov-report xml --cov=corbo/ --cov-config .coveragerc |
10 | 11 |
deps = |
11 | 12 |
django18: django>=1.8,<1.9 |
13 |
http://git.entrouvert.org/hobo.git/snapshot/hobo-master.tar.gz |
|
12 | 14 |
pytest-cov |
13 | 15 |
pytest-django>=3.1.1 |
14 | 16 |
pytest>=3.0.4 |
15 |
- |