From c941411ec3534ab47634f784631ea2e4b3c64ea3 Mon Sep 17 00:00:00 2001 From: Paul Marillonnet Date: Wed, 4 Mar 2020 14:31:36 +0100 Subject: [PATCH] python3: migrate authentic (#40407) --- hobo/agent/authentic2/provisionning.py | 25 +++++++++++---------- hobo/multitenant/settings_loaders.py | 9 ++++---- tests_authentic/test_hobo_deploy.py | 11 ++++----- tests_authentic/test_rest_authentication.py | 2 +- 4 files changed, 24 insertions(+), 23 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/test_hobo_deploy.py b/tests_authentic/test_hobo_deploy.py index 9572da1..ed03825 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() @@ -465,10 +465,10 @@ 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(): + for key in list(input.keys()): if key == 'uuid': input.pop('uuid') - return {k: with_uuid_removed(v) for k, v in input.iteritems()} + return {k: with_uuid_removed(v) for k, v in input.items()} elif isinstance(input, list): return [with_uuid_removed(e) for e in input] else: @@ -476,9 +476,10 @@ def test_import_template(db, tenant_base): def with_lists_sorted(input): if isinstance(input, dict): - return {k: with_lists_sorted(v) for k, v in input.iteritems()} + return {k: with_lists_sorted(v) for k, v in input.items()} if isinstance(input, list): - return with_lists_sorted(input.sort()) + return with_lists_sorted(input.sort( + key=lambda l: sorted(tuple(d.items()) if isinstance(d, dict) else d for d in l))) else: return input 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