From b4182e8ad2255930bcb9163226a054910faa82f4 Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Wed, 26 Jan 2022 16:56:03 +0100 Subject: [PATCH 2/2] misc: use new signing.dumps/loads implementation (#61130) --- src/authentic2/backends/ldap_backend.py | 3 ++- src/authentic2/manager/role_views.py | 6 +++--- src/authentic2/manager/views.py | 6 +++--- src/authentic2/manager/widgets.py | 4 ++-- src/authentic2/models.py | 2 +- src/authentic2/utils/misc.py | 8 ++++---- src/authentic2/views.py | 18 +++++++++--------- src/authentic2_auth_fc/views.py | 2 +- src/authentic2_auth_oidc/backends.py | 2 +- src/authentic2_auth_oidc/views.py | 8 ++++---- src/authentic2_idp_oidc/utils.py | 3 ++- tests/test_ldap.py | 4 ++-- 12 files changed, 34 insertions(+), 32 deletions(-) diff --git a/src/authentic2/backends/ldap_backend.py b/src/authentic2/backends/ldap_backend.py index a4b19b29..bac42d8e 100644 --- a/src/authentic2/backends/ldap_backend.py +++ b/src/authentic2/backends/ldap_backend.py @@ -42,7 +42,7 @@ from ldap.dn import escape_dn_chars from ldap.filter import filter_format from ldap.ldapobject import ReconnectLDAPObject as NativeLDAPObject -from authentic2 import app_settings, crypto +from authentic2 import app_settings from authentic2.a2_rbac.models import OrganizationalUnit, Role from authentic2.a2_rbac.utils import get_default_ou from authentic2.backends import is_user_authenticable @@ -51,6 +51,7 @@ from authentic2.ldap_utils import FilterFormatter from authentic2.middleware import StoreRequestMiddleware from authentic2.models import UserExternalId from authentic2.user_login_failure import user_login_failure, user_login_success +from authentic2.utils import crypto from authentic2.utils.misc import PasswordChangeError, to_list # code originaly copied from by now merely inspired by diff --git a/src/authentic2/manager/role_views.py b/src/authentic2/manager/role_views.py index 28e37d5d..9617d27d 100644 --- a/src/authentic2/manager/role_views.py +++ b/src/authentic2/manager/role_views.py @@ -20,7 +20,6 @@ from functools import reduce from django.contrib import messages from django.contrib.auth import get_user_model from django.contrib.contenttypes.models import ContentType -from django.core import signing from django.core.exceptions import PermissionDenied, ValidationError from django.core.paginator import EmptyPage, Paginator from django.db import transaction @@ -39,6 +38,7 @@ from authentic2.a2_rbac.models import OrganizationalUnit, Permission, Role, Role from authentic2.a2_rbac.utils import get_default_ou from authentic2.apps.journal.views import JournalViewWithContext from authentic2.forms.profile import modelform_factory +from authentic2.utils import crypto from authentic2.utils.misc import redirect from . import forms, resources, tables, views @@ -820,8 +820,8 @@ class UserOrRoleSelect2View(DetailView): field_id = self.kwargs.get('field_id', self.request.GET.get('field_id', None)) try: - signing.loads(field_id) - except (signing.SignatureExpired, signing.BadSignature): + crypto.loads(field_id) + except (crypto.SignatureExpired, crypto.BadSignature): raise Http404('Invalid or expired signature.') search_term = request.GET.get('term', '') diff --git a/src/authentic2/manager/views.py b/src/authentic2/manager/views.py index 236ccf74..11c821a2 100644 --- a/src/authentic2/manager/views.py +++ b/src/authentic2/manager/views.py @@ -21,7 +21,6 @@ import json import pickle from django.contrib.messages.views import SuccessMessageMixin -from django.core import signing from django.core.exceptions import PermissionDenied, ValidationError from django.db import transaction from django.forms import MediaDefiningClass @@ -44,6 +43,7 @@ from authentic2.a2_rbac.models import OrganizationalUnit from authentic2.data_transfer import ImportContext, export_site, import_site from authentic2.decorators import json as json_view from authentic2.forms.profile import modelform_factory +from authentic2.utils import crypto from authentic2.utils.misc import batch_queryset, redirect from . import app_settings, forms, utils, widgets @@ -745,8 +745,8 @@ class Select2View(AutoResponseView): raise Http404('Invalid user') field_data = self.kwargs.get('field_id', self.request.GET.get('field_id', None)) try: - field_data = signing.loads(field_data) - except (signing.SignatureExpired, signing.BadSignature): + field_data = crypto.loads(field_data) + except (crypto.SignatureExpired, crypto.BadSignature): raise Http404('Invalid or expired signature.') widget_class = field_data.get('class') if not widget_class or not hasattr(widgets, widget_class): diff --git a/src/authentic2/manager/widgets.py b/src/authentic2/manager/widgets.py index a4265188..74583a8d 100644 --- a/src/authentic2/manager/widgets.py +++ b/src/authentic2/manager/widgets.py @@ -20,11 +20,11 @@ import operator import pickle from django.contrib.auth import get_user_model -from django.core import signing from django.utils.encoding import force_text from django_select2.forms import ModelSelect2MultipleWidget, ModelSelect2Widget from authentic2.a2_rbac.models import Role +from authentic2.utils import crypto from authentic2_idp_oidc.models import OIDCAuthorization from . import utils @@ -57,7 +57,7 @@ class Select2Mixin: 'class': self.__class__.__name__, 'where_clause': force_text(base64.b64encode(pickle.dumps(self.queryset.query.where))), } - attrs['data-field_id'] = signing.dumps(field_data) + attrs['data-field_id'] = crypto.dumps(field_data) return attrs @classmethod diff --git a/src/authentic2/models.py b/src/authentic2/models.py index c7dddb49..c805d49c 100644 --- a/src/authentic2/models.py +++ b/src/authentic2/models.py @@ -36,7 +36,7 @@ from django.utils.translation import ugettext_lazy as _ from model_utils.managers import QueryManager from authentic2.a2_rbac.models import Role -from authentic2.crypto import base64url_decode, base64url_encode +from authentic2.utils.crypto import base64url_decode, base64url_encode # install our natural_key implementation from . import managers diff --git a/src/authentic2/utils/misc.py b/src/authentic2/utils/misc.py index 8cd6e871..a7c149f0 100644 --- a/src/authentic2/utils/misc.py +++ b/src/authentic2/utils/misc.py @@ -32,7 +32,6 @@ from django.contrib.auth import REDIRECT_FIELD_NAME from django.contrib.auth import authenticate as dj_authenticate from django.contrib.auth import get_user_model from django.contrib.auth import login as auth_login -from django.core import signing from django.core.exceptions import FieldDoesNotExist, ImproperlyConfigured from django.core.mail import EmailMessage, send_mail from django.forms.utils import ErrorList, to_current_timezone @@ -48,8 +47,9 @@ from django.utils.formats import localize from django.utils.translation import ungettext from authentic2.saml.saml2utils import filter_attribute_private_key, filter_element_private_key +from authentic2.utils import crypto -from .. import app_settings, constants, crypto, plugins +from .. import app_settings, constants, plugins from .service import set_service_ref @@ -774,7 +774,7 @@ def build_activation_url(request, email, next_url=None, ou=None, **kwargs): def build_deletion_url(request, **kwargs): data = kwargs.copy() data['user_pk'] = request.user.pk - deletion_token = signing.dumps(data) + deletion_token = crypto.dumps(data) delete_url = request.build_absolute_uri( reverse('validate_deletion', kwargs={'deletion_token': deletion_token}) ) @@ -1176,7 +1176,7 @@ def send_email_change_email(user, email, request=None, context=None, template_na legacy_body_templates = None # build verify email URL containing a signed token - token = signing.dumps( + token = crypto.dumps( { 'email': email, 'user_pk': user.pk, diff --git a/src/authentic2/views.py b/src/authentic2/views.py index 1eab8dad..be875618 100644 --- a/src/authentic2/views.py +++ b/src/authentic2/views.py @@ -26,7 +26,6 @@ from django.contrib.auth import REDIRECT_FIELD_NAME, get_user_model from django.contrib.auth import logout as auth_logout from django.contrib.auth.decorators import login_required from django.contrib.auth.views import PasswordChangeView as DjPasswordChangeView -from django.core import signing from django.core.exceptions import ValidationError from django.db.models.fields import FieldDoesNotExist from django.db.models.query import Q @@ -60,6 +59,7 @@ from .a2_rbac.utils import get_default_ou from .forms import passwords as passwords_forms from .forms import profile as profile_forms from .forms import registration as registration_forms +from .utils import crypto from .utils import misc as utils_misc from .utils import switch_user as utils_switch_user from .utils.evaluate import make_condition_context @@ -229,7 +229,7 @@ class EmailChangeVerifyView(TemplateView): def get(self, request, *args, **kwargs): if 'token' in request.GET: try: - token = signing.loads( + token = crypto.loads( request.GET['token'], max_age=app_settings.A2_EMAIL_CHANGE_TOKEN_LIFETIME ) user_pk = token['user_pk'] @@ -260,9 +260,9 @@ class EmailChangeVerifyView(TemplateView): old_email=old_email, new_email=user.email, ) - except signing.SignatureExpired: + except crypto.SignatureExpired: messages.error(request, _('your request for changing your email is too old, try again')) - except signing.BadSignature: + except crypto.BadSignature: messages.error(request, _('your request for changing your email is invalid, try again')) except ValueError: messages.error( @@ -903,10 +903,10 @@ class BaseRegistrationView(FormView): # load pre-filled values if request.GET.get('token'): try: - self.token = signing.loads( + self.token = crypto.loads( request.GET.get('token'), max_age=settings.ACCOUNT_ACTIVATION_DAYS * 3600 * 24 ) - except (TypeError, ValueError, signing.BadSignature) as e: + except (TypeError, ValueError, crypto.BadSignature) as e: logger.warning('registration_view: invalid token: %s', e) return HttpResponseBadRequest('invalid token', content_type='text/plain') if 'ou' in self.token: @@ -1348,7 +1348,7 @@ class ValidateDeletionView(TemplateView): def dispatch(self, request, *args, **kwargs): try: - deletion_token = signing.loads( + deletion_token = crypto.loads( kwargs['deletion_token'], max_age=app_settings.A2_DELETION_REQUEST_LIFETIME ) user_pk = deletion_token['user_pk'] @@ -1357,9 +1357,9 @@ class ValidateDeletionView(TemplateView): if not self.user.is_active: raise ValidationError(_('This account is inactive, it cannot be deleted.')) logger.info('user %s confirmed the deletion of their own account', self.user) - except signing.SignatureExpired: + except crypto.SignatureExpired: error = _('The account deletion request is too old, try again') - except signing.BadSignature: + except crypto.BadSignature: error = _('The account deletion request is invalid, try again') except ValueError: error = _('The account deletion request was not on this site, try again') diff --git a/src/authentic2_auth_fc/views.py b/src/authentic2_auth_fc/views.py index b69f9154..cd145333 100644 --- a/src/authentic2_auth_fc/views.py +++ b/src/authentic2_auth_fc/views.py @@ -37,10 +37,10 @@ from authentic2 import app_settings as a2_app_settings from authentic2 import constants, hooks from authentic2 import models as a2_models from authentic2.a2_rbac.utils import get_default_ou -from authentic2.crypto import check_hmac_url, hash_chain, hmac_url from authentic2.forms.passwords import SetPasswordForm from authentic2.utils import misc as utils_misc from authentic2.utils import views as utils_views +from authentic2.utils.crypto import check_hmac_url, hash_chain, hmac_url from authentic2.utils.models import safe_get_or_create from authentic2.utils.service import get_service_from_ref, get_service_from_request, service_ref diff --git a/src/authentic2_auth_oidc/backends.py b/src/authentic2_auth_oidc/backends.py index 6c75b321..81a4fd03 100644 --- a/src/authentic2_auth_oidc/backends.py +++ b/src/authentic2_auth_oidc/backends.py @@ -26,7 +26,7 @@ from jwcrypto.jwt import JWT from authentic2 import app_settings, hooks from authentic2.a2_rbac.models import OrganizationalUnit -from authentic2.crypto import base64url_encode +from authentic2.utils.crypto import base64url_encode from authentic2.utils.template import Template from . import models, utils diff --git a/src/authentic2_auth_oidc/views.py b/src/authentic2_auth_oidc/views.py index 1ed9203a..41e12cf6 100644 --- a/src/authentic2_auth_oidc/views.py +++ b/src/authentic2_auth_oidc/views.py @@ -23,7 +23,6 @@ import requests from django.conf import settings from django.contrib import messages from django.contrib.auth import REDIRECT_FIELD_NAME -from django.core import signing from django.http import HttpResponseBadRequest from django.urls import reverse from django.utils.translation import get_language @@ -31,6 +30,7 @@ from django.utils.translation import ugettext as _ from django.views.generic.base import View from authentic2.decorators import setting_enabled +from authentic2.utils import crypto from authentic2.utils.misc import authenticate, good_next_url, login, redirect from . import app_settings, models @@ -65,7 +65,7 @@ def oidc_login(request, pk, next_url=None, *args, **kwargs): 'scope': ' '.join(scopes), 'response_type': 'code', 'redirect_uri': request.build_absolute_uri(reverse('oidc-login-callback')), - 'state': signing.dumps(state_content), + 'state': crypto.dumps(state_content), 'nonce': nonce, } if provider.claims_parameter_supported: @@ -140,8 +140,8 @@ class LoginCallback(View): if not raw_state: return redirect(request, settings.LOGIN_REDIRECT_URL) try: - state_content = signing.loads(raw_state) - except signing.BadSignature: + state_content = crypto.loads(raw_state) + except crypto.BadSignature: return redirect(request, settings.LOGIN_REDIRECT_URL) state = state_content['state_id'] diff --git a/src/authentic2_idp_oidc/utils.py b/src/authentic2_idp_oidc/utils.py index 39e97d85..810066ca 100644 --- a/src/authentic2_idp_oidc/utils.py +++ b/src/authentic2_idp_oidc/utils.py @@ -27,9 +27,10 @@ from django.utils.encoding import force_bytes, force_text from jwcrypto.jwk import JWK, InvalidJWKValue, JWKSet from jwcrypto.jwt import JWT -from authentic2 import crypto, hooks +from authentic2 import hooks from authentic2.attributes_ng.engine import get_attributes from authentic2.decorators import GlobalCache +from authentic2.utils import crypto from authentic2.utils.template import Template from . import app_settings diff --git a/tests/test_ldap.py b/tests/test_ldap.py index 2a3eefed..2e0641dc 100644 --- a/tests/test_ldap.py +++ b/tests/test_ldap.py @@ -32,12 +32,12 @@ from django.utils.encoding import force_bytes, force_text from ldap.dn import escape_dn_chars from ldaptools.slapd import Slapd, has_slapd -from authentic2 import crypto, models +from authentic2 import models from authentic2.a2_rbac.models import OrganizationalUnit, Role from authentic2.a2_rbac.utils import get_default_ou from authentic2.backends import ldap_backend from authentic2.models import Service -from authentic2.utils import switch_user +from authentic2.utils import crypto, switch_user from authentic2.utils.misc import PasswordChangeError, authenticate from . import utils -- 2.34.1