From 2457c72d61992596a1c3873192ea77b442d82230 Mon Sep 17 00:00:00 2001 From: Valentin Deniaud Date: Thu, 22 Sep 2022 11:13:52 +0200 Subject: [PATCH 2/3] misc: apply django-upgrade (#69426) --- src/authentic2/api_urls.py | 30 +-- src/authentic2/api_views.py | 5 +- src/authentic2/cbv.py | 2 +- src/authentic2/decorators.py | 4 +- .../disco_service/disco_responder.py | 7 +- src/authentic2/forms/widgets.py | 9 +- src/authentic2/idp/saml/urls.py | 28 +-- src/authentic2/idp/urls.py | 4 +- src/authentic2/manager/urls.py | 184 +++++++++--------- src/authentic2/middleware.py | 2 +- src/authentic2/saml/admin.py | 6 +- src/authentic2/saml/common.py | 2 +- src/authentic2/urls.py | 104 +++++----- src/authentic2/utils/misc.py | 2 +- src/authentic2/views.py | 2 +- src/authentic2_auth_fc/urls.py | 10 +- src/authentic2_auth_oidc/urls.py | 7 +- src/authentic2_auth_saml/urls.py | 5 +- src/authentic2_idp_cas/urls.py | 16 +- src/authentic2_idp_oidc/manager/urls.py | 16 +- src/authentic2_idp_oidc/urls.py | 16 +- src/authentic2_idp_oidc/views.py | 4 +- tests/cache_urls.py | 4 +- tests/conftest.py | 4 - tests/test_journal_app/urls.py | 4 +- 25 files changed, 233 insertions(+), 244 deletions(-) diff --git a/src/authentic2/api_urls.py b/src/authentic2/api_urls.py index 3ddf5f244..4431a12c5 100644 --- a/src/authentic2/api_urls.py +++ b/src/authentic2/api_urls.py @@ -14,49 +14,49 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -from django.conf.urls import url +from django.urls import path, re_path from . import api_views urlpatterns = [ - url(r'^register/$', api_views.register, name='a2-api-register'), - url(r'^password-change/$', api_views.password_change, name='a2-api-password-change'), - url(r'^user/$', api_views.user, name='a2-api-user'), - url( + path('register/', api_views.register, name='a2-api-register'), + path('password-change/', api_views.password_change, name='a2-api-password-change'), + path('user/', api_views.user, name='a2-api-user'), + re_path( r'^users/(?P[\w+]*)/profiles/(?P[^/]+)/$', api_views.user_profiles, name='a2-api-user-profiles', ), - url( + re_path( r'^roles/(?P[\w+]*)/members/$', api_views.roles_members, name='a2-api-role-members-list', ), - url( + re_path( r'^roles/(?P[\w+]*)/members/(?P[^/]+)/$', api_views.role_membership, name='a2-api-role-member', ), - url( + re_path( r'^roles/(?P[\w+]*)/relationships/members/$', api_views.role_memberships, name='a2-api-role-members', ), - url( + re_path( r'^roles/(?P[0-9a-z]{32})/parents/$', api_views.roles_parents, name='a2-api-role-parents', ), - url( + re_path( r'^roles/(?P[0-9a-z]{32})/relationships/parents/$', api_views.roles_parents_relationships, name='a2-api-role-parents-relationships', ), - url(r'^check-password/$', api_views.check_password, name='a2-api-check-password'), - url(r'^check-api-client/$', api_views.check_api_client, name='a2-api-check-api-client'), - url(r'^validate-password/$', api_views.validate_password, name='a2-api-validate-password'), - url(r'^password-strength/$', api_views.password_strength, name='a2-api-password-strength'), - url(r'^address-autocomplete/$', api_views.address_autocomplete, name='a2-api-address-autocomplete'), + path('check-password/', api_views.check_password, name='a2-api-check-password'), + path('check-api-client/', api_views.check_api_client, name='a2-api-check-api-client'), + path('validate-password/', api_views.validate_password, name='a2-api-validate-password'), + path('password-strength/', api_views.password_strength, name='a2-api-password-strength'), + path('address-autocomplete/', api_views.address_autocomplete, name='a2-api-address-autocomplete'), ] urlpatterns += api_views.router.urls diff --git a/src/authentic2/api_views.py b/src/authentic2/api_views.py index 9ac75ee67..01e06e49b 100644 --- a/src/authentic2/api_views.py +++ b/src/authentic2/api_views.py @@ -39,7 +39,7 @@ from django_filters.rest_framework import FilterSet from django_filters.utils import handle_timezone from pytz.exceptions import AmbiguousTimeError, NonExistentTimeError from requests.exceptions import RequestException -from rest_framework import authentication, pagination, permissions, serializers, status +from rest_framework import pagination, permissions, serializers, status from rest_framework.authentication import SessionAuthentication from rest_framework.exceptions import AuthenticationFailed, ErrorDetail, PermissionDenied, ValidationError from rest_framework.fields import CreateOnlyDefault @@ -73,9 +73,6 @@ if django.VERSION < (2,): from . import validators rest_framework.fields.ProhibitNullCharactersValidator = validators.ProhibitNullCharactersValidator -if django.VERSION < (1, 11): - authentication.authenticate = utils_misc.authenticate - User = get_user_model() diff --git a/src/authentic2/cbv.py b/src/authentic2/cbv.py index 6b25197fa..6e8a60658 100644 --- a/src/authentic2/cbv.py +++ b/src/authentic2/cbv.py @@ -69,7 +69,7 @@ class NextURLViewMixin(RedirectToNextURLViewMixin): if REDIRECT_FIELD_NAME in request.GET: pass else: - next_url = request.META.get('HTTP_REFERER') or self.next_url_default + next_url = request.headers.get('Referer') or self.next_url_default return utils_misc.redirect( request, request.path, diff --git a/src/authentic2/decorators.py b/src/authentic2/decorators.py index 03fa4347b..0760fa928 100644 --- a/src/authentic2/decorators.py +++ b/src/authentic2/decorators.py @@ -145,13 +145,13 @@ def json(func): break # 1. check origin if jsonp: - origin = request.META.get('HTTP_REFERER') + origin = request.headers.get('Referer') if not origin: # JSONP is unusable for people without referers return HttpResponseForbidden('missing referrer', content_type='text/plain') origin = cors.make_origin(origin) else: - origin = request.META.get('HTTP_ORIGIN') + origin = request.headers.get('Origin') if origin: if not cors.check_origin(request, origin): return HttpResponseForbidden('bad origin', content_type='text/plain') diff --git a/src/authentic2/disco_service/disco_responder.py b/src/authentic2/disco_service/disco_responder.py index 20fdb28bf..bca9a3d64 100644 --- a/src/authentic2/disco_service/disco_responder.py +++ b/src/authentic2/disco_service/disco_responder.py @@ -26,9 +26,8 @@ import logging import urllib.parse from xml.dom.minidom import parseString -from django.conf.urls import url from django.http import HttpResponseRedirect -from django.urls import reverse +from django.urls import path, reverse from django.utils.http import urlquote from django.utils.translation import ugettext as _ @@ -226,6 +225,6 @@ def idp_selection(request): urlpatterns = [ - url(r'^disco$', disco), - url(r'^idp_selection$', idp_selection), + path('disco', disco), + path('idp_selection', idp_selection), ] diff --git a/src/authentic2/forms/widgets.py b/src/authentic2/forms/widgets.py index ecb6fabc6..62f5a2a37 100644 --- a/src/authentic2/forms/widgets.py +++ b/src/authentic2/forms/widgets.py @@ -28,7 +28,6 @@ import json import re import uuid -import django from django import forms from django.contrib.auth import get_user_model from django.forms.widgets import ClearableFileInput, DateInput, DateTimeInput @@ -321,13 +320,7 @@ class CheckPasswordInput(PasswordInput): class ProfileImageInput(ClearableFileInput): - if django.VERSION < (1, 9): - template_with_initial = ( - '%(initial_text)s: ' - ' %(clear_template)s
%(input_text)s: %(input)s' - ) - else: - template_name = "authentic2/profile_image_input.html" + template_name = "authentic2/profile_image_input.html" def __init__(self, *args, **kwargs): attrs = kwargs.pop('attrs', {}) diff --git a/src/authentic2/idp/saml/urls.py b/src/authentic2/idp/saml/urls.py index df87f69b7..148d0bab9 100644 --- a/src/authentic2/idp/saml/urls.py +++ b/src/authentic2/idp/saml/urls.py @@ -14,7 +14,7 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -from django.conf.urls import url +from django.urls import path, re_path from authentic2.idp.saml.saml2_endpoints import ( artifact, @@ -32,18 +32,18 @@ from authentic2.idp.saml.saml2_endpoints import ( from . import views urlpatterns = [ - url(r'^metadata$', metadata, name='a2-idp-saml-metadata'), - url(r'^sso$', sso, name='a2-idp-saml-sso'), - url(r'^continue$', continue_sso, name='a2-idp-saml-continue'), - url(r'^slo$', slo, name='a2-idp-saml-slo'), - url(r'^slo/soap$', slo_soap, name='a2-idp-saml-slo-soap'), - url(r'^idp_slo/(.*)$', idp_slo, name='a2-idp-saml-slo-idp'), - url(r'^slo_return$', slo_return, name='a2-idp-saml-slo-return'), - url(r'^finish_slo$', finish_slo, name='a2-idp-saml-finish-slo'), - url(r'^artifact$', artifact, name='a2-idp-saml-artifact'), + path('metadata', metadata, name='a2-idp-saml-metadata'), + path('sso', sso, name='a2-idp-saml-sso'), + path('continue', continue_sso, name='a2-idp-saml-continue'), + path('slo', slo, name='a2-idp-saml-slo'), + path('slo/soap', slo_soap, name='a2-idp-saml-slo-soap'), + re_path(r'^idp_slo/(.*)$', idp_slo, name='a2-idp-saml-slo-idp'), + path('slo_return', slo_return, name='a2-idp-saml-slo-return'), + path('finish_slo', finish_slo, name='a2-idp-saml-finish-slo'), + path('artifact', artifact, name='a2-idp-saml-artifact'), # legacy endpoint, now it's prefered to pass the entity_id in a parameter - url(r'^idp_sso/(.+)$', idp_sso, name='a2-idp-saml-idp-sso-named'), - url(r'^idp_sso/$', idp_sso, name='a2-idp-saml2-idp-sso'), - url(r'^federations/create/(?P\d+)/$', views.create_federation, name='a2-idp-saml2-federation-create'), - url(r'^federations/(?P\d+)/delete/$', views.delete_federation, name='a2-idp-saml2-federation-delete'), + re_path(r'^idp_sso/(.+)$', idp_sso, name='a2-idp-saml-idp-sso-named'), + path('idp_sso/', idp_sso, name='a2-idp-saml2-idp-sso'), + path('federations/create//', views.create_federation, name='a2-idp-saml2-federation-create'), + path('federations//delete/', views.delete_federation, name='a2-idp-saml2-federation-delete'), ] diff --git a/src/authentic2/idp/urls.py b/src/authentic2/idp/urls.py index abdba3091..ddf508731 100644 --- a/src/authentic2/idp/urls.py +++ b/src/authentic2/idp/urls.py @@ -14,10 +14,10 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -from django.conf.urls import url +from django.urls import re_path from authentic2.idp.interactions import consent_federation urlpatterns = [ - url(r'^consent_federation', consent_federation, name='a2-consent-federation'), + re_path(r'^consent_federation', consent_federation, name='a2-consent-federation'), ] diff --git a/src/authentic2/manager/urls.py b/src/authentic2/manager/urls.py index ea665ab2e..b932326aa 100644 --- a/src/authentic2/manager/urls.py +++ b/src/authentic2/manager/urls.py @@ -14,7 +14,7 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -from django.conf.urls import url +from django.urls import path, re_path from django.views.i18n import JavaScriptCatalog from authentic2.apps.authenticators.manager_urls import urlpatterns as authenticator_urlpatterns @@ -27,182 +27,186 @@ urlpatterns = required( utils.manager_login_required, [ # homepage - url(r'^$', views.homepage, name='a2-manager-homepage'), - url(r'^me/$', user_views.me, name='a2-manager-me'), + path('', views.homepage, name='a2-manager-homepage'), + path('me/', user_views.me, name='a2-manager-me'), # Authentic2 users - url(r'^users/$', user_views.users, name='a2-manager-users'), - url(r'^users/export/(?Pcsv)/$', user_views.users_export, name='a2-manager-users-export'), - url( + path('users/', user_views.users, name='a2-manager-users'), + re_path(r'^users/export/(?Pcsv)/$', user_views.users_export, name='a2-manager-users-export'), + re_path( r'^users/export/(?P[a-z0-9-]+)/progress/$', user_views.users_export_progress, name='a2-manager-users-export-progress', ), - url( + re_path( r'^users/export/(?P[a-z0-9-]+)/$', user_views.users_export_file, name='a2-manager-users-export-file', ), - url(r'^users/add/$', user_views.user_add_default_ou, name='a2-manager-user-add-default-ou'), - url(r'^users/add/choose-ou/$', user_views.user_add_choose_ou, name='a2-manager-user-add-choose-ou'), - url(r'^users/import/$', user_views.user_imports, name='a2-manager-users-imports'), - url( + path('users/add/', user_views.user_add_default_ou, name='a2-manager-user-add-default-ou'), + path('users/add/choose-ou/', user_views.user_add_choose_ou, name='a2-manager-user-add-choose-ou'), + path('users/import/', user_views.user_imports, name='a2-manager-users-imports'), + re_path( r'^users/import/(?P[a-z0-9]+)/download/(?P.*)$', user_views.user_import, name='a2-manager-users-import-download', ), - url(r'^users/import/(?P[a-z0-9]+)/$', user_views.user_import, name='a2-manager-users-import'), - url( + re_path( + r'^users/import/(?P[a-z0-9]+)/$', user_views.user_import, name='a2-manager-users-import' + ), + re_path( r'^users/import/(?P[a-z0-9]+)/(?P[a-z0-9]+)/$', user_views.user_import_report, name='a2-manager-users-import-report', ), - url(r'^users/(?P\d+)/add/$', user_views.user_add, name='a2-manager-user-add'), - url(r'^users/(?P\d+)/$', user_views.user_detail, name='a2-manager-user-detail'), - url(r'^users/(?P\d+)/edit/$', user_views.user_edit, name='a2-manager-user-edit'), - url(r'^users/(?P\d+)/delete/$', user_views.user_delete, name='a2-manager-user-delete'), - url(r'^users/(?P\d+)/roles/$', user_views.roles, name='a2-manager-user-roles'), - url( - r'^users/(?P\d+)/change-password/$', + path('users//add/', user_views.user_add, name='a2-manager-user-add'), + path('users//', user_views.user_detail, name='a2-manager-user-detail'), + path('users//edit/', user_views.user_edit, name='a2-manager-user-edit'), + path('users//delete/', user_views.user_delete, name='a2-manager-user-delete'), + path('users//roles/', user_views.roles, name='a2-manager-user-roles'), + path( + 'users//change-password/', user_views.user_change_password, name='a2-manager-user-change-password', ), - url( - r'^users/(?P\d+)/change-email/$', + path( + 'users//change-email/', user_views.user_change_email, name='a2-manager-user-change-email', ), - url(r'^users/(?P\d+)/su/$', user_views.su, name='a2-manager-user-su'), - url( - r'^users/(?P\d+)/authorizations/$', + path('users//su/', user_views.su, name='a2-manager-user-su'), + path( + 'users//authorizations/', user_views.user_authorizations, name='a2-manager-user-authorizations', ), - url(r'^users/(?P\d+)/journal/$', user_views.user_journal, name='a2-manager-user-journal'), + path('users//journal/', user_views.user_journal, name='a2-manager-user-journal'), # by uuid - url( + re_path( r'^users/uuid:(?P[a-z0-9]+)/$', user_views.user_detail, name='a2-manager-user-by-uuid-detail', ), - url( + re_path( r'^users/uuid:(?P[a-z0-9]+)/edit/$', user_views.user_edit, name='a2-manager-user-by-uuid-edit', ), - url( + re_path( r'^users/uuid:(?P[a-z0-9]+)/roles/$', user_views.roles, name='a2-manager-user-by-uuid-roles' ), - url( + re_path( r'^users/uuid:(?P[a-z0-9]+)/change-password/$', user_views.user_change_password, name='a2-manager-user-by-uuid-change-password', ), - url( + re_path( r'^users/uuid:(?P[a-z0-9]+)/change-email/$', user_views.user_change_email, name='a2-manager-user-by-uuid-change-email', ), - url( + re_path( r'^users/uuid:(?P[a-z0-9]+)/journal/$', user_views.user_journal, name='a2-manager-user-journal', ), # Authentic2 roles - url(r'^roles/$', role_views.listing, name='a2-manager-roles'), - url(r'^roles/import/$', role_views.roles_import, name='a2-manager-roles-import'), - url(r'^roles/csv-import/$', role_views.roles_csv_import, name='a2-manager-roles-csv-import'), - url( - r'^roles/csv-import-sample/$', + path('roles/', role_views.listing, name='a2-manager-roles'), + path('roles/import/', role_views.roles_import, name='a2-manager-roles-import'), + path('roles/csv-import/', role_views.roles_csv_import, name='a2-manager-roles-csv-import'), + path( + 'roles/csv-import-sample/', role_views.roles_csv_import_sample, name='a2-manager-roles-csv-import-sample', ), - url(r'^roles/add/$', role_views.add, name='a2-manager-role-add'), - url(r'^roles/export/(?Pcsv|json)/$', role_views.export, name='a2-manager-roles-export'), - url(r'^roles/journal/$', role_views.roles_journal, name='a2-manager-roles-journal'), - url(r'^roles/(?P\d+)/$', role_views.members, name='a2-manager-role-members'), - url(r'^roles/uuid:(?P[a-z0-9]+)/$', role_views.members, name='a2-manager-roles-by-uuid-detail'), - url(r'^roles/(?P\d+)/children/$', role_views.children, name='a2-manager-role-children'), - url(r'^roles/(?P\d+)/parents/$', role_views.parents, name='a2-manager-role-parents'), - url( - r'^roles/(?P\d+)/add-admin-user/$', + path('roles/add/', role_views.add, name='a2-manager-role-add'), + re_path(r'^roles/export/(?Pcsv|json)/$', role_views.export, name='a2-manager-roles-export'), + path('roles/journal/', role_views.roles_journal, name='a2-manager-roles-journal'), + path('roles//', role_views.members, name='a2-manager-role-members'), + re_path( + r'^roles/uuid:(?P[a-z0-9]+)/$', role_views.members, name='a2-manager-roles-by-uuid-detail' + ), + path('roles//children/', role_views.children, name='a2-manager-role-children'), + path('roles//parents/', role_views.parents, name='a2-manager-role-parents'), + path( + 'roles//add-admin-user/', role_views.add_admin_user, name='a2-manager-role-add-admin-user', ), - url( - r'^roles/(?P\d+)/remove-admin-user/(?P\d+)/$', + path( + 'roles//remove-admin-user//', role_views.remove_admin_user, name='a2-manager-role-remove-admin-user', ), - url( - r'^roles/(?P\d+)/add-admin-role/$', + path( + 'roles//add-admin-role/', role_views.add_admin_role, name='a2-manager-role-add-admin-role', ), - url( - r'^roles/(?P\d+)/remove-admin-role/(?P\d+)/$', + path( + 'roles//remove-admin-role//', role_views.remove_admin_role, name='a2-manager-role-remove-admin-role', ), - url( + re_path( r'^roles/(?P\d+)/export/(?Pcsv)/$', role_views.members_export, name='a2-manager-role-members-export', ), - url(r'^roles/(?P\d+)/delete/$', role_views.delete, name='a2-manager-role-delete'), - url(r'^roles/(?P\d+)/edit/$', role_views.edit, name='a2-manager-role-edit'), - url(r'^roles/(?P\d+)/permissions/$', role_views.permissions, name='a2-manager-role-permissions'), - url(r'^roles/(?P\d+)/journal/$', role_views.journal, name='a2-manager-role-journal'), - url( + path('roles//delete/', role_views.delete, name='a2-manager-role-delete'), + path('roles//edit/', role_views.edit, name='a2-manager-role-edit'), + path('roles//permissions/', role_views.permissions, name='a2-manager-role-permissions'), + path('roles//journal/', role_views.journal, name='a2-manager-role-journal'), + re_path( r'^roles/(?P\d+)/user-or-role-select2.json$', role_views.user_or_role_select2, name='user-or-role-select2-json', ), # Authentic2 organizational units - url(r'^organizational-units/$', ou_views.listing, name='a2-manager-ous'), - url(r'^organizational-units/add/$', ou_views.add, name='a2-manager-ou-add'), - url(r'^organizational-units/(?P\d+)/$', ou_views.detail, name='a2-manager-ou-detail'), - url(r'^organizational-units/(?P\d+)/edit/$', ou_views.edit, name='a2-manager-ou-edit'), - url(r'^organizational-units/(?P\d+)/delete/$', ou_views.delete, name='a2-manager-ou-delete'), - url(r'^organizational-units/export/(?Pjson)/$', ou_views.export, name='a2-manager-ou-export'), - url(r'^organizational-units/import/$', ou_views.ous_import, name='a2-manager-ous-import'), + path('organizational-units/', ou_views.listing, name='a2-manager-ous'), + path('organizational-units/add/', ou_views.add, name='a2-manager-ou-add'), + path('organizational-units//', ou_views.detail, name='a2-manager-ou-detail'), + path('organizational-units//edit/', ou_views.edit, name='a2-manager-ou-edit'), + path('organizational-units//delete/', ou_views.delete, name='a2-manager-ou-delete'), + re_path( + r'^organizational-units/export/(?Pjson)/$', ou_views.export, name='a2-manager-ou-export' + ), + path('organizational-units/import/', ou_views.ous_import, name='a2-manager-ous-import'), # Services - url(r'^services/$', service_views.listing, name='a2-manager-services'), - url(r'^services/(?P\d+)/$', service_views.service_detail, name='a2-manager-service'), - url( - r'^services/(?P\d+)/settings/$', + path('services/', service_views.listing, name='a2-manager-services'), + path('services//', service_views.service_detail, name='a2-manager-service'), + path( + 'services//settings/', service_views.service_settings, name='a2-manager-service-settings', ), - url( - r'^services/(?P\d+)/settings/edit/$', + path( + 'services//settings/edit/', service_views.edit_service, name='a2-manager-service-settings-edit', ), - url( - r'^services/(?P\d+)/delete/$', + path( + 'services//delete/', service_views.delete_service, name='a2-manager-service-delete', ), # Journal - url(r'^journal/$', journal_views.journal, name='a2-manager-journal'), - url( - r'^journal/event-types/$', + path('journal/', journal_views.journal, name='a2-manager-journal'), + path( + 'journal/event-types/', journal_views.journal_event_types, name='a2-manager-journal-event-types', ), # backoffice menu as json - url(r'^menu.json$', views.menu_json), + re_path(r'^menu.json$', views.menu_json), # general management - url(r'^site-export/$', views.site_export, name='a2-manager-site-export'), - url(r'^site-import/$', views.site_import, name='a2-manager-site-import'), + path('site-export/', views.site_export, name='a2-manager-site-export'), + path('site-import/', views.site_import, name='a2-manager-site-import'), # technical information including ldap config - url(r'^tech-info/$', views.tech_info, name='a2-manager-tech-info'), - url(r'^api-clients/$', views.api_clients, name='a2-manager-api-clients'), - url(r'^api-clients/add/$', views.api_client_add, name='a2-manager-api-client-add'), - url(r'^api-clients/(?P\d+)/$', views.api_client_detail, name='a2-manager-api-client-detail'), - url(r'^api-clients/(?P\d+)/edit/$', views.api_client_edit, name='a2-manager-api-client-edit'), - url( - r'^api-clients/(?P\d+)/delete/$', views.api_client_delete, name='a2-manager-api-client-delete' - ), + path('tech-info/', views.tech_info, name='a2-manager-tech-info'), + path('api-clients/', views.api_clients, name='a2-manager-api-clients'), + path('api-clients/add/', views.api_client_add, name='a2-manager-api-client-add'), + path('api-clients//', views.api_client_detail, name='a2-manager-api-client-detail'), + path('api-clients//edit/', views.api_client_edit, name='a2-manager-api-client-edit'), + path('api-clients//delete/', views.api_client_delete, name='a2-manager-api-client-delete'), ], ) @@ -210,10 +214,10 @@ urlpatterns += authenticator_urlpatterns urlpatterns += oidc_manager_urlpatterns urlpatterns += [ - url( - r'^jsi18n/$', + path( + 'jsi18n/', JavaScriptCatalog.as_view(packages=['authentic2.manager']), name='a2-manager-javascript-catalog', ), - url(r'^select2.json$', views.select2, name='django_select2-json'), + re_path(r'^select2.json$', views.select2, name='django_select2-json'), ] diff --git a/src/authentic2/middleware.py b/src/authentic2/middleware.py index aa187aaac..467074fd7 100644 --- a/src/authentic2/middleware.py +++ b/src/authentic2/middleware.py @@ -208,7 +208,7 @@ class XForwardedForMiddleware(MiddlewareMixin): def process_request(self, request): if 'HTTP_X_FORWARDED_FOR' in request.META: - request.META['REMOTE_ADDR'] = request.META['HTTP_X_FORWARDED_FOR'].split(",")[0].strip() + request.META['REMOTE_ADDR'] = request.headers['X-Forwarded-For'].split(",")[0].strip() return None diff --git a/src/authentic2/saml/admin.py b/src/authentic2/saml/admin.py index dc71de2f4..712a657a4 100644 --- a/src/authentic2/saml/admin.py +++ b/src/authentic2/saml/admin.py @@ -18,10 +18,10 @@ import logging from django import forms from django.conf import settings -from django.conf.urls import url from django.contrib import admin, messages from django.core.exceptions import ValidationError from django.forms import ModelForm +from django.urls import path from django.utils.translation import ugettext as _ try: @@ -171,8 +171,8 @@ class LibertyProviderAdmin(admin.ModelAdmin): def get_urls(self): urls = super().get_urls() urls = [ - url( - r'^add-from-url/$', + path( + 'add-from-url/', self.admin_site.admin_view( admin_views.AddLibertyProviderFromUrlView.as_view(model_admin=self) ), diff --git a/src/authentic2/saml/common.py b/src/authentic2/saml/common.py index 9fb9ccf80..641401ccf 100644 --- a/src/authentic2/saml/common.py +++ b/src/authentic2/saml/common.py @@ -510,7 +510,7 @@ def error_page(request, message, back=None, logger=None, warning=False): else: logging.error('Showing message %r on an error page', message) if back is None: - referer = request.META.get('HTTP_REFERER') + referer = request.headers.get('Referer') if referer: root_referer = __root_refererer_re.match(referer) if root_referer: diff --git a/src/authentic2/urls.py b/src/authentic2/urls.py index 119139a09..b23d0b516 100644 --- a/src/authentic2/urls.py +++ b/src/authentic2/urls.py @@ -15,11 +15,11 @@ # along with this program. If not, see . from django.conf import settings -from django.conf.urls import include, url from django.contrib import admin from django.contrib.auth import views as dj_auth_views from django.contrib.auth.decorators import login_required from django.contrib.staticfiles.views import serve +from django.urls import include, path, re_path from django.utils.translation import ugettext_lazy as _ from django.views.decorators.clickjacking import xframe_options_deny from django.views.generic import RedirectView @@ -39,94 +39,94 @@ from . import plugins, views admin.autodiscover() accounts_urlpatterns = [ - url( + re_path( r'^activate/(?P[A-Za-z0-9_ -]+)/$', views.registration_completion, name='registration_activate', ), - url(r'^delete/$', login_required(views.AccountDeleteView.as_view()), name='delete_account'), - url( + path('delete/', login_required(views.AccountDeleteView.as_view()), name='delete_account'), + re_path( r'validate-deletion/(?P[\w: -]+)/$', views.ValidateDeletionView.as_view(), name='validate_deletion', ), - url(r'^logged-in/$', views.logged_in, name='logged-in'), - url(r'^edit/$', views.edit_profile, name='profile_edit'), - url(r'^edit/required/$', views.edit_required_profile, name='profile_required_edit'), - url(r'^edit/(?P[-\w]+)/$', views.edit_profile, name='profile_edit_with_scope'), - url(r'^change-email/$', views.email_change, name='email-change'), - url(r'^change-email/verify/$', views.email_change_verify, name='email-change-verify'), - url( - r'^consents/$', + path('logged-in/', views.logged_in, name='logged-in'), + path('edit/', views.edit_profile, name='profile_edit'), + path('edit/required/', views.edit_required_profile, name='profile_required_edit'), + re_path(r'^edit/(?P[-\w]+)/$', views.edit_profile, name='profile_edit_with_scope'), + path('change-email/', views.email_change, name='email-change'), + path('change-email/verify/', views.email_change_verify, name='email-change-verify'), + path( + 'consents/', login_required(views.consents), name='consents', ), - url( - r'^consents/(?P\d+)/delete/$', + path( + 'consents//delete/', login_required(views.consent_delete), name='consent-delete', ), - url(r'^$', views.profile, name='account_management'), + path('', views.profile, name='account_management'), # Password change - url(r'^password/change/$', views.password_change, name='password_change'), - url( - r'^password/change/done/$', + path('password/change/', views.password_change, name='password_change'), + path( + 'password/change/done/', dj_auth_views.PasswordChangeDoneView.as_view(), name='password_change_done', ), # permament redirections for views moved to root - url(r'^register/$', RedirectView.as_view(permanent=True, pattern_name='registration_register')), - url(r'^register/complete/$', RedirectView.as_view(permanent=True, pattern_name='registration_complete')), - url(r'^register/closed/$', RedirectView.as_view(permanent=True, pattern_name='registration_disallowed')), - url( + path('register/', RedirectView.as_view(permanent=True, pattern_name='registration_register')), + path('register/complete/', RedirectView.as_view(permanent=True, pattern_name='registration_complete')), + path('register/closed/', RedirectView.as_view(permanent=True, pattern_name='registration_disallowed')), + re_path( r'^password/reset/confirm/(?P[A-Za-z0-9_ -]+)/$', RedirectView.as_view(permanent=True, pattern_name='password_reset_confirm'), ), - url(r'^password/reset/$', RedirectView.as_view(permanent=True, pattern_name='password_reset')), - url( - r'^password/reset/instructions/$', + path('password/reset/', RedirectView.as_view(permanent=True, pattern_name='password_reset')), + path( + 'password/reset/instructions/', RedirectView.as_view(permanent=True, pattern_name='password_reset_instructions'), ), - url( + re_path( r'^password/reset/.*', RedirectView.as_view(permanent=True, pattern_name='invalid-password-reset-urls'), ), ] urlpatterns = [ - url(r'^$', views.homepage, name='auth_homepage'), - url(r'^login/$', views.login, name='auth_login'), - url(r'^login/token/(?P[A-Za-z0-9_ -]+)/$', views.token_login, name='token_login'), - url(r'^logout/$', views.logout, name='auth_logout'), - url(r'^su/(?P[A-Za-z0-9_-]+)/$', views.su, name='su'), - url(r'^accounts/', include(accounts_urlpatterns)), - url(r'^admin/', admin.site.urls), - url(r'^idp/', include('authentic2.idp.urls')), - url(r'^manage/', include('authentic2.manager.urls')), - url(r'^api/', include('authentic2.api_urls')), - url(r'^continue/$', views.display_message_and_continue, name='continue'), - url(r'^\.well-known/change-password$', RedirectView.as_view(pattern_name='password_change')), + path('', views.homepage, name='auth_homepage'), + path('login/', views.login, name='auth_login'), + re_path(r'^login/token/(?P[A-Za-z0-9_ -]+)/$', views.token_login, name='token_login'), + path('logout/', views.logout, name='auth_logout'), + re_path(r'^su/(?P[A-Za-z0-9_-]+)/$', views.su, name='su'), + re_path(r'^accounts/', include(accounts_urlpatterns)), + re_path(r'^admin/', admin.site.urls), + re_path(r'^idp/', include('authentic2.idp.urls')), + re_path(r'^manage/', include('authentic2.manager.urls')), + re_path(r'^api/', include('authentic2.api_urls')), + path('continue/', views.display_message_and_continue, name='continue'), + re_path(r'^\.well-known/change-password$', RedirectView.as_view(pattern_name='password_change')), # Registration - url(r'^register/$', views.RegistrationView.as_view(), name='registration_register'), - url(r'^register/complete/$', views.registration_complete, name='registration_complete'), - url( - r'^register/closed/$', + path('register/', views.RegistrationView.as_view(), name='registration_register'), + path('register/complete/', views.registration_complete, name='registration_complete'), + path( + 'register/closed/', TemplateView.as_view(template_name='registration/registration_closed.html'), name='registration_disallowed', ), # Password reset - url( + re_path( r'^password/reset/confirm/(?P[A-Za-z0-9_ -]+)/$', views.password_reset_confirm, name='password_reset_confirm', ), - url(r'^password/reset/$', views.password_reset, name='password_reset'), - url( - r'^password/reset/instructions/$', + path('password/reset/', views.password_reset, name='password_reset'), + path( + 'password/reset/instructions/', views.password_reset_instructions, name='password_reset_instructions', ), - url( + re_path( r'^password/reset/.*', views.old_view_redirect, kwargs={ @@ -146,14 +146,14 @@ except Exception: pass if settings.DEBUG: - urlpatterns += [url(r'^static/(?P.*)$', serve)] - urlpatterns += [url(r'^media/(?P.*)$', media_serve, {'document_root': settings.MEDIA_ROOT})] + urlpatterns += [re_path(r'^static/(?P.*)$', serve)] + urlpatterns += [re_path(r'^media/(?P.*)$', media_serve, {'document_root': settings.MEDIA_ROOT})] if settings.DEBUG and 'debug_toolbar' in settings.INSTALLED_APPS: import debug_toolbar # pylint: disable=import-error urlpatterns = [ - url(r'^__debug__/', include(debug_toolbar.urls)), + re_path(r'^__debug__/', include(debug_toolbar.urls)), ] + urlpatterns # prevent click-jacking on authentic views @@ -163,12 +163,12 @@ urlpatterns = plugins.register_plugins_urls(urlpatterns) authentic2_idp_saml_urls = required( (setting_enabled('ENABLE', settings=authentic2.idp.saml.app_settings), lasso_required()), - [url(r'^idp/saml2/', include('authentic2.idp.saml.urls'))], + [re_path(r'^idp/saml2/', include('authentic2.idp.saml.urls'))], ) authentic2_idp_cas_urls = required( (setting_enabled('ENABLE', settings=authentic2_idp_cas.app_settings),), - [url(r'^idp/cas/', include('authentic2_idp_cas.urls'))], + [re_path(r'^idp/cas/', include('authentic2_idp_cas.urls'))], ) urlpatterns = ( diff --git a/src/authentic2/utils/misc.py b/src/authentic2/utils/misc.py index 95a030ab5..6e5b4f54d 100644 --- a/src/authentic2/utils/misc.py +++ b/src/authentic2/utils/misc.py @@ -550,7 +550,7 @@ def check_referer(request, skip_post=True): """ if skip_post and request.method == 'POST': return True - referer = request.META.get('HTTP_REFERER') + referer = request.headers.get('Referer') return referer and same_origin(request.build_absolute_uri(), referer) diff --git a/src/authentic2/views.py b/src/authentic2/views.py index cb8d410d6..050d55d5d 100644 --- a/src/authentic2/views.py +++ b/src/authentic2/views.py @@ -778,7 +778,7 @@ class LoggedInView(View): def check_referrer(self): '''Check if the given referer is authorized''' - referer = self.request.META.get('HTTP_REFERER', '') + referer = self.request.headers.get('Referer', '') for valid_referer in app_settings.VALID_REFERERS: if referer.startswith(valid_referer): return True diff --git a/src/authentic2_auth_fc/urls.py b/src/authentic2_auth_fc/urls.py index 1b27c4839..746989270 100644 --- a/src/authentic2_auth_fc/urls.py +++ b/src/authentic2_auth_fc/urls.py @@ -14,16 +14,16 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -from django.conf.urls import include, url +from django.urls import include, path, re_path from . import views fcpatterns = [ - url(r'^callback/$', views.login_or_link, name='fc-login-or-link'), - url(r'^callback_logout/$', views.logout, name='fc-logout'), + path('callback/', views.login_or_link, name='fc-login-or-link'), + path('callback_logout/', views.logout, name='fc-logout'), ] urlpatterns = [ - url(r'^fc/', include(fcpatterns)), - url(r'^accounts/fc/unlink/$', views.unlink, name='fc-unlink'), + re_path(r'^fc/', include(fcpatterns)), + path('accounts/fc/unlink/', views.unlink, name='fc-unlink'), ] diff --git a/src/authentic2_auth_oidc/urls.py b/src/authentic2_auth_oidc/urls.py index 87003b77c..d96aef8b7 100644 --- a/src/authentic2_auth_oidc/urls.py +++ b/src/authentic2_auth_oidc/urls.py @@ -14,7 +14,6 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -from django.conf.urls import url from django.urls import path from authentic2.apps.authenticators.manager_urls import superuser_login_required @@ -23,9 +22,9 @@ from authentic2.decorators import required from . import views urlpatterns = [ - url(r'^accounts/oidc/login/(?P\d+)/$', views.oidc_login, name='oidc-login'), - url(r'^accounts/oidc/login/$', views.login_initiate, name='oidc-login-initiate'), - url(r'^accounts/oidc/callback/$', views.login_callback, name='oidc-login-callback'), + path('accounts/oidc/login//', views.oidc_login, name='oidc-login'), + path('accounts/oidc/login/', views.login_initiate, name='oidc-login-initiate'), + path('accounts/oidc/callback/', views.login_callback, name='oidc-login-callback'), ] urlpatterns += required( diff --git a/src/authentic2_auth_saml/urls.py b/src/authentic2_auth_saml/urls.py index f2473f404..fe892e91d 100644 --- a/src/authentic2_auth_saml/urls.py +++ b/src/authentic2_auth_saml/urls.py @@ -14,8 +14,7 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -from django.conf.urls import include, url -from django.urls import path +from django.urls import include, path, re_path from authentic2.apps.authenticators.manager_urls import superuser_login_required from authentic2.decorators import required @@ -23,7 +22,7 @@ from authentic2.decorators import required from . import views urlpatterns = [ - url(r'^accounts/saml/', include('mellon.urls'), kwargs={'template_base': 'authentic2/base.html'}) + re_path(r'^accounts/saml/', include('mellon.urls'), kwargs={'template_base': 'authentic2/base.html'}) ] urlpatterns += required( diff --git a/src/authentic2_idp_cas/urls.py b/src/authentic2_idp_cas/urls.py index ca7c01af0..e96d8ca5c 100644 --- a/src/authentic2_idp_cas/urls.py +++ b/src/authentic2_idp_cas/urls.py @@ -14,16 +14,16 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -from django.conf.urls import url +from django.urls import path, re_path from . import views urlpatterns = [ - url('^login/?$', views.login, name='a2-idp-cas-login'), - url('^continue/$', views._continue, name='a2-idp-cas-continue'), - url('^validate/?$', views.validate, name='a2-idp-cas-validate'), - url('^serviceValidate/?$', views.service_validate, name='a2-idp-cas-service-validate'), - url('^logout/?$', views.logout, name='a2-idp-cas-logout'), - url('^proxy/?$', views.proxy, name='a2-idp-cas-proxy'), - url('^proxyValidate/?$', views.proxy_validate, name='a2-idp-cas-proxy-validate'), + re_path('^login/?$', views.login, name='a2-idp-cas-login'), + path('continue/', views._continue, name='a2-idp-cas-continue'), + re_path('^validate/?$', views.validate, name='a2-idp-cas-validate'), + re_path('^serviceValidate/?$', views.service_validate, name='a2-idp-cas-service-validate'), + re_path('^logout/?$', views.logout, name='a2-idp-cas-logout'), + re_path('^proxy/?$', views.proxy, name='a2-idp-cas-proxy'), + re_path('^proxyValidate/?$', views.proxy_validate, name='a2-idp-cas-proxy-validate'), ] diff --git a/src/authentic2_idp_oidc/manager/urls.py b/src/authentic2_idp_oidc/manager/urls.py index 117ebb334..f94d85309 100644 --- a/src/authentic2_idp_oidc/manager/urls.py +++ b/src/authentic2_idp_oidc/manager/urls.py @@ -15,7 +15,7 @@ # along with this program. If not, see . -from django.conf.urls import url +from django.urls import path from authentic2.decorators import required from authentic2.manager.utils import manager_login_required @@ -25,19 +25,19 @@ from . import views urlpatterns = required( manager_login_required, [ - url(r'^services/add-oidc/$', views.add_oidc_service, name='a2-manager-add-oidc-service'), - url( - r'^services/(?P\d+)/claim/add/$', + path('services/add-oidc/', views.add_oidc_service, name='a2-manager-add-oidc-service'), + path( + 'services//claim/add/', views.oidc_claim_add, name='a2-manager-oidc-claim-add', ), - url( - r'^services/(?P\d+)/claim/(?P\d+)/edit/$', + path( + 'services//claim//edit/', views.oidc_claim_edit, name='a2-manager-oidc-claim-edit', ), - url( - r'^services/(?P\d+)/claim/(?P\d+)/delete/$', + path( + 'services//claim//delete/', views.oidc_claim_delete, name='a2-manager-oidc-claim-delete', ), diff --git a/src/authentic2_idp_oidc/urls.py b/src/authentic2_idp_oidc/urls.py index 19427aa27..623769155 100644 --- a/src/authentic2_idp_oidc/urls.py +++ b/src/authentic2_idp_oidc/urls.py @@ -14,15 +14,17 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -from django.conf.urls import url +from django.urls import re_path from . import views urlpatterns = [ - url(r'^.well-known/openid-configuration$', views.openid_configuration, name='oidc-openid-configuration'), - url(r'^idp/oidc/certs/?$', views.certs, name='oidc-certs'), - url(r'^idp/oidc/authorize/?$', views.authorize, name='oidc-authorize'), - url(r'^idp/oidc/token/?$', views.token, name='oidc-token'), - url(r'^idp/oidc/user_info/?$', views.user_info, name='oidc-user-info'), - url(r'^idp/oidc/logout/?$', views.logout, name='oidc-logout'), + re_path( + r'^.well-known/openid-configuration$', views.openid_configuration, name='oidc-openid-configuration' + ), + re_path(r'^idp/oidc/certs/?$', views.certs, name='oidc-certs'), + re_path(r'^idp/oidc/authorize/?$', views.authorize, name='oidc-authorize'), + re_path(r'^idp/oidc/token/?$', views.token, name='oidc-token'), + re_path(r'^idp/oidc/user_info/?$', views.user_info, name='oidc-user-info'), + re_path(r'^idp/oidc/logout/?$', views.logout, name='oidc-logout'), ] diff --git a/src/authentic2_idp_oidc/views.py b/src/authentic2_idp_oidc/views.py index 4a8fa1a93..6d59ca4e5 100644 --- a/src/authentic2_idp_oidc/views.py +++ b/src/authentic2_idp_oidc/views.py @@ -535,7 +535,7 @@ def authorize_for_client(request, client, redirect_uri): def parse_http_basic(request): - authorization = request.META['HTTP_AUTHORIZATION'].split() + authorization = request.headers['Authorization'].split() if authorization[0] != 'Basic' or len(authorization) != 2: return None, None try: @@ -817,7 +817,7 @@ def token(request, *args, **kwargs): def authenticate_access_token(request): if 'HTTP_AUTHORIZATION' not in request.META: raise InvalidRequest(_('Bearer authentication is mandatory'), status=401) - authorization = request.META['HTTP_AUTHORIZATION'].split() + authorization = request.headers['Authorization'].split() if authorization[0] != 'Bearer' or len(authorization) != 2: raise InvalidRequest(_('Invalid Bearer authentication'), status=401) try: diff --git a/tests/cache_urls.py b/tests/cache_urls.py index 5ca85c8c7..660c7ee22 100644 --- a/tests/cache_urls.py +++ b/tests/cache_urls.py @@ -14,8 +14,8 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -from django.conf.urls import url from django.http import HttpResponse +from django.urls import path from authentic2.utils.cache import SessionCache @@ -32,4 +32,4 @@ def session_cache(request): return HttpResponse('%s' % value) -urlpatterns = [url(r'^session_cache/$', session_cache)] +urlpatterns = [path('session_cache/', session_cache)] diff --git a/tests/conftest.py b/tests/conftest.py index 3d3971a09..5d50ca05e 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -20,7 +20,6 @@ import inspect import urllib.parse from unittest import mock -import django import django_webtest import pytest from django.contrib.auth import get_user_model @@ -448,9 +447,6 @@ def service(db): @pytest.fixture() def migration(request, transactional_db): # see https://gist.github.com/asfaltboy/b3e6f9b5d95af8ba2cc46f2ba6eae5e2 - if django.VERSION < (1, 9): - pytest.skip('migration fixture only works with Django 1.9') - # pylint: disable=pointless-string-statement """ This fixture returns a helper object to test Django data migrations. The fixture returns an object with two methods; diff --git a/tests/test_journal_app/urls.py b/tests/test_journal_app/urls.py index 3a76202c9..97fc49977 100644 --- a/tests/test_journal_app/urls.py +++ b/tests/test_journal_app/urls.py @@ -14,10 +14,10 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -from django.conf.urls import url +from django.urls import re_path from . import views urlpatterns = [ - url('^login/(?P[^/]+)/', views.login_view), + re_path('^login/(?P[^/]+)/', views.login_view), ] -- 2.30.2