0001-misc-apply-pyupgrade-69708.patch
debian/debian_config_common.py | ||
---|---|---|
391 | 391 |
# Locale and timezone |
392 | 392 |
LANGUAGE_CODE = 'fr-fr' |
393 | 393 |
TIME_ZONE = 'Europe/Paris' |
394 |
LANGUAGES = (('fr', u'Fran\xe7ais'),)
|
|
394 |
LANGUAGES = (('fr', 'Fran\xe7ais'),) |
|
395 | 395 |
USE_L10N = True |
396 | 396 |
USE_TZ = True |
397 | 397 |
hobo/agent/authentic2/management/commands/hobo_deploy.py | ||
---|---|---|
31 | 31 | |
32 | 32 |
def __init__(self, *args, **kwargs): |
33 | 33 |
self.logger = logging.getLogger(__name__) |
34 |
super(Command, self).__init__(*args, **kwargs)
|
|
34 |
super().__init__(*args, **kwargs) |
|
35 | 35 | |
36 | 36 |
def deploy_specifics(self, hobo_environment, tenant): |
37 | 37 |
# generate SAML keys |
hobo/agent/authentic2/management/commands/hobo_provision.py | ||
---|---|---|
38 | 38 |
def provision_roles(self, engine, ous): |
39 | 39 |
roles = get_role_model().objects.all() |
40 | 40 |
if self.verbosity > 0: |
41 |
self.stdout.write('Provisionning {} roles.'.format(roles.count()))
|
|
41 |
self.stdout.write(f'Provisionning {roles.count()} roles.')
|
|
42 | 42 |
engine.notify_roles(ous, roles, full=True) |
43 | 43 | |
44 | 44 |
def provision_users(self, engine, ous, batch_size=512, batch_sleep=30, verbosity=1): |
... | ... | |
66 | 66 |
normal_users = qs.exclude(roles__in=roles_with_attributes) |
67 | 67 | |
68 | 68 |
if self.verbosity > 0: |
69 |
self.stdout.write('Provisionning {} normal users.'.format(normal_users.count()))
|
|
69 |
self.stdout.write(f'Provisionning {normal_users.count()} normal users.')
|
|
70 | 70 |
do_provision(normal_users) |
71 | 71 |
# then those with an admin attribute, use distinct to prevent |
72 | 72 |
# duplicates caused by join on a m2m relation |
73 | 73 |
admin_users = qs.filter(roles__in=roles_with_attributes).distinct() |
74 | 74 |
if self.verbosity > 0: |
75 |
self.stdout.write('Provisionning {} admin users.'.format(admin_users.count()))
|
|
75 |
self.stdout.write(f'Provisionning {admin_users.count()} admin users.')
|
|
76 | 76 |
do_provision(admin_users) |
hobo/agent/authentic2/provisionning.py | ||
---|---|---|
202 | 202 |
) |
203 | 203 | |
204 | 204 |
all_roles = Role.objects.all().prefetch_related('attributes') |
205 |
roles = dict((r.id, r) for r in all_roles)
|
|
205 |
roles = {r.id: r for r in all_roles}
|
|
206 | 206 |
user_roles = {} |
207 | 207 |
parents = {} |
208 | 208 |
for rp in RoleParenting.objects.filter(deleted__isnull=True): |
... | ... | |
249 | 249 |
if not audience: |
250 | 250 |
continue |
251 | 251 |
logger.info( |
252 |
u'provisionning users %s to %s',
|
|
253 |
u', '.join(map(force_text, users)),
|
|
254 |
u', '.join(audience),
|
|
252 |
'provisionning users %s to %s', |
|
253 |
', '.join(map(force_text, users)), |
|
254 |
', '.join(audience), |
|
255 | 255 |
) |
256 | 256 |
self.notify_agents( |
257 | 257 |
{ |
... | ... | |
269 | 269 |
elif users: |
270 | 270 |
audience = [audience for ou in ous.keys() for s, audience in self.get_audience(ou)] |
271 | 271 |
logger.info( |
272 |
u'deprovisionning users %s from %s', u', '.join(map(force_text, users)), u', '.join(audience)
|
|
272 |
'deprovisionning users %s from %s', ', '.join(map(force_text, users)), ', '.join(audience)
|
|
273 | 273 |
) |
274 | 274 |
self.notify_agents( |
275 | 275 |
{ |
... | ... | |
298 | 298 |
tuple(allowed_technical_roles_prefixes) |
299 | 299 |
) |
300 | 300 | |
301 |
roles = set([role for role in roles if not is_forbidden_technical_role(role)])
|
|
301 |
roles = {role for role in roles if not is_forbidden_technical_role(role)}
|
|
302 | 302 |
if mode == 'provision': |
303 | 303 |
self.complete_roles(roles) |
304 | 304 | |
... | ... | |
333 | 333 |
] |
334 | 334 | |
335 | 335 |
audience = [entity_id for service, entity_id in self.get_audience(ou)] |
336 |
logger.info(u'%sning roles %s to %s', mode, roles, audience)
|
|
336 |
logger.info('%sning roles %s to %s', mode, roles, audience) |
|
337 | 337 |
self.notify_agents( |
338 | 338 |
{ |
339 | 339 |
'@type': mode, |
... | ... | |
381 | 381 |
self.notify_users(ous, deleted.get(User, []), mode='deprovision') |
382 | 382 |
except Exception: |
383 | 383 |
# last step, clear everything |
384 |
logger.exception(u'error in provisionning thread')
|
|
384 |
logger.exception('error in provisionning thread') |
|
385 | 385 |
finally: |
386 | 386 |
self.threads.discard(threading.current_thread()) |
387 | 387 | |
... | ... | |
408 | 408 |
for role in roles: |
409 | 409 |
role.emails = [] |
410 | 410 |
role.emails_to_members = True |
411 |
role.details = u''
|
|
411 |
role.details = '' |
|
412 | 412 |
for attribute in role.attributes.all(): |
413 | 413 |
if attribute.name in ('emails', 'emails_to_members', 'details') and attribute.kind == 'json': |
414 | 414 |
setattr(role, attribute.name, json.loads(attribute.value)) |
... | ... | |
428 | 428 |
if not isinstance(instance, (User, Role, RoleAttribute, AttributeValue)): |
429 | 429 |
return |
430 | 430 |
# ignore last_login update on login |
431 |
if isinstance(instance, User) and (update_fields and set(update_fields) == set(['last_login'])):
|
|
431 |
if isinstance(instance, User) and (update_fields and set(update_fields) == {'last_login'}):
|
|
432 | 432 |
return |
433 | 433 |
if isinstance(instance, RoleAttribute): |
434 | 434 |
instance = instance.role |
... | ... | |
506 | 506 |
f.write('%s %s ' % (datetime.datetime.now().isoformat(), connection.tenant.domain_url)) |
507 | 507 |
json.dump(data, f, indent=2) |
508 | 508 |
f.write('\n') |
509 |
except IOError:
|
|
509 |
except OSError:
|
|
510 | 510 |
pass |
511 | 511 | |
512 | 512 |
if getattr(settings, 'HOBO_HTTP_PROVISIONNING', True): |
... | ... | |
543 | 543 |
response = requests.put(sign_url(url, service['secret']), json=data) |
544 | 544 |
response.raise_for_status() |
545 | 545 |
except requests.RequestException as e: |
546 |
logger.error(u'error provisionning to %s (%s)', audience, e)
|
|
546 |
logger.error('error provisionning to %s (%s)', audience, e) |
|
547 | 547 |
else: |
548 | 548 |
leftover_audience.remove(audience) |
549 | 549 |
return leftover_audience |
hobo/agent/authentic2/role_forms.py | ||
---|---|---|
25 | 25 |
from django.utils.translation import ugettext_lazy as _ |
26 | 26 | |
27 | 27 | |
28 |
class ListValidator(object):
|
|
28 |
class ListValidator: |
|
29 | 29 |
def __init__(self, item_validator): |
30 | 30 |
self.item_validator = item_validator |
31 | 31 | |
... | ... | |
42 | 42 |
if not value: |
43 | 43 |
return '' |
44 | 44 |
if not isinstance(value, str): |
45 |
return u', '.join(value)
|
|
45 |
return ', '.join(value) |
|
46 | 46 |
return value |
47 | 47 | |
48 | 48 | |
... | ... | |
54 | 54 |
self.max_length = max_length |
55 | 55 |
self.min_length = min_length |
56 | 56 |
item_validators = kwargs.pop('item_validators', []) |
57 |
super(CommaSeparatedCharField, self).__init__(*args, **kwargs)
|
|
57 |
super().__init__(*args, **kwargs) |
|
58 | 58 |
for item_validator in item_validators: |
59 | 59 |
self.validators.append(ListValidator(item_validator)) |
60 | 60 | |
... | ... | |
97 | 97 |
if role_attribute.name in fields: |
98 | 98 |
continue |
99 | 99 |
initial[role_attribute.name] = json.loads(role_attribute.value) |
100 |
super(RoleForm, self).__init__(*args, **kwargs)
|
|
100 |
super().__init__(*args, **kwargs) |
|
101 | 101 | |
102 | 102 |
def save(self, commit=True): |
103 | 103 |
fields = [x.name for x in Role._meta.get_fields()] |
104 | 104 |
assert commit |
105 |
instance = super(RoleForm, self).save(commit=commit)
|
|
105 |
instance = super().save(commit=commit) |
|
106 | 106 |
for field in self.cleaned_data: |
107 | 107 |
if field in fields: |
108 | 108 |
continue |
hobo/agent/combo/management/commands/import_template.py | ||
---|---|---|
21 | 21 |
class Command(import_template.Command): |
22 | 22 |
def handle(self, *args, **kwargs): |
23 | 23 |
try: |
24 |
return super(Command, self).handle(*args, **kwargs)
|
|
24 |
return super().handle(*args, **kwargs) |
|
25 | 25 |
except import_template.UnknownTemplateError: |
26 | 26 |
# ignore errors if template name contains portal-user or portal-agent as |
27 | 27 |
# those names do not actually require an existing file to work. |
hobo/agent/common/management/commands/hobo_deploy.py | ||
---|---|---|
1 |
from __future__ import print_function |
|
2 | ||
3 | 1 |
import json |
4 | 2 |
import os |
5 | 3 |
import subprocess |
... | ... | |
51 | 49 |
for tenant in TenantMiddleware.get_tenants(): |
52 | 50 |
try: |
53 | 51 |
hobo_environment = tenant.get_hobo_json() |
54 |
except IOError:
|
|
52 |
except OSError:
|
|
55 | 53 |
continue |
56 | 54 |
try: |
57 | 55 |
me = [x for x in hobo_environment.get('services') if x.get('this') is True][0] |
hobo/agent/common/migrations/0001_initial.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 |
from __future__ import unicode_literals |
|
3 | ||
4 | 1 |
from django.db import migrations, models |
5 | 2 | |
6 | 3 |
hobo/agent/common/migrations/0002_auto_20160105_1702.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 |
from __future__ import unicode_literals |
|
3 | ||
4 | 1 |
from django.db import migrations, models |
5 | 2 | |
6 | 3 |
hobo/agent/common/migrations/0003_auto_20200707_1656.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 | 1 |
# Generated by Django 1.11.18 on 2020-07-07 14:56 |
3 |
from __future__ import unicode_literals |
|
4 | 2 | |
5 | 3 |
import django.contrib.postgres.fields |
6 | 4 |
from django.db import migrations, models |
hobo/agent/common/models.py | ||
---|---|---|
5 | 5 | |
6 | 6 |
class Role(Group): |
7 | 7 |
uuid = models.CharField(max_length=32, db_index=True) |
8 |
description = models.TextField(default=u'')
|
|
9 |
details = models.TextField(default=u'')
|
|
8 |
description = models.TextField(default='') |
|
9 |
details = models.TextField(default='') |
|
10 | 10 |
emails = ArrayField(models.CharField(max_length=128), default=list) |
11 | 11 |
emails_to_members = models.BooleanField(default=True) |
12 | 12 |
hobo/agent/hobo/management/commands/hobo_deploy.py | ||
---|---|---|
17 | 17 |
def deploy_specifics(self, hobo_environment, tenant): |
18 | 18 |
me = [x for x in hobo_environment.get('services') if x.get('this')][0] |
19 | 19 |
if not me.get('secondary'): |
20 |
super(Command, self).deploy_specifics(hobo_environment, tenant)
|
|
20 |
super().deploy_specifics(hobo_environment, tenant) |
|
21 | 21 | |
22 | 22 |
with tenant_context(tenant): |
23 | 23 |
services = hobo_environment.get('services') |
hobo/agent/worker/celery.py | ||
---|---|---|
14 | 14 |
# You should have received a copy of the GNU Affero General Public License |
15 | 15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | 16 | |
17 |
from __future__ import absolute_import |
|
18 | 17 | |
19 | 18 |
from celery import Celery |
20 | 19 |
from kombu.common import Broadcast |
hobo/agent/worker/services.py | ||
---|---|---|
14 | 14 |
# You should have received a copy of the GNU Affero General Public License |
15 | 15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | 16 | |
17 |
from __future__ import print_function |
|
18 | 17 | |
19 | 18 |
import fnmatch |
20 | 19 |
import json |
... | ... | |
30 | 29 |
from . import settings |
31 | 30 | |
32 | 31 | |
33 |
class BaseService(object):
|
|
32 |
class BaseService: |
|
34 | 33 |
tenants_dirs = None |
35 | 34 | |
36 | 35 |
def __init__(self, base_url, title, secret_key, **kwargs): |
hobo/applications/migrations/0001_initial.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 | 1 |
# Generated by Django 1.11.29 on 2022-01-09 13:16 |
3 |
from __future__ import unicode_literals |
|
4 | 2 | |
5 | 3 |
import django.contrib.postgres.fields.jsonb |
6 | 4 |
import django.db.models.deletion |
hobo/context_processors.py | ||
---|---|---|
39 | 39 |
return template_vars |
40 | 40 | |
41 | 41 | |
42 |
class RemoteTemplate(object):
|
|
42 |
class RemoteTemplate: |
|
43 | 43 |
PAGE_CACHE_KEY = 'page-cache' |
44 | 44 | |
45 | 45 |
def __init__(self, source): |
hobo/debug/views.py | ||
---|---|---|
37 | 37 |
return get_setting_variable('INTERNAL_IPS.extend') |
38 | 38 | |
39 | 39 |
def get_initial(self): |
40 |
initial = super(HomeView, self).get_initial()
|
|
40 |
initial = super().get_initial() |
|
41 | 41 |
initial['debug_log'] = bool(self.debug_log_variable.json) |
42 | 42 |
initial['debug_ips'] = self.debug_ips_variable.json |
43 | 43 |
return initial |
... | ... | |
47 | 47 |
return self.request.META.get('REMOTE_ADDR') or None |
48 | 48 | |
49 | 49 |
def get_context_data(self, **kwargs): |
50 |
ctx = super(HomeView, self).get_context_data(**kwargs)
|
|
50 |
ctx = super().get_context_data(**kwargs) |
|
51 | 51 |
ctx['current_ip_debug'] = self.current_ip in self.debug_ips_variable.json |
52 | 52 |
return ctx |
53 | 53 | |
... | ... | |
67 | 67 |
debug_ips = self.toggle_value(debug_ips, self.current_ip) |
68 | 68 |
self.debug_ips_variable.json = debug_ips |
69 | 69 |
self.debug_ips_variable.save() |
70 |
return super(HomeView, self).form_valid(form)
|
|
70 |
return super().form_valid(form) |
|
71 | 71 | |
72 | 72 | |
73 | 73 |
home = HomeView.as_view() |
hobo/emails/forms.py | ||
---|---|---|
50 | 50 |
) |
51 | 51 | |
52 | 52 |
def __init__(self, *args, **kwargs): |
53 |
super(EmailsForm, self).__init__(*args, **kwargs)
|
|
53 |
super().__init__(*args, **kwargs) |
|
54 | 54 |
self.fields['email_signature'].widget.attrs = {'rows': 4, 'cols': 80} |
hobo/emails/validators.py | ||
---|---|---|
45 | 45 |
smtp.quit() |
46 | 46 |
finally: |
47 | 47 |
smtp.close() |
48 |
except (socket.error, IOError, OSError) as e:
|
|
48 |
except OSError as e:
|
|
49 | 49 |
raise ValidationError( |
50 | 50 |
_('Error while connecting to %(server)s: %(msg)s') % {'server': mx_server, 'msg': e} |
51 | 51 |
) |
hobo/environment/forms.py | ||
---|---|---|
37 | 37 |
class BaseForm(forms.ModelForm): |
38 | 38 |
def __init__(self, *args, **kwargs): |
39 | 39 |
choices = self.get_template_choices() |
40 |
super(BaseForm, self).__init__(*args, **kwargs)
|
|
40 |
super().__init__(*args, **kwargs) |
|
41 | 41 |
if len(choices) < 2 or self.instance.id: |
42 | 42 |
del self.fields['template_name'] |
43 | 43 |
else: |
... | ... | |
84 | 84 |
choices = self.get_template_choices() |
85 | 85 |
if not self.instance.id and len(choices) == 1: |
86 | 86 |
self.instance.template_name = choices[0][0] |
87 |
return super(BaseForm, self).save(commit=commit)
|
|
87 |
return super().save(commit=commit) |
|
88 | 88 | |
89 | 89 | |
90 | 90 |
class AuthenticForm(BaseForm): |
... | ... | |
93 | 93 |
exclude = EXCLUDED_FIELDS |
94 | 94 | |
95 | 95 |
def __init__(self, *args, **kwargs): |
96 |
super(AuthenticForm, self).__init__(*args, **kwargs)
|
|
96 |
super().__init__(*args, **kwargs) |
|
97 | 97 |
if not self.instance.is_operational() and not self.initial.get('use_as_idp_for_self'): |
98 | 98 |
del self.fields['use_as_idp_for_self'] |
99 | 99 | |
... | ... | |
102 | 102 |
if self.cleaned_data.get('use_as_idp_for_self'): |
103 | 103 |
# this idp was just marked as the idp to use, unmark all others |
104 | 104 |
Authentic.objects.update(use_as_idp_for_self=False) |
105 |
return super(AuthenticForm, self).save(commit=commit)
|
|
105 |
return super().save(commit=commit) |
|
106 | 106 | |
107 | 107 | |
108 | 108 |
class WcsForm(BaseForm): |
... | ... | |
166 | 166 | |
167 | 167 |
def __init__(self, service=None, **kwargs): |
168 | 168 |
self.service = service |
169 |
super(VariableForm, self).__init__(**kwargs)
|
|
169 |
super().__init__(**kwargs) |
|
170 | 170 | |
171 | 171 |
def save(self, commit=True): |
172 | 172 |
if self.service: |
173 | 173 |
self.instance.service = self.service |
174 |
return super(VariableForm, self).save(commit=commit)
|
|
174 |
return super().save(commit=commit) |
|
175 | 175 | |
176 | 176 | |
177 |
class VariablesFormMixin(object):
|
|
177 |
class VariablesFormMixin: |
|
178 | 178 |
form_class = None |
179 | 179 |
success_message = None |
180 | 180 |
variables = [] |
181 | 181 | |
182 | 182 |
def get_context_data(self, **kwargs): |
183 |
context = super(VariablesFormMixin, self).get_context_data(**kwargs)
|
|
183 |
context = super().get_context_data(**kwargs) |
|
184 | 184 |
if self.request.POST: |
185 | 185 |
form_data = self.request.POST |
186 | 186 |
else: |
hobo/environment/management/commands/check_operational.py | ||
---|---|---|
1 |
from __future__ import print_function |
|
2 | ||
3 | 1 |
from optparse import make_option |
4 | 2 | |
5 | 3 |
from django.core.management.base import BaseCommand |
hobo/environment/management/commands/cook.py | ||
---|---|---|
14 | 14 |
# You should have received a copy of the GNU Affero General Public License |
15 | 15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | 16 | |
17 |
from __future__ import print_function |
|
18 | 17 | |
19 | 18 |
import json |
20 | 19 |
import os |
hobo/environment/migrations/0001_initial.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 |
from __future__ import unicode_literals |
|
3 | ||
4 | 1 |
from django.db import migrations, models |
5 | 2 | |
6 | 3 |
hobo/environment/migrations/0002_authentic_use_as_idp_for_self.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 |
from __future__ import unicode_literals |
|
3 | ||
4 | 1 |
from django.db import migrations, models |
5 | 2 | |
6 | 3 |
hobo/environment/migrations/0003_auto_20150309_0811.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 |
from __future__ import unicode_literals |
|
3 | ||
4 | 1 |
from django.db import migrations, models |
5 | 2 | |
6 | 3 |
hobo/environment/migrations/0004_fargo.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 |
from __future__ import unicode_literals |
|
3 | ||
4 | 1 |
from django.db import migrations, models |
5 | 2 | |
6 | 3 |
hobo/environment/migrations/0005_variable_label.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 |
from __future__ import unicode_literals |
|
3 | ||
4 | 1 |
from django.db import migrations, models |
5 | 2 | |
6 | 3 |
hobo/environment/migrations/0006_auto_20150708_0830.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 |
from __future__ import unicode_literals |
|
3 | ||
4 | 1 |
from django.db import migrations, models |
5 | 2 | |
6 | 3 |
hobo/environment/migrations/0007_auto_20151008_1406.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 |
from __future__ import unicode_literals |
|
3 | ||
4 | 1 |
from django.db import migrations, models |
5 | 2 | |
6 | 3 |
hobo/environment/migrations/0008_auto_20151021_1414.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 |
from __future__ import unicode_literals |
|
3 | ||
4 | 1 |
from django.db import migrations, models |
5 | 2 | |
6 | 3 |
hobo/environment/migrations/0009_mandayejs.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 |
from __future__ import unicode_literals |
|
3 | ||
4 | 1 |
from django.db import migrations, models |
5 | 2 | |
6 | 3 |
hobo/environment/migrations/0010_variable_auto.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 |
from __future__ import unicode_literals |
|
3 | ||
4 | 1 |
from django.db import migrations, models |
5 | 2 | |
6 | 3 |
hobo/environment/migrations/0011_chrono.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 |
from __future__ import unicode_literals |
|
3 | ||
4 | 1 |
from django.db import migrations, models |
5 | 2 | |
6 | 3 |
hobo/environment/migrations/0012_mandayejs_site_app.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 |
from __future__ import unicode_literals |
|
3 | ||
4 | 1 |
from django.db import migrations, models |
5 | 2 | |
6 | 3 |
hobo/environment/migrations/0013_auto_20160226_1633.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 |
from __future__ import unicode_literals |
|
3 | ||
4 | 1 |
from django.db import migrations, models |
5 | 2 | |
6 | 3 |
hobo/environment/migrations/0014_piwik.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 |
from __future__ import unicode_literals |
|
3 | ||
4 | 1 |
from django.db import migrations, models |
5 | 2 | |
6 | 3 |
hobo/environment/migrations/0015_corbo.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 |
from __future__ import unicode_literals |
|
3 | ||
4 | 1 |
from django.db import migrations, models |
5 | 2 | |
6 | 3 |
hobo/environment/migrations/0016_bijoe.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 |
from __future__ import unicode_literals |
|
3 | ||
4 | 1 |
from django.db import migrations, models |
5 | 2 | |
6 | 3 |
hobo/environment/migrations/0017_hobo.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 |
from __future__ import unicode_literals |
|
3 | ||
4 | 1 |
from django.db import migrations, models |
5 | 2 | |
6 | 3 |
hobo/environment/migrations/0018_auto_20161102_1929.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 |
from __future__ import unicode_literals |
|
3 | ||
4 | 1 |
from django.db import migrations, models |
5 | 2 | |
6 | 3 |
hobo/environment/migrations/0019_delete_piwik.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 | 1 |
# Generated by Django 1.11.12 on 2019-02-28 10:28 |
3 |
from __future__ import unicode_literals |
|
4 | 2 | |
5 | 3 |
from django.db import migrations |
6 | 4 |
hobo/environment/migrations/0020_delete_corbo_mandaye.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 | 1 |
# Generated by Django 1.11.29 on 2021-02-28 09:57 |
3 |
from __future__ import unicode_literals |
|
4 | 2 | |
5 | 3 |
import django.core.validators |
6 | 4 |
from django.db import migrations, models |
hobo/environment/models.py | ||
---|---|---|
152 | 152 |
return (self.last_operational_check_timestamp - self.last_update_timestamp) < two_minutes |
153 | 153 | |
154 | 154 |
def as_dict(self): |
155 |
as_dict = dict([(x, y) for (x, y) in self.__dict__.items() if isinstance(y, (int, str))])
|
|
155 |
as_dict = {x: y for (x, y) in self.__dict__.items() if isinstance(y, (int, str))}
|
|
156 | 156 |
as_dict['base_url'] = self.get_base_url_path() |
157 | 157 |
if self.legacy_urls: |
158 | 158 |
as_dict['legacy_urls'] = self.legacy_urls |
159 | 159 |
as_dict['service-id'] = self.Extra.service_id |
160 | 160 |
as_dict['service-label'] = force_text(self.Extra.service_label) |
161 |
as_dict['variables'] = dict(((v.name, v.json) for v in self.variables.all()))
|
|
161 |
as_dict['variables'] = {v.name: v.json for v in self.variables.all()}
|
|
162 | 162 |
as_dict['secondary'] = self.secondary |
163 | 163 |
if self.get_saml_sp_metadata_url(): |
164 | 164 |
as_dict['saml-sp-metadata-url'] = self.get_saml_sp_metadata_url() |
... | ... | |
182 | 182 |
raise ValidationError(_('This slug is already used. It must be unique.')) |
183 | 183 |
if service.title == self.title and service.secondary is False and self.secondary is False: |
184 | 184 |
raise ValidationError(_('This title is already used. It must be unique.')) |
185 |
return super(ServiceBase, self).clean(*args, **kwargs)
|
|
185 |
return super().clean(*args, **kwargs) |
|
186 | 186 | |
187 | 187 |
def save(self, *args, **kwargs): |
188 | 188 |
self.base_url = self.base_url.strip().lower() |
... | ... | |
192 | 192 |
self.secret_key = get_random_string(50, SECRET_CHARS) |
193 | 193 | |
194 | 194 |
is_new = self.id is None |
195 |
super(ServiceBase, self).save(*args, **kwargs)
|
|
195 |
super().save(*args, **kwargs) |
|
196 | 196 | |
197 | 197 |
if is_new and settings.SERVICE_EXTRA_VARIABLES: |
198 | 198 |
for variable in settings.SERVICE_EXTRA_VARIABLES.get(self.Extra.service_id, []): |
hobo/environment/views.py | ||
---|---|---|
33 | 33 |
from .models import AVAILABLE_SERVICES, Variable |
34 | 34 | |
35 | 35 | |
36 |
class AvailableService(object):
|
|
36 |
class AvailableService: |
|
37 | 37 |
def __init__(self, klass): |
38 | 38 |
self.id = klass.Extra.service_id |
39 | 39 |
self.label = klass._meta.verbose_name |
... | ... | |
43 | 43 |
template_name = 'environment/home.html' |
44 | 44 | |
45 | 45 |
def get_context_data(self, **kwargs): |
46 |
context = super(HomeView, self).get_context_data(**kwargs)
|
|
46 |
context = super().get_context_data(**kwargs) |
|
47 | 47 |
context['available_services'] = [AvailableService(x) for x in AVAILABLE_SERVICES if x.is_enabled()] |
48 | 48 |
installed_services = [x for x in utils.get_installed_services() if not x.secondary] |
49 | 49 |
for service in installed_services: |
... | ... | |
62 | 62 |
template_name = 'environment/variables.html' |
63 | 63 | |
64 | 64 |
def get_context_data(self, **kwargs): |
65 |
context = super(VariablesView, self).get_context_data(**kwargs)
|
|
65 |
context = super().get_context_data(**kwargs) |
|
66 | 66 |
context['variables'] = Variable.objects.filter(auto=False, service_pk__isnull=True).order_by('label') |
67 | 67 |
return context |
68 | 68 | |
... | ... | |
72 | 72 |
form_class = forms.VariableForm |
73 | 73 | |
74 | 74 |
def get_form_kwargs(self): |
75 |
kwargs = super(VariableCreateView, self).get_form_kwargs()
|
|
75 |
kwargs = super().get_form_kwargs() |
|
76 | 76 |
if 'service' in self.kwargs: |
77 | 77 |
service_id = self.kwargs.pop('service') |
78 | 78 |
service_slug = self.kwargs.pop('slug') |
... | ... | |
130 | 130 |
success_url = reverse_lazy('environment-home') |
131 | 131 | |
132 | 132 |
def get_context_data(self, **kwargs): |
133 |
context = super(ServiceCreateView, self).get_context_data(**kwargs)
|
|
133 |
context = super().get_context_data(**kwargs) |
|
134 | 134 |
context['model_name'] = self.model._meta.verbose_name |
135 | 135 |
return context |
136 | 136 | |
137 | 137 |
def get_initial(self): |
138 |
initial = super(ServiceCreateView, self).get_initial()
|
|
138 |
initial = super().get_initial() |
|
139 | 139 |
initial['base_url'] = utils.create_base_url( |
140 | 140 |
self.request.build_absolute_uri(), self.model.Extra.service_default_slug |
141 | 141 |
) |
... | ... | |
147 | 147 | |
148 | 148 |
def get(self, request, *args, **kwargs): |
149 | 149 |
self.service_id = kwargs.pop('service') |
150 |
return super(ServiceCreateView, self).get(request, *args, **kwargs)
|
|
150 |
return super().get(request, *args, **kwargs) |
|
151 | 151 | |
152 | 152 |
def post(self, request, *args, **kwargs): |
153 | 153 |
self.service_id = kwargs.pop('service') |
154 |
return super(ServiceCreateView, self).post(request, *args, **kwargs)
|
|
154 |
return super().post(request, *args, **kwargs) |
|
155 | 155 | |
156 | 156 |
def get_form_class(self): |
157 | 157 |
for service in AVAILABLE_SERVICES: |
... | ... | |
166 | 166 |
success_url = reverse_lazy('environment-home') |
167 | 167 | |
168 | 168 |
def get_context_data(self, **kwargs): |
169 |
context = super(ServiceUpdateView, self).get_context_data(**kwargs)
|
|
169 |
context = super().get_context_data(**kwargs) |
|
170 | 170 |
context['model_name'] = self.model._meta.verbose_name |
171 | 171 |
return context |
172 | 172 | |
... | ... | |
176 | 176 |
def get(self, request, *args, **kwargs): |
177 | 177 |
self.service_id = kwargs.pop('service') |
178 | 178 |
self.get_form_class() |
179 |
return super(ServiceUpdateView, self).get(request, *args, **kwargs)
|
|
179 |
return super().get(request, *args, **kwargs) |
|
180 | 180 | |
181 | 181 |
def post(self, request, *args, **kwargs): |
182 | 182 |
self.service_id = kwargs.pop('service') |
183 | 183 |
self.get_form_class() |
184 |
return super(ServiceUpdateView, self).post(request, *args, **kwargs)
|
|
184 |
return super().post(request, *args, **kwargs) |
|
185 | 185 | |
186 | 186 |
def get_form_class(self): |
187 | 187 |
for service in AVAILABLE_SERVICES: |
... | ... | |
219 | 219 |
return self.form_invalid(form) |
220 | 220 | |
221 | 221 |
utils.import_parameters(parameters_json) |
222 |
return super(ImportView, self).form_valid(form)
|
|
222 |
return super().form_valid(form) |
|
223 | 223 | |
224 | 224 | |
225 | 225 |
class ExportView(View): |
hobo/forms.py | ||
---|---|---|
12 | 12 |
required_css_class = 'required' |
13 | 13 | |
14 | 14 |
def __init__(self, *args, **kwargs): |
15 |
super(HoboForm, self).__init__(*args, **kwargs)
|
|
15 |
super().__init__(*args, **kwargs) |
|
16 | 16 |
self.fields['schema_name'].required = False |
17 | 17 | |
18 | 18 |
def clean(self): |
19 | 19 |
from django.template.defaultfilters import slugify |
20 | 20 | |
21 |
cleaned_data = super(HoboForm, self).clean()
|
|
21 |
cleaned_data = super().clean() |
|
22 | 22 |
if not cleaned_data.get('schema_name') and cleaned_data.get('domain_url'): |
23 | 23 |
cleaned_data['schema_name'] = slugify(cleaned_data['domain_url']) |
24 | 24 |
return cleaned_data |
hobo/journal.py | ||
---|---|---|
1 |
# -*- Mode: python; coding:utf-8; indent-tabs-mode: nil -*- */ |
|
2 | 1 |
# |
3 | 2 |
# |
4 | 3 |
# Copyright 2012 David Strauss <david@davidstrauss.net> |
... | ... | |
79 | 78 |
if CODE_FILE is not None: |
80 | 79 |
args.append('CODE_FILE=' + CODE_FILE) |
81 | 80 |
if CODE_LINE is not None: |
82 |
args.append('CODE_LINE={:d}'.format(CODE_LINE))
|
|
81 |
args.append(f'CODE_LINE={CODE_LINE:d}')
|
|
83 | 82 |
if CODE_FUNC is not None: |
84 | 83 |
args.append('CODE_FUNC=' + CODE_FUNC) |
85 | 84 | |
... | ... | |
140 | 139 |
""" |
141 | 140 | |
142 | 141 |
def __init__(self, level=_logging.NOTSET, sender_function=send, **kwargs): |
143 |
super(JournalHandler, self).__init__(level)
|
|
142 |
super().__init__(level) |
|
144 | 143 | |
145 | 144 |
for name in kwargs: |
146 | 145 |
if not _valid_field_name(name): |
hobo/logger.py | ||
---|---|---|
34 | 34 |
warnings.warn( |
35 | 35 |
'SettingsLogLevel is deprecated, use DEBUG_LOG instead.', DeprecationWarning, stacklevel=2 |
36 | 36 |
) |
37 |
return super(SettingsLogLevel, cls).__new__(value)
|
|
37 |
return super().__new__(value) |
|
38 | 38 | |
39 | 39 | |
40 | 40 |
class RequestContextFilter(logging.Filter): |
... | ... | |
120 | 120 |
def filter(self, record): |
121 | 121 |
record.levelno = logging.DEBUG |
122 | 122 |
record.levelname = 'DEBUG' |
123 |
return super(ForceDebugFilter, self).filter(record)
|
|
123 |
return super().filter(record) |
|
124 | 124 | |
125 | 125 | |
126 | 126 |
class LogRecord(logging.LogRecord): |
127 | 127 |
'''Subclass LogRecord to make multiline log parseable''' |
128 | 128 | |
129 | 129 |
def getMessage(self): |
130 |
return super(LogRecord, self).getMessage().replace('\n', '\n ')
|
|
130 |
return super().getMessage().replace('\n', '\n ') |
|
131 | 131 | |
132 | 132 | |
133 | 133 |
class TimedRotatingFileHandler(logging.handlers.TimedRotatingFileHandler): |
... | ... | |
135 | 135 |
old_class = record.__class__ |
136 | 136 |
record.__class__ = LogRecord |
137 | 137 |
try: |
138 |
return super(TimedRotatingFileHandler, self).format(record)
|
|
138 |
return super().format(record) |
|
139 | 139 |
finally: |
140 | 140 |
record.__class__ = old_class |
141 | 141 | |
142 | 142 | |
143 |
class DebugLogFilter(object):
|
|
143 |
class DebugLogFilter: |
|
144 | 144 |
'''Filter debug log records based on the DEBUG_LOG setting''' |
145 | 145 | |
146 | 146 |
def filter(self, record): |
... | ... | |
163 | 163 |
return bool(debug_log) |
164 | 164 | |
165 | 165 | |
166 |
class DebugLog(object):
|
|
166 |
class DebugLog: |
|
167 | 167 |
def __init__(self, path): |
168 | 168 |
self.path = path |
169 | 169 | |
... | ... | |
228 | 228 |
return |
229 | 229 |
if not os.path.exists(debug_log_path): |
230 | 230 |
return |
231 |
for record in cls(debug_log_path)._parse(cursor=cursor): |
|
232 |
yield record |
|
231 |
yield from cls(debug_log_path)._parse(cursor=cursor) |
|
233 | 232 | |
234 | 233 | |
235 | 234 |
class ClampLogLevel(logging.Filter): |
236 | 235 |
def __init__(self, level): |
237 | 236 |
self.levelname = level.upper() |
238 | 237 |
self.levelno = getattr(logging, self.levelname) |
239 |
super(ClampLogLevel, self).__init__()
|
|
238 |
super().__init__() |
|
240 | 239 | |
241 | 240 |
def filter(self, record): |
242 | 241 |
if record.levelno > self.levelno: |
243 | 242 |
record.levelno = self.levelno |
244 | 243 |
record.levelname = self.levelname |
245 |
return super(ClampLogLevel, self).filter(record) |
|
244 |
return super().filter(record) |
hobo/matomo/utils.py | ||
---|---|---|
109 | 109 |
"""expected Matomo error responses""" |
110 | 110 | |
111 | 111 | |
112 |
class MatomoWS(object):
|
|
112 |
class MatomoWS: |
|
113 | 113 |
"""api for matomo webservices""" |
114 | 114 | |
115 | 115 |
def __init__(self): |
hobo/matomo/views.py | ||
---|---|---|
39 | 39 |
success_url = reverse_lazy('matomo-home') |
40 | 40 | |
41 | 41 |
def get_initial(self): |
42 |
initial = super(HomeView, self).get_initial()
|
|
42 |
initial = super().get_initial() |
|
43 | 43 |
initial['tracking_js'] = get_tracking_js() |
44 | 44 |
return initial |
45 | 45 | |
46 | 46 |
def form_valid(self, form): |
47 | 47 |
tracking_js = form.cleaned_data['tracking_js'] |
48 | 48 |
put_tracking_js(tracking_js) |
49 |
return super(HomeView, self).form_valid(form)
|
|
49 |
return super().form_valid(form) |
|
50 | 50 | |
51 | 51 |
def get_context_data(self, **kwargs): |
52 |
context = super(HomeView, self).get_context_data(**kwargs)
|
|
52 |
context = super().get_context_data(**kwargs) |
|
53 | 53 |
tracking_js = get_tracking_js() |
54 | 54 |
logme_url = get_variable_value('matomo_logme_url') |
55 | 55 |
context['logme_url'] = logme_url |
... | ... | |
80 | 80 |
success_url = reverse_lazy('matomo-home') |
81 | 81 | |
82 | 82 |
def get_initial(self): |
83 |
initial = super(EnableManualView, self).get_initial()
|
|
83 |
initial = super().get_initial() |
|
84 | 84 |
initial['tracking_js'] = get_tracking_js() |
85 | 85 |
return initial |
86 | 86 | |
... | ... | |
89 | 89 |
put_tracking_js(tracking_js) |
90 | 90 |
logme_url = get_variable('matomo_logme_url') |
91 | 91 |
logme_url.delete() |
92 |
return super(EnableManualView, self).form_valid(form)
|
|
92 |
return super().form_valid(form) |
|
93 | 93 | |
94 | 94 | |
95 | 95 |
enable_manual = EnableManualView.as_view() |
... | ... | |
111 | 111 |
matomo.create_fake_first_tracking_visit(id_site) |
112 | 112 |
except MatomoException as exc: |
113 | 113 |
messages.warning(self.request, 'ping: ' + str(exc)) |
114 |
return super(EnableAutoView, self).form_valid(form)
|
|
114 |
return super().form_valid(form) |
|
115 | 115 | |
116 | 116 | |
117 | 117 |
enable_auto = EnableAutoView.as_view() |
... | ... | |
126 | 126 |
put_tracking_js('') |
127 | 127 |
variable = get_variable('matomo_logme_url') |
128 | 128 |
variable.delete() |
129 |
return super(DisableView, self).form_valid(form)
|
|
129 |
return super().form_valid(form) |
|
130 | 130 | |
131 | 131 | |
132 | 132 |
disable = DisableView.as_view() |
hobo/middleware/debug.py | ||
---|---|---|
17 | 17 |
from django.conf import settings |
18 | 18 | |
19 | 19 | |
20 |
class InternalIPMiddleware(object):
|
|
20 |
class InternalIPMiddleware: |
|
21 | 21 |
def __init__(self, get_response=None): |
22 | 22 |
self.get_response = get_response |
23 | 23 |
hobo/middleware/stats.py | ||
---|---|---|
97 | 97 | |
98 | 98 |
if connection.queries_logged: |
99 | 99 |
sql_queries_count = len(connection.queries) |
100 |
sql_queries_time = sum([float(x['time']) for x in connection.queries])
|
|
100 |
sql_queries_time = sum(float(x['time']) for x in connection.queries)
|
|
101 | 101 |
requests_queries_count_by_host_view_status_method.labels( |
102 | 102 |
host_name, view_name, status_code, http_method |
103 | 103 |
).observe(sql_queries_count) |
hobo/multitenant/cache.py | ||
---|---|---|
4 | 4 |
from django.utils.module_loading import import_string |
5 | 5 | |
6 | 6 | |
7 |
class TenantBaseCache(object):
|
|
7 |
class TenantBaseCache: |
|
8 | 8 |
'''Prepend the tenant schema name to the cache prefix''' |
9 | 9 | |
10 | 10 |
def set_key_prefix(self, prefix): |
hobo/multitenant/haystack.py | ||
---|---|---|
14 | 14 |
# You should have received a copy of the GNU Affero General Public License |
15 | 15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | 16 | |
17 |
from __future__ import absolute_import |
|
18 | 17 | |
19 | 18 |
import os |
20 | 19 |
import shutil |
... | ... | |
43 | 42 |
# when there are opened files. |
44 | 43 |
renamed_path = self.path + '.deleted-%s' % time.time() |
45 | 44 |
os.rename(self.path, renamed_path) |
46 |
super(WhooshSearchBackend, self).delete_index()
|
|
45 |
super().delete_index() |
|
47 | 46 |
if renamed_path: |
48 | 47 |
# remove afterwards and ignore errors (residual directories will |
49 | 48 |
# have to be cleaned manually) |
50 | 49 |
try: |
51 | 50 |
shutil.rmtree(renamed_path) |
52 |
except (IOError, OSError):
|
|
51 |
except OSError:
|
|
53 | 52 |
pass |
54 | 53 | |
55 | 54 |
@property |
... | ... | |
62 | 61 |
pass |
63 | 62 | |
64 | 63 |
def setup(self): |
65 |
super(WhooshSearchBackend, self).setup()
|
|
64 |
super().setup() |
|
66 | 65 |
# make it be always reinitialized |
67 | 66 |
self.setup_complete = False |
68 | 67 |
hobo/multitenant/log.py | ||
---|---|---|
22 | 22 |
def format_subject(self, subject): |
23 | 23 |
from .models import Tenant |
24 | 24 | |
25 |
subject = super(AdminEmailHandler, self).format_subject(subject)
|
|
25 |
subject = super().format_subject(subject) |
|
26 | 26 |
try: |
27 | 27 |
subject = '[%s] %s' % (connection.get_tenant().domain_url, subject) |
28 | 28 |
except AttributeError: |
hobo/multitenant/management/commands/__init__.py | ||
---|---|---|
26 | 26 |
""" |
27 | 27 |
Sets option_list and help dynamically. |
28 | 28 |
""" |
29 |
obj = super(BaseTenantCommand, cls).__new__(cls, *args, **kwargs)
|
|
29 |
obj = super().__new__(cls, *args, **kwargs) |
|
30 | 30 | |
31 | 31 |
app_name = get_commands()[obj.COMMAND_NAME] |
32 | 32 |
if isinstance(app_name, BaseCommand): |
... | ... | |
48 | 48 |
return obj |
49 | 49 | |
50 | 50 |
def add_arguments(self, parser): |
51 |
super(BaseTenantCommand, self).add_arguments(parser)
|
|
51 |
super().add_arguments(parser) |
|
52 | 52 |
parser.add_argument("-d", "--domain", dest="domain") |
53 | 53 |
# use the privately held reference to the underlying command to invoke |
54 | 54 |
# the add_arguments path on this parser instance |
... | ... | |
88 | 88 |
self.execute_command(tenant, self.COMMAND_NAME, *args, **options) |
89 | 89 | |
90 | 90 | |
91 |
class InteractiveTenantOption(object):
|
|
91 |
class InteractiveTenantOption: |
|
92 | 92 |
def add_arguments(self, parser): |
93 | 93 |
parser.add_argument("-d", "--domain", dest="domain", help='specify tenant domain') |
94 | 94 | |
... | ... | |
135 | 135 |
""" |
136 | 136 | |
137 | 137 |
def __new__(cls, *args, **kwargs): |
138 |
obj = super(TenantWrappedCommand, cls).__new__(cls, *args, **kwargs)
|
|
138 |
obj = super().__new__(cls, *args, **kwargs) |
|
139 | 139 |
obj.command_instance = obj.COMMAND() |
140 | 140 |
return obj |
141 | 141 | |
142 | 142 |
def add_arguments(self, parser): |
143 |
super(TenantWrappedCommand, self).add_arguments(parser)
|
|
143 |
super().add_arguments(parser) |
|
144 | 144 |
self.command_instance.add_arguments(parser) |
145 | 145 | |
146 | 146 |
def handle(self, *args, **options): |
hobo/multitenant/management/commands/create_hobo_tenant.py | ||
---|---|---|
22 | 22 |
hostnames.remove('-') |
23 | 23 |
hostnames.extend([x.strip() for x in sys.stdin.readlines()]) |
24 | 24 | |
25 |
super(Command, self).handle(hostnames, **options)
|
|
25 |
super().handle(hostnames, **options) |
|
26 | 26 | |
27 | 27 |
# create SP keys for each tenant |
28 | 28 |
for hostname in hostnames: |
hobo/multitenant/management/commands/create_schemas.py | ||
---|---|---|
1 |
from __future__ import print_function |
|
2 | ||
3 | 1 |
from django.core.management.base import BaseCommand |
4 | 2 |
from django.db import connection |
5 | 3 |
hobo/multitenant/management/commands/list_tenants.py | ||
---|---|---|
11 | 11 |
all_tenants = TenantMiddleware.get_tenants() |
12 | 12 | |
13 | 13 |
for tenant in all_tenants: |
14 |
print("{0} {1}".format(tenant.schema_name, tenant.domain_url)) |
|
14 |
print(f"{tenant.schema_name} {tenant.domain_url}") |
hobo/multitenant/management/commands/migrate.py | ||
---|---|---|
21 | 21 |
"instead. Please read the documentation if you don't know why you " |
22 | 22 |
"shouldn't call migrate directly!".format(database) |
23 | 23 |
) |
24 |
super(Command, self).handle(*args, **options)
|
|
24 |
super().handle(*args, **options) |
|
25 | 25 | |
26 | 26 | |
27 | 27 |
if django_is_in_test_mode(): |
hobo/multitenant/management/commands/migrate_schemas.py | ||
---|---|---|
33 | 33 |
requires_system_checks = [] |
34 | 34 | |
35 | 35 |
def add_arguments(self, parser): |
36 |
super(MigrateSchemasCommand, self).add_arguments(parser)
|
|
36 |
super().add_arguments(parser) |
|
37 | 37 |
command = MigrateCommand() |
38 | 38 |
command.add_arguments(parser) |
39 | 39 |
parser.set_defaults(verbosity=0) |
40 | 40 | |
41 | 41 |
def handle(self, *args, **options): |
42 |
super(MigrateSchemasCommand, self).handle(*args, **options)
|
|
42 |
super().handle(*args, **options) |
|
43 | 43 |
if self.domain: |
44 | 44 |
try: |
45 | 45 |
tenant = TenantMiddleware.get_tenant_by_hostname(self.domain) |
46 | 46 |
except TenantNotFound: |
47 |
raise RuntimeError('Tenant "{}" does not exist'.format(self.domain))
|
|
47 |
raise RuntimeError(f'Tenant "{self.domain}" does not exist')
|
|
48 | 48 |
else: |
49 | 49 |
self.run_migrations(tenant, settings.TENANT_APPS) |
50 | 50 |
elif self.schema_name: |
... | ... | |
56 | 56 |
app_labels.append(app.label) |
57 | 57 |
loader = MigrationLoader(None) |
58 | 58 |
loader.load_disk() |
59 |
all_migrations = set(
|
|
60 |
[(app, migration) for app, migration in loader.disk_migrations if app in app_labels]
|
|
61 |
)
|
|
59 |
all_migrations = {
|
|
60 |
(app, migration) for app, migration in loader.disk_migrations if app in app_labels
|
|
61 |
}
|
|
62 | 62 |
for tenant in TenantMiddleware.get_tenants(): |
63 | 63 |
connection.set_tenant(tenant, include_public=False) |
64 | 64 |
applied_migrations = self.get_applied_migrations(app_labels) |
hobo/multitenant/management/commands/runserver.py | ||
---|---|---|
40 | 40 |
handler. |
41 | 41 | |
42 | 42 |
""" |
43 |
handler = super(Command, self).get_handler(*args, **options)
|
|
43 |
handler = super().get_handler(*args, **options) |
|
44 | 44 |
use_static_handler = options.get('use_static_handler', True) |
45 | 45 |
insecure_serving = options.get('insecure_serving', False) |
46 | 46 |
if use_static_handler and (settings.DEBUG or insecure_serving): |
hobo/multitenant/management/commands/shell.py | ||
---|---|---|
8 | 8 | |
9 | 9 |
def handle(self, *args, **kwargs): |
10 | 10 |
disable_global_logging() |
11 |
super(Command, self).handle(*args, **kwargs) |
|
11 |
super().handle(*args, **kwargs) |
hobo/multitenant/management/commands/showmigrations_schemas.py | ||
---|---|---|
26 | 26 |
help = "Show database schema migrations." |
27 | 27 | |
28 | 28 |
def add_arguments(self, parser): |
29 |
super(ShowMigrationsSchemasCommand, self).add_arguments(parser)
|
|
29 |
super().add_arguments(parser) |
|
30 | 30 |
command = ShowMigrationsCommand() |
31 | 31 |
command.add_arguments(parser) |
32 | 32 | |
33 | 33 |
def handle(self, *args, **options): |
34 |
super(ShowMigrationsSchemasCommand, self).handle(*args, **options)
|
|
34 |
super().handle(*args, **options) |
|
35 | 35 |
if self.domain: |
36 | 36 |
try: |
37 | 37 |
tenant = TenantMiddleware.get_tenant_by_hostname(self.domain) |
38 | 38 |
except TenantNotFound: |
39 |
raise RuntimeError('Schema "{}" does not exist'.format(self.schema_name))
|
|
39 |
raise RuntimeError(f'Schema "{self.schema_name}" does not exist')
|
|
40 | 40 |
self.run_showmigrations(tenant, settings.TENANT_APPS) |
41 | 41 |
else: |
42 | 42 |
for tenant in TenantMiddleware.get_tenants(): |
hobo/multitenant/management/commands/syncdb.py | ||
---|---|---|
21 | 21 |
and not django_is_in_test_mode() |
22 | 22 |
): |
23 | 23 |
raise CommandError( |
24 |
"syncdb has been disabled, for database '{0}'. "
|
|
24 |
"syncdb has been disabled, for database '{}'. " |
|
25 | 25 |
"Use sync_schemas instead. Please read the " |
26 | 26 |
"documentation if you don't know why " |
27 | 27 |
"you shouldn't call syncdb directly!".format(database) |
28 | 28 |
) |
29 |
super(Command, self).handle(*args, **options) |
|
29 |
super().handle(*args, **options) |
hobo/multitenant/management/commands/tenant_command.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 | 1 |
# this file derive from django-tenant-schemas |
3 | 2 |
# Author: Bernardo Pires Carneiro |
4 | 3 |
# Email: carneiro.be@gmail.com |
... | ... | |
141 | 140 |
print(prefix + msg) |
142 | 141 |
continue |
143 | 142 |
if args_verbosity.verbosity > 1: |
144 |
print(u'* Running command %s on tenant %s' % (command, tenant.domain_url))
|
|
143 |
print('* Running command %s on tenant %s' % (command, tenant.domain_url)) |
|
145 | 144 |
error = run_command_from_argv(klass, args) |
146 | 145 |
if error: |
147 | 146 |
errors.append(error) |
hobo/multitenant/mellon.py | ||
---|---|---|
1 |
from __future__ import absolute_import |
|
2 | ||
3 | 1 |
import json |
4 | 2 |
import logging |
5 | 3 |
import os |
hobo/multitenant/models.py | ||
---|---|---|
20 | 20 |
pass |
21 | 21 | |
22 | 22 |
def __unicode__(self): |
23 |
return u'Tenant %s (%s)' % (self.domain_url, self.schema_name)
|
|
23 |
return 'Tenant %s (%s)' % (self.domain_url, self.schema_name) |
|
24 | 24 | |
25 | 25 |
def __str__(self): |
26 | 26 |
return 'Tenant %s (%s)' % (self.domain_url, self.schema_name) |
hobo/multitenant/settings.py | ||
---|---|---|
27 | 27 |
return getattr(import_module(module), attr) |
28 | 28 | |
29 | 29 | |
30 |
class TenantSettingsWrapper(object):
|
|
30 |
class TenantSettingsWrapper: |
|
31 | 31 |
local = threading.local() |
32 | 32 | |
33 | 33 |
def __init__(self, default_settings): |
hobo/multitenant/settings_loaders.py | ||
---|---|---|
10 | 10 |
from hobo.theme.utils import get_theme |
11 | 11 | |
12 | 12 | |
13 |
class FileBaseSettingsLoader(object):
|
|
13 |
class FileBaseSettingsLoader: |
|
14 | 14 |
""" |
15 | 15 |
Base middleware class for loading settings from FILENAME. |
16 | 16 |
Child classes MUST override update_settings_from_path(). |
... | ... | |
36 | 36 |
raise NotImplemented |
37 | 37 | |
38 | 38 | |
39 |
class SettingsDictUpdateMixin(object):
|
|
39 |
class SettingsDictUpdateMixin: |
|
40 | 40 |
def do_update(self, tenant_settings, key, value): |
41 | 41 |
old_value = getattr(tenant_settings, key, {}) |
42 | 42 |
new_value = old_value.copy() |
... | ... | |
306 | 306 |
break |
307 | 307 | |
308 | 308 | |
309 |
class CookieNames(object):
|
|
309 |
class CookieNames: |
|
310 | 310 |
def get_new_time(self, tenant): |
311 | 311 |
return 0 |
312 | 312 | |
... | ... | |
395 | 395 |
tenant_settings.MELLON_PRIVATE_KEY = saml_key |
396 | 396 | |
397 | 397 | |
398 |
class SiteBaseUrl(object):
|
|
398 |
class SiteBaseUrl: |
|
399 | 399 |
def get_new_time(self, tenant): |
400 | 400 |
tenant_dir = os.path.join(settings.TENANT_BASE, tenant.domain_url) |
401 | 401 |
for filename in ['unsecure', 'base_url']: |
hobo/multitenant/template_loader.py | ||
---|---|---|
19 | 19 | |
20 | 20 |
class CachedLoader(DjangoCachedLoader): |
21 | 21 |
def cache_key(self, template_name, template_dirs, skip=None): |
22 |
key = super(CachedLoader, self).cache_key(template_name, template_dirs, skip=skip)
|
|
22 |
key = super().cache_key(template_name, template_dirs, skip=skip) |
|
23 | 23 |
if connection.tenant: |
24 | 24 |
return connection.tenant.domain_url + '-' + key |
25 | 25 |
return key |
... | ... | |
51 | 51 |
known_dirnames = ( |
52 | 52 |
list( |
53 | 53 |
itertools.chain( |
54 |
*[
|
|
54 |
*(
|
|
55 | 55 |
( |
56 | 56 |
'%s/variants/%s/portal-agent' % (x, theme_value), |
57 | 57 |
'%s/variants/%s' % (x, theme_value), |
58 | 58 |
) |
59 | 59 |
for x in known_dirnames |
60 |
]
|
|
60 |
)
|
|
61 | 61 |
) |
62 | 62 |
) |
63 | 63 |
+ known_dirnames |
... | ... | |
66 | 66 |
known_dirnames = ( |
67 | 67 |
list( |
68 | 68 |
itertools.chain( |
69 |
*[
|
|
69 |
*(
|
|
70 | 70 |
( |
71 | 71 |
'%s/variants/%s/portal-user' % (x, theme_value), |
72 | 72 |
'%s/variants/%s' % (x, theme_value), |
73 | 73 |
) |
74 | 74 |
for x in known_dirnames |
75 |
]
|
|
75 |
)
|
|
76 | 76 |
) |
77 | 77 |
) |
78 | 78 |
+ known_dirnames |
hobo/profile/migrations/0001_initial.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 |
from __future__ import unicode_literals |
|
3 | ||
4 | 1 |
import django.core.validators |
5 | 2 |
from django.db import migrations, models |
6 | 3 |
hobo/profile/migrations/0002_add_data.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 |
from __future__ import unicode_literals |
|
3 | ||
4 | 1 |
from django.db import migrations |
5 | 2 | |
6 | 3 | |
... | ... | |
8 | 5 |
AttributeDefinition = apps.get_model('profile', 'AttributeDefinition') |
9 | 6 | |
10 | 7 |
attributes = [ |
11 |
{'label': u'Civilité', 'name': 'title', 'kind': 'title', 'disabled': True},
|
|
12 |
{'label': u'Prénom', 'name': 'first_name', 'required': True, 'asked_on_registration': True},
|
|
13 |
{'label': u'Nom', 'name': 'last_name', 'required': True, 'asked_on_registration': True},
|
|
14 |
{'label': u'Adresse électronique', 'name': 'email', 'kind': 'email', 'required': True},
|
|
15 |
{'label': u'Adresse', 'name': 'address'},
|
|
16 |
{'label': u'Code postal', 'name': 'zipcode'},
|
|
17 |
{'label': u'Commune', 'name': 'city'},
|
|
18 |
{'label': u'Pays', 'name': 'country', 'disabled': True},
|
|
19 |
{'label': u'Date de naissance', 'name': 'birthdate', 'kind': 'birthdate', 'disabled': True},
|
|
20 |
{'label': u'Téléphone', 'name': 'phone', 'kind': 'phone_number'},
|
|
21 |
{'label': u'Mobile', 'name': 'mobile', 'kind': 'phone_number'},
|
|
8 |
{'label': 'Civilité', 'name': 'title', 'kind': 'title', 'disabled': True}, |
|
9 |
{'label': 'Prénom', 'name': 'first_name', 'required': True, 'asked_on_registration': True}, |
|
10 |
{'label': 'Nom', 'name': 'last_name', 'required': True, 'asked_on_registration': True}, |
|
11 |
{'label': 'Adresse électronique', 'name': 'email', 'kind': 'email', 'required': True}, |
|
12 |
{'label': 'Adresse', 'name': 'address'}, |
|
13 |
{'label': 'Code postal', 'name': 'zipcode'}, |
|
14 |
{'label': 'Commune', 'name': 'city'}, |
|
15 |
{'label': 'Pays', 'name': 'country', 'disabled': True}, |
|
16 |
{'label': 'Date de naissance', 'name': 'birthdate', 'kind': 'birthdate', 'disabled': True}, |
|
17 |
{'label': 'Téléphone', 'name': 'phone', 'kind': 'phone_number'}, |
|
18 |
{'label': 'Mobile', 'name': 'mobile', 'kind': 'phone_number'}, |
|
22 | 19 |
] |
23 | 20 | |
24 | 21 |
for i, attribute_dict in enumerate(attributes): |
hobo/profile/migrations/0003_attributedefinition_searchable.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 | 1 |
# Generated by Django 1.11.12 on 2019-01-01 09:46 |
3 |
from __future__ import unicode_literals |
|
4 | 2 | |
5 | 3 |
from django.db import migrations, models |
6 | 4 |
hobo/profile/migrations/0004_auto_20200518_1810.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 | 1 |
# Generated by Django 1.11.17 on 2020-05-18 18:10 |
3 |
from __future__ import unicode_literals |
|
4 | 2 | |
5 | 3 |
import django.core.validators |
6 | 4 |
from django.db import migrations, models |
hobo/profile/models.py | ||
---|---|---|
67 | 67 |
ordering = ['order'] |
68 | 68 | |
69 | 69 |
def as_dict(self): |
70 |
as_dict = dict([(x, y) for (x, y) in self.__dict__.items() if type(y) in (str, bool)])
|
|
70 |
as_dict = {x: y for (x, y) in self.__dict__.items() if type(y) in (str, bool)}
|
|
71 | 71 |
return as_dict |
72 | 72 | |
73 | 73 |
def get_real_kind_display(self): |
... | ... | |
78 | 78 |
def save(self, *args, **kwargs): |
79 | 79 |
if self.order is None: |
80 | 80 |
self.order = max([0] + [x.order for x in AttributeDefinition.objects.all()]) + 1 |
81 |
super(AttributeDefinition, self).save(*args, **kwargs) |
|
81 |
super().save(*args, **kwargs) |
hobo/rest_authentication.py | ||
---|---|---|
90 | 90 |
class PublikAuthentication(authentication.BaseAuthentication): |
91 | 91 |
def __init__(self, *args, **kwargs): |
92 | 92 |
self.logger = logging.getLogger(__name__) |
93 |
super(PublikAuthentication, self).__init__(*args, **kwargs)
|
|
93 |
super().__init__(*args, **kwargs) |
|
94 | 94 | |
95 | 95 |
def resolve_user(self, request): |
96 | 96 |
User = get_user_model() |
hobo/seo/views.py | ||
---|---|---|
42 | 42 |
success_url = reverse_lazy('seo-home') |
43 | 43 | |
44 | 44 |
def get_initial(self): |
45 |
initial = super(HomeView, self).get_initial()
|
|
45 |
initial = super().get_initial() |
|
46 | 46 |
initial['meta_description'] = get_variable('meta_description').value |
47 | 47 |
initial['meta_keywords'] = get_variable('meta_keywords').value |
48 | 48 |
return initial |
... | ... | |
50 | 50 |
def form_valid(self, form): |
51 | 51 |
set_variable('meta_description', form.cleaned_data['meta_description']) |
52 | 52 |
set_variable('meta_keywords', form.cleaned_data['meta_keywords']) |
53 |
return super(HomeView, self).form_valid(form)
|
|
53 |
return super().form_valid(form) |
|
54 | 54 | |
55 | 55 |
def get_context_data(self, **kwargs): |
56 |
context = super(HomeView, self).get_context_data(**kwargs)
|
|
56 |
context = super().get_context_data(**kwargs) |
|
57 | 57 |
context['robots_txt'] = get_variable('robots_txt').value |
58 | 58 |
context['mode'] = get_mode(context['robots_txt']) |
59 | 59 |
return context |
... | ... | |
78 | 78 |
success_url = reverse_lazy('seo-home') |
79 | 79 | |
80 | 80 |
def get_initial(self): |
81 |
initial = super(CustomizeView, self).get_initial()
|
|
81 |
initial = super().get_initial() |
|
82 | 82 |
initial['content'] = get_variable('robots_txt').value |
83 | 83 |
return initial |
84 | 84 | |
85 | 85 |
def form_valid(self, form): |
86 | 86 |
set_variable('robots_txt', form.cleaned_data['content']) |
87 |
return super(CustomizeView, self).form_valid(form)
|
|
87 |
return super().form_valid(form) |
|
88 | 88 | |
89 | 89 | |
90 | 90 |
customize = CustomizeView.as_view() |
hobo/theme/views.py | ||
---|---|---|
32 | 32 |
template_name = 'hobo/theme_home.html' |
33 | 33 | |
34 | 34 |
def get_context_data(self, **kwargs): |
35 |
context = super(HomeView, self).get_context_data(**kwargs)
|
|
35 |
context = super().get_context_data(**kwargs) |
|
36 | 36 | |
37 | 37 |
def hsv(theme): |
38 | 38 |
theme_colour = theme.get('variables').get('theme_color') or '#FFFFFF' |
39 | 39 |
if theme_colour == '#FFFFFF': |
40 | 40 |
return (1, 1, 1) |
41 | 41 |
theme_rgb = [int(x, 16) for x in (theme_colour[1:3], theme_colour[3:5], theme_colour[5:])] |
42 |
theme_hsv = colorsys.rgb_to_hsv(*[1.0 * x / 255 for x in theme_rgb])
|
|
42 |
theme_hsv = colorsys.rgb_to_hsv(*(1.0 * x / 255 for x in theme_rgb))
|
|
43 | 43 |
return theme_hsv |
44 | 44 | |
45 | 45 |
context['themes'] = get_themes() |
hobo/urls_utils.py | ||
---|---|---|
10 | 10 | |
11 | 11 |
class DecoratedURLPattern(URLPattern): |
12 | 12 |
def resolve(self, *args, **kwargs): |
13 |
result = super(DecoratedURLPattern, self).resolve(*args, **kwargs)
|
|
13 |
result = super().resolve(*args, **kwargs) |
|
14 | 14 |
if result: |
15 | 15 |
result.func = self._decorate_with(result.func) |
16 | 16 |
return result |
... | ... | |
18 | 18 | |
19 | 19 |
class DecoratedRegexURLResolver(URLResolver): |
20 | 20 |
def resolve(self, *args, **kwargs): |
21 |
result = super(DecoratedRegexURLResolver, self).resolve(*args, **kwargs)
|
|
21 |
result = super().resolve(*args, **kwargs) |
|
22 | 22 |
if result: |
23 | 23 |
result.func = self._decorate_with(result.func) |
24 | 24 |
return result |
hobo/views.py | ||
---|---|---|
34 | 34 |
template_name = 'hobo/home.html' |
35 | 35 | |
36 | 36 |
def get_context_data(self, **kwargs): |
37 |
context = super(Home, self).get_context_data(**kwargs)
|
|
37 |
context = super().get_context_data(**kwargs) |
|
38 | 38 |
context['services'] = [x for x in get_installed_services() if not x.secondary] |
39 | 39 |
context['has_authentic'] = bool(Authentic.objects.filter(secondary=False)) |
40 | 40 |
context['has_global_title'] = Variable.objects.filter(name='global_title').exists() |
setup.py | ||
---|---|---|
1 | 1 |
#! /usr/bin/env python |
2 |
# -*- coding: utf-8 -*- |
|
3 | 2 | |
4 | 3 |
import glob |
5 | 4 |
import os |
... | ... | |
31 | 30 | |
32 | 31 |
def get_version(): |
33 | 32 |
if os.path.exists('VERSION'): |
34 |
version_file = open('VERSION', 'r')
|
|
33 |
version_file = open('VERSION') |
|
35 | 34 |
version = version_file.read() |
36 | 35 |
version_file.close() |
37 | 36 |
return version |
tests/test_cook.py | ||
---|---|---|
1 | 1 |
import json |
2 | 2 |
import os |
3 | 3 |
from io import StringIO |
4 |
from unittest.mock import Mock, call, mock_open, patch |
|
4 | 5 | |
5 | 6 |
import pytest |
6 | 7 |
from django.contrib.auth.models import User |
7 | 8 |
from django.contrib.contenttypes.models import ContentType |
8 | 9 |
from django.core.management.base import CommandError |
9 |
from mock import Mock, call, mock_open, patch |
|
10 | 10 | |
11 | 11 |
from hobo.environment.management.commands.cook import Command |
12 | 12 |
from hobo.environment.models import ( |
... | ... | |
30 | 30 |
"""no exception raised if url are available""" |
31 | 31 |
command = Command() |
32 | 32 |
command.server_action = 'mock a server_action handler (ex: hobo-create)' |
33 |
action, action_args = 'server-action', {u'url': u'https://test.org/'}
|
|
33 |
action, action_args = 'server-action', {'url': 'https://test.org/'}
|
|
34 | 34 | |
35 | 35 |
monkeypatch.setattr(ServiceBase, 'is_resolvable', lambda x: True) |
36 | 36 |
monkeypatch.setattr(ServiceBase, 'has_valid_certificate', lambda x: True) |
... | ... | |
42 | 42 |
"""raise CommandError""" |
43 | 43 |
command = Command() |
44 | 44 |
command.server_action = 'mock a server_action handler (ex: hobo-create)' |
45 |
action, action_args = 'not-a-server-action', {u'url': u'https://test.org/'}
|
|
45 |
action, action_args = 'not-a-server-action', {'url': 'https://test.org/'}
|
|
46 | 46 | |
47 | 47 |
monkeypatch.setattr(ServiceBase, 'is_resolvable', lambda x: True) |
48 | 48 |
monkeypatch.setattr(ServiceBase, 'has_valid_certificate', lambda x: True) |
... | ... | |
55 | 55 |
"""raise CommandError""" |
56 | 56 |
command = Command() |
57 | 57 |
command.server_action = 'mock a server_action handler (ex: hobo-create)' |
58 |
action, action_args = 'server-action', {u'url': u'https://test.org/'}
|
|
58 |
action, action_args = 'server-action', {'url': 'https://test.org/'}
|
|
59 | 59 | |
60 | 60 |
monkeypatch.setattr(ServiceBase, 'is_resolvable', lambda x: False) |
61 | 61 |
monkeypatch.setattr(ServiceBase, 'has_valid_certificate', lambda x: True) |
... | ... | |
68 | 68 |
"""raise CommandError""" |
69 | 69 |
command = Command() |
70 | 70 |
command.server_action = 'mock a server_action handler (ex: hobo-create)' |
71 |
action, action_args = 'server-action', {u'url': u'https://test.org/'}
|
|
71 |
action, action_args = 'server-action', {'url': 'https://test.org/'}
|
|
72 | 72 | |
73 | 73 |
monkeypatch.setattr(ServiceBase, 'is_resolvable', lambda x: True) |
74 | 74 |
monkeypatch.setattr(ServiceBase, 'has_valid_certificate', lambda x: False) |
... | ... | |
106 | 106 |
handler.write(json.dumps(recipe)) |
107 | 107 | |
108 | 108 |
command.run_cook(recipe_path) |
109 |
assert command.check_action.mock_calls == [call(u'create-hobo', {u'url': u'https://entrouvert.org/'})]
|
|
110 |
assert command.create_hobo.mock_calls == [call(url=u'https://entrouvert.org/')]
|
|
109 |
assert command.check_action.mock_calls == [call('create-hobo', {'url': 'https://entrouvert.org/'})]
|
|
110 |
assert command.create_hobo.mock_calls == [call(url='https://entrouvert.org/')] |
|
111 | 111 |
assert mocked_notify_agents.mock_calls == [] |
112 | 112 |
assert command.wait_operationals.mock_calls == [call(timeout=42)] |
113 | 113 | |
... | ... | |
123 | 123 |
handler.write(json.dumps(recipe)) |
124 | 124 | |
125 | 125 |
command.run_cook(recipe_path) |
126 |
assert command.create_authentic.mock_calls == [call(title=u'Connexion', url=u'https://entrouvert.org/')]
|
|
126 |
assert command.create_authentic.mock_calls == [call(title='Connexion', url='https://entrouvert.org/')]
|
|
127 | 127 | |
128 | 128 | |
129 | 129 |
def test_load_variables_from(db, tmpdir): |
... | ... | |
153 | 153 |
handler.write(json.dumps(recipe)) |
154 | 154 | |
155 | 155 |
command.run_cook(recipe_path) |
156 |
assert command.create_hobo.mock_calls == [call(url=u'https://entrouvert.org/')]
|
|
157 |
assert command.create_authentic.mock_calls == [call(url=u'https://foo1/')]
|
|
158 |
assert command.create_combo.mock_calls == [call(not_a_string=[], url=u'https://bar2/')]
|
|
156 |
assert command.create_hobo.mock_calls == [call(url='https://entrouvert.org/')] |
|
157 |
assert command.create_authentic.mock_calls == [call(url='https://foo1/')] |
|
158 |
assert command.create_combo.mock_calls == [call(not_a_string=[], url='https://bar2/')] |
|
159 | 159 | |
160 | 160 | |
161 | 161 |
def test_wait_operationals(db, monkeypatch): |
... | ... | |
357 | 357 |
with patch('hobo.environment.management.commands.cook.open', mocked_open, create=True): |
358 | 358 |
command.create_hobo('http://entrouvert.org/and_much') |
359 | 359 |
assert command.create_site.mock_calls == [ |
360 |
call(Hobo, 'http://entrouvert.org/and_much', None, u'hobo-none', template_name='', variables=None)
|
|
360 |
call(Hobo, 'http://entrouvert.org/and_much', None, 'hobo-none', template_name='', variables=None) |
|
361 | 361 |
] |
362 | 362 |
assert mocked_call_command.mock_calls == [] |
363 | 363 |
assert len(mocked_connection.set_tenant.mock_calls) == 1 |
tests/test_emails.py | ||
---|---|---|
4 | 4 |
import smtplib |
5 | 5 |
import socket |
6 | 6 |
import threading |
7 |
from unittest import mock |
|
7 | 8 | |
8 | 9 |
import dns.resolver |
9 |
import mock |
|
10 | 10 |
import pytest |
11 | 11 |
from django.core.exceptions import ValidationError |
12 | 12 |
from django.utils.encoding import force_text |
tests/test_environment.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 | 1 |
import json |
3 | 2 | |
4 | 3 |
import pytest |
... | ... | |
44 | 43 |
with pytest.raises(ValidationError) as e: |
45 | 44 |
passerelle.clean() |
46 | 45 | |
47 |
assert e.value.messages[0] == u'This slug is already used. It must be unique.'
|
|
46 |
assert e.value.messages[0] == 'This slug is already used. It must be unique.' |
|
48 | 47 | |
49 | 48 | |
50 | 49 |
def test_unique_title(): |
... | ... | |
69 | 68 |
with pytest.raises(ValidationError) as e: |
70 | 69 |
combo.clean() |
71 | 70 | |
72 |
assert e.value.messages[0] == u'This title is already used. It must be unique.'
|
|
71 |
assert e.value.messages[0] == 'This title is already used. It must be unique.' |
|
73 | 72 | |
74 | 73 |
# secondary services can be added |
75 | 74 |
combo.secondary = True |
tests/test_health_api.py | ||
---|---|---|
1 | 1 |
import json |
2 | 2 |
import socket |
3 |
from unittest.mock import MagicMock |
|
3 | 4 | |
4 | 5 |
import pytest |
5 | 6 |
import requests |
6 | 7 |
from django.core.cache import cache |
7 | 8 |
from django.utils import timezone |
8 | 9 |
from httmock import HTTMock, remember_called, urlmatch |
9 |
from mock import MagicMock |
|
10 | 10 | |
11 | 11 |
from hobo.environment.models import Authentic, Combo |
12 | 12 |
tests/test_hobo_deploy.py | ||
---|---|---|
4 | 4 |
import os |
5 | 5 |
import sys |
6 | 6 |
from io import StringIO |
7 |
from unittest.mock import Mock, call, patch |
|
7 | 8 | |
8 | 9 |
import pytest |
9 |
from mock import Mock, call, patch |
|
10 | 10 |
from requests import Response, exceptions |
11 | 11 | |
12 | 12 |
from hobo.agent.common.management.commands.hobo_deploy import Command, CommandError, replace_file |
... | ... | |
21 | 21 | |
22 | 22 |
content = 'content of my new file' |
23 | 23 |
replace_file(path, content) |
24 |
with open(path, 'r') as handler:
|
|
24 |
with open(path) as handler: |
|
25 | 25 |
assert handler.read() == content |
26 | 26 | |
27 | 27 |
content = 'new content for my file' |
28 | 28 |
replace_file(path, content) |
29 |
with open(path, 'r') as handler:
|
|
29 |
with open(path) as handler: |
|
30 | 30 |
assert handler.read() == content |
31 | 31 | |
32 | 32 | |
... | ... | |
164 | 164 |
tenant, |
165 | 165 |
) |
166 | 166 |
] |
167 |
with open(tenant_hobo_json, 'r') as handler: # hobo.json file
|
|
167 |
with open(tenant_hobo_json) as handler: # hobo.json file |
|
168 | 168 |
content = json.load(handler) |
169 | 169 |
assert ENVIRONMENT['services'][0]['this'] is True # new entry added |
170 | 170 |
assert json.dumps(content, sort_keys=True), json.dumps(ENVIRONMENT, sort_keys=True) |
... | ... | |
224 | 224 |
tenant.domain_url = 'combo.dev.publik.love' |
225 | 225 | |
226 | 226 |
command.generate_saml_keys(tenant) |
227 |
with open('%s/saml.key' % str(tmpdir), 'r') as handler:
|
|
227 |
with open('%s/saml.key' % str(tmpdir)) as handler: |
|
228 | 228 |
key = handler.read() |
229 |
with open('%s/saml.crt' % str(tmpdir), 'r') as handler:
|
|
229 |
with open('%s/saml.crt' % str(tmpdir)) as handler: |
|
230 | 230 |
crt = handler.read() |
231 | 231 | |
232 | 232 |
# if files exist don't regenerate them |
233 | 233 |
command.generate_saml_keys(tenant) |
234 |
with open('%s/saml.key' % str(tmpdir), 'r') as handler:
|
|
234 |
with open('%s/saml.key' % str(tmpdir)) as handler: |
|
235 | 235 |
assert key == handler.read() |
236 |
with open('%s/saml.crt' % str(tmpdir), 'r') as handler:
|
|
236 |
with open('%s/saml.crt' % str(tmpdir)) as handler: |
|
237 | 237 |
assert crt == handler.read() |
238 | 238 | |
239 | 239 | |
... | ... | |
269 | 269 |
# normal case (stop when configuration on a service success for this tenant) |
270 | 270 |
mocked_get.side_effect = [response1] |
271 | 271 |
command.configure_service_provider(ENVIRONMENT, tenant) |
272 |
with open(tenant_idp_metadata, 'r') as handler:
|
|
272 |
with open(tenant_idp_metadata) as handler: |
|
273 | 273 |
assert handler.read() == 'my saml idp metadata (1)' |
274 | 274 | |
275 | 275 |
# no 'idp_url' JSON entry |
... | ... | |
277 | 277 |
os.remove(tenant_idp_metadata) |
278 | 278 |
command.configure_service_provider(env, tenant) |
279 | 279 |
with pytest.raises(IOError, match='No such file or directory'): |
280 |
open(tenant_idp_metadata, 'r')
|
|
280 |
open(tenant_idp_metadata) |
|
281 | 281 | |
282 | 282 |
# idp not available |
283 | 283 |
response1.status_code = 500 |
284 | 284 |
mocked_get.side_effect = [exceptions.RequestException, response1] |
285 | 285 |
command.configure_service_provider(ENVIRONMENT, tenant) |
286 | 286 |
with pytest.raises(IOError, match='No such file or directory'): |
287 |
open(tenant_idp_metadata, 'r')
|
|
287 |
open(tenant_idp_metadata) |
|
288 | 288 | |
289 | 289 |
# case when idp is becoming available |
290 | 290 |
mocked_get.side_effect = [response1, response2] |
291 | 291 |
command.configure_service_provider(ENVIRONMENT, tenant) |
292 |
with open(tenant_idp_metadata, 'r') as handler:
|
|
292 |
with open(tenant_idp_metadata) as handler: |
|
293 | 293 |
assert handler.read() == 'my saml idp metadata (2)' |
294 | 294 | |
295 | 295 |
tests/test_home_views.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 | 1 |
import json |
3 | 2 |
import re |
3 |
from unittest import mock |
|
4 | 4 | |
5 |
import mock |
|
6 | 5 |
import pytest |
7 | 6 |
from django.contrib.auth.models import User |
8 | 7 |
from test_manager import login |
tests/test_import_template.py | ||
---|---|---|
1 |
import mock |
|
1 |
from unittest import mock |
|
2 | ||
2 | 3 |
import pytest |
3 | 4 |
from django.conf import settings |
4 | 5 |
from django.core.management import load_command_class |
tests/test_maintenance.py | ||
---|---|---|
1 |
import mock |
|
1 |
from unittest import mock |
|
2 | ||
2 | 3 |
from test_manager import login |
3 | 4 | |
4 | 5 |
from hobo.environment.models import Variable |
tests/test_matomo_utils.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 | ||
3 | 1 |
import json |
2 |
from unittest import mock |
|
4 | 3 | |
5 |
import mock |
|
6 | 4 |
import pytest |
7 | 5 |
from django.test import override_settings |
8 | 6 |
from django.utils.encoding import force_text |
... | ... | |
630 | 628 |
content = PING_NOSTATUS_ERROR |
631 | 629 |
response.json = mock.MagicMock(return_value=json.loads(content)) |
632 | 630 |
mocked_post.return_value = response |
633 |
with pytest.raises(MatomoException, match='internal error on ping \(status expected\)'): |
|
631 |
with pytest.raises(MatomoException, match=r'internal error on ping \(status expected\)'):
|
|
634 | 632 |
matomo.create_fake_first_tracking_visit('42') |
635 | 633 | |
636 | 634 |
# failure (no dict) |
637 | 635 |
content = PING_NODICT_ERROR |
638 | 636 |
response.json = mock.MagicMock(return_value=content) |
639 | 637 |
mocked_post.return_value = response |
640 |
with pytest.raises(MatomoException, match='internal error on ping \(dict expected\)'): |
|
638 |
with pytest.raises(MatomoException, match=r'internal error on ping \(dict expected\)'):
|
|
641 | 639 |
matomo.create_fake_first_tracking_visit('42') |
642 | 640 | |
643 | 641 |
# failure (no JSON) |
644 | 642 |
response.json = mock.MagicMock(side_effect=ValueError('not a JSON')) |
645 | 643 |
mocked_post.return_value = response |
646 |
with pytest.raises(MatomoException, match='internal error on ping \(JSON expected\)'): |
|
644 |
with pytest.raises(MatomoException, match=r'internal error on ping \(JSON expected\)'):
|
|
647 | 645 |
matomo.create_fake_first_tracking_visit('42') |
648 | 646 | |
649 | 647 |
# failure (status 500) |
tests/test_matomo_views.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 | ||
3 | 1 |
import json |
4 | 2 |
import re |
3 |
from unittest import mock |
|
5 | 4 | |
6 |
import mock |
|
7 | 5 |
import pytest |
8 | 6 |
from django.contrib.auth.models import User |
9 | 7 |
from django.test import override_settings |
tests/test_settings_loaders.py | ||
---|---|---|
21 | 21 |
env = get_hobo_json() |
22 | 22 |
fields = env['profile']['fields'] |
23 | 23 |
assert [x['name'] for x in fields] == [ |
24 |
u'title',
|
|
25 |
u'first_name',
|
|
26 |
u'last_name',
|
|
27 |
u'email',
|
|
28 |
u'address',
|
|
29 |
u'zipcode',
|
|
30 |
u'city',
|
|
31 |
u'country',
|
|
32 |
u'birthdate',
|
|
33 |
u'phone',
|
|
34 |
u'mobile',
|
|
24 |
'title', |
|
25 |
'first_name', |
|
26 |
'last_name', |
|
27 |
'email', |
|
28 |
'address', |
|
29 |
'zipcode', |
|
30 |
'city', |
|
31 |
'country', |
|
32 |
'birthdate', |
|
33 |
'phone', |
|
34 |
'mobile', |
|
35 | 35 |
] |
36 | 36 | |
37 | 37 |
# swap title and mobile fields |
... | ... | |
44 | 44 |
env = get_hobo_json() |
45 | 45 |
fields = env['profile']['fields'] |
46 | 46 |
assert [x['name'] for x in fields] == [ |
47 |
u'mobile',
|
|
48 |
u'first_name',
|
|
49 |
u'last_name',
|
|
50 |
u'email',
|
|
51 |
u'address',
|
|
52 |
u'zipcode',
|
|
53 |
u'city',
|
|
54 |
u'country',
|
|
55 |
u'birthdate',
|
|
56 |
u'phone',
|
|
57 |
u'title',
|
|
47 |
'mobile', |
|
48 |
'first_name', |
|
49 |
'last_name', |
|
50 |
'email', |
|
51 |
'address', |
|
52 |
'zipcode', |
|
53 |
'city', |
|
54 |
'country', |
|
55 |
'birthdate', |
|
56 |
'phone', |
|
57 |
'title', |
|
58 | 58 |
] |
59 | 59 | |
60 | 60 |
assert [x['name'] for x in fields if x['disabled']] == ['country', 'birthdate', 'title'] |
61 | 61 |
profile_fields = [x['name'] for x in fields if not x['disabled']] |
62 | 62 |
assert profile_fields == [ |
63 |
u'mobile',
|
|
64 |
u'first_name',
|
|
65 |
u'last_name',
|
|
66 |
u'email',
|
|
67 |
u'address',
|
|
68 |
u'zipcode',
|
|
69 |
u'city',
|
|
70 |
u'phone',
|
|
63 |
'mobile', |
|
64 |
'first_name', |
|
65 |
'last_name', |
|
66 |
'email', |
|
67 |
'address', |
|
68 |
'zipcode', |
|
69 |
'city', |
|
70 |
'phone', |
|
71 | 71 |
] |
72 | 72 | |
73 | 73 |
# serialize hobo.json |
... | ... | |
82 | 82 |
loader = AuthenticLoader() |
83 | 83 |
loader.update_settings_from_path(tenant_settings, path) |
84 | 84 |
assert tenant_settings.A2_PROFILE_FIELDS == profile_fields |
85 |
assert tenant_settings.A2_REQUIRED_FIELDS == [u'first_name', u'last_name', u'email']
|
|
86 |
assert tenant_settings.A2_REGISTRATION_FIELDS == [u'first_name', u'last_name']
|
|
85 |
assert tenant_settings.A2_REQUIRED_FIELDS == ['first_name', 'last_name', 'email']
|
|
86 |
assert tenant_settings.A2_REGISTRATION_FIELDS == ['first_name', 'last_name']
|
|
87 | 87 | |
88 | 88 | |
89 | 89 |
def test_mellon_backoffice_login_hint_setting_from_path(tmpdir): |
tests/test_signature.py | ||
---|---|---|
32 | 32 |
assert '&nonce=' in signature.sign_url(URL, KEY) |
33 | 33 | |
34 | 34 |
# Test unicode key conversion to UTF-8 |
35 |
assert signature.check_url(signature.sign_url(URL, u'\xe9\xe9'), b'\xc3\xa9\xc3\xa9')
|
|
36 |
assert signature.check_url(signature.sign_url(URL, b'\xc3\xa9\xc3\xa9'), u'\xe9\xe9')
|
|
35 |
assert signature.check_url(signature.sign_url(URL, '\xe9\xe9'), b'\xc3\xa9\xc3\xa9') |
|
36 |
assert signature.check_url(signature.sign_url(URL, b'\xc3\xa9\xc3\xa9'), '\xe9\xe9') |
|
37 | 37 | |
38 | 38 |
# Test timedelta parameter |
39 | 39 |
now = datetime.datetime.utcnow() |
tests/test_theme.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
1 |
from unittest.mock import patch |
|
2 | ||
2 | 3 |
import pytest |
3 | 4 |
from django.core.exceptions import ValidationError |
4 |
from mock import patch |
|
5 | 5 |
from test_manager import login |
6 | 6 | |
7 | 7 |
from hobo.environment.models import Variable |
tests/test_version.py | ||
---|---|---|
14 | 14 | |
15 | 15 |
settings.MIDDLEWARE = ('hobo.middleware.version.VersionMiddleware',) + tuple(settings.MIDDLEWARE) |
16 | 16 |
json_response = client.get('/__version__').json() |
17 |
assert set(json_response.keys()) == set(['pytest', 'pytest-django']) |
|
17 |
assert set(json_response.keys()) == {'pytest', 'pytest-django'} |
tests_authentic/settings.py | ||
---|---|---|
1 | 1 |
import builtins |
2 | 2 |
import os |
3 | ||
4 |
from mock import mock_open, patch |
|
3 |
from unittest.mock import mock_open, patch |
|
5 | 4 | |
6 | 5 |
import hobo.test_utils |
7 | 6 |
tests_authentic/test_hobo_deploy.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 | 1 |
import json |
3 | 2 |
import os |
4 | 3 |
import shutil |
5 | 4 |
import tempfile |
6 | 5 |
import time |
6 |
from unittest import mock |
|
7 | 7 | |
8 |
import mock |
|
9 | 8 |
import pytest |
10 | 9 |
from authentic2.data_transfer import export_site |
11 | 10 |
from django.core.management import call_command |
... | ... | |
45 | 44 |
{ |
46 | 45 |
'model': 'a2_rbac.role', |
47 | 46 |
'fields': { |
48 |
'name': u'Service petite enfance',
|
|
49 |
'slug': u'service-petite-enfance',
|
|
47 |
'name': 'Service petite enfance', |
|
48 |
'slug': 'service-petite-enfance', |
|
50 | 49 |
}, |
51 | 50 |
}, |
52 | 51 |
{ |
53 | 52 |
'model': 'a2_rbac.role', |
54 | 53 |
'fields': { |
55 |
'name': u'Service état-civil',
|
|
56 |
'slug': u'service-etat-civil',
|
|
54 |
'name': 'Service état-civil', |
|
55 |
'slug': 'service-etat-civil', |
|
57 | 56 |
}, |
58 | 57 |
}, |
59 | 58 |
], |
... | ... | |
151 | 150 |
'description': '', |
152 | 151 |
'required': False, |
153 | 152 |
'user_visible': True, |
154 |
'label': u'Civilité',
|
|
153 |
'label': 'Civilité', |
|
155 | 154 |
'disabled': True, |
156 | 155 |
'user_editable': True, |
157 | 156 |
'asked_on_registration': False, |
... | ... | |
162 | 161 |
'description': '', |
163 | 162 |
'required': True, |
164 | 163 |
'user_visible': True, |
165 |
'label': u'Prénom',
|
|
164 |
'label': 'Prénom', |
|
166 | 165 |
'disabled': False, |
167 | 166 |
'user_editable': True, |
168 | 167 |
'asked_on_registration': True, |
... | ... | |
184 | 183 |
'description': '', |
185 | 184 |
'required': True, |
186 | 185 |
'user_visible': True, |
187 |
'label': u'Adresse électronique',
|
|
186 |
'label': 'Adresse électronique', |
|
188 | 187 |
'disabled': False, |
189 | 188 |
'user_editable': True, |
190 | 189 |
'asked_on_registration': False, |
... | ... | |
228 | 227 |
'description': '', |
229 | 228 |
'required': False, |
230 | 229 |
'user_visible': True, |
231 |
'label': u'Téléphone',
|
|
230 |
'label': 'Téléphone', |
|
232 | 231 |
'disabled': False, |
233 | 232 |
'user_editable': True, |
234 | 233 |
'asked_on_registration': False, |
... | ... | |
312 | 311 |
'service-id': 'wcs', |
313 | 312 |
'template_name': 'commune', |
314 | 313 |
'slug': 'montpellier-metropole', |
315 |
'title': u'Montpellier-Métropole',
|
|
314 |
'title': 'Montpellier-Métropole', |
|
316 | 315 |
'base_url': 'http://eservices.example.net', |
317 | 316 |
'saml-sp-metadata-url': 'http://eservices.example.net/saml/metadata', |
318 | 317 |
}, |
319 | 318 |
{ |
320 | 319 |
'service-id': 'passerelle', |
321 | 320 |
'slug': 'passerelle', |
322 |
'title': u'Passerelle',
|
|
321 |
'title': 'Passerelle', |
|
323 | 322 |
'base_url': 'http://passerelle.example.net', |
324 | 323 |
'saml-sp-metadata-url': 'http://passerelle.example.net/saml/metadata', |
325 | 324 |
}, |
... | ... | |
340 | 339 |
'service-id': 'combo', |
341 | 340 |
'template_name': 'portal-user', |
342 | 341 |
'slug': 'portal', |
343 |
'title': u'Portail Montpellier-Métropole',
|
|
342 |
'title': 'Portail Montpellier-Métropole', |
|
344 | 343 |
'base_url': 'http://portal.example.net', |
345 | 344 |
'saml-sp-metadata-url': 'http://portal.example.net/saml/metadata', |
346 | 345 |
}, |
... | ... | |
364 | 363 |
# check role mass provisionning to new services |
365 | 364 |
# two wcs => two ous => two audiences |
366 | 365 |
assert mock_notify.call_count == 2 |
367 |
audiences = sorted([arg[0][0]['audience'] for arg in mock_notify.call_args_list])
|
|
366 |
audiences = sorted(arg[0][0]['audience'] for arg in mock_notify.call_args_list)
|
|
368 | 367 |
assert audiences == [ |
369 | 368 |
['http://clapiers.example.net/saml/metadata'], |
370 | 369 |
[ |
... | ... | |
466 | 465 |
# to their "ou" excluding their superuser role, 3 admin roles for users, |
467 | 466 |
# roles and services, and 2 loaded roles, petite enfance and état-civil |
468 | 467 |
assert Role.objects.filter(ou__isnull=False, service__isnull=True).count() == 10 |
469 |
for service_id in set(s['service-id'] for s in other_services):
|
|
468 |
for service_id in {s['service-id'] for s in other_services}:
|
|
470 | 469 |
same_services = [s for s in other_services if s['service-id'] == service_id] |
471 | 470 |
for i, service in enumerate(same_services): |
472 | 471 |
assert LibertyProvider.objects.filter(slug=service['slug']).count() == 1 |
... | ... | |
517 | 516 |
assert Role.objects.filter(ou=provider.ou, service__isnull=True).count() == 5 |
518 | 517 |
assert ( |
519 | 518 |
Role.objects.filter( |
520 |
ou=provider.ou, service__isnull=True, name=u'Service petite enfance'
|
|
519 |
ou=provider.ou, service__isnull=True, name='Service petite enfance' |
|
521 | 520 |
).count() |
522 | 521 |
== 1 |
523 | 522 |
) |
524 | 523 |
assert ( |
525 | 524 |
Role.objects.filter( |
526 |
ou=provider.ou, service__isnull=True, name=u'Service état-civil'
|
|
525 |
ou=provider.ou, service__isnull=True, name='Service état-civil' |
|
527 | 526 |
).count() |
528 | 527 |
== 1 |
529 | 528 |
) |
... | ... | |
679 | 678 |
{ |
680 | 679 |
'service-id': 'passerelle', |
681 | 680 |
'slug': 'passerelle', |
682 |
'title': u'Passerelle',
|
|
681 |
'title': 'Passerelle', |
|
683 | 682 |
'base_url': 'http://passerelle.example.net', |
684 | 683 |
'saml-sp-metadata-url': 'http://passerelle.example.net/saml/metadata', |
685 | 684 |
}, |
... | ... | |
731 | 730 |
{ |
732 | 731 |
'service-id': 'passerelle', |
733 | 732 |
'slug': 'passerelle', |
734 |
'title': u'Passerelle',
|
|
733 |
'title': 'Passerelle', |
|
735 | 734 |
'base_url': 'http://new-passerelle.example.net', |
736 | 735 |
'saml-sp-metadata-url': 'http://new-passerelle.example.net/saml/metadata', |
737 | 736 |
'legacy_urls': [ |
tests_authentic/test_provisionning.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 | ||
3 | 1 |
import json |
4 | 2 |
import os |
3 |
from unittest.mock import ANY, call, patch |
|
5 | 4 | |
6 | 5 |
import lasso |
7 | 6 |
import pytest |
... | ... | |
13 | 12 |
from django.contrib.auth import get_user_model |
14 | 13 |
from django.core.management import call_command |
15 | 14 |
from django_rbac.utils import get_ou_model |
16 |
from mock import ANY, call, patch |
|
17 | 15 |
from tenant_schemas.utils import tenant_context |
18 | 16 | |
19 | 17 |
from hobo import signature |
... | ... | |
41 | 39 |
assert arg == call(ANY) |
42 | 40 |
arg = arg[0][0] |
43 | 41 |
assert isinstance(arg, dict) |
44 |
assert set(arg.keys()) == set(['audience', '@type', 'objects', 'full'])
|
|
42 |
assert set(arg.keys()) == {'audience', '@type', 'objects', 'full'}
|
|
45 | 43 |
assert arg['audience'] == ['http://provider.com'] |
46 | 44 |
assert arg['@type'] == 'provision' |
47 | 45 |
assert arg['full'] is False |
48 | 46 |
objects = arg['objects'] |
49 | 47 |
assert isinstance(objects, dict) |
50 |
assert set(objects.keys()) == set(['data', '@type'])
|
|
48 |
assert set(objects.keys()) == {'data', '@type'}
|
|
51 | 49 |
assert objects['@type'] == 'role' |
52 | 50 |
data = objects['data'] |
53 | 51 |
assert isinstance(data, list) |
54 | 52 |
assert len(data) == 1 |
55 | 53 |
o = data[0] |
56 |
assert set(o.keys()) == set( |
|
57 |
['details', 'emails_to_members', 'description', 'uuid', 'name', 'slug', 'emails'] |
|
58 |
) |
|
54 |
assert set(o.keys()) == { |
|
55 |
'details', |
|
56 |
'emails_to_members', |
|
57 |
'description', |
|
58 |
'uuid', |
|
59 |
'name', |
|
60 |
'slug', |
|
61 |
'emails', |
|
62 |
} |
|
59 | 63 |
assert o['details'] == '' |
60 | 64 |
assert o['emails_to_members'] is True |
61 | 65 |
assert o['emails'] == [] |
... | ... | |
73 | 77 |
assert arg == call(ANY) |
74 | 78 |
arg = arg[0][0] |
75 | 79 |
assert isinstance(arg, dict) |
76 |
assert set(arg.keys()) == set(['audience', '@type', 'objects', 'full'])
|
|
80 |
assert set(arg.keys()) == {'audience', '@type', 'objects', 'full'}
|
|
77 | 81 |
assert arg['audience'] == ['http://provider.com'] |
78 | 82 |
assert arg['@type'] == 'provision' |
79 | 83 |
assert arg['full'] is False |
80 | 84 |
objects = arg['objects'] |
81 | 85 |
assert isinstance(objects, dict) |
82 |
assert set(objects.keys()) == set(['data', '@type'])
|
|
86 |
assert set(objects.keys()) == {'data', '@type'}
|
|
83 | 87 |
assert objects['@type'] == 'role' |
84 | 88 |
data = objects['data'] |
85 | 89 |
assert isinstance(data, list) |
86 | 90 |
assert len(data) == 1 |
87 | 91 |
o = data[0] |
88 |
assert set(o.keys()) == set( |
|
89 |
['details', 'emails_to_members', 'description', 'uuid', 'name', 'slug', 'emails'] |
|
90 |
) |
|
92 |
assert set(o.keys()) == { |
|
93 |
'details', |
|
94 |
'emails_to_members', |
|
95 |
'description', |
|
96 |
'uuid', |
|
97 |
'name', |
|
98 |
'slug', |
|
99 |
'emails', |
|
100 |
} |
|
91 | 101 |
assert o['details'] == '' |
92 | 102 |
assert o['emails_to_members'] is True |
93 | 103 |
assert o['emails'] == emails |
... | ... | |
101 | 111 |
assert arg == call(ANY) |
102 | 112 |
arg = arg[0][0] |
103 | 113 |
assert isinstance(arg, dict) |
104 |
assert set(arg.keys()) == set(['audience', '@type', 'objects', 'full'])
|
|
114 |
assert set(arg.keys()) == {'audience', '@type', 'objects', 'full'}
|
|
105 | 115 |
assert arg['audience'] == ['http://provider.com'] |
106 | 116 |
assert arg['@type'] == 'deprovision' |
107 | 117 |
assert arg['full'] is False |
108 | 118 |
objects = arg['objects'] |
109 | 119 |
assert isinstance(objects, dict) |
110 |
assert set(objects.keys()) == set(['data', '@type'])
|
|
120 |
assert set(objects.keys()) == {'data', '@type'}
|
|
111 | 121 |
assert objects['@type'] == 'role' |
112 | 122 |
data = objects['data'] |
113 | 123 |
assert isinstance(data, list) |
114 | 124 |
assert len(data) == 1 |
115 | 125 |
o = data[0] |
116 |
assert set(o.keys()) == set(['uuid'])
|
|
126 |
assert set(o.keys()) == {'uuid'}
|
|
117 | 127 | |
118 | 128 | |
119 | 129 |
def test_provision_user(transactional_db, tenant, caplog): |
... | ... | |
134 | 144 |
attribute = Attribute.objects.create(label='Code postal', name='code_postal', kind='string') |
135 | 145 |
with provisionning: |
136 | 146 |
user1 = User.objects.create( |
137 |
username=u'Étienne',
|
|
147 |
username='Étienne', |
|
138 | 148 |
email='etienne.dugenou@example.net', |
139 |
first_name=u'Étienne',
|
|
140 |
last_name=u'Dugenou',
|
|
149 |
first_name='Étienne', |
|
150 |
last_name='Dugenou', |
|
141 | 151 |
ou=get_default_ou(), |
142 | 152 |
) |
143 | 153 |
user2 = User.objects.create( |
144 |
username=u'john.doe',
|
|
154 |
username='john.doe', |
|
145 | 155 |
email='iohn.doe@example.net', |
146 |
first_name=u'John',
|
|
147 |
last_name=u'Doe',
|
|
156 |
first_name='John', |
|
157 |
last_name='Doe', |
|
148 | 158 |
is_active=False, |
149 | 159 |
ou=get_default_ou(), |
150 | 160 |
) |
... | ... | |
156 | 166 |
assert arg == call(ANY) |
157 | 167 |
arg = arg[0][0] |
158 | 168 |
assert isinstance(arg, dict) |
159 |
assert set(arg.keys()) == set(['issuer', 'audience', '@type', 'objects', 'full'])
|
|
169 |
assert set(arg.keys()) == {'issuer', 'audience', '@type', 'objects', 'full'}
|
|
160 | 170 |
assert arg['issuer'] == 'https://%s/idp/saml2/metadata' % tenant.domain_url |
161 | 171 |
assert arg['audience'] == ['http://provider.com'] |
162 | 172 |
assert arg['@type'] == 'provision' |
163 | 173 |
assert arg['full'] is False |
164 | 174 |
objects = arg['objects'] |
165 | 175 |
assert isinstance(objects, dict) |
166 |
assert set(objects.keys()) == set(['data', '@type'])
|
|
176 |
assert set(objects.keys()) == {'data', '@type'}
|
|
167 | 177 |
assert objects['@type'] == 'user' |
168 | 178 |
data = objects['data'] |
169 | 179 |
assert isinstance(data, list) |
170 | 180 |
assert len(data) == 2 |
171 |
assert len(set([o['uuid'] for o in data])) == 2
|
|
181 |
assert len({o['uuid'] for o in data}) == 2
|
|
172 | 182 |
for o in data: |
173 |
assert set(o.keys()) >= set( |
|
174 |
['uuid', 'username', 'first_name', 'is_superuser', 'last_name', 'email', 'roles'] |
|
175 |
) |
|
183 |
assert set(o.keys()) >= { |
|
184 |
'uuid', |
|
185 |
'username', |
|
186 |
'first_name', |
|
187 |
'is_superuser', |
|
188 |
'last_name', |
|
189 |
'email', |
|
190 |
'roles', |
|
191 |
} |
|
176 | 192 |
assert o['uuid'] in users |
177 | 193 |
user = users[o['uuid']] |
178 | 194 |
assert o['username'] == user.username |
... | ... | |
197 | 213 |
assert arg == call(ANY) |
198 | 214 |
arg = arg[0][0] |
199 | 215 |
assert isinstance(arg, dict) |
200 |
assert set(arg.keys()) == set(['issuer', 'audience', '@type', 'objects', 'full'])
|
|
216 |
assert set(arg.keys()) == {'issuer', 'audience', '@type', 'objects', 'full'}
|
|
201 | 217 |
assert arg['issuer'] == 'https://%s/idp/saml2/metadata' % tenant.domain_url |
202 | 218 |
assert arg['audience'] == ['http://provider.com'] |
203 | 219 |
assert arg['@type'] == 'provision' |
204 | 220 |
assert arg['full'] is False |
205 | 221 |
objects = arg['objects'] |
206 | 222 |
assert isinstance(objects, dict) |
207 |
assert set(objects.keys()) == set(['data', '@type'])
|
|
223 |
assert set(objects.keys()) == {'data', '@type'}
|
|
208 | 224 |
assert objects['@type'] == 'user' |
209 | 225 |
data = objects['data'] |
210 | 226 |
assert isinstance(data, list) |
211 | 227 |
assert len(data) == 2 |
212 | 228 |
for o, user in zip(data, [user1, user2]): |
213 |
assert set(o.keys()) >= set( |
|
214 |
[ |
|
215 |
'code_postal', |
|
216 |
'uuid', |
|
217 |
'username', |
|
218 |
'first_name', |
|
219 |
'is_superuser', |
|
220 |
'last_name', |
|
221 |
'email', |
|
222 |
'roles', |
|
223 |
] |
|
224 |
) |
|
229 |
assert set(o.keys()) >= { |
|
230 |
'code_postal', |
|
231 |
'uuid', |
|
232 |
'username', |
|
233 |
'first_name', |
|
234 |
'is_superuser', |
|
235 |
'last_name', |
|
236 |
'email', |
|
237 |
'roles', |
|
238 |
} |
|
225 | 239 |
assert o['uuid'] == user.uuid |
226 | 240 |
assert o['username'] == user.username |
227 | 241 |
assert o['first_name'] == user.first_name |
... | ... | |
235 | 249 | |
236 | 250 |
# test a service in a second OU also get the provisionning message |
237 | 251 |
notify_agents.reset_mock() |
238 |
ou2 = get_ou_model().objects.create(name=u'ou2', slug=u'ou2')
|
|
252 |
ou2 = get_ou_model().objects.create(name='ou2', slug='ou2')
|
|
239 | 253 |
LibertyProvider.objects.create( |
240 | 254 |
ou=ou2, |
241 | 255 |
name='provider2', |
... | ... | |
251 | 265 |
assert notify_agents.call_count == 2 |
252 | 266 |
assert set( |
253 | 267 |
notify_agents.mock_calls[0][1][0]['audience'] + notify_agents.mock_calls[1][1][0]['audience'] |
254 |
) == set(['http://provider.com', 'http://provider2.com'])
|
|
268 |
) == {'http://provider.com', 'http://provider2.com'}
|
|
255 | 269 |
ou2.delete() |
256 | 270 | |
257 | 271 |
notify_agents.reset_mock() |
... | ... | |
263 | 277 |
assert arg == call(ANY) |
264 | 278 |
arg = arg[0][0] |
265 | 279 |
assert isinstance(arg, dict) |
266 |
assert set(arg.keys()) == set(['issuer', 'audience', '@type', 'objects', 'full'])
|
|
280 |
assert set(arg.keys()) == {'issuer', 'audience', '@type', 'objects', 'full'}
|
|
267 | 281 |
assert arg['issuer'] == 'https://%s/idp/saml2/metadata' % tenant.domain_url |
268 | 282 |
assert arg['audience'] == ['http://provider.com'] |
269 | 283 |
assert arg['@type'] == 'provision' |
270 | 284 |
assert arg['full'] is False |
271 | 285 |
objects = arg['objects'] |
272 | 286 |
assert isinstance(objects, dict) |
273 |
assert set(objects.keys()) == set(['data', '@type'])
|
|
287 |
assert set(objects.keys()) == {'data', '@type'}
|
|
274 | 288 |
assert objects['@type'] == 'user' |
275 | 289 |
data = objects['data'] |
276 | 290 |
assert isinstance(data, list) |
277 | 291 |
assert len(data) == 1 |
278 | 292 |
for o in data: |
279 |
assert set(o.keys()) >= set( |
|
280 |
['uuid', 'username', 'first_name', 'is_superuser', 'last_name', 'email', 'roles'] |
|
281 |
) |
|
293 |
assert set(o.keys()) >= { |
|
294 |
'uuid', |
|
295 |
'username', |
|
296 |
'first_name', |
|
297 |
'is_superuser', |
|
298 |
'last_name', |
|
299 |
'email', |
|
300 |
'roles', |
|
301 |
} |
|
282 | 302 |
assert o['uuid'] == user1.uuid |
283 | 303 |
assert o['username'] == user1.username |
284 | 304 |
assert o['first_name'] == user1.first_name |
... | ... | |
301 | 321 |
assert arg == call(ANY) |
302 | 322 |
arg = arg[0][0] |
303 | 323 |
assert isinstance(arg, dict) |
304 |
assert set(arg.keys()) == set(['issuer', 'audience', '@type', 'objects', 'full'])
|
|
324 |
assert set(arg.keys()) == {'issuer', 'audience', '@type', 'objects', 'full'}
|
|
305 | 325 |
assert arg['issuer'] == 'https://%s/idp/saml2/metadata' % tenant.domain_url |
306 | 326 |
assert arg['audience'] == ['http://provider.com'] |
307 | 327 |
assert arg['@type'] == 'provision' |
308 | 328 |
assert arg['full'] is False |
309 | 329 |
objects = arg['objects'] |
310 | 330 |
assert isinstance(objects, dict) |
311 |
assert set(objects.keys()) == set(['data', '@type'])
|
|
331 |
assert set(objects.keys()) == {'data', '@type'}
|
|
312 | 332 |
assert objects['@type'] == 'user' |
313 | 333 |
data = objects['data'] |
314 | 334 |
assert isinstance(data, list) |
315 | 335 |
assert len(data) == 2 |
316 | 336 |
for o in data: |
317 |
assert set(o.keys()) >= set( |
|
318 |
['uuid', 'username', 'first_name', 'is_superuser', 'last_name', 'email', 'roles'] |
|
319 |
) |
|
337 |
assert set(o.keys()) >= { |
|
338 |
'uuid', |
|
339 |
'username', |
|
340 |
'first_name', |
|
341 |
'is_superuser', |
|
342 |
'last_name', |
|
343 |
'email', |
|
344 |
'roles', |
|
345 |
} |
|
320 | 346 |
assert o['uuid'] in users |
321 | 347 |
user = users[o['uuid']] |
322 | 348 |
assert o['uuid'] == user.uuid |
... | ... | |
328 | 354 |
{'name': r.name, 'slug': r.slug, 'uuid': r.uuid} for r in user.roles.all() |
329 | 355 |
] |
330 | 356 |
assert o['is_superuser'] is (user == user1) |
331 |
assert len(set(x['uuid'] for x in notify_agents.call_args_list[1][0][0]['objects']['data'])) == 2
|
|
357 |
assert len({x['uuid'] for x in notify_agents.call_args_list[1][0][0]['objects']['data']}) == 2
|
|
332 | 358 | |
333 | 359 |
notify_agents.reset_mock() |
334 | 360 |
with provisionning: |
... | ... | |
339 | 365 |
assert arg == call(ANY) |
340 | 366 |
arg = arg[0][0] |
341 | 367 |
assert isinstance(arg, dict) |
342 |
assert set(arg.keys()) == set(['issuer', 'audience', '@type', 'objects', 'full'])
|
|
368 |
assert set(arg.keys()) == {'issuer', 'audience', '@type', 'objects', 'full'}
|
|
343 | 369 |
assert arg['issuer'] == 'https://%s/idp/saml2/metadata' % tenant.domain_url |
344 | 370 |
assert arg['audience'] == ['http://provider.com'] |
345 | 371 |
assert arg['@type'] == 'provision' |
346 | 372 |
assert arg['full'] is False |
347 | 373 |
objects = arg['objects'] |
348 | 374 |
assert isinstance(objects, dict) |
349 |
assert set(objects.keys()) == set(['data', '@type'])
|
|
375 |
assert set(objects.keys()) == {'data', '@type'}
|
|
350 | 376 |
assert objects['@type'] == 'user' |
351 | 377 |
data = objects['data'] |
352 | 378 |
assert isinstance(data, list) |
353 | 379 |
assert len(data) == 1 |
354 | 380 |
for o in data: |
355 |
assert set(o.keys()) >= set( |
|
356 |
['uuid', 'username', 'first_name', 'is_superuser', 'last_name', 'email', 'roles'] |
|
357 |
) |
|
381 |
assert set(o.keys()) >= { |
|
382 |
'uuid', |
|
383 |
'username', |
|
384 |
'first_name', |
|
385 |
'is_superuser', |
|
386 |
'last_name', |
|
387 |
'email', |
|
388 |
'roles', |
|
389 |
} |
|
358 | 390 |
assert o['uuid'] == user1.uuid |
359 | 391 |
assert o['username'] == user1.username |
360 | 392 |
assert o['first_name'] == user1.first_name |
... | ... | |
373 | 405 |
assert arg == call(ANY) |
374 | 406 |
arg = arg[0][0] |
375 | 407 |
assert isinstance(arg, dict) |
376 |
assert set(arg.keys()) == set(['issuer', 'audience', '@type', 'objects', 'full'])
|
|
408 |
assert set(arg.keys()) == {'issuer', 'audience', '@type', 'objects', 'full'}
|
|
377 | 409 |
assert arg['issuer'] == 'https://%s/idp/saml2/metadata' % tenant.domain_url |
378 | 410 |
assert arg['audience'] == ['http://provider.com'] |
379 | 411 |
assert arg['@type'] == 'provision' |
380 | 412 |
assert arg['full'] is False |
381 | 413 |
objects = arg['objects'] |
382 | 414 |
assert isinstance(objects, dict) |
383 |
assert set(objects.keys()) == set(['data', '@type'])
|
|
415 |
assert set(objects.keys()) == {'data', '@type'}
|
|
384 | 416 |
assert objects['@type'] == 'user' |
385 | 417 |
data = objects['data'] |
386 | 418 |
assert isinstance(data, list) |
387 | 419 |
assert len(data) == 1 |
388 | 420 |
for o in data: |
389 |
assert set(o.keys()) >= set( |
|
390 |
['uuid', 'username', 'first_name', 'is_superuser', 'last_name', 'email', 'roles'] |
|
391 |
) |
|
421 |
assert set(o.keys()) >= { |
|
422 |
'uuid', |
|
423 |
'username', |
|
424 |
'first_name', |
|
425 |
'is_superuser', |
|
426 |
'last_name', |
|
427 |
'email', |
|
428 |
'roles', |
|
429 |
} |
|
392 | 430 |
assert o['uuid'] == user1.uuid |
393 | 431 |
assert o['username'] == user1.username |
394 | 432 |
assert o['first_name'] == user1.first_name |
... | ... | |
399 | 437 |
r1 = {'uuid': role.uuid, 'name': role.name, 'slug': role.slug} |
400 | 438 |
r2 = {'uuid': child_role.uuid, 'name': child_role.name, 'slug': child_role.slug} |
401 | 439 |
assert r == r1 or r == r2 |
402 |
assert len(set(r['uuid'] for r in o['roles'])) == 2
|
|
440 |
assert len({r['uuid'] for r in o['roles']}) == 2
|
|
403 | 441 |
assert o['is_superuser'] is True |
404 | 442 | |
405 | 443 |
notify_agents.reset_mock() |
... | ... | |
411 | 449 |
assert arg == call(ANY) |
412 | 450 |
arg = arg[0][0] |
413 | 451 |
assert isinstance(arg, dict) |
414 |
assert set(arg.keys()) == set(['issuer', 'audience', '@type', 'objects', 'full'])
|
|
452 |
assert set(arg.keys()) == {'issuer', 'audience', '@type', 'objects', 'full'}
|
|
415 | 453 |
assert arg['issuer'] == 'https://%s/idp/saml2/metadata' % tenant.domain_url |
416 | 454 |
assert arg['audience'] == ['http://provider.com'] |
417 | 455 |
assert arg['@type'] == 'provision' |
418 | 456 |
assert arg['full'] is False |
419 | 457 |
objects = arg['objects'] |
420 | 458 |
assert isinstance(objects, dict) |
421 |
assert set(objects.keys()) == set(['data', '@type'])
|
|
459 |
assert set(objects.keys()) == {'data', '@type'}
|
|
422 | 460 |
assert objects['@type'] == 'user' |
423 | 461 |
data = objects['data'] |
424 | 462 |
assert isinstance(data, list) |
425 | 463 |
assert len(data) == 1 |
426 | 464 |
for o in data: |
427 |
assert set(o.keys()) >= set( |
|
428 |
['uuid', 'username', 'first_name', 'is_superuser', 'last_name', 'email', 'roles'] |
|
429 |
) |
|
465 |
assert set(o.keys()) >= { |
|
466 |
'uuid', |
|
467 |
'username', |
|
468 |
'first_name', |
|
469 |
'is_superuser', |
|
470 |
'last_name', |
|
471 |
'email', |
|
472 |
'roles', |
|
473 |
} |
|
430 | 474 |
assert o['uuid'] == user1.uuid |
431 | 475 |
assert o['username'] == user1.username |
432 | 476 |
assert o['first_name'] == user1.first_name |
... | ... | |
438 | 482 |
assert o['is_superuser'] is False |
439 | 483 | |
440 | 484 |
notify_agents.reset_mock() |
441 |
ou2 = get_ou_model().objects.create(name=u'ou2', slug=u'ou2')
|
|
485 |
ou2 = get_ou_model().objects.create(name='ou2', slug='ou2')
|
|
442 | 486 |
LibertyProvider.objects.create( |
443 | 487 |
ou=get_default_ou(), |
444 | 488 |
name='provider2', |
... | ... | |
454 | 498 |
assert arg == call(ANY) |
455 | 499 |
arg = arg[0][0] |
456 | 500 |
assert isinstance(arg, dict) |
457 |
assert set(arg.keys()) == set(['issuer', 'audience', '@type', 'objects', 'full'])
|
|
501 |
assert set(arg.keys()) == {'issuer', 'audience', '@type', 'objects', 'full'}
|
|
458 | 502 |
assert arg['issuer'] == 'https://%s/idp/saml2/metadata' % tenant.domain_url |
459 |
assert set(arg['audience']) == set(['http://provider.com', 'http://provider2.com'])
|
|
503 |
assert set(arg['audience']) == {'http://provider.com', 'http://provider2.com'}
|
|
460 | 504 |
assert arg['@type'] == 'deprovision' |
461 | 505 |
assert arg['full'] is False |
462 | 506 |
objects = arg['objects'] |
463 | 507 |
assert isinstance(objects, dict) |
464 |
assert set(objects.keys()) == set(['data', '@type'])
|
|
508 |
assert set(objects.keys()) == {'data', '@type'}
|
|
465 | 509 |
assert objects['@type'] == 'user' |
466 | 510 |
data = objects['data'] |
467 | 511 |
assert isinstance(data, list) |
468 | 512 |
assert len(data) == 2 |
469 |
assert len(set([o['uuid'] for o in data])) == 2
|
|
513 |
assert len({o['uuid'] for o in data}) == 2
|
|
470 | 514 |
for o in data: |
471 |
assert set(o.keys()) == set(['uuid'])
|
|
515 |
assert set(o.keys()) == {'uuid'}
|
|
472 | 516 |
assert o['uuid'] in users |
473 | 517 | |
474 | 518 |
tests_multipublik/settings.py | ||
---|---|---|
1 | 1 |
import builtins |
2 | 2 |
import os.path |
3 | ||
4 |
from mock import mock_open, patch |
|
3 |
from unittest.mock import mock_open, patch |
|
5 | 4 | |
6 | 5 |
import hobo.test_utils |
7 | 6 |
from hobo.settings import * |
tests_multitenant/settings.py | ||
---|---|---|
1 | 1 |
import builtins |
2 | 2 |
import os |
3 | ||
4 |
from mock import mock_open, patch |
|
3 |
from unittest.mock import mock_open, patch |
|
5 | 4 | |
6 | 5 |
import hobo.test_utils |
7 | 6 |
tests_multitenant/test_agent_worker.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 | 1 |
import importlib |
3 | 2 |
import json |
4 | 3 |
import os |
4 |
from unittest import mock |
|
5 | 5 | |
6 |
import mock |
|
7 | 6 |
import pytest |
8 | 7 |
from django.utils.encoding import force_text |
9 | 8 | |
... | ... | |
11 | 10 |
from hobo.agent.worker.services import deploy, notify |
12 | 11 | |
13 | 12 |
ENVIRONMENT = { |
14 |
u'timestamp': '2022-02-22',
|
|
15 |
u'services': [
|
|
13 |
'timestamp': '2022-02-22', |
|
14 |
'services': [ |
|
16 | 15 |
{ |
17 |
u'service-id': u'hobo',
|
|
18 |
u'slug': u'hobo',
|
|
19 |
u'title': u'Hobo primary',
|
|
20 |
u'base_url': u'https://hobo1.dev.publik.love/',
|
|
21 |
u'this': True,
|
|
22 |
u'secret_key': u'1nesüper5Cr!eteKAaY~',
|
|
16 |
'service-id': 'hobo',
|
|
17 |
'slug': 'hobo',
|
|
18 |
'title': 'Hobo primary',
|
|
19 |
'base_url': 'https://hobo1.dev.publik.love/',
|
|
20 |
'this': True, |
|
21 |
'secret_key': '1nesüper5Cr!eteKAaY~',
|
|
23 | 22 |
}, |
24 | 23 |
{ |
25 |
u'service-id': u'combo',
|
|
26 |
u'slug': u'portal',
|
|
27 |
u'title': u'Compte citoyen',
|
|
28 |
u'base_url': u'https://combo.dev.publik.love/',
|
|
29 |
u'secret_key': u'1nesüper5Cr!eteKAaY~',
|
|
24 |
'service-id': 'combo',
|
|
25 |
'slug': 'portal',
|
|
26 |
'title': 'Compte citoyen',
|
|
27 |
'base_url': 'https://combo.dev.publik.love/',
|
|
28 |
'secret_key': '1nesüper5Cr!eteKAaY~',
|
|
30 | 29 |
}, |
31 | 30 |
{ |
32 |
u'service-id': u'wcs',
|
|
33 |
u'slug': u'eservices',
|
|
34 |
u'title': u'Démarches',
|
|
35 |
u'base_url': u'https://wcs.dev.publik.love/',
|
|
36 |
u'secret_key': u'1nesüper5Cr!eteKAaY~',
|
|
31 |
'service-id': 'wcs',
|
|
32 |
'slug': 'eservices',
|
|
33 |
'title': 'Démarches',
|
|
34 |
'base_url': 'https://wcs.dev.publik.love/',
|
|
35 |
'secret_key': '1nesüper5Cr!eteKAaY~',
|
|
37 | 36 |
}, |
38 | 37 |
{ |
39 |
u'service-id': u'hobo',
|
|
40 |
u'slug': u'hobo',
|
|
41 |
u'title': u'skip beacause of agent host patterns',
|
|
42 |
u'base_url': u'https://hobo2.dev.publik.love/',
|
|
43 |
u'secondary': True,
|
|
44 |
u'secret_key': u'1nesüper5Cr!eteKAaY~',
|
|
38 |
'service-id': 'hobo',
|
|
39 |
'slug': 'hobo',
|
|
40 |
'title': 'skip beacause of agent host patterns',
|
|
41 |
'base_url': 'https://hobo2.dev.publik.love/',
|
|
42 |
'secondary': True, |
|
43 |
'secret_key': '1nesüper5Cr!eteKAaY~',
|
|
45 | 44 |
}, |
46 | 45 |
{ |
47 |
u'service-id': u'passerelle',
|
|
48 |
u'slug': u'passerelle',
|
|
49 |
u'title': u'skipped because no secret_key',
|
|
50 |
u'base_url': u'https://passerelle.dev.publik.love/',
|
|
46 |
'service-id': 'passerelle',
|
|
47 |
'slug': 'passerelle',
|
|
48 |
'title': 'skipped because no secret_key',
|
|
49 |
'base_url': 'https://passerelle.dev.publik.love/',
|
|
51 | 50 |
}, |
52 | 51 |
{ |
53 |
u'service-id': u'unknown',
|
|
54 |
u'title': u'skipped because unknown service-id',
|
|
52 |
'service-id': 'unknown',
|
|
53 |
'title': 'skipped because unknown service-id',
|
|
55 | 54 |
}, |
56 | 55 |
], |
57 | 56 |
} |
... | ... | |
96 | 95 |
deploy(ENVIRONMENT) |
97 | 96 | |
98 | 97 |
# process called |
99 |
mock_calls = set(x[1][0] for x in mocked_subprocess.Popen.mock_calls)
|
|
98 |
mock_calls = {x[1][0] for x in mocked_subprocess.Popen.mock_calls}
|
|
100 | 99 |
assert len(mock_calls) == 4 |
101 | 100 |
assert '/usr/bin/hobo-manage hobo_deploy https://hobo1.dev.publik.love/ -' in mock_calls |
102 | 101 |
assert '/usr/bin/wcsctl hobo_deploy https://wcs.dev.publik.love/ -' in mock_calls |
... | ... | |
125 | 124 |
importlib.reload(settings) |
126 | 125 |
deploy(ENVIRONMENT) |
127 | 126 |
# process called |
128 |
mock_calls = set(x[1][0] for x in mocked_subprocess.Popen.mock_calls)
|
|
127 |
mock_calls = {x[1][0] for x in mocked_subprocess.Popen.mock_calls}
|
|
129 | 128 |
assert len(mock_calls) == 3 |
130 | 129 |
assert '/usr/bin/hobo-manage hobo_deploy https://hobo1.dev.publik.love/ -' in mock_calls |
131 | 130 |
assert '/usr/bin/wcsctl hobo_deploy https://wcs.dev.publik.love/ -' in mock_calls |
... | ... | |
146 | 145 |
notify(NOTIFICATION) |
147 | 146 | |
148 | 147 |
# process called |
149 |
mock_calls = set(x[1][0] for x in mocked_subprocess.Popen.mock_calls)
|
|
148 |
mock_calls = {x[1][0] for x in mocked_subprocess.Popen.mock_calls}
|
|
150 | 149 |
assert mock_calls == {'/usr/lib/combo/manage.py hobo_notify -'} |
151 | 150 | |
152 | 151 |
# notification sent |
tests_multitenant/test_create_tenant.py | ||
---|---|---|
14 | 14 |
# You should have received a copy of the GNU Affero General Public License |
15 | 15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | 16 | |
17 |
import mock |
|
17 |
from unittest import mock |
|
18 | ||
18 | 19 |
import pytest |
19 | 20 |
from django.contrib.auth.models import User |
20 | 21 |
from django.core.management import call_command |
tests_multitenant/test_hobo_notify.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 | ||
3 | 1 |
import logging |
4 | 2 | |
5 | 3 |
import pytest |
... | ... | |
20 | 18 |
for tenant in tenants: |
21 | 19 |
with tenant_context(tenant): |
22 | 20 |
notification = { |
23 |
u'@type': u'provision',
|
|
24 |
u'audience': [u'http://coin.com/saml/metadata'],
|
|
25 |
u'objects': {
|
|
26 |
u'@type': 'role',
|
|
27 |
u'data': [
|
|
21 |
'@type': 'provision',
|
|
22 |
'audience': ['http://coin.com/saml/metadata'],
|
|
23 |
'objects': { |
|
24 |
'@type': 'role', |
|
25 |
'data': [ |
|
28 | 26 |
{ |
29 |
u'uuid': u'12345',
|
|
30 |
u'name': u'Service petite enfance',
|
|
31 |
u'slug': u'service-petite-enfance',
|
|
32 |
u'description': u'Role du service petite enfance %s' % tenant.domain_url,
|
|
27 |
'uuid': '12345',
|
|
28 |
'name': 'Service petite enfance',
|
|
29 |
'slug': 'service-petite-enfance',
|
|
30 |
'description': 'Role du service petite enfance %s' % tenant.domain_url,
|
|
33 | 31 |
} |
34 | 32 |
], |
35 | 33 |
}, |
... | ... | |
42 | 40 |
for tenant in tenants: |
43 | 41 |
with tenant_context(tenant): |
44 | 42 |
notification = { |
45 |
u'@type': u'provision',
|
|
46 |
u'audience': [u'%s/saml/metadata' % tenant.get_base_url()],
|
|
47 |
u'objects': {
|
|
48 |
u'@type': 'role',
|
|
49 |
u'data': [
|
|
43 |
'@type': 'provision',
|
|
44 |
'audience': ['%s/saml/metadata' % tenant.get_base_url()],
|
|
45 |
'objects': { |
|
46 |
'@type': 'role', |
|
47 |
'data': [ |
|
50 | 48 |
{ |
51 |
u'uuid': u'12345',
|
|
52 |
u'name': u'Service petite enfance',
|
|
53 |
u'slug': u'service-petite-enfance',
|
|
54 |
u'description': u'Role du service petite enfance %s' % tenant.domain_url,
|
|
55 |
u'details': u'Some details',
|
|
56 |
u'emails': [u'foo@bar.com', u'test@entrouvert.org'],
|
|
57 |
u'emails_to_members': False,
|
|
49 |
'uuid': '12345',
|
|
50 |
'name': 'Service petite enfance',
|
|
51 |
'slug': 'service-petite-enfance',
|
|
52 |
'description': 'Role du service petite enfance %s' % tenant.domain_url,
|
|
53 |
'details': 'Some details',
|
|
54 |
'emails': ['foo@bar.com', 'test@entrouvert.org'],
|
|
55 |
'emails_to_members': False, |
|
58 | 56 |
} |
59 | 57 |
], |
60 | 58 |
}, |
... | ... | |
63 | 61 |
assert Group.objects.count() == 1 |
64 | 62 |
assert Role.objects.count() == 1 |
65 | 63 |
role = Role.objects.get() |
66 |
assert role.uuid == u'12345'
|
|
67 |
assert role.name == u'Service petite enfance'
|
|
68 |
assert role.description == u'Role du service petite enfance %s' % tenant.domain_url
|
|
69 |
assert role.details == u'Some details'
|
|
70 |
assert role.emails == [u'foo@bar.com', u'test@entrouvert.org']
|
|
64 |
assert role.uuid == '12345' |
|
65 |
assert role.name == 'Service petite enfance' |
|
66 |
assert role.description == 'Role du service petite enfance %s' % tenant.domain_url |
|
67 |
assert role.details == 'Some details' |
|
68 |
assert role.emails == ['foo@bar.com', 'test@entrouvert.org']
|
|
71 | 69 |
assert role.emails_to_members is False |
72 | 70 | |
73 | 71 |
# test full provisionning |
74 | 72 |
for tenant in tenants: |
75 | 73 |
with tenant_context(tenant): |
76 | 74 |
notification = { |
77 |
u'@type': u'provision',
|
|
78 |
u'full': True,
|
|
79 |
u'audience': [u'%s/saml/metadata' % tenant.get_base_url()],
|
|
80 |
u'objects': {
|
|
81 |
u'@type': 'role',
|
|
82 |
u'data': [
|
|
75 |
'@type': 'provision',
|
|
76 |
'full': True, |
|
77 |
'audience': ['%s/saml/metadata' % tenant.get_base_url()],
|
|
78 |
'objects': { |
|
79 |
'@type': 'role', |
|
80 |
'data': [ |
|
83 | 81 |
{ |
84 |
u'uuid': u'xyz',
|
|
85 |
u'name': u'Service état civil',
|
|
86 |
u'slug': u'service-etat-civil',
|
|
87 |
u'description': u'Role du service état civil %s' % tenant.domain_url,
|
|
82 |
'uuid': 'xyz',
|
|
83 |
'name': 'Service état civil',
|
|
84 |
'slug': 'service-etat-civil',
|
|
85 |
'description': 'Role du service état civil %s' % tenant.domain_url,
|
|
88 | 86 |
} |
89 | 87 |
], |
90 | 88 |
}, |
... | ... | |
93 | 91 |
assert Group.objects.count() == 1 |
94 | 92 |
assert Role.objects.count() == 1 |
95 | 93 |
role = Role.objects.get() |
96 |
assert role.uuid == u'xyz'
|
|
97 |
assert role.name == u'Service état civil'
|
|
98 |
assert role.description == u'Role du service état civil %s' % tenant.domain_url
|
|
94 |
assert role.uuid == 'xyz' |
|
95 |
assert role.name == 'Service état civil' |
|
96 |
assert role.description == 'Role du service état civil %s' % tenant.domain_url |
|
99 | 97 | |
100 | 98 |
# test deprovision |
101 | 99 |
for tenant in tenants: |
102 | 100 |
with tenant_context(tenant): |
103 | 101 |
notification = { |
104 |
u'@type': u'deprovision',
|
|
105 |
u'audience': [u'%s/saml/metadata' % tenant.get_base_url()],
|
|
106 |
u'objects': {
|
|
107 |
u'@type': 'role',
|
|
108 |
u'data': [
|
|
102 |
'@type': 'deprovision',
|
|
103 |
'audience': ['%s/saml/metadata' % tenant.get_base_url()],
|
|
104 |
'objects': { |
|
105 |
'@type': 'role', |
|
106 |
'data': [ |
|
109 | 107 |
{ |
110 |
u'uuid': u'xyz',
|
|
111 |
u'name': u'Service état civil',
|
|
112 |
u'slug': u'service-etat-civil',
|
|
113 |
u'description': u'Role du service état civil %s' % tenant.domain_url,
|
|
108 |
'uuid': 'xyz',
|
|
109 |
'name': 'Service état civil',
|
|
110 |
'slug': 'service-etat-civil',
|
|
111 |
'description': 'Role du service état civil %s' % tenant.domain_url,
|
|
114 | 112 |
} |
115 | 113 |
], |
116 | 114 |
}, |
... | ... | |
123 | 121 |
for tenant in tenants: |
124 | 122 |
with tenant_context(tenant): |
125 | 123 |
notification = { |
126 |
u'@type': u'provision',
|
|
127 |
u'audience': [u'%s/saml/metadata' % tenant.get_base_url()],
|
|
128 |
u'objects': {
|
|
129 |
u'@type': 'role',
|
|
130 |
u'data': [
|
|
124 |
'@type': 'provision',
|
|
125 |
'audience': ['%s/saml/metadata' % tenant.get_base_url()],
|
|
126 |
'objects': { |
|
127 |
'@type': 'role', |
|
128 |
'data': [ |
|
131 | 129 |
{ |
132 |
u'uuid': u'12345',
|
|
133 |
u'name': u'Service petite enfance',
|
|
134 |
u'slug': u'service-petite-enfance',
|
|
135 |
u'description': u'Role du service petite enfance %s' % tenant.domain_url,
|
|
130 |
'uuid': '12345',
|
|
131 |
'name': 'Service petite enfance',
|
|
132 |
'slug': 'service-petite-enfance',
|
|
133 |
'description': 'Role du service petite enfance %s' % tenant.domain_url,
|
|
136 | 134 |
} |
137 | 135 |
], |
138 | 136 |
}, |
... | ... | |
142 | 140 |
assert Role.objects.count() == 1 |
143 | 141 |
# test update by uuid |
144 | 142 |
notification = { |
145 |
u'@type': u'provision',
|
|
146 |
u'audience': [u'%s/saml/metadata' % tenant.get_base_url()],
|
|
147 |
u'objects': {
|
|
148 |
u'@type': 'role',
|
|
149 |
u'data': [
|
|
143 |
'@type': 'provision',
|
|
144 |
'audience': ['%s/saml/metadata' % tenant.get_base_url()],
|
|
145 |
'objects': { |
|
146 |
'@type': 'role', |
|
147 |
'data': [ |
|
150 | 148 |
{ |
151 |
u'uuid': u'12345',
|
|
152 |
u'name': u'Service petite enfance2',
|
|
153 |
u'slug': u'service-petite-enfance2',
|
|
154 |
u'description': u'Role du service petite enfance %s' % tenant.domain_url,
|
|
149 |
'uuid': '12345',
|
|
150 |
'name': 'Service petite enfance2',
|
|
151 |
'slug': 'service-petite-enfance2',
|
|
152 |
'description': 'Role du service petite enfance %s' % tenant.domain_url,
|
|
155 | 153 |
} |
156 | 154 |
], |
157 | 155 |
}, |
... | ... | |
162 | 160 |
assert Role.objects.get().name == notification['objects']['data'][0]['name'] |
163 | 161 |
# test uuid change |
164 | 162 |
notification = { |
165 |
u'@type': u'provision',
|
|
166 |
u'audience': [u'%s/saml/metadata' % tenant.get_base_url()],
|
|
167 |
u'objects': {
|
|
168 |
u'@type': 'role',
|
|
169 |
u'data': [
|
|
163 |
'@type': 'provision',
|
|
164 |
'audience': ['%s/saml/metadata' % tenant.get_base_url()],
|
|
165 |
'objects': { |
|
166 |
'@type': 'role', |
|
167 |
'data': [ |
|
170 | 168 |
{ |
171 |
u'uuid': u'xyz',
|
|
172 |
u'name': u'Service petite enfance2',
|
|
173 |
u'slug': u'service-petite-enfance2',
|
|
174 |
u'description': u'Role du service petite enfance %s' % tenant.domain_url,
|
|
169 |
'uuid': 'xyz',
|
|
170 |
'name': 'Service petite enfance2',
|
|
171 |
'slug': 'service-petite-enfance2',
|
|
172 |
'description': 'Role du service petite enfance %s' % tenant.domain_url,
|
|
175 | 173 |
} |
176 | 174 |
], |
177 | 175 |
}, |
... | ... | |
184 | 182 |
Role.objects.create(uuid='12345', name='Foo', description='foo') |
185 | 183 |
assert Role.objects.count() == 2 |
186 | 184 |
notification = { |
187 |
u'@type': u'provision',
|
|
188 |
u'audience': [u'%s/saml/metadata' % tenant.get_base_url()],
|
|
189 |
u'objects': {
|
|
190 |
u'@type': 'role',
|
|
191 |
u'data': [
|
|
185 |
'@type': 'provision',
|
|
186 |
'audience': ['%s/saml/metadata' % tenant.get_base_url()],
|
|
187 |
'objects': { |
|
188 |
'@type': 'role', |
|
189 |
'data': [ |
|
192 | 190 |
{ |
193 |
u'uuid': u'12345',
|
|
194 |
u'name': u'Service petite enfance2',
|
|
195 |
u'slug': u'service-petite-enfance2',
|
|
196 |
u'description': u'Role du service petite enfance %s' % tenant.domain_url,
|
|
191 |
'uuid': '12345',
|
|
192 |
'name': 'Service petite enfance2',
|
|
193 |
'slug': 'service-petite-enfance2',
|
|
194 |
'description': 'Role du service petite enfance %s' % tenant.domain_url,
|
|
197 | 195 |
} |
198 | 196 |
], |
199 | 197 |
}, |
... | ... | |
201 | 199 |
Command.process_notification(tenant, notification) |
202 | 200 |
assert Group.objects.count() == 2 |
203 | 201 |
assert Role.objects.count() == 2 |
204 |
assert Role.objects.filter(uuid='12345', name=u'Service petite enfance').count() == 0
|
|
202 |
assert Role.objects.filter(uuid='12345', name='Service petite enfance').count() == 0 |
|
205 | 203 |
assert caplog.records[-1].levelno == logging.ERROR |
206 | 204 |
assert caplog.records[-1].msg.startswith('cannot provision') |
207 |
assert caplog.records[-1].args == (u'Service petite enfance2', u'12345')
|
|
205 |
assert caplog.records[-1].args == ('Service petite enfance2', '12345')
|
|
208 | 206 | |
209 | 207 | |
210 | 208 |
def test_hobo_notify_roles_db_queries(caplog, tenants): |
... | ... | |
358 | 356 |
for tenant in tenants: |
359 | 357 |
with tenant_context(tenant): |
360 | 358 |
notification = { |
361 |
u'@type': u'provision',
|
|
362 |
u'audience': [u'%s/saml/metadata' % tenant.get_base_url()],
|
|
363 |
u'objects': {
|
|
364 |
u'@type': 'role',
|
|
365 |
u'data': [
|
|
359 |
'@type': 'provision',
|
|
360 |
'audience': ['%s/saml/metadata' % tenant.get_base_url()],
|
|
361 |
'objects': { |
|
362 |
'@type': 'role', |
|
363 |
'data': [ |
|
366 | 364 |
{ |
367 |
u'uuid': u'12345',
|
|
368 |
u'name': u'Service petite enfance',
|
|
369 |
u'slug': u'service-petite-enfance',
|
|
370 |
u'description': u'Role du service petite enfance %s' % tenant.domain_url,
|
|
365 |
'uuid': '12345',
|
|
366 |
'name': 'Service petite enfance',
|
|
367 |
'slug': 'service-petite-enfance',
|
|
368 |
'description': 'Role du service petite enfance %s' % tenant.domain_url,
|
|
371 | 369 |
} |
372 | 370 |
], |
373 | 371 |
}, |
... | ... | |
376 | 374 |
assert Group.objects.count() == 1 |
377 | 375 |
assert Role.objects.count() == 1 |
378 | 376 |
role = Role.objects.get() |
379 |
assert role.uuid == u'12345'
|
|
380 |
assert role.name == u'Service petite enfance'
|
|
381 |
assert role.description == u'Role du service petite enfance %s' % tenant.domain_url
|
|
377 |
assert role.uuid == '12345' |
|
378 |
assert role.name == 'Service petite enfance' |
|
379 |
assert role.description == 'Role du service petite enfance %s' % tenant.domain_url |
|
382 | 380 | |
383 | 381 |
# test user provisionning |
384 | 382 |
for tenant in tenants: |
385 | 383 |
with tenant_context(tenant): |
386 | 384 |
notification = { |
387 |
u'@type': u'provision',
|
|
388 |
u'issuer': 'http://idp.example.net/idp/saml/metadata',
|
|
389 |
u'audience': [u'%s/saml/metadata' % tenant.get_base_url()],
|
|
390 |
u'objects': {
|
|
391 |
u'@type': 'user',
|
|
392 |
u'data': [
|
|
385 |
'@type': 'provision',
|
|
386 |
'issuer': 'http://idp.example.net/idp/saml/metadata', |
|
387 |
'audience': ['%s/saml/metadata' % tenant.get_base_url()],
|
|
388 |
'objects': { |
|
389 |
'@type': 'user', |
|
390 |
'data': [ |
|
393 | 391 |
{ |
394 |
u'uuid': u'a' * 32,
|
|
395 |
u'first_name': u'John',
|
|
396 |
u'last_name': u'Doe',
|
|
397 |
u'email': u'john.doe@example.net',
|
|
398 |
u'is_superuser': False,
|
|
399 |
u'roles': [
|
|
392 |
'uuid': 'a' * 32,
|
|
393 |
'first_name': 'John',
|
|
394 |
'last_name': 'Doe',
|
|
395 |
'email': 'john.doe@example.net',
|
|
396 |
'is_superuser': False, |
|
397 |
'roles': [ |
|
400 | 398 |
{ |
401 |
u'uuid': u'12345',
|
|
402 |
u'name': u'Service petite enfance',
|
|
403 |
u'description': u'etc.',
|
|
399 |
'uuid': '12345',
|
|
400 |
'name': 'Service petite enfance',
|
|
401 |
'description': 'etc.',
|
|
404 | 402 |
}, |
405 | 403 |
{ |
406 |
u'uuid': u'xyz',
|
|
407 |
u'name': u'Service état civil',
|
|
408 |
u'description': u'etc.',
|
|
404 |
'uuid': 'xyz',
|
|
405 |
'name': 'Service état civil',
|
|
406 |
'description': 'etc.',
|
|
409 | 407 |
}, |
410 | 408 |
], |
411 | 409 |
} |
... | ... | |
437 | 435 |
for tenant in tenants: |
438 | 436 |
with tenant_context(tenant): |
439 | 437 |
notification = { |
440 |
u'@type': u'provision',
|
|
441 |
u'issuer': 'http://idp.example.net/idp/saml/metadata',
|
|
442 |
u'audience': [u'%s/saml/metadata' % tenant.get_base_url()],
|
|
443 |
u'objects': {
|
|
444 |
u'@type': 'user',
|
|
445 |
u'data': [
|
|
438 |
'@type': 'provision',
|
|
439 |
'issuer': 'http://idp.example.net/idp/saml/metadata', |
|
440 |
'audience': ['%s/saml/metadata' % tenant.get_base_url()],
|
|
441 |
'objects': { |
|
442 |
'@type': 'user', |
|
443 |
'data': [ |
|
446 | 444 |
{ |
447 |
u'uuid': u'a' * 32,
|
|
448 |
u'first_name': u'John',
|
|
449 |
u'last_name': u'Doe',
|
|
450 |
u'email': u'john.doe@example.net',
|
|
451 |
u'is_superuser': True,
|
|
452 |
u'roles': [
|
|
445 |
'uuid': 'a' * 32,
|
|
446 |
'first_name': 'John',
|
|
447 |
'last_name': 'Doe',
|
|
448 |
'email': 'john.doe@example.net',
|
|
449 |
'is_superuser': True, |
|
450 |
'roles': [ |
|
453 | 451 |
{ |
454 |
u'uuid': u'12345',
|
|
455 |
u'name': u'Service petite enfance',
|
|
456 |
u'description': u'etc.',
|
|
452 |
'uuid': '12345',
|
|
453 |
'name': 'Service petite enfance',
|
|
454 |
'description': 'etc.',
|
|
457 | 455 |
}, |
458 | 456 |
{ |
459 |
u'uuid': u'xyz',
|
|
460 |
u'name': u'Service état civil',
|
|
461 |
u'description': u'etc.',
|
|
457 |
'uuid': 'xyz',
|
|
458 |
'name': 'Service état civil',
|
|
459 |
'description': 'etc.',
|
|
462 | 460 |
}, |
463 | 461 |
], |
464 | 462 |
} |
... | ... | |
490 | 488 |
for tenant in tenants: |
491 | 489 |
with tenant_context(tenant): |
492 | 490 |
notification = { |
493 |
u'@type': u'deprovision',
|
|
494 |
u'issuer': 'http://idp.example.net/idp/saml/metadata',
|
|
495 |
u'audience': [u'%s/saml/metadata' % tenant.get_base_url()],
|
|
496 |
u'objects': {
|
|
497 |
u'@type': 'user',
|
|
498 |
u'data': [
|
|
491 |
'@type': 'deprovision',
|
|
492 |
'issuer': 'http://idp.example.net/idp/saml/metadata', |
|
493 |
'audience': ['%s/saml/metadata' % tenant.get_base_url()],
|
|
494 |
'objects': { |
|
495 |
'@type': 'user', |
|
496 |
'data': [ |
|
499 | 497 |
{ |
500 |
u'uuid': u'a' * 32,
|
|
498 |
'uuid': 'a' * 32,
|
|
501 | 499 |
} |
502 | 500 |
], |
503 | 501 |
}, |
tests_multitenant/test_middleware.py | ||
---|---|---|
1 |
from __future__ import unicode_literals |
|
2 | ||
3 | 1 |
import pytest |
4 | 2 | |
5 | 3 |
from hobo.multitenant.middleware import TenantMiddleware |
tests_multitenant/test_settings.py | ||
---|---|---|
193 | 193 |
assert 'authentic' in settings.KNOWN_SERVICES |
194 | 194 |
assert 'other' in settings.KNOWN_SERVICES['authentic'] |
195 | 195 |
authentic_other_keys = set(settings.KNOWN_SERVICES['authentic']['other'].keys()) |
196 |
assert ( |
|
197 |
set( |
|
198 |
[ |
|
199 |
'url', |
|
200 |
'backoffice-menu-url', |
|
201 |
'title', |
|
202 |
'orig', |
|
203 |
'verif_orig', |
|
204 |
'secret', |
|
205 |
'template_name', |
|
206 |
'variables', |
|
207 |
'saml-sp-metadata-url', |
|
208 |
'provisionning-url', |
|
209 |
'secondary', |
|
210 |
] |
|
211 |
) |
|
212 |
== authentic_other_keys |
|
213 |
) |
|
196 |
assert { |
|
197 |
'url', |
|
198 |
'backoffice-menu-url', |
|
199 |
'title', |
|
200 |
'orig', |
|
201 |
'verif_orig', |
|
202 |
'secret', |
|
203 |
'template_name', |
|
204 |
'variables', |
|
205 |
'saml-sp-metadata-url', |
|
206 |
'provisionning-url', |
|
207 |
'secondary', |
|
208 |
} == authentic_other_keys |
|
214 | 209 |
assert ( |
215 | 210 |
settings.KNOWN_SERVICES['authentic']['other']['url'] == hobo_json['services'][2]['base_url'] |
216 | 211 |
) |
tests_multitenant/test_tenant_command.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 | ||
3 | 1 |
import json |
4 | 2 |
import os |
5 | 3 |
import sys |
4 |
from unittest import mock |
|
6 | 5 | |
7 |
import mock |
|
8 | 6 |
import pytest |
9 | 7 |
from django.core.management import BaseCommand, call_command, load_command_class |
10 | 8 |
from django.core.management.base import CommandError |
... | ... | |
15 | 13 |
pytestmark = pytest.mark.django_db |
16 | 14 | |
17 | 15 | |
18 |
class RecordTenant(object):
|
|
16 |
class RecordTenant: |
|
19 | 17 |
def __init__(self): |
20 | 18 |
self.tenants = [] |
21 | 19 | |
... | ... | |
41 | 39 |
execute_from_command_line(['manage.py', 'tenant_command', 'clearsessions', '--all-tenants']) |
42 | 40 |
assert handle.call_count == 2 |
43 | 41 |
assert len(handle.side_effect.tenants) == 2 |
44 |
assert set(tenant.domain_url for tenant in handle.side_effect.tenants) == set( |
|
45 |
['tenant1.example.net', 'tenant2.example.net'] |
|
46 |
) |
|
42 |
assert {tenant.domain_url for tenant in handle.side_effect.tenants} == { |
|
43 |
'tenant1.example.net', |
|
44 |
'tenant2.example.net', |
|
45 |
} |
|
47 | 46 | |
48 | 47 | |
49 | 48 |
@mock.patch('django.contrib.sessions.management.commands.clearsessions.Command.handle') |
... | ... | |
127 | 126 | |
128 | 127 |
class UnicodeErrorCommand(BaseCommand): |
129 | 128 |
def handle(self, *args, **kwargs): |
130 |
raise Exception(u'héhé')
|
|
129 |
raise Exception('héhé') |
|
131 | 130 | |
132 | 131 |
class BytesErrorCommand(BaseCommand): |
133 | 132 |
def handle(self, *args, **kwargs): |
... | ... | |
135 | 134 | |
136 | 135 |
class MixOfBothCommand(BaseCommand): |
137 | 136 |
def handle(self, *args, **kwargs): |
138 |
raise Exception([force_bytes('héhé'), u'hého'])
|
|
137 |
raise Exception([force_bytes('héhé'), 'hého']) |
|
139 | 138 | |
140 | 139 |
class WtfExceptionCommand(BaseCommand): |
141 | 140 |
def handle(self, *args, **kwargs): |
... | ... | |
166 | 165 |
with pytest.raises(SystemExit): |
167 | 166 |
klass.run_from_argv(['manage.py', 'tenant_command', 'uni-error', '--all-tenants']) |
168 | 167 |
captured = capsys.readouterr() |
169 |
assert u'Tenant tenant1.example.net (tenant1_example_net): Exception: héhé' in captured.err
|
|
170 |
assert u'Tenant tenant2.example.net (tenant2_example_net): Exception: héhé' in captured.err
|
|
171 |
assert u'Command failed on multiple tenants' in captured.err
|
|
168 |
assert 'Tenant tenant1.example.net (tenant1_example_net): Exception: héhé' in captured.err |
|
169 |
assert 'Tenant tenant2.example.net (tenant2_example_net): Exception: héhé' in captured.err |
|
170 |
assert 'Command failed on multiple tenants' in captured.err |
|
172 | 171 | |
173 | 172 |
with pytest.raises(SystemExit): |
174 | 173 |
klass.run_from_argv(['manage.py', 'tenant_command', 'bytes-error', '--all-tenants']) |
... | ... | |
181 | 180 | |
182 | 181 |
captured = capsys.readouterr() |
183 | 182 |
assert repr(force_bytes('héhé')) in captured.err |
184 |
assert repr(u'hého') in captured.err
|
|
183 |
assert repr('hého') in captured.err |
|
185 | 184 | |
186 | 185 |
with pytest.raises(SystemExit): |
187 | 186 |
klass.run_from_argv(['manage.py', 'tenant_command', 'wtf-error', '--all-tenants']) |
tests_multitenant/test_uwsgidecorators.py | ||
---|---|---|
1 | 1 |
import importlib |
2 | 2 |
import pickle |
3 |
from unittest import mock |
|
3 | 4 | |
4 |
import mock |
|
5 | 5 |
import pytest |
6 | 6 | |
7 | 7 |
import hobo.multitenant.uwsgidecorators |
tests_multitenant/utilities.py | ||
---|---|---|
1 |
class PatchDefaultSettings(object):
|
|
1 |
class PatchDefaultSettings: |
|
2 | 2 |
empty = object() |
3 | 3 | |
4 | 4 |
def __init__(self, settings, **kwargs): |
tests_passerelle/settings.py | ||
---|---|---|
1 | 1 |
import builtins |
2 | 2 |
import os |
3 | ||
4 |
from mock import mock_open, patch |
|
3 |
from unittest.mock import mock_open, patch |
|
5 | 4 | |
6 | 5 |
import hobo.test_utils |
7 | 6 |
tests_schemas/test_cook.py | ||
---|---|---|
39 | 39 |
# below JSON file was created by this instruction |
40 | 40 |
# json.dump(environment, open('tests_schemas/example_env.json', 'w'), |
41 | 41 |
# sort_keys=True, indent=4, separators=(',', ': ')) |
42 |
expected_env = json.load(open('tests_schemas/example_env.json', 'r'))
|
|
42 |
expected_env = json.load(open('tests_schemas/example_env.json')) |
|
43 | 43 | |
44 | 44 |
# remove secret_key and timestamp values that alway change |
45 | 45 |
environment['timestamp'] = 'XXXXXXXXXX.XX' |
tests_schemas/test_hobo_deploy.py | ||
---|---|---|
1 | 1 |
import os |
2 |
from unittest import mock |
|
2 | 3 | |
3 |
import mock |
|
4 | 4 |
import pytest |
5 | 5 |
from django.core.management import call_command, get_commands, load_command_class |
6 | 6 |
from tenant_schemas.utils import tenant_context |
tests_schemas/test_import_template.py | ||
---|---|---|
1 | 1 |
import os |
2 |
from unittest import mock |
|
2 | 3 | |
3 |
import mock |
|
4 | 4 |
import pytest |
5 | 5 |
from django.core.management import call_command, load_command_class |
6 | 6 |
tests_schemas/test_rename_hobo_service.py | ||
---|---|---|
1 |
from unittest.mock import Mock |
|
2 | ||
1 | 3 |
import pytest |
2 | 4 |
from django.core.management import call_command |
3 | 5 |
from django.core.management.base import CommandError |
4 |
from mock import Mock |
|
5 | 6 |
from tenant_schemas.utils import tenant_context |
6 | 7 | |
7 | 8 |
from hobo.environment.models import Passerelle, ServiceBase |
tests_schemas/test_rename_service.py | ||
---|---|---|
1 |
from unittest.mock import Mock |
|
2 | ||
1 | 3 |
import pytest |
2 | 4 |
from django.core.management import call_command |
3 | 5 |
from django.core.management.base import CommandError |
4 |
from mock import Mock |
|
5 | 6 |
from tenant_schemas.utils import tenant_context |
6 | 7 | |
7 | 8 |
from hobo.environment.models import Passerelle, ServiceBase |
8 |
- |