misc: change django-upgrade target version to 3.2 (#75442)

This commit is contained in:
Valentin Deniaud 2023-03-15 16:02:17 +01:00
parent 7ee0ad90ab
commit e1290397a9
44 changed files with 73 additions and 175 deletions

View File

@ -7,10 +7,10 @@ repos:
- id: pyupgrade - id: pyupgrade
args: ['--keep-percent-format', '--py37-plus'] args: ['--keep-percent-format', '--py37-plus']
- repo: https://github.com/adamchainz/django-upgrade - repo: https://github.com/adamchainz/django-upgrade
rev: 1.10.0 rev: 1.13.0
hooks: hooks:
- id: django-upgrade - id: django-upgrade
args: ['--target-version', '2.2'] args: ['--target-version', '3.2']
- repo: https://github.com/psf/black - repo: https://github.com/psf/black
rev: 22.3.0 rev: 22.3.0
hooks: hooks:

2
README
View File

@ -93,7 +93,7 @@ djhtml is used to automatically indent html files, using those parameters:
django-upgrade is used to automatically upgrade Django syntax, using those parameters: django-upgrade is used to automatically upgrade Django syntax, using those parameters:
django-upgrade --target-version 2.2 django-upgrade --target-version 3.2
There is .pre-commit-config.yaml to use pre-commit to automatically run these tools There is .pre-commit-config.yaml to use pre-commit to automatically run these tools
before commits. (execute `pre-commit install` to install the git hook.) before commits. (execute `pre-commit install` to install the git hook.)

View File

@ -16,8 +16,6 @@
import django import django
default_app_config = 'authentic2.app.Authentic2Config'
if django.VERSION < (2,): if django.VERSION < (2,):
from django.forms import fields from django.forms import fields

View File

@ -13,5 +13,3 @@
# #
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
default_app_config = 'authentic2.a2_rbac.apps.Authentic2RBACConfig'

View File

@ -86,11 +86,10 @@ class PermissionAdmin(admin.ModelAdmin):
list_display = ('name', 'operation', 'ou', 'target') list_display = ('name', 'operation', 'ou', 'target')
list_select_related = True list_select_related = True
@admin.display(description=_('name'))
def name(self, obj): def name(self, obj):
return str(obj) return str(obj)
name.short_description = _('name')
admin.site.register(models.Role, RoleAdmin) admin.site.register(models.Role, RoleAdmin)
admin.site.register(models.OrganizationalUnit, OrganizationalUnitAdmin) admin.site.register(models.OrganizationalUnit, OrganizationalUnitAdmin)

View File

@ -36,13 +36,11 @@ from .nonce.models import Nonce
from .utils import misc as utils_misc from .utils import misc as utils_misc
@admin.action(description=_('Cleanup expired objects'))
def cleanup_action(modeladmin, request, queryset): def cleanup_action(modeladmin, request, queryset):
queryset.cleanup() queryset.cleanup()
cleanup_action.short_description = _('Cleanup expired objects')
class CleanupAdminMixin(admin.ModelAdmin): class CleanupAdminMixin(admin.ModelAdmin):
def get_actions(self, request): def get_actions(self, request):
actions = super().get_actions(request) actions = super().get_actions(request)
@ -51,13 +49,11 @@ class CleanupAdminMixin(admin.ModelAdmin):
return actions return actions
@admin.register(Nonce)
class NonceModelAdmin(admin.ModelAdmin): class NonceModelAdmin(admin.ModelAdmin):
list_display = ("value", "context", "not_on_or_after") list_display = ("value", "context", "not_on_or_after")
admin.site.register(Nonce, NonceModelAdmin)
class AttributeValueAdmin(admin.ModelAdmin): class AttributeValueAdmin(admin.ModelAdmin):
list_display = ('content_type', 'owner', 'attribute', 'content') list_display = ('content_type', 'owner', 'attribute', 'content')
@ -100,25 +96,25 @@ DB_SESSION_ENGINES = (
if settings.SESSION_ENGINE in DB_SESSION_ENGINES: if settings.SESSION_ENGINE in DB_SESSION_ENGINES:
@admin.register(Session)
class SessionAdmin(admin.ModelAdmin): class SessionAdmin(admin.ModelAdmin):
@admin.display(description=_('session data'))
def _session_data(self, obj): def _session_data(self, obj):
return pprint.pformat(obj.get_decoded()).replace('\n', '<br>\n') return pprint.pformat(obj.get_decoded()).replace('\n', '<br>\n')
_session_data.allow_tags = True
_session_data.short_description = _('session data')
list_display = ['session_key', 'ips', 'user', '_session_data', 'expire_date'] list_display = ['session_key', 'ips', 'user', '_session_data', 'expire_date']
fields = ['session_key', 'ips', 'user', '_session_data', 'expire_date'] fields = ['session_key', 'ips', 'user', '_session_data', 'expire_date']
readonly_fields = ['ips', 'user', '_session_data'] readonly_fields = ['ips', 'user', '_session_data']
date_hierarchy = 'expire_date' date_hierarchy = 'expire_date'
actions = ['clear_expired'] actions = ['clear_expired']
@admin.display(description=_('IP adresses'))
def ips(self, session): def ips(self, session):
content = session.get_decoded() content = session.get_decoded()
ips = content.get('ips', set()) ips = content.get('ips', set())
return ', '.join(ips) return ', '.join(ips)
ips.short_description = _('IP adresses') @admin.display(description=_('user'))
def user(self, session): def user(self, session):
from django.contrib import auth from django.contrib import auth
from django.contrib.auth import models as auth_models from django.contrib.auth import models as auth_models
@ -137,15 +133,10 @@ if settings.SESSION_ENGINE in DB_SESSION_ENGINES:
user = _('deleted user %r') % user_id user = _('deleted user %r') % user_id
return user return user
user.short_description = _('user') @admin.action(description=_('clear expired sessions'))
def clear_expired(self, request, queryset): def clear_expired(self, request, queryset):
queryset.filter(expire_date__lt=timezone.now()).delete() queryset.filter(expire_date__lt=timezone.now()).delete()
clear_expired.short_description = _('clear expired sessions')
admin.site.register(Session, SessionAdmin)
class ExternalUserListFilter(admin.SimpleListFilter): class ExternalUserListFilter(admin.SimpleListFilter):
title = _('external') title = _('external')
@ -283,6 +274,7 @@ class UserCreationForm(BaseUserForm):
return user return user
@admin.register(User)
class AuthenticUserAdmin(UserAdmin): class AuthenticUserAdmin(UserAdmin):
fieldsets = ( fieldsets = (
(None, {'fields': ('uuid', 'ou', 'password')}), (None, {'fields': ('uuid', 'ou', 'password')}),
@ -371,17 +363,13 @@ class AuthenticUserAdmin(UserAdmin):
kwargs['fields'] = fields kwargs['fields'] = fields
return super().get_form(request, obj=obj, **kwargs) return super().get_form(request, obj=obj, **kwargs)
@admin.action(description=_('Mark as inactive'))
@transaction.atomic @transaction.atomic
def mark_as_inactive(self, request, queryset): def mark_as_inactive(self, request, queryset):
timestamp = timezone.now() timestamp = timezone.now()
for user in queryset: for user in queryset:
user.mark_as_inactive(timestamp=timestamp) user.mark_as_inactive(timestamp=timestamp)
mark_as_inactive.short_description = _('Mark as inactive')
admin.site.register(User, AuthenticUserAdmin)
class AttributeForm(forms.ModelForm): class AttributeForm(forms.ModelForm):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
@ -421,30 +409,24 @@ class AttributeAdmin(admin.ModelAdmin):
admin.site.register(models.Attribute, AttributeAdmin) admin.site.register(models.Attribute, AttributeAdmin)
@admin.register(DeletedUser)
class DeletedUserAdmin(admin.ModelAdmin): class DeletedUserAdmin(admin.ModelAdmin):
list_display = ['deleted', 'old_user_id', 'old_uuid', 'old_email'] list_display = ['deleted', 'old_user_id', 'old_uuid', 'old_email']
date_hierarchy = 'deleted' date_hierarchy = 'deleted'
search_fields = ['=old_user_id', '^old_uuid', 'old_email'] search_fields = ['=old_user_id', '^old_uuid', 'old_email']
admin.site.register(DeletedUser, DeletedUserAdmin) @admin.register(ProfileType)
class ProfileTypeAdmin(admin.ModelAdmin): class ProfileTypeAdmin(admin.ModelAdmin):
list_display = ['uuid', 'name', 'slug'] list_display = ['uuid', 'name', 'slug']
readonly_fields = ['uuid'] readonly_fields = ['uuid']
admin.site.register(ProfileType, ProfileTypeAdmin) @admin.register(Profile)
class ProfileAdmin(admin.ModelAdmin): class ProfileAdmin(admin.ModelAdmin):
list_display = ['profile_type', 'user', 'identifier', 'email'] list_display = ['profile_type', 'user', 'identifier', 'email']
admin.site.register(Profile, ProfileAdmin)
@never_cache @never_cache
def login(request, extra_context=None): def login(request, extra_context=None):
return utils_misc.redirect_to_login(request, login_url=utils_misc.get_manager_login_url()) return utils_misc.redirect_to_login(request, login_url=utils_misc.get_manager_login_url())

View File

@ -14,5 +14,3 @@
# #
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
default_app_config = 'authentic2.apps.journal.app.JournalAppConfig'

View File

@ -22,6 +22,7 @@ from django.utils.html import format_html
from .models import Event, EventType from .models import Event, EventType
@admin.register(EventType)
class EventTypeAdmin(admin.ModelAdmin): class EventTypeAdmin(admin.ModelAdmin):
list_display = [ list_display = [
'__str__', '__str__',
@ -29,9 +30,7 @@ class EventTypeAdmin(admin.ModelAdmin):
] ]
admin.site.register(EventType, EventTypeAdmin) @admin.register(Event)
class EventAdmin(admin.ModelAdmin): class EventAdmin(admin.ModelAdmin):
date_hierarchy = 'timestamp' date_hierarchy = 'timestamp'
list_filter = ['type'] list_filter = ['type']
@ -65,6 +64,3 @@ class EventAdmin(admin.ModelAdmin):
def raw_json(self, event): def raw_json(self, event):
return format_html('<pre>{}</pre>', json.dumps(event.data or {}, indent=4)) return format_html('<pre>{}</pre>', json.dumps(event.data or {}, indent=4))
admin.site.register(Event, EventAdmin)

View File

@ -5,13 +5,9 @@ import django.contrib.postgres.fields
import django.db.models.deletion import django.db.models.deletion
from django.conf import settings from django.conf import settings
from django.db import migrations, models from django.db import migrations, models
from django.db.models import JSONField
from django.utils import timezone from django.utils import timezone
if django.VERSION < (3, 1):
from django.contrib.postgres.fields.jsonb import JSONField # noqa pylint: disable=ungrouped-imports
else:
from django.db.models import JSONField
class Migration(migrations.Migration): class Migration(migrations.Migration):

View File

@ -27,10 +27,10 @@ from django.conf import settings
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.contrib.postgres.fields import ArrayField from django.contrib.postgres.fields import ArrayField
from django.contrib.postgres.fields.jsonb import KeyTextTransform
from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ObjectDoesNotExist
from django.db import models from django.db import models
from django.db.models import Count, F, Q, QuerySet, Value from django.db.models import Count, F, JSONField, Q, QuerySet, Value
from django.db.models.fields.json import KeyTextTransform
from django.db.models.functions import Trunc from django.db.models.functions import Trunc
from django.utils.timezone import now, utc from django.utils.timezone import now, utc
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
@ -40,11 +40,6 @@ from authentic2.utils.cache import GlobalCache
from . import sql from . import sql
from .utils import Statistics from .utils import Statistics
if django.VERSION < (3, 1):
from django.contrib.postgres.fields.jsonb import JSONField # noqa pylint: disable=ungrouped-imports
else:
from django.db.models import JSONField
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
User = get_user_model() User = get_user_model()

View File

@ -18,8 +18,6 @@ from django.contrib.auth import get_user_model
from authentic2 import app_settings from authentic2 import app_settings
default_app_config = 'authentic2.backends.apps.AppConfig'
def get_user_queryset(): def get_user_queryset():
User = get_user_model() User = get_user_model()

View File

@ -13,5 +13,3 @@
# #
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
default_app_config = 'authentic2.custom_user.apps.CustomUserConfig'

View File

@ -28,7 +28,7 @@ from django.utils.encoding import force_str
class Command(BaseCommand): class Command(BaseCommand):
help = "Change a user's password for django.contrib.auth." help = "Change a user's password for django.contrib.auth."
requires_system_checks = False requires_system_checks = []
def add_arguments(self, parser): def add_arguments(self, parser):
parser.add_argument('username', nargs='?', type=str) parser.add_argument('username', nargs='?', type=str)

View File

@ -23,7 +23,7 @@ from authentic2.custom_user.models import User
class Command(BaseCommand): class Command(BaseCommand):
help = "Fix user attributes" help = "Fix user attributes"
requires_system_checks = False requires_system_checks = []
def handle(self, *args, **options): def handle(self, *args, **options):
user_ids = User.objects.values_list('id', flat=True) user_ids = User.objects.values_list('id', flat=True)

View File

@ -1,12 +1,7 @@
# Generated by Django 2.2.12 on 2020-05-05 14:16 # Generated by Django 2.2.12 on 2020-05-05 14:16
import django
from django.db import migrations, models from django.db import migrations, models
from django.db.models import JSONField
if django.VERSION < (3, 1):
from django.contrib.postgres.fields.jsonb import JSONField # noqa pylint: disable=ungrouped-imports
else:
from django.db.models import JSONField
class Migration(migrations.Migration): class Migration(migrations.Migration):

View File

@ -6,11 +6,7 @@ import django
import django.db.models.deletion import django.db.models.deletion
from django.conf import settings from django.conf import settings
from django.db import migrations, models from django.db import migrations, models
from django.db.models import JSONField
if django.VERSION < (3, 1):
from django.contrib.postgres.fields.jsonb import JSONField # noqa pylint: disable=ungrouped-imports
else:
from django.db.models import JSONField
class Migration(migrations.Migration): class Migration(migrations.Migration):

View File

@ -22,7 +22,6 @@ import operator
import os import os
import uuid import uuid
import django
from django.contrib import auth from django.contrib import auth
from django.contrib.auth.models import AbstractBaseUser, Group from django.contrib.auth.models import AbstractBaseUser, Group
from django.contrib.auth.models import Permission as AuthPermission from django.contrib.auth.models import Permission as AuthPermission
@ -46,6 +45,8 @@ except ImportError:
return _user_get_permissions(user, obj, 'all') return _user_get_permissions(user, obj, 'all')
from django.db.models import JSONField
from authentic2 import app_settings from authentic2 import app_settings
from authentic2.a2_rbac.models import RoleParenting from authentic2.a2_rbac.models import RoleParenting
from authentic2.decorators import errorcollector from authentic2.decorators import errorcollector
@ -58,11 +59,6 @@ from authentic2.validators import PhoneNumberValidator, email_validator
from .backends import DjangoRBACBackend from .backends import DjangoRBACBackend
from .managers import UserManager, UserQuerySet from .managers import UserManager, UserQuerySet
if django.VERSION < (3, 1):
from django.contrib.postgres.fields.jsonb import JSONField # noqa pylint: disable=ungrouped-imports
else:
from django.db.models import JSONField
@RequestCache @RequestCache
def get_attributes_map(): def get_attributes_map():

View File

@ -24,11 +24,11 @@
import logging import logging
import urllib.parse import urllib.parse
from urllib.parse import quote
from xml.dom.minidom import parseString from xml.dom.minidom import parseString
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect
from django.urls import path, reverse from django.urls import path, reverse
from django.utils.http import urlquote
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from authentic2 import settings from authentic2 import settings
@ -220,7 +220,7 @@ def disco(request):
def idp_selection(request): def idp_selection(request):
# XXX: Code here the IdP selection # XXX: Code here the IdP selection
idp_selected = urlquote('http://www.identity-hub.com/idp/saml2/metadata') idp_selected = quote('http://www.identity-hub.com/idp/saml2/metadata')
return HttpResponseRedirect('%s?idp_selected=%s' % (reverse(disco), idp_selected)) return HttpResponseRedirect('%s?idp_selected=%s' % (reverse(disco), idp_selected))

View File

@ -38,9 +38,6 @@ class SAML2IdPConfig(AppConfig):
return Plugin() return Plugin()
default_app_config = 'authentic2.idp.saml.SAML2IdPConfig'
def check_authentic2_config(app_configs, **kwargs): def check_authentic2_config(app_configs, **kwargs):
from . import app_settings from . import app_settings

View File

@ -111,7 +111,7 @@ class Command(BaseCommand):
'''Load LDAP ldif file''' '''Load LDAP ldif file'''
can_import_django_settings = True can_import_django_settings = True
requires_system_checks = True requires_system_checks = "__all__"
help = 'Load/update LDIF files as users' help = 'Load/update LDIF files as users'
def add_arguments(self, parser): def add_arguments(self, parser):

View File

@ -16,5 +16,3 @@
# django_select2.conf must be loaded early to modify django.conf.settings before everybody # django_select2.conf must be loaded early to modify django.conf.settings before everybody
import django_select2.conf # noqa: F401 import django_select2.conf # noqa: F401
default_app_config = 'authentic2.manager.apps.AppConfig'

View File

@ -207,7 +207,7 @@ class XForwardedForMiddleware(MiddlewareMixin):
forged (behind a reverse proxy for example).""" forged (behind a reverse proxy for example)."""
def process_request(self, request): def process_request(self, request):
if 'HTTP_X_FORWARDED_FOR' in request.META: if 'x-forwarded-for' in request.headers:
request.META['REMOTE_ADDR'] = request.headers['X-Forwarded-For'].split(",")[0].strip() request.META['REMOTE_ADDR'] = request.headers['X-Forwarded-For'].split(",")[0].strip()
return None return None

View File

@ -2,13 +2,8 @@
import uuid import uuid
import django
from django.db import migrations, models from django.db import migrations, models
from django.db.models import JSONField
if django.VERSION < (3, 1):
from django.contrib.postgres.fields.jsonb import JSONField # noqa pylint: disable=ungrouped-imports
else:
from django.db.models import JSONField
class Migration(migrations.Migration): class Migration(migrations.Migration):

View File

@ -21,8 +21,8 @@ import os
import time import time
import urllib.parse import urllib.parse
import uuid import uuid
from urllib.parse import quote
import django
from django.conf import settings from django.conf import settings
from django.contrib import auth from django.contrib import auth
from django.contrib.contenttypes.fields import GenericForeignKey from django.contrib.contenttypes.fields import GenericForeignKey
@ -32,10 +32,10 @@ from django.contrib.postgres.indexes import GinIndex
from django.contrib.postgres.search import SearchVectorField from django.contrib.postgres.search import SearchVectorField
from django.core.exceptions import PermissionDenied, ValidationError from django.core.exceptions import PermissionDenied, ValidationError
from django.db import DatabaseError, models, transaction from django.db import DatabaseError, models, transaction
from django.db.models import JSONField
from django.db.models.query import Q from django.db.models.query import Q
from django.urls import reverse from django.urls import reverse
from django.utils import timezone from django.utils import timezone
from django.utils.http import urlquote
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from model_utils.managers import QueryManager from model_utils.managers import QueryManager
@ -51,11 +51,6 @@ from . import natural_key as unused_natural_key # pylint: disable=unused-import
from .utils.misc import ServiceAccessDenied from .utils.misc import ServiceAccessDenied
from .utils.sms import create_sms_code from .utils.sms import create_sms_code
if django.VERSION < (3, 1):
from django.contrib.postgres.fields.jsonb import JSONField # noqa pylint: disable=ungrouped-imports
else:
from django.db.models import JSONField
class UserExternalId(models.Model): class UserExternalId(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=_('user'), on_delete=models.CASCADE) user = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=_('user'), on_delete=models.CASCADE)
@ -135,7 +130,7 @@ class LogoutUrlAbstract(models.Model):
request.build_absolute_uri(urllib.parse.urljoin(settings.STATIC_URL, 'authentic2/images/ok.png')) request.build_absolute_uri(urllib.parse.urljoin(settings.STATIC_URL, 'authentic2/images/ok.png'))
+ '?nonce=%s' % time.time() + '?nonce=%s' % time.time()
) )
return self.logout_url.format(urlquote(ok_icon_url)) return self.logout_url.format(quote(ok_icon_url))
class Meta: class Meta:
abstract = True abstract = True

View File

@ -23,7 +23,7 @@ import logging
import pkg_resources import pkg_resources
from django.apps import apps from django.apps import apps
from django.urls import include, re_path from django.urls import include, path
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -80,10 +80,10 @@ def register_plugins_urls(urlpatterns, group_name=DEFAULT_GROUP_NAME):
for plugin in plugins: for plugin in plugins:
if hasattr(plugin, 'get_before_urls'): if hasattr(plugin, 'get_before_urls'):
urls = plugin.get_before_urls() urls = plugin.get_before_urls()
before_urls.append(re_path('^', include(urls))) before_urls.append(path('', include(urls)))
if hasattr(plugin, 'get_after_urls'): if hasattr(plugin, 'get_after_urls'):
urls = plugin.get_after_urls() urls = plugin.get_after_urls()
after_urls.append(re_path('^', include(urls))) after_urls.append(path('', include(urls)))
return before_urls + urlpatterns + after_urls return before_urls + urlpatterns + after_urls

View File

@ -16,8 +16,6 @@
from django.apps import AppConfig from django.apps import AppConfig
default_app_config = 'authentic2.saml.A2SAMLAppConfig'
class A2SAMLAppConfig(AppConfig): class A2SAMLAppConfig(AppConfig):
name = 'authentic2.saml' name = 'authentic2.saml'

View File

@ -148,6 +148,7 @@ class SAMLAttributeInlineAdmin(GenericTabularInline):
return super().get_formset(request, obj=obj, **kwargs) return super().get_formset(request, obj=obj, **kwargs)
@admin.register(LibertyProvider)
class LibertyProviderAdmin(admin.ModelAdmin): class LibertyProviderAdmin(admin.ModelAdmin):
form = LibertyProviderForm form = LibertyProviderForm
list_display = ('name', 'ou', 'slug', 'entity_id') list_display = ('name', 'ou', 'slug', 'entity_id')
@ -194,6 +195,7 @@ class LibertyFederationAdmin(admin.ModelAdmin):
return name_id_format return name_id_format
@admin.register(SPOptionsIdPPolicy)
class SPOptionsIdPPolicyAdmin(admin.ModelAdmin): class SPOptionsIdPPolicyAdmin(admin.ModelAdmin):
inlines = [SAMLAttributeInlineAdmin] inlines = [SAMLAttributeInlineAdmin]
fields = ( fields = (
@ -215,9 +217,6 @@ class SPOptionsIdPPolicyAdmin(admin.ModelAdmin):
) )
admin.site.register(SPOptionsIdPPolicy, SPOptionsIdPPolicyAdmin)
admin.site.register(LibertyProvider, LibertyProviderAdmin)
if settings.DEBUG: if settings.DEBUG:
admin.site.register(LibertyFederation, LibertyFederationAdmin) admin.site.register(LibertyFederation, LibertyFederationAdmin)
admin.site.register(LibertySession) admin.site.register(LibertySession)

View File

@ -64,8 +64,8 @@ def get_soap_message(request):
'''Verify that POST content looks like a SOAP message and returns it''' '''Verify that POST content looks like a SOAP message and returns it'''
assert ( assert (
request.method == 'POST' request.method == 'POST'
and 'CONTENT_TYPE' in request.META and 'content-type' in request.headers
and 'text/xml' in request.META['CONTENT_TYPE'] and 'text/xml' in request.headers['content-type']
), 'not a SOAP message' ), 'not a SOAP message'
return request.body return request.body
@ -75,7 +75,10 @@ def get_http_binding(request):
return 'GET' return 'GET'
elif request.method == 'POST': elif request.method == 'POST':
# disambiguate SOAP and form POST # disambiguate SOAP and form POST
if request.META.get('CONTENT_TYPE') in ['application/x-www-form-urlencoded', 'multipart/form-data']: if request.headers.get('content-type') in [
'application/x-www-form-urlencoded',
'multipart/form-data',
]:
return 'POST' return 'POST'
else: else:
return 'SOAP' return 'SOAP'

View File

@ -255,7 +255,7 @@ class Command(BaseCommand):
can_import_django_settings = True can_import_django_settings = True
output_transaction = True output_transaction = True
requires_system_checks = True requires_system_checks = "__all__"
help = 'Load the specified SAMLv2 metadata file' help = 'Load the specified SAMLv2 metadata file'

View File

@ -19,7 +19,6 @@ import logging.config
import os import os
# Load default from Django # Load default from Django
import django
from django.conf import global_settings from django.conf import global_settings
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
@ -51,7 +50,7 @@ DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
DATABASES = { DATABASES = {
'default': { 'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2', 'ENGINE': 'django.db.backends.postgresql',
'NAME': 'authentic2', 'NAME': 'authentic2',
} }
} }
@ -61,12 +60,8 @@ SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True CSRF_COOKIE_SECURE = True
LANGUAGE_COOKIE_SECURE = True LANGUAGE_COOKIE_SECURE = True
CSRF_COOKIE_SAMESITE = 'Lax' CSRF_COOKIE_SAMESITE = 'Lax'
if django.VERSION < (3, 1): SESSION_COOKIE_SAMESITE = 'None'
SESSION_COOKIE_SAMESITE = 'Lax' LANGUAGE_COOKIE_SAMESITE = 'None'
LANGUAGE_COOKIE_SAMESITE = 'Lax'
else:
SESSION_COOKIE_SAMESITE = 'None'
LANGUAGE_COOKIE_SAMESITE = 'None'
# Hey Entr'ouvert is in France !! # Hey Entr'ouvert is in France !!
TIME_ZONE = 'Europe/Paris' TIME_ZONE = 'Europe/Paris'

View File

@ -99,11 +99,11 @@ urlpatterns = [
re_path(r'^login/token/(?P<token>[A-Za-z0-9_ -]+)/$', views.token_login, name='token_login'), re_path(r'^login/token/(?P<token>[A-Za-z0-9_ -]+)/$', views.token_login, name='token_login'),
path('logout/', views.logout, name='auth_logout'), path('logout/', views.logout, name='auth_logout'),
re_path(r'^su/(?P<uuid>[A-Za-z0-9_-]+)/$', views.su, name='su'), re_path(r'^su/(?P<uuid>[A-Za-z0-9_-]+)/$', views.su, name='su'),
re_path(r'^accounts/', include(accounts_urlpatterns)), path('accounts/', include(accounts_urlpatterns)),
re_path(r'^admin/', admin.site.urls), re_path(r'^admin/', admin.site.urls),
re_path(r'^idp/', include('authentic2.idp.urls')), path('idp/', include('authentic2.idp.urls')),
re_path(r'^manage/', include('authentic2.manager.urls')), path('manage/', include('authentic2.manager.urls')),
re_path(r'^api/', include('authentic2.api_urls')), path('api/', include('authentic2.api_urls')),
path('continue/', views.display_message_and_continue, name='continue'), path('continue/', views.display_message_and_continue, name='continue'),
re_path(r'^\.well-known/change-password$', RedirectView.as_view(pattern_name='password_change')), re_path(r'^\.well-known/change-password$', RedirectView.as_view(pattern_name='password_change')),
# Registration # Registration
@ -158,7 +158,7 @@ if settings.DEBUG and 'debug_toolbar' in settings.INSTALLED_APPS:
import debug_toolbar # pylint: disable=import-error import debug_toolbar # pylint: disable=import-error
urlpatterns = [ urlpatterns = [
re_path(r'^__debug__/', include(debug_toolbar.urls)), path('__debug__/', include(debug_toolbar.urls)),
] + urlpatterns ] + urlpatterns
# prevent click-jacking on authentic views # prevent click-jacking on authentic views
@ -168,12 +168,12 @@ urlpatterns = plugins.register_plugins_urls(urlpatterns)
authentic2_idp_saml_urls = required( authentic2_idp_saml_urls = required(
(setting_enabled('ENABLE', settings=authentic2.idp.saml.app_settings), lasso_required()), (setting_enabled('ENABLE', settings=authentic2.idp.saml.app_settings), lasso_required()),
[re_path(r'^idp/saml2/', include('authentic2.idp.saml.urls'))], [path('idp/saml2/', include('authentic2.idp.saml.urls'))],
) )
authentic2_idp_cas_urls = required( authentic2_idp_cas_urls = required(
(setting_enabled('ENABLE', settings=authentic2_idp_cas.app_settings),), (setting_enabled('ENABLE', settings=authentic2_idp_cas.app_settings),),
[re_path(r'^idp/cas/', include('authentic2_idp_cas.urls'))], [path('idp/cas/', include('authentic2_idp_cas.urls'))],
) )
urlpatterns = ( urlpatterns = (

View File

@ -14,7 +14,7 @@
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from django.urls import include, path, re_path from django.urls import include, path
from . import views from . import views
@ -24,6 +24,6 @@ fcpatterns = [
] ]
urlpatterns = [ urlpatterns = [
re_path(r'^fc/', include(fcpatterns)), path('fc/', include(fcpatterns)),
path('accounts/fc/unlink/', views.unlink, name='fc-unlink'), path('accounts/fc/unlink/', views.unlink, name='fc-unlink'),
] ]

View File

@ -13,5 +13,3 @@
# #
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
default_app_config = 'authentic2_auth_oidc.apps.AppConfig'

View File

@ -31,7 +31,7 @@ class Command(BaseCommand):
'''Load LDAP ldif file''' '''Load LDAP ldif file'''
can_import_django_settings = True can_import_django_settings = True
requires_system_checks = True requires_system_checks = "__all__"
help = 'Register an OpenID Connect OP' help = 'Register an OpenID Connect OP'
def add_arguments(self, parser): def add_arguments(self, parser):

View File

@ -1,14 +1,9 @@
import django
from django.conf import settings from django.conf import settings
from django.db import migrations, models from django.db import migrations, models
from django.db.models import JSONField
import authentic2_auth_oidc.models import authentic2_auth_oidc.models
if django.VERSION < (3, 1):
from django.contrib.postgres.fields.jsonb import JSONField # noqa pylint: disable=ungrouped-imports
else:
from django.db.models import JSONField
class Migration(migrations.Migration): class Migration(migrations.Migration):

View File

@ -18,11 +18,11 @@ import json
import logging import logging
from datetime import datetime, timedelta from datetime import datetime, timedelta
import django
import requests import requests
from django.conf import settings from django.conf import settings
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.db import models from django.db import models
from django.db.models import JSONField
from django.shortcuts import render from django.shortcuts import render
from django.utils.timezone import now from django.utils.timezone import now
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
@ -40,11 +40,6 @@ from authentic2.utils.template import validate_template
from . import managers, utils from . import managers, utils
if django.VERSION < (3, 1):
from django.contrib.postgres.fields.jsonb import JSONField # noqa pylint: disable=ungrouped-imports
else:
from django.db.models import JSONField
def validate_jwkset(data): def validate_jwkset(data):
data = json.dumps(data) data = json.dumps(data)

View File

@ -3,15 +3,11 @@
import django import django
import django.db.models.deletion import django.db.models.deletion
from django.db import migrations, models from django.db import migrations, models
from django.db.models import JSONField
import authentic2_auth_saml.models import authentic2_auth_saml.models
from authentic2_auth_saml.models import NAME_ID_FORMAT_CHOICES from authentic2_auth_saml.models import NAME_ID_FORMAT_CHOICES
if django.VERSION < (3, 1):
from django.contrib.postgres.fields.jsonb import JSONField # noqa pylint: disable=ungrouped-imports
else:
from django.db.models import JSONField
class Migration(migrations.Migration): class Migration(migrations.Migration):

View File

@ -16,11 +16,11 @@
import xml.etree.ElementTree as ET import xml.etree.ElementTree as ET
import django
import lasso import lasso
from django.conf import settings from django.conf import settings
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.db import models from django.db import models
from django.db.models import JSONField
from django.urls import reverse from django.urls import reverse
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
@ -32,11 +32,6 @@ from authentic2.apps.authenticators.models import (
) )
from authentic2.utils.misc import redirect_to_login from authentic2.utils.misc import redirect_to_login
if django.VERSION < (3, 1):
from django.contrib.postgres.fields.jsonb import JSONField # noqa pylint: disable=ungrouped-imports
else:
from django.db.models import JSONField
NAME_ID_FORMAT_CHOICES = ( NAME_ID_FORMAT_CHOICES = (
('', _('None')), ('', _('None')),
( (

View File

@ -14,13 +14,13 @@
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from django.urls import include, path, re_path from django.urls import include, path
from . import views from . import views
urlpatterns = [ urlpatterns = [
re_path( path(
r'^accounts/saml/', 'accounts/saml/',
include('mellon.urls'), include('mellon.urls'),
kwargs={'template_base': 'authentic2/base.html', 'logout_next_url': '/logout/'}, kwargs={'template_base': 'authentic2/base.html', 'logout_next_url': '/logout/'},
), ),

View File

@ -13,5 +13,3 @@
# #
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
default_app_config = 'authentic2_idp_cas.apps.AppConfig'

View File

@ -13,5 +13,3 @@
# #
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
default_app_config = 'authentic2_idp_oidc.apps.AppConfig'

View File

@ -587,7 +587,7 @@ def is_ro_cred_grant_ratelimited(request, key='ip', increment=True):
def authenticate_client(request, ratelimit=False, client=None): def authenticate_client(request, ratelimit=False, client=None):
'''Authenticate client on the token endpoint''' '''Authenticate client on the token endpoint'''
if 'HTTP_AUTHORIZATION' in request.META: if 'authorization' in request.headers:
client_id, client_secret = parse_http_basic(request) client_id, client_secret = parse_http_basic(request)
elif 'client_id' in request.POST: elif 'client_id' in request.POST:
client_id = request.POST.get('client_id', '') client_id = request.POST.get('client_id', '')
@ -631,7 +631,7 @@ def idtoken_from_user_credential(request):
client=client, client=client,
) )
if request.META.get('CONTENT_TYPE') != 'application/x-www-form-urlencoded': if request.headers.get('content-type') != 'application/x-www-form-urlencoded':
raise InvalidRequest( raise InvalidRequest(
_('Wrong content type. request content type must be \'application/x-www-form-urlencoded\''), _('Wrong content type. request content type must be \'application/x-www-form-urlencoded\''),
client=client, client=client,
@ -841,7 +841,7 @@ def token(request, *args, **kwargs):
def authenticate_access_token(request): def authenticate_access_token(request):
if 'HTTP_AUTHORIZATION' not in request.META: if 'authorization' not in request.headers:
raise InvalidRequest(_('Bearer authentication is mandatory'), status=401) raise InvalidRequest(_('Bearer authentication is mandatory'), status=401)
authorization = request.headers['Authorization'].split() authorization = request.headers['Authorization'].split()
if authorization[0] != 'Bearer' or len(authorization) != 2: if authorization[0] != 'Bearer' or len(authorization) != 2:

View File

@ -1 +0,0 @@
default_app_config = 'django_rbac.apps.DjangoRBACConfig'

View File

@ -17,12 +17,11 @@
import json import json
from datetime import date, timedelta from datetime import date, timedelta
from unittest import mock from unittest import mock
from urllib.parse import urlparse from urllib.parse import quote, urlparse
import requests import requests
from django.contrib.auth import REDIRECT_FIELD_NAME, get_user_model from django.contrib.auth import REDIRECT_FIELD_NAME, get_user_model
from django.urls import reverse from django.urls import reverse
from django.utils.http import urlquote
from httmock import HTTMock, remember_called, urlmatch from httmock import HTTMock, remember_called, urlmatch
from authentic2 import models from authentic2 import models
@ -552,7 +551,7 @@ def test_registration_redirect(app, db, settings, mailoutbox, external_redirect)
new_next_url = settings.A2_REGISTRATION_REDIRECT new_next_url = settings.A2_REGISTRATION_REDIRECT
if good_next_url: if good_next_url:
new_next_url += '?next=' + urlquote(next_url) new_next_url += '?next=' + quote(next_url)
# disable existing attributes # disable existing attributes
models.Attribute.objects.update(disabled=True) models.Attribute.objects.update(disabled=True)
@ -605,7 +604,7 @@ def test_registration_redirect_tuple(app, db, settings, mailoutbox, external_red
new_next_url = settings.A2_REGISTRATION_REDIRECT[0] new_next_url = settings.A2_REGISTRATION_REDIRECT[0]
if good_next_url: if good_next_url:
new_next_url += '?target=' + urlquote(next_url) new_next_url += '?target=' + quote(next_url)
# disable existing attributes # disable existing attributes
models.Attribute.objects.update(disabled=True) models.Attribute.objects.update(disabled=True)