From d4052daa75b81bd1b902bd1d1c4ba2aef7570f85 Mon Sep 17 00:00:00 2001 From: Paul Marillonnet Date: Wed, 4 Mar 2020 14:31:36 +0100 Subject: [PATCH 2/2] python3: migrate authentic (#40407) --- hobo/agent/authentic2/provisionning.py | 25 +- hobo/multitenant/settings_loaders.py | 9 +- .../data_authentic_export_site.json | 486 +++++++++++------- tests_authentic/settings.py | 2 + tests_authentic/test_hobo_deploy.py | 43 +- tests_authentic/test_rest_authentication.py | 2 +- 6 files changed, 333 insertions(+), 234 deletions(-) diff --git a/hobo/agent/authentic2/provisionning.py b/hobo/agent/authentic2/provisionning.py index 16b2421..078dd4b 100644 --- a/hobo/agent/authentic2/provisionning.py +++ b/hobo/agent/authentic2/provisionning.py @@ -1,5 +1,5 @@ import json -from urlparse import urljoin +from django.utils.six.moves.urllib.parse import urljoin import threading import copy import logging @@ -8,6 +8,7 @@ from django.contrib.auth import get_user_model from django.db import connection from django.core.urlresolvers import reverse from django.conf import settings +from django.utils.encoding import force_text from django_rbac.utils import get_role_model, get_ou_model, get_role_parenting_model from hobo.agent.common import notify_agents @@ -25,9 +26,9 @@ logger = logging.getLogger(__name__) class Provisionning(threading.local): __slots__ = ['threads'] - threads = set() def __init__(self): + self.threads = set() self.stack = [] def start(self): @@ -100,7 +101,7 @@ class Provisionning(threading.local): def is_forbidden_technical_role(role): return role.slug.startswith('_') and not role.slug.startswith(tuple(allowed_technical_roles_prefixes)) - issuer = unicode(self.get_entity_id()) + issuer = force_text(self.get_entity_id()) if mode == 'provision': def user_to_json(ou, service, user, user_roles): @@ -151,8 +152,8 @@ class Provisionning(threading.local): for rp in RoleParenting.objects.filter(child__in=all_roles): parents.setdefault(rp.child.id, []).append(rp.parent.id) Through = Role.members.through - for u_id, r_id in Through.objects.filter(role__members__in=users).values_list('user_id', - 'role_id'): + qs = Through.objects.filter(role__members__in=users).values_list('user_id', 'role_id') + for u_id, r_id in qs: user_roles.setdefault(u_id, set()).add(roles[r_id]) for p_id in parents.get(r_id, []): user_roles[u_id].add(roles[p_id]) @@ -163,7 +164,7 @@ class Provisionning(threading.local): ous.setdefault(r.ou, set()).add(user) if roles_with_attributes: - for ou, users in ous.iteritems(): + for ou, users in ous.items(): for service, audience in self.get_audience(ou): for user in users: logger.info(u'provisionning user %s to %s', user, audience) @@ -178,12 +179,12 @@ class Provisionning(threading.local): } }) else: - for ou, users in ous.iteritems(): + for ou, users in ous.items(): audience = [a for service, a in self.get_audience(ou)] if not audience: continue - logger.info(u'provisionning users %s to %s', - u', '.join(map(unicode, users)), u', '.join(audience)) + logger.info(u'provisionning users %s to %s', u', '.join( + map(force_text, users)), u', '.join(audience)) notify_agents({ '@type': 'provision', 'issuer': issuer, @@ -197,8 +198,8 @@ class Provisionning(threading.local): elif users: audience = [audience for ou in OU.objects.all() for s, audience in self.get_audience(ou)] - logger.info(u'deprovisionning users %s from %s', u', '.join(map(unicode, users)), - u', '.join(audience)) + logger.info(u'deprovisionning users %s from %s', u', '.join( + map(force_text, users)), u', '.join(audience)) notify_agents({ '@type': 'deprovision', 'issuer': issuer, @@ -263,7 +264,7 @@ class Provisionning(threading.local): }) global_roles = set(ous.get(None, [])) - for ou, ou_roles in ous.iteritems(): + for ou, ou_roles in ous.items(): sent_roles = set(ou_roles) | global_roles helper(ou, sent_roles) diff --git a/hobo/multitenant/settings_loaders.py b/hobo/multitenant/settings_loaders.py index 941aa0d..f66e4c6 100644 --- a/hobo/multitenant/settings_loaders.py +++ b/hobo/multitenant/settings_loaders.py @@ -1,10 +1,9 @@ import os import json import hashlib -from importlib import import_module from django.conf import settings -from django.utils.encoding import smart_bytes +from django.utils.encoding import force_bytes from django.utils.http import urlencode from django.utils.six.moves.urllib import parse as urlparse @@ -277,14 +276,14 @@ class CookieNames(object): return 0 def update_settings(self, tenant_settings, tenant): - domain_hash = hashlib.md5(smart_bytes(tenant.domain_url)).hexdigest()[:6] + domain_hash = hashlib.md5(force_bytes(tenant.domain_url)).hexdigest()[:6] tenant_settings.CSRF_COOKIE_NAME = 'csrftoken-%s' % domain_hash tenant_settings.SESSION_COOKIE_NAME = 'sessionid-%s' % domain_hash # unique but common name for authentic opened session cookie name if getattr(tenant_settings, 'TEMPLATE_VARS', None): idp_url = tenant_settings.TEMPLATE_VARS.get('idp_url') if idp_url: - idp_hash = hashlib.md5(smart_bytes(idp_url)).hexdigest()[:6] + idp_hash = hashlib.md5(force_bytes(idp_url)).hexdigest()[:6] cookie_name = 'a2-opened-session-%s' % idp_hash tenant_settings.A2_OPENED_SESSION_COOKIE_NAME = cookie_name tenant_settings.MELLON_OPENED_SESSION_COOKIE_NAME = cookie_name @@ -308,7 +307,7 @@ class Authentic(FileBaseSettingsLoader): if not getattr(tenant_settings, 'A2_IDP_OIDC_JWKSET', None): from jwcrypto import jwk jwkkey = jwk.JWK.from_pem( - tenant_settings.A2_IDP_SAML2_SIGNATURE_PRIVATE_KEY) + force_bytes(tenant_settings.A2_IDP_SAML2_SIGNATURE_PRIVATE_KEY)) jwkset = jwk.JWKSet() jwkset['keys'].add(jwkkey) tenant_settings.A2_IDP_OIDC_JWKSET = json.loads(jwkset.export()) diff --git a/tests_authentic/data_authentic_export_site.json b/tests_authentic/data_authentic_export_site.json index 25084d0..dc6a296 100644 --- a/tests_authentic/data_authentic_export_site.json +++ b/tests_authentic/data_authentic_export_site.json @@ -15,148 +15,64 @@ { "attributes" : [ { - "kind" : "string", - "name" : "is_superuser", - "value" : "true" - } - ], - "description" : "", - "external_id" : "", - "name" : "Administrateur de Hobo", - "ou" : { - "name" : "Collectivité par défaut", - "slug" : "default", - "uuid" : "69b0a02cf58a4c71b1ae548f1375baff" - }, - "service" : { - "ou" : { - "name" : "Collectivité par défaut", - "slug" : "default", - "uuid" : "69b0a02cf58a4c71b1ae548f1375baff" + "kind" : "json", + "name" : "emails", + "value" : "[]" }, - "slug" : "hobo" - }, - "slug" : "_a2-hobo-superuser", - "uuid" : "25f33158b7e2449b9a5b00dbc57bf416" - }, - { - "attributes" : [ { - "kind" : "string", - "name" : "is_superuser", - "value" : "true" - } - ], - "description" : "", - "external_id" : "", - "name" : "Administrateur de Compte citoyen", - "ou" : { - "name" : "Collectivité par défaut", - "slug" : "default", - "uuid" : "69b0a02cf58a4c71b1ae548f1375baff" - }, - "service" : { - "ou" : { - "name" : "Collectivité par défaut", - "slug" : "default", - "uuid" : "69b0a02cf58a4c71b1ae548f1375baff" + "kind" : "json", + "name" : "details", + "value" : "\"\"" }, - "slug" : "portal" - }, - "slug" : "_a2-hobo-superuser", - "uuid" : "84b3b1ba76e44bcdb4fd4437c448a981" - }, - { - "attributes" : [ { - "kind" : "string", - "name" : "is_superuser", - "value" : "true" + "kind" : "json", + "name" : "emails_to_members", + "value" : "false" } ], "description" : "", "external_id" : "", - "name" : "Administrateur de Démarches", + "name" : "Debug eo", "ou" : { "name" : "Collectivité par défaut", "slug" : "default", "uuid" : "69b0a02cf58a4c71b1ae548f1375baff" }, - "service" : { - "ou" : { - "name" : "Collectivité par défaut", - "slug" : "default", - "uuid" : "69b0a02cf58a4c71b1ae548f1375baff" - }, - "slug" : "eservices" - }, - "slug" : "_a2-hobo-superuser", - "uuid" : "9054a61ccf684396b38189f1ca1ec087" + "service" : null, + "slug" : "debug-eo", + "uuid" : "18e7bf78dc9a432396a99f32060052ec" }, { - "attributes" : [ - { - "kind" : "string", - "name" : "is_superuser", - "value" : "true" - } - ], "description" : "", "external_id" : "", - "name" : "Administrateur de Portail agent", + "name" : "Managers of role \"Debug eo\"", "ou" : { "name" : "Collectivité par défaut", "slug" : "default", "uuid" : "69b0a02cf58a4c71b1ae548f1375baff" }, - "service" : { - "ou" : { - "name" : "Collectivité par défaut", - "slug" : "default", - "uuid" : "69b0a02cf58a4c71b1ae548f1375baff" - }, - "slug" : "portal-agent" - }, - "slug" : "_a2-hobo-superuser", - "uuid" : "e6e22e5c0ca04ac0bf3b50d88eafe6d5" - }, - { - "attributes" : [ + "permissions" : [ { - "kind" : "string", - "name" : "is_superuser", - "value" : "true" - } - ], - "description" : "", - "external_id" : "", - "name" : "Administrateur de Passerelle", - "ou" : { - "name" : "Collectivité par défaut", - "slug" : "default", - "uuid" : "69b0a02cf58a4c71b1ae548f1375baff" - }, - "service" : { - "ou" : { - "name" : "Collectivité par défaut", - "slug" : "default", - "uuid" : "69b0a02cf58a4c71b1ae548f1375baff" + "operation" : { + "slug" : "change" + }, + "ou" : null, + "target" : { + "name" : "Managers of role \"Debug eo\"", + "ou" : { + "name" : "Collectivité par défaut", + "slug" : "default", + "uuid" : "69b0a02cf58a4c71b1ae548f1375baff" + }, + "service" : null, + "slug" : "_a2-managers-of-role-debug-eo", + "uuid" : "db1386c86701400f8f0b35af45079099" + }, + "target_ct" : { + "app_label" : "a2_rbac", + "model" : "role" + } }, - "slug" : "passerelle" - }, - "slug" : "_a2-hobo-superuser", - "uuid" : "243f58712aa248e9b27aae669341c156" - }, - { - "description" : "", - "external_id" : "", - "name" : "Administrateur du rôle « Debug eo »", - "ou" : { - "name" : "Collectivité par défaut", - "slug" : "default", - "uuid" : "69b0a02cf58a4c71b1ae548f1375baff" - }, - "permissions" : [ { "operation" : { "slug" : "view" @@ -195,89 +111,207 @@ "app_label" : "a2_rbac", "model" : "role" } + } + ], + "service" : null, + "slug" : "_a2-managers-of-role-debug-eo", + "uuid" : "db1386c86701400f8f0b35af45079099" + }, + { + "description" : "", + "external_id" : "", + "name" : "Roles - Collectivité par défaut", + "ou" : { + "name" : "Collectivité par défaut", + "slug" : "default", + "uuid" : "69b0a02cf58a4c71b1ae548f1375baff" + }, + "permissions" : [ + { + "operation" : { + "slug" : "admin" + }, + "ou" : { + "name" : "Collectivité par défaut", + "slug" : "default", + "uuid" : "69b0a02cf58a4c71b1ae548f1375baff" + }, + "target" : { + "app_label" : "a2_rbac", + "model" : "role" + }, + "target_ct" : { + "app_label" : "contenttypes", + "model" : "contenttype" + } }, { "operation" : { - "slug" : "change" + "slug" : "view" + }, + "ou" : { + "name" : "Collectivité par défaut", + "slug" : "default", + "uuid" : "69b0a02cf58a4c71b1ae548f1375baff" + }, + "target" : { + "app_label" : "custom_user", + "model" : "user" + }, + "target_ct" : { + "app_label" : "contenttypes", + "model" : "contenttype" + } + }, + { + "operation" : { + "slug" : "search" }, "ou" : null, "target" : { - "name" : "Administrateur du rôle « Debug eo »", - "ou" : { - "name" : "Collectivité par défaut", - "slug" : "default", - "uuid" : "69b0a02cf58a4c71b1ae548f1375baff" - }, - "service" : null, - "slug" : "_a2-managers-of-role-debug-eo", - "uuid" : "3049444b35874b3b9a8377ad2f10b8b6" + "name" : "Collectivité par défaut", + "slug" : "default", + "uuid" : "69b0a02cf58a4c71b1ae548f1375baff" }, "target_ct" : { "app_label" : "a2_rbac", - "model" : "role" + "model" : "organizationalunit" } } ], "service" : null, - "slug" : "_a2-managers-of-role-debug-eo", - "uuid" : "3049444b35874b3b9a8377ad2f10b8b6" + "slug" : "_a2-manager-of-roles-default", + "uuid" : "74b1f374133d426a8045f43e92ae5565" }, { - "attributes" : [ - { - "kind" : "json", - "name" : "emails_to_members", - "value" : "false" - }, + "description" : "", + "external_id" : "", + "name" : "Services - Collectivité par défaut", + "ou" : { + "name" : "Collectivité par défaut", + "slug" : "default", + "uuid" : "69b0a02cf58a4c71b1ae548f1375baff" + }, + "permissions" : [ { - "kind" : "json", - "name" : "details", - "value" : "\"\"" + "operation" : { + "slug" : "admin" + }, + "ou" : { + "name" : "Collectivité par défaut", + "slug" : "default", + "uuid" : "69b0a02cf58a4c71b1ae548f1375baff" + }, + "target" : { + "app_label" : "authentic2", + "model" : "service" + }, + "target_ct" : { + "app_label" : "contenttypes", + "model" : "contenttype" + } }, { - "kind" : "json", - "name" : "emails", - "value" : "[]" + "operation" : { + "slug" : "search" + }, + "ou" : null, + "target" : { + "name" : "Collectivité par défaut", + "slug" : "default", + "uuid" : "69b0a02cf58a4c71b1ae548f1375baff" + }, + "target_ct" : { + "app_label" : "a2_rbac", + "model" : "organizationalunit" + } } ], + "service" : null, + "slug" : "_a2-manager-of-services-default", + "uuid" : "56b97b27cacd4b53a9b2c30304c23226" + }, + { "description" : "", "external_id" : "", - "name" : "Debug eo", + "name" : "Users - Collectivité par défaut", "ou" : { "name" : "Collectivité par défaut", "slug" : "default", "uuid" : "69b0a02cf58a4c71b1ae548f1375baff" }, + "permissions" : [ + { + "operation" : { + "slug" : "admin" + }, + "ou" : { + "name" : "Collectivité par défaut", + "slug" : "default", + "uuid" : "69b0a02cf58a4c71b1ae548f1375baff" + }, + "target" : { + "app_label" : "custom_user", + "model" : "user" + }, + "target_ct" : { + "app_label" : "contenttypes", + "model" : "contenttype" + } + }, + { + "operation" : { + "slug" : "search" + }, + "ou" : null, + "target" : { + "name" : "Collectivité par défaut", + "slug" : "default", + "uuid" : "69b0a02cf58a4c71b1ae548f1375baff" + }, + "target_ct" : { + "app_label" : "a2_rbac", + "model" : "organizationalunit" + } + } + ], "service" : null, - "slug" : "debug-eo", - "uuid" : "18e7bf78dc9a432396a99f32060052ec" + "slug" : "_a2-manager-of-users-default", + "uuid" : "81a20ddf235c41a49097cc25d82bcd23" }, { "description" : "", "external_id" : "", - "name" : "Administrateur", + "name" : "Manager", "ou" : null, "parents" : [ { - "name" : "Administrateur des entités", + "name" : "Manager of users", "ou" : null, "service" : null, - "slug" : "_a2-administrateur-des-entites", - "uuid" : "a1ff1b3da88f47cea91e344998dfdfbf" + "slug" : "_a2-manager-of-users", + "uuid" : "8cab8f8406694a688fa178f434a82d95" }, { - "name" : "Administrateur des rôles", + "name" : "Manager of services", "ou" : null, "service" : null, - "slug" : "_a2-administrateur-des-roles", - "uuid" : "8dd625b74cff40aa8531d7d72616550e" + "slug" : "_a2-manager-of-services", + "uuid" : "d769527e686b486ca61c9d3ffa2505bb" }, { - "name" : "Administrateur des utilisateurs", + "name" : "Manager of organizational units", "ou" : null, "service" : null, - "slug" : "_a2-administrateur-des-utilisateurs", - "uuid" : "4ab5effedc404fb1bcba4d21ee89b719" + "slug" : "_a2-manager-of-organizational-units", + "uuid" : "65e1bd46c67d45e394a065505dfe512c" + }, + { + "name" : "Manager of roles", + "ou" : null, + "service" : null, + "slug" : "_a2-manager-of-roles", + "uuid" : "19effa77518a406bb3ea3afe0fe223c6" } ], "permissions" : [ @@ -287,11 +321,11 @@ }, "ou" : null, "target" : { - "name" : "Administrateur", + "name" : "Manager", "ou" : null, "service" : null, "slug" : "_a2-manager", - "uuid" : "81a8708382bb4e8ea12ed0e172aa48b9" + "uuid" : "c4814eac3cab4187be5a44efe7c87568" }, "target_ct" : { "app_label" : "a2_rbac", @@ -301,28 +335,14 @@ ], "service" : null, "slug" : "_a2-manager", - "uuid" : "81a8708382bb4e8ea12ed0e172aa48b9" + "uuid" : "c4814eac3cab4187be5a44efe7c87568" }, { "description" : "", "external_id" : "", - "name" : "Administrateur des entités", + "name" : "Manager of organizational units", "ou" : null, "permissions" : [ - { - "operation" : { - "slug" : "view" - }, - "ou" : null, - "target" : { - "app_label" : "a2_rbac", - "model" : "organizationalunit" - }, - "target_ct" : { - "app_label" : "contenttypes", - "model" : "contenttype" - } - }, { "operation" : { "slug" : "admin" @@ -353,15 +373,29 @@ } ], "service" : null, - "slug" : "_a2-administrateur-des-entites", - "uuid" : "a1ff1b3da88f47cea91e344998dfdfbf" + "slug" : "_a2-manager-of-organizational-units", + "uuid" : "65e1bd46c67d45e394a065505dfe512c" }, { "description" : "", "external_id" : "", - "name" : "Administrateur des rôles", + "name" : "Manager of roles", "ou" : null, "permissions" : [ + { + "operation" : { + "slug" : "admin" + }, + "ou" : null, + "target" : { + "app_label" : "a2_rbac", + "model" : "role" + }, + "target_ct" : { + "app_label" : "contenttypes", + "model" : "contenttype" + } + }, { "operation" : { "slug" : "view" @@ -378,7 +412,7 @@ }, { "operation" : { - "slug" : "view" + "slug" : "search" }, "ou" : null, "target" : { @@ -389,15 +423,26 @@ "app_label" : "contenttypes", "model" : "contenttype" } - }, + } + ], + "service" : null, + "slug" : "_a2-manager-of-roles", + "uuid" : "19effa77518a406bb3ea3afe0fe223c6" + }, + { + "description" : "", + "external_id" : "", + "name" : "Manager of services", + "ou" : null, + "permissions" : [ { "operation" : { "slug" : "admin" }, "ou" : null, "target" : { - "app_label" : "a2_rbac", - "model" : "role" + "app_label" : "authentic2", + "model" : "service" }, "target_ct" : { "app_label" : "contenttypes", @@ -420,23 +465,23 @@ } ], "service" : null, - "slug" : "_a2-administrateur-des-roles", - "uuid" : "8dd625b74cff40aa8531d7d72616550e" + "slug" : "_a2-manager-of-services", + "uuid" : "d769527e686b486ca61c9d3ffa2505bb" }, { "description" : "", "external_id" : "", - "name" : "Administrateur des utilisateurs", + "name" : "Manager of users", "ou" : null, "permissions" : [ { "operation" : { - "slug" : "view" + "slug" : "admin" }, "ou" : null, "target" : { - "app_label" : "a2_rbac", - "model" : "organizationalunit" + "app_label" : "custom_user", + "model" : "user" }, "target_ct" : { "app_label" : "contenttypes", @@ -445,36 +490,83 @@ }, { "operation" : { - "slug" : "admin" + "slug" : "search" }, "ou" : null, "target" : { - "app_label" : "custom_user", - "model" : "user" + "app_label" : "a2_rbac", + "model" : "organizationalunit" }, "target_ct" : { "app_label" : "contenttypes", "model" : "contenttype" } + } + ], + "service" : null, + "slug" : "_a2-manager-of-users", + "uuid" : "8cab8f8406694a688fa178f434a82d95" + }, + { + "description" : "", + "external_id" : "", + "name" : "Managers of \"Collectivité par défaut\"", + "ou" : null, + "parents" : [ + { + "name" : "Roles - Collectivité par défaut", + "ou" : { + "name" : "Collectivité par défaut", + "slug" : "default", + "uuid" : "69b0a02cf58a4c71b1ae548f1375baff" + }, + "service" : null, + "slug" : "_a2-manager-of-roles-default", + "uuid" : "74b1f374133d426a8045f43e92ae5565" + }, + { + "name" : "Users - Collectivité par défaut", + "ou" : { + "name" : "Collectivité par défaut", + "slug" : "default", + "uuid" : "69b0a02cf58a4c71b1ae548f1375baff" + }, + "service" : null, + "slug" : "_a2-manager-of-users-default", + "uuid" : "81a20ddf235c41a49097cc25d82bcd23" }, + { + "name" : "Services - Collectivité par défaut", + "ou" : { + "name" : "Collectivité par défaut", + "slug" : "default", + "uuid" : "69b0a02cf58a4c71b1ae548f1375baff" + }, + "service" : null, + "slug" : "_a2-manager-of-services-default", + "uuid" : "56b97b27cacd4b53a9b2c30304c23226" + } + ], + "permissions" : [ { "operation" : { - "slug" : "search" + "slug" : "view" }, "ou" : null, "target" : { - "app_label" : "a2_rbac", - "model" : "organizationalunit" + "name" : "Collectivité par défaut", + "slug" : "default", + "uuid" : "69b0a02cf58a4c71b1ae548f1375baff" }, "target_ct" : { - "app_label" : "contenttypes", - "model" : "contenttype" + "app_label" : "a2_rbac", + "model" : "organizationalunit" } } ], "service" : null, - "slug" : "_a2-administrateur-des-utilisateurs", - "uuid" : "4ab5effedc404fb1bcba4d21ee89b719" + "slug" : "_a2-managers-of-default", + "uuid" : "88b309df04f0447ba08be8e197fa9d2d" } ] } diff --git a/tests_authentic/settings.py b/tests_authentic/settings.py index 0ce9b67..c51e0d4 100644 --- a/tests_authentic/settings.py +++ b/tests_authentic/settings.py @@ -44,3 +44,5 @@ HOBO_ROLE_EXPORT = True SESSION_COOKIE_SECURE = False CSRF_COOKIE_SECURE = False + +LANGUAGE_CODE = 'en' diff --git a/tests_authentic/test_hobo_deploy.py b/tests_authentic/test_hobo_deploy.py index 9572da1..61f9213 100644 --- a/tests_authentic/test_hobo_deploy.py +++ b/tests_authentic/test_hobo_deploy.py @@ -308,7 +308,7 @@ def test_hobo_deploy(monkeypatch, tenant_base, mocker, skeleton_dir): ] } hobo_json_content = json.dumps(env) - hobo_json = tempfile.NamedTemporaryFile() + hobo_json = tempfile.NamedTemporaryFile(mode='w') hobo_json.write(hobo_json_content) hobo_json.flush() @@ -463,28 +463,33 @@ def test_hobo_deploy(monkeypatch, tenant_base, mocker, skeleton_dir): def test_import_template(db, tenant_base): - def with_uuid_removed(input): - if isinstance(input, dict): - for key in input.keys(): - if key == 'uuid': - input.pop('uuid') - return {k: with_uuid_removed(v) for k, v in input.iteritems()} - elif isinstance(input, list): - return [with_uuid_removed(e) for e in input] - else: - return input + def listify(value): + if isinstance(value, dict): + value = list((k, listify(v)) for k, v in value.items()) + value.sort() + if isinstance(value, list): + value = list(listify(x) for x in value) + value.sort() + return value - def with_lists_sorted(input): - if isinstance(input, dict): - return {k: with_lists_sorted(v) for k, v in input.iteritems()} - if isinstance(input, list): - return with_lists_sorted(input.sort()) - else: - return input + def sort_and_remove_uuid(value): + if isinstance(value, dict): + if 'uuid' in value: + value.pop('uuid') + value = {k: sort_and_remove_uuid(v) for k, v in value.items()} + if isinstance(value, list): + value = [sort_and_remove_uuid(elt) for elt in value] + value.sort(key=lambda elt: listify(elt)) + return value call_command('create_tenant', 'authentic.example.net') tenant = TenantMiddleware.get_tenant_by_hostname('authentic.example.net') connection.set_tenant(tenant) call_command('import_template', '--basepath=%s' % os.path.dirname(__file__), 'data_authentic_export_site') content = open('%s/data_authentic_export_site.json' % os.path.dirname(__file__)).read() - assert byteify(with_lists_sorted(with_uuid_removed(export_site()))) == byteify(with_lists_sorted(with_uuid_removed(json.loads(content)))) + + with open('/tmp/export.json', 'w') as fd: + fd.write(json.dumps(export_site(), indent=4)) + export_ref = sort_and_remove_uuid(export_site()) + file_ref = sort_and_remove_uuid(json.loads(content)) + assert export_ref == file_ref diff --git a/tests_authentic/test_rest_authentication.py b/tests_authentic/test_rest_authentication.py index b769d56..349247d 100644 --- a/tests_authentic/test_rest_authentication.py +++ b/tests_authentic/test_rest_authentication.py @@ -1,5 +1,5 @@ import pytest -import urllib +from django.utils.six.moves.urllib import parse as urllib from rest_framework.exceptions import AuthenticationFailed -- 2.24.0