misc: apply pyupgrade (#55519)

This commit is contained in:
Valentin Deniaud 2021-07-12 12:03:07 +02:00
parent 7408e493a2
commit 7bc0fcadff
303 changed files with 944 additions and 1500 deletions

View File

@ -1,5 +1,4 @@
#!/usr/bin/python
from __future__ import print_function
import logging
import os
@ -145,7 +144,7 @@ def filter_xml(xmlfile):
for pckg in packages:
name = pckg.get('name')
if not include_package(name):
logging.debug('excluding package "{0}"'.format(name))
logging.debug(f'excluding package "{name}"')
packageroot.remove(pckg)
else:
included.append(pckg)
@ -158,7 +157,7 @@ def prepare_packagefilters():
# create simple regexp from given filter
for i in range(len(packagefilters)):
packagefilters[i] = '^' + packagefilters[i].replace('.', '\.').replace('*', '.*') + '$'
packagefilters[i] = '^' + packagefilters[i].replace('.', r'\.').replace('*', '.*') + '$'
def include_package(name):
@ -265,7 +264,7 @@ if filteronly:
for xmlfile in xmlfiles:
xml = ET.parse(xmlfile)
filter_xml(xml)
logging.debug('{1}/{2} filtering: {0}'.format(xmlfile, currfile, totalfiles))
logging.debug(f'{currfile}/{totalfiles} filtering: {xmlfile}')
xml.write(xmlfile + filtersuffix, encoding="UTF-8", xml_declaration=True)
currfile += 1
else:
@ -283,12 +282,12 @@ else:
sys.exit(0)
currfile = 1
logging.debug('{2}/{3} merging: {0} & {1}'.format(xmlfiles[0], xmlfiles[1], currfile, totalfiles - 1))
logging.debug(f'{currfile}/{totalfiles - 1} merging: {xmlfiles[0]} & {xmlfiles[1]}')
merge_xml(xmlfiles[0], xmlfiles[1], finalxml)
currfile = 2
for i in range(totalfiles - 2):
xmlfile = xmlfiles[i + 2]
logging.debug('{2}/{3} merging: {0} & {1}'.format(finalxml, xmlfile, currfile, totalfiles - 1))
logging.debug(f'{currfile}/{totalfiles - 1} merging: {finalxml} & {xmlfile}')
merge_xml(finalxml, xmlfile, finalxml)
currfile += 1

View File

@ -79,7 +79,7 @@ def get_version():
tag exists, take 0.0- and add the length of the commit log.
"""
if os.path.exists('VERSION'):
with open('VERSION', 'r') as v:
with open('VERSION') as v:
return v.read()
if os.path.exists('.git'):
p = subprocess.Popen(

View File

@ -26,7 +26,7 @@ class RoleParentInline(admin.TabularInline):
fields = ['parent']
def get_queryset(self, request):
return super(RoleParentInline, self).get_queryset(request).filter(direct=True)
return super().get_queryset(request).filter(direct=True)
class RoleChildInline(admin.TabularInline):
@ -35,7 +35,7 @@ class RoleChildInline(admin.TabularInline):
fields = ['child']
def get_queryset(self, request):
return super(RoleChildInline, self).get_queryset(request).filter(direct=True)
return super().get_queryset(request).filter(direct=True)
class RoleAttributeInline(admin.TabularInline):

View File

@ -17,7 +17,7 @@
import sys
class AppSettings(object):
class AppSettings:
__DEFAULTS = dict(
MANAGED_CONTENT_TYPES=None,
ROLE_ADMIN_RESTRICT_TO_OU_USERS=False,

View File

@ -39,13 +39,13 @@ class UniqueBooleanField(NullBooleanField):
return name, path, args, kwargs
def to_python(self, value):
value = super(UniqueBooleanField, self).to_python(value)
value = super().to_python(value)
if value is None:
return False
return value
def get_db_prep_value(self, value, connection, prepared=False):
value = super(UniqueBooleanField, self).get_db_prep_value(value, connection, prepared=prepared)
value = super().get_db_prep_value(value, connection, prepared=prepared)
if value is False:
return None
return value

View File

@ -29,7 +29,7 @@ def update_ou_admin_roles(ou):
Role = get_role_model()
if app_settings.MANAGED_CONTENT_TYPES == ():
Role.objects.filter(slug='a2-managers-of-{ou.slug}'.format(ou=ou)).delete()
Role.objects.filter(slug=f'a2-managers-of-{ou.slug}').delete()
else:
ou_admin_role = ou.get_admin_role()

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations, models
@ -210,14 +207,14 @@ class Migration(migrations.Migration):
),
migrations.AlterUniqueTogether(
name='organizationalunit',
unique_together=set([('name',), ('slug',)]),
unique_together={('name',), ('slug',)},
),
migrations.AlterUniqueTogether(
name='roleattribute',
unique_together=set([('role', 'name', 'kind', 'value')]),
unique_together={('role', 'name', 'kind', 'value')},
),
migrations.AlterUniqueTogether(
name='role',
unique_together=set([('slug', 'service'), ('slug', 'admin_scope_ct', 'admin_scope_id', 'ou')]),
unique_together={('slug', 'service'), ('slug', 'admin_scope_ct', 'admin_scope_id', 'ou')},
),
]

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
from authentic2.migrations import CreatePartialIndexes

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
@ -21,6 +18,6 @@ class Migration(migrations.Migration):
),
migrations.AlterUniqueTogether(
name='role',
unique_together=set([]),
unique_together=set(),
),
]

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations, models

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
from authentic2.migrations import CreatePartialIndexes

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from collections import defaultdict
from django.db import migrations
@ -26,8 +23,8 @@ def deduplicate_admin_roles(apps, schema_editor):
children = set()
for role in duplicates:
members |= set(role.members.all())
parents |= set(rp.parent for rp in RoleParenting.objects.filter(child=role, direct=True))
children |= set(rp.child for rp in RoleParenting.objects.filter(parent=role, direct=True))
parents |= {rp.parent for rp in RoleParenting.objects.filter(child=role, direct=True)}
children |= {rp.child for rp in RoleParenting.objects.filter(parent=role, direct=True)}
duplicates[0].members = members
for parent in parents:
RoleParenting.objects.get_or_crate(parent=parent, child=duplicates[0], direct=True)

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
@ -13,6 +10,6 @@ class Migration(migrations.Migration):
operations = [
migrations.AlterUniqueTogether(
name='role',
unique_together=set([('admin_scope_ct', 'admin_scope_id')]),
unique_together={('admin_scope_ct', 'admin_scope_id')},
),
]

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
@ -13,10 +10,10 @@ class Migration(migrations.Migration):
operations = [
migrations.AlterUniqueTogether(
name='roleparenting',
unique_together=set([('parent', 'child', 'direct')]),
unique_together={('parent', 'child', 'direct')},
),
migrations.AlterIndexTogether(
name='roleparenting',
index_together=set([('child', 'parent', 'direct')]),
index_together={('child', 'parent', 'direct')},
),
]

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models

View File

@ -1,6 +1,4 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.18 on 2019-03-08 10:22
from __future__ import unicode_literals
from django.db import migrations, models

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
from authentic2.migrations import CreatePartialIndexes

View File

@ -1,6 +1,4 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.18 on 2020-03-17 14:14
from __future__ import unicode_literals
from django.db import migrations, models

View File

@ -1,6 +1,4 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.18 on 2020-04-02 09:01
from __future__ import unicode_literals
import django.core.validators
from django.db import migrations, models

View File

@ -1,6 +1,4 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.18 on 2020-05-27 13:22
from __future__ import unicode_literals
from django.db import migrations, models

View File

@ -1,6 +1,4 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.18 on 2020-05-12 08:58
from __future__ import unicode_literals
from django.db import migrations

View File

@ -148,14 +148,14 @@ class OrganizationalUnit(OrganizationalUnitAbstractBase):
and self.clean_unused_accounts_alert >= self.clean_unused_accounts_deletion
):
raise ValidationError(_('Deletion alert delay must be less than actual deletion delay.'))
super(OrganizationalUnit, self).clean()
super().clean()
def get_admin_role(self):
"""Get or create the generic admin role for this organizational
unit.
"""
name = _('Managers of "{ou}"').format(ou=self)
slug = '_a2-managers-of-{ou.slug}'.format(ou=self)
slug = f'_a2-managers-of-{self.slug}'
return Role.objects.get_admin_role(
instance=self,
name=name,
@ -256,7 +256,7 @@ class Role(RoleAbstractBase):
admin_role = self.__class__.objects.get_admin_role(
self,
name=_('Managers of role "{role}"').format(role=str(self)),
slug='_a2-managers-of-role-{role}'.format(role=slugify(str(self))),
slug=f'_a2-managers-of-role-{slugify(str(self))}',
permissions=(view_user_perm,),
self_administered=True,
update_name=True,
@ -270,7 +270,7 @@ class Role(RoleAbstractBase):
errors = {}
with errorcollector(errors):
super(Role, self).validate_unique(exclude=exclude)
super().validate_unique(exclude=exclude)
exclude = exclude or []
@ -295,7 +295,7 @@ class Role(RoleAbstractBase):
# Service roles can only be part of the same ou as the service
if self.service:
self.ou = self.service.ou
result = super(Role, self).save(*args, **kwargs)
result = super().save(*args, **kwargs)
self.get_admin_role(create=False)
return result
@ -402,7 +402,7 @@ class RoleParenting(RoleParentingAbstractBase):
verbose_name_plural = _('role parenting relations')
def __str__(self):
return '{0} {1}> {2}'.format(self.parent.name, '-' if self.direct else '~', self.child.name)
return '{} {}> {}'.format(self.parent.name, '-' if self.direct else '~', self.child.name)
class RoleAttribute(models.Model):

View File

@ -44,7 +44,7 @@ cleanup_action.short_description = _('Cleanup expired objects')
class CleanupAdminMixin(admin.ModelAdmin):
def get_actions(self, request):
actions = super(CleanupAdminMixin, self).get_actions(request)
actions = super().get_actions(request)
if hasattr(self.model.objects.none(), 'cleanup'):
actions['cleanup_action'] = cleanup_action, 'cleanup_action', cleanup_action.short_description
return actions
@ -192,7 +192,7 @@ class UserRealmListFilter(admin.SimpleListFilter):
`self.value()`.
"""
if self.value():
return queryset.filter(username__endswith=u'@' + self.value())
return queryset.filter(username__endswith='@' + self.value())
return queryset
@ -215,7 +215,7 @@ class UserChangeForm(BaseUserForm):
fields = '__all__'
def __init__(self, *args, **kwargs):
super(UserChangeForm, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
f = self.fields.get('user_permissions', None)
if f is not None:
f.queryset = f.queryset.select_related('content_type')
@ -276,7 +276,7 @@ class UserCreationForm(BaseUserForm):
)
def save(self, commit=True):
user = super(UserCreationForm, self).save(commit=False)
user = super().save(commit=False)
user.set_password(self.cleaned_data["password1"])
if commit:
user.save()
@ -305,7 +305,7 @@ class AuthenticUserAdmin(UserAdmin):
actions = UserAdmin.actions + ['mark_as_inactive']
def get_fieldsets(self, request, obj=None):
fieldsets = deepcopy(super(AuthenticUserAdmin, self).get_fieldsets(request, obj))
fieldsets = deepcopy(super().get_fieldsets(request, obj))
if obj:
if not request.user.is_superuser:
fieldsets[2][1]['fields'] = filter(lambda x: x != 'is_superuser', fieldsets[2][1]['fields'])
@ -342,10 +342,10 @@ class AuthenticUserAdmin(UserAdmin):
qs = models.Attribute.objects.all()
else:
qs = models.Attribute.objects.filter(required=True)
non_model_fields = set([a.name for a in qs]) - set(['first_name', 'last_name'])
non_model_fields = {a.name for a in qs} - {'first_name', 'last_name'}
fields = list(set(fields) - set(non_model_fields))
kwargs['fields'] = fields
return super(AuthenticUserAdmin, self).get_form(request, obj=obj, **kwargs)
return super().get_form(request, obj=obj, **kwargs)
@transaction.atomic
def mark_as_inactive(self, request, queryset):
@ -361,7 +361,7 @@ admin.site.register(User, AuthenticUserAdmin)
class AttributeForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(AttributeForm, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
choices = self.kind_choices()
self.fields['kind'].choices = choices
self.fields['kind'].widget = forms.Select(choices=choices)

View File

@ -28,13 +28,13 @@ class Conflict(APIException):
default_code = 'conflict'
class GetOrCreateMixinView(object):
class GetOrCreateMixinView:
_lookup_object = None
def get_object(self):
if self._lookup_object is not None:
return self._lookup_object
return super(GetOrCreateMixinView, self).get_object()
return super().get_object()
def _get_lookup_keys(self, name):
return self.request.GET.getlist(name)
@ -85,4 +85,4 @@ class GetOrCreateMixinView(object):
self._lookup_object = self._lookup_instance(update_or_create_keys)
if self._lookup_object is not None:
return self.partial_update(request, *args, **kwargs)
return super(GetOrCreateMixinView, self).create(request, *args, **kwargs)
return super().create(request, *args, **kwargs)

View File

@ -77,9 +77,9 @@ if django.VERSION < (1, 11):
User = get_user_model()
class HookMixin(object):
class HookMixin:
def get_serializer(self, *args, **kwargs):
serializer = super(HookMixin, self).get_serializer(*args, **kwargs)
serializer = super().get_serializer(*args, **kwargs)
# if the serializer is a ListSerializer, we modify the child
if hasattr(serializer, 'child'):
hooks.call_hooks('api_modify_serializer', self, serializer.child)
@ -89,7 +89,7 @@ class HookMixin(object):
def get_object(self):
hooks.call_hooks('api_modify_view_before_get_object', self)
return super(HookMixin, self).get_object()
return super().get_object()
class DjangoPermission(permissions.BasePermission):
@ -106,16 +106,16 @@ class DjangoPermission(permissions.BasePermission):
return self
class ExceptionHandlerMixin(object):
class ExceptionHandlerMixin:
def handle_exception(self, exc):
if hasattr(exc, 'detail'):
exc.detail = {
'result': 0,
'errors': exc.detail,
}
return super(ExceptionHandlerMixin, self).handle_exception(exc)
return super().handle_exception(exc)
else:
response = super(ExceptionHandlerMixin, self).handle_exception(exc)
response = super().handle_exception(exc)
response.data = {
'result': 0,
'errors': response.data,
@ -182,7 +182,7 @@ class RegistrationSerializer(serializers.Serializer):
return data
class RpcMixin(object):
class RpcMixin:
def post(self, request, format=None):
serializer = self.get_serializer(data=request.data)
if serializer.is_valid():
@ -373,7 +373,7 @@ class BaseUserSerializer(serializers.ModelSerializer):
hashed_password = serializers.CharField(max_length=128, required=False)
def __init__(self, *args, **kwargs):
super(BaseUserSerializer, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
for at in Attribute.objects.all():
if at.name in self.fields:
@ -408,7 +408,7 @@ class BaseUserSerializer(serializers.ModelSerializer):
password = validated_data.pop('password', None)
hashed_password = validated_data.pop('hashed_password', None)
self.check_perm('custom_user.add_user', validated_data.get('ou'))
instance = super(BaseUserSerializer, self).create(validated_data)
instance = super().create(validated_data)
# prevent update on a get_or_create
if not getattr(instance, '_a2_created', True):
return instance
@ -466,7 +466,7 @@ class BaseUserSerializer(serializers.ModelSerializer):
self.check_perm('custom_user.change_user', validated_data.get('ou'))
if validated_data.get('email') != instance.email and not validated_data.get('email_verified'):
instance.email_verified = False
super(BaseUserSerializer, self).update(instance, validated_data)
super().update(instance, validated_data)
for key, value in attributes.items():
if is_verified.get(key):
setattr(instance.verified_attributes, key, value)
@ -582,7 +582,7 @@ class RoleSerializer(serializers.ModelSerializer):
return self.context['request'].user
def __init__(self, instance=None, **kwargs):
super(RoleSerializer, self).__init__(instance, **kwargs)
super().__init__(instance, **kwargs)
if self.instance:
self.fields['ou'].read_only = True
@ -590,21 +590,21 @@ class RoleSerializer(serializers.ModelSerializer):
ou = validated_data.get('ou')
# Creating roles also means being allowed to within the OU:
if not self.user.has_ou_perm('a2_rbac.add_role', ou):
raise PermissionDenied(u'User %s can\'t create role in OU %s' % (self.user, ou))
return super(RoleSerializer, self).create(validated_data)
raise PermissionDenied('User %s can\'t create role in OU %s' % (self.user, ou))
return super().create(validated_data)
def update(self, instance, validated_data):
# Check role-updating permissions:
if not self.user.has_perm('a2_rbac.change_role', obj=instance):
raise PermissionDenied(u'User %s can\'t change role %s' % (self.user, instance))
super(RoleSerializer, self).update(instance, validated_data)
raise PermissionDenied('User %s can\'t change role %s' % (self.user, instance))
super().update(instance, validated_data)
return instance
def partial_update(self, instance, validated_data):
# Check role-updating permissions:
if not self.user.has_perm('a2_rbac.change_role', obj=instance):
raise PermissionDenied(u'User %s can\'t change role %s' % (self.user, instance))
super(RoleSerializer, self).partial_update(instance, validated_data)
raise PermissionDenied('User %s can\'t change role %s' % (self.user, instance))
super().partial_update(instance, validated_data)
return instance
class Meta:
@ -627,11 +627,11 @@ class IsoDateTimeField(IsoDateTimeField):
def __init__(self, *args, **kwargs):
self.bound = kwargs.pop('bound')
assert self.bound in ['upper', 'lesser']
super(IsoDateTimeField, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
def strptime(self, value, format):
try:
return super(IsoDateTimeField, self).strptime(value, format)
return super().strptime(value, format)
except (NonExistentTimeError, AmbiguousTimeError):
parsed = parse_datetime(value)
possible = sorted(
@ -657,7 +657,7 @@ class IsoDateTimeFilter(IsoDateTimeFilter):
raise NotImplementedError
def filter(self, qs, value):
return super(IsoDateTimeFilter, self).filter(qs, value)
return super().filter(qs, value)
class UsersFilter(FilterSet):
@ -779,10 +779,10 @@ class UsersAPI(api_mixins.GetOrCreateMixinView, HookMixin, ExceptionHandlerMixin
def check_perm(self, perm, ou):
if ou:
if not self.request.user.has_ou_perm(perm, ou):
raise PermissionDenied(u'You do not have permission %s in %s' % (perm, ou))
raise PermissionDenied('You do not have permission %s in %s' % (perm, ou))
else:
if not self.request.user.has_perm(perm):
raise PermissionDenied(u'You do not have permission %s' % perm)
raise PermissionDenied('You do not have permission %s' % perm)
def perform_create(self, serializer):
super().perform_create(serializer)
@ -797,7 +797,7 @@ class UsersAPI(api_mixins.GetOrCreateMixinView, HookMixin, ExceptionHandlerMixin
def perform_destroy(self, instance):
self.check_perm('custom_user.delete_user', instance.ou)
self.request.journal.record('manager.user.deletion', target_user=instance, api=True)
super(UsersAPI, self).perform_destroy(instance)
super().perform_destroy(instance)
class SynchronizationSerializer(serializers.Serializer):
known_uuids = serializers.ListField(child=serializers.CharField())
@ -896,9 +896,9 @@ class RolesAPI(api_mixins.GetOrCreateMixinView, ExceptionHandlerMixin, ModelView
def perform_destroy(self, instance):
if not self.request.user.has_perm(perm='a2_rbac.delete_role', obj=instance):
raise PermissionDenied(u'User %s can\'t create role %s' % (self.request.user, instance))
raise PermissionDenied('User %s can\'t create role %s' % (self.request.user, instance))
self.request.journal.record('manager.role.deletion', role=instance, api=True)
super(RolesAPI, self).perform_destroy(instance)
super().perform_destroy(instance)
def perform_create(self, serializer):
super().perform_create(serializer)
@ -911,7 +911,7 @@ class RolesAPI(api_mixins.GetOrCreateMixinView, ExceptionHandlerMixin, ModelView
class RolesMembersAPI(UsersAPI):
def initial(self, request, *args, **kwargs):
super(RolesMembersAPI, self).initial(request, *args, **kwargs)
super().initial(request, *args, **kwargs)
Role = get_role_model()
self.role = get_object_or_404(Role, uuid=kwargs['role_uuid'])
@ -930,7 +930,7 @@ class RoleMembershipAPI(ExceptionHandlerMixin, APIView):
permission_classes = (permissions.IsAuthenticated,)
def initial(self, request, *args, **kwargs):
super(RoleMembershipAPI, self).initial(request, *args, **kwargs)
super().initial(request, *args, **kwargs)
Role = get_role_model()
User = get_user_model()
self.role = get_object_or_404(Role, uuid=kwargs['role_uuid'])
@ -938,7 +938,7 @@ class RoleMembershipAPI(ExceptionHandlerMixin, APIView):
def get(self, request, *args, **kwargs):
if not request.user.has_perm('a2_rbac.view_role', obj=self.role):
raise PermissionDenied(u'User not allowed to view role')
raise PermissionDenied('User not allowed to view role')
if self.request.GET.get('nested', 'false').lower() in ('true', '1'):
qs = self.role.all_members()
else:
@ -948,7 +948,7 @@ class RoleMembershipAPI(ExceptionHandlerMixin, APIView):
def post(self, request, *args, **kwargs):
if not request.user.has_perm('a2_rbac.manage_members_role', obj=self.role):
raise PermissionDenied(u'User not allowed to manage role members')
raise PermissionDenied('User not allowed to manage role members')
self.role.members.add(self.member)
request.journal.record('manager.role.membership.grant', role=self.role, member=self.member, api=True)
return Response(
@ -957,7 +957,7 @@ class RoleMembershipAPI(ExceptionHandlerMixin, APIView):
def delete(self, request, *args, **kwargs):
if not request.user.has_perm('a2_rbac.manage_members_role', obj=self.role):
raise PermissionDenied(u'User not allowed to manage role members')
raise PermissionDenied('User not allowed to manage role members')
self.role.members.remove(self.member)
request.journal.record(
'manager.role.membership.removal', role=self.role, member=self.member, api=True
@ -975,7 +975,7 @@ class RoleMembershipsAPI(ExceptionHandlerMixin, APIView):
http_method_names = ['post', 'put', 'patch', 'delete']
def initial(self, request, *args, **kwargs):
super(RoleMembershipsAPI, self).initial(request, *args, **kwargs)
super().initial(request, *args, **kwargs)
Role = get_role_model()
User = get_user_model()
self.role = get_object_or_404(Role, uuid=kwargs['role_uuid'])
@ -984,7 +984,7 @@ class RoleMembershipsAPI(ExceptionHandlerMixin, APIView):
perm = 'a2_rbac.manage_members_role'
authorized = request.user.has_perm(perm, obj=self.role)
if not authorized:
raise PermissionDenied(u'User not allowed to manage role members')
raise PermissionDenied('User not allowed to manage role members')
if not isinstance(request.data, dict):
raise ValidationError(_('Payload must be a dictionary'))

View File

@ -20,7 +20,7 @@ from django.core.exceptions import ImproperlyConfigured
from django.utils.translation import ugettext_lazy as _
class Setting(object):
class Setting:
SENTINEL = object()
def __init__(self, default=SENTINEL, definition='', names=None):
@ -35,7 +35,7 @@ class Setting(object):
return self.default != self.SENTINEL
class AppSettings(object):
class AppSettings:
def __init__(self, defaults):
self.defaults = defaults

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations, models
@ -472,7 +469,7 @@ class Migration(migrations.Migration):
),
migrations.AlterUniqueTogether(
name='useraliasinsource',
unique_together=set([('name', 'source')]),
unique_together={('name', 'source')},
),
migrations.AddField(
model_name='attributeitem',

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations, models

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations, models

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models

View File

@ -69,7 +69,7 @@ class DateRestField(serializers.DateField):
def __init__(self, **kwargs):
self.allow_blank = kwargs.pop('allow_blank', False)
self.trim_whitespace = kwargs.pop('trim_whitespace', True)
super(DateRestField, self).__init__(**kwargs)
super().__init__(**kwargs)
def run_validation(self, data=empty):
# Test for the empty string here so that it does not get validated,
@ -79,7 +79,7 @@ class DateRestField(serializers.DateField):
if not self.allow_blank:
self.fail('blank')
return ''
return super(DateRestField, self).run_validation(data)
return super().run_validation(data)
class BirthdateWidget(DateWidget):
@ -90,7 +90,7 @@ class BirthdateWidget(DateWidget):
options['startDate'] = '1900-01-01'
attrs['min'] = '1900-01-01'
attrs['max'] = (datetime.date.today() - datetime.timedelta(days=1)).isoformat()
super(BirthdateWidget, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
def validate_birthdate(value):
@ -158,7 +158,7 @@ class PhoneNumberField(forms.CharField):
def __init__(self, *args, **kwargs):
kwargs['max_length'] = 30
kwargs.setdefault('help_text', _('ex.: 0699999999, +33 6 99 99 99 99'))
super(PhoneNumberField, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
def clean(self, value):
if value not in self.empty_values:
@ -179,10 +179,10 @@ validate_fr_postcode = RegexValidator(r'^\d{5}$', message=_('The value must be a
class FrPostcodeField(forms.CharField):
def __init__(self, *args, **kwargs):
kwargs.setdefault('help_text', _('ex.: 13260'))
super(FrPostcodeField, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
def clean(self, value):
value = super(FrPostcodeField, self).clean(value)
value = super().clean(value)
if value not in self.empty_values:
value = value.strip()
validate_fr_postcode(value)
@ -196,7 +196,7 @@ class FrPostcodeDRFField(serializers.CharField):
default_validators = [validate_fr_postcode]
class ProfileImageFile(object):
class ProfileImageFile:
def __init__(self, name):
self.name = name
@ -370,7 +370,7 @@ class SIRETField(forms.CharField):
default_validators = [validate_siret]
def to_python(self, value):
value = super(SIRETField, self).to_python(value)
value = super().to_python(value)
value = only_digits(value)
return value

View File

@ -97,8 +97,7 @@ def get_attribute_names(ctx):
"""
for source in get_sources():
for instance in source.get_instances(ctx):
for attribute_name, attribute_description in source.get_attribute_names(instance, ctx):
yield attribute_name, attribute_description
yield from source.get_attribute_names(instance, ctx)
def get_attributes(ctx):
@ -110,7 +109,7 @@ def get_attributes(ctx):
"""
source_and_instances = []
for source in get_sources():
source_and_instances.extend(((source, instance) for instance in source.get_instances(ctx)))
source_and_instances.extend((source, instance) for instance in source.get_instances(ctx))
source_and_instances = topological_sort(source_and_instances, ctx)
ctx = ctx.copy()
for source, instance in source_and_instances:

View File

@ -17,7 +17,7 @@
import abc
class BaseAttributeSource(object, metaclass=abc.ABCMeta):
class BaseAttributeSource(metaclass=abc.ABCMeta):
"""
Base class for attribute sources
"""

View File

@ -18,7 +18,7 @@ from django.core.exceptions import ImproperlyConfigured
from ...decorators import to_list
AUTHORIZED_KEYS = set(('name', 'label', 'template'))
AUTHORIZED_KEYS = {'name', 'label', 'template'}
@to_list

View File

@ -18,9 +18,9 @@ from django.core.exceptions import ImproperlyConfigured
from ...decorators import to_list
AUTHORIZED_KEYS = set(('name', 'label', 'dependencies', 'function'))
AUTHORIZED_KEYS = {'name', 'label', 'dependencies', 'function'}
REQUIRED_KEYS = set(('name', 'dependencies', 'function'))
REQUIRED_KEYS = {'name', 'dependencies', 'function'}
UNEXPECTED_KEYS_ERROR = '{0}: unexpected key(s) {1} in configuration'
MISSING_KEYS_ERROR = '{0}: missing key(s) {1} in configuration'

View File

@ -15,6 +15,6 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
class Plugin(object):
class Plugin:
def get_apps(self):
return [__name__]

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations, models

View File

@ -1,6 +1,4 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-06-14 12:38
from __future__ import unicode_literals
from django.db import migrations

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.core import validators
from django.db import migrations, models
from django.utils import timezone

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import django.core.validators
from django.db import migrations, models

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import django.core.validators
import django.utils.timezone
from django.db import migrations, models

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import django.contrib.auth.models
import django.core.validators
from django.db import migrations, models

View File

@ -27,7 +27,7 @@ from rest_framework.exceptions import AuthenticationFailed
from authentic2_idp_oidc.models import OIDCClient
class OIDCUser(object):
class OIDCUser:
"""Fake user class to return in case OIDC authentication"""
def __init__(self, oidc_client):
@ -68,12 +68,7 @@ class Authentic2Authentication(BasicAuthentication):
except OIDCClient.DoesNotExist:
pass
# try BasicAuthentication
if (
'request'
in inspect.signature(super(Authentic2Authentication, self).authenticate_credentials).parameters
):
if 'request' in inspect.signature(super().authenticate_credentials).parameters:
# compatibility with DRF 3.4
return super(Authentic2Authentication, self).authenticate_credentials(
userid, password, request=request
)
return super(Authentic2Authentication, self).authenticate_credentials(userid, password)
return super().authenticate_credentials(userid, password, request=request)
return super().authenticate_credentials(userid, password)

View File

@ -34,7 +34,7 @@ from .utils.views import csrf_token_check
logger = logging.getLogger(__name__)
class BaseAuthenticator(object):
class BaseAuthenticator:
def __init__(self, show_condition=None, **kwargs):
self.show_condition = show_condition

View File

@ -412,11 +412,11 @@ class LDAPUser(User):
if self.block.get('keep_password_in_session', False):
self.keep_password_in_session(password)
if self.block['keep_password']:
if not super(LDAPUser, self).check_password(password):
super(LDAPUser, self).set_password(password)
if not super().check_password(password):
super().set_password(password)
self._changed = True
else:
if super(LDAPUser, self).has_usable_password():
if super().has_usable_password():
self.set_unusable_password()
self._changed = True
@ -478,7 +478,7 @@ class LDAPUser(User):
self._current_password = new_password
self.keep_password_in_session(new_password)
if self.block['keep_password']:
super(LDAPUser, self).set_password(new_password)
super().set_password(new_password)
else:
self.set_unusable_password()
@ -515,7 +515,7 @@ class LDAPUser(User):
if hasattr(self, 'keep_pk'):
pk = self.pk
self.pk = self.keep_pk
super(LDAPUser, self).save(*args, **kwargs)
super().save(*args, **kwargs)
if hasattr(self, 'keep_pk'):
self.pk = pk
@ -527,7 +527,7 @@ class LDAPUser(User):
return self.block.get('user_can_change_password', False)
class LDAPBackend(object):
class LDAPBackend:
_DEFAULTS = {
'basedn': '',
'binddn': '',
@ -699,7 +699,7 @@ class LDAPBackend(object):
# 1.1 is special attribute meaning, "no attribute requested"
results = conn.search_s(group_base_dn, ldap.SCOPE_SUBTREE, block['group_filter'], ['1.1'])
results = cls.normalize_ldap_results(results)
return set([group_dn for group_dn, attrs in results])
return {group_dn for group_dn, attrs in results}
def authenticate(self, request=None, username=None, password=None, realm=None, ou=None):
if username is None or password is None:
@ -762,7 +762,7 @@ class LDAPBackend(object):
log.debug(
'[%s] looking up dn for username %r using query %r', ldap_uri, username, query
)
results = conn.search_s(user_basedn, ldap.SCOPE_SUBTREE, query, [u'1.1'])
results = conn.search_s(user_basedn, ldap.SCOPE_SUBTREE, query, ['1.1'])
results = self.normalize_ldap_results(results)
# remove search references
results = [result for result in results if result[0] is not None]
@ -808,7 +808,7 @@ class LDAPBackend(object):
try:
self.bind(block, conn)
except Exception:
log.exception(u'rebind failure after login bind')
log.exception('rebind failure after login bind')
raise ldap.SERVER_DOWN
break
except ldap.INVALID_CREDENTIALS as e:
@ -1180,7 +1180,7 @@ class LDAPBackend(object):
for key in at_mapping:
if at_mapping[key] != 'dn':
attributes.add(at_mapping[key])
return list(set(attribute.lower() for attribute in attributes))
return list({attribute.lower() for attribute in attributes})
@classmethod
def get_ppolicy_attributes(cls, block, conn, dn):
@ -1188,7 +1188,7 @@ class LDAPBackend(object):
def get_attributes(dn, attributes):
try:
results = conn.search_s(dn, ldap.SCOPE_BASE, u'(objectclass=*)', attributes)
results = conn.search_s(dn, ldap.SCOPE_BASE, '(objectclass=*)', attributes)
except ldap.LDAPError as e:
log.error('[%s] unable to retrieve attributes of dn %r: %r', ldap_uri, dn, e)
return {}
@ -1369,8 +1369,8 @@ class LDAPBackend(object):
decoded.append((attribute, urllib.parse.unquote(value)))
else:
decoded.append((attribute, force_text(value)))
filters = [filter_format(u'(%s=%s)', (a, b)) for a, b in decoded]
return '(&{0})'.format(''.join(filters))
filters = [filter_format('(%s=%s)', (a, b)) for a, b in decoded]
return '(&{})'.format(''.join(filters))
def build_external_id(self, external_id_tuple, attributes):
"""Build the exernal id for the user, use attribute that eventually
@ -1529,15 +1529,14 @@ class LDAPBackend(object):
msgid = conn.search_ext(*args, serverctrls=[pg_ctrl], **kwargs)
result_type, data, msgid, serverctrls = conn.result3(msgid)
pg_ctrl.cookie = serverctrls[0].cookie
for dn, attrs in cls.normalize_ldap_results(data):
yield dn, attrs
yield from cls.normalize_ldap_results(data)
@classmethod
def get_users(cls):
for block in cls.get_config():
conn = cls.get_connection(block)
if conn is None:
log.warning(u'unable to synchronize with LDAP servers %s', force_text(block['url']))
log.warning('unable to synchronize with LDAP servers %s', force_text(block['url']))
continue
cls.check_group_to_role_mappings(block)
user_basedn = force_text(block.get('user_basedn') or block['basedn'])
@ -1601,7 +1600,7 @@ class LDAPBackend(object):
@classmethod
def ad_encoding(cls, s):
'''Encode a string for AD consumption as a password'''
return (u'"{0}"'.format(s)).encode('utf-16-le')
return (f'"{s}"').encode('utf-16-le')
@classmethod
def modify_password(cls, conn, block, dn, old_password, new_password):
@ -1705,9 +1704,9 @@ class LDAPBackend(object):
yield conn
else:
if block['replicas']:
log.warning(u'admin bind failed on %s: %s', url, error)
log.warning('admin bind failed on %s: %s', url, error)
else:
log.error(u'admin bind failed on %s: %s', url, error)
log.error('admin bind failed on %s: %s', url, error)
@classmethod
def bind(cls, block, conn, credentials=()):

View File

@ -14,7 +14,6 @@
# 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/>.
from __future__ import unicode_literals
import functools
@ -30,7 +29,7 @@ from .. import app_settings
def upn(username, realm):
'''Build an UPN from a username and a realm'''
return '{0}@{1}'.format(username, realm)
return f'{username}@{realm}'
PROXY_USER_MODEL = None

View File

@ -24,7 +24,7 @@ from . import hooks, utils
from .utils.views import csrf_token_check
class ValidateCSRFMixin(object):
class ValidateCSRFMixin:
"""Move CSRF token validation inside the form validation.
This mixin must always be the leftest one and if your class override
@ -35,7 +35,7 @@ class ValidateCSRFMixin(object):
@method_decorator(csrf_exempt)
@method_decorator(ensure_csrf_cookie)
def dispatch(self, *args, **kwargs):
return super(ValidateCSRFMixin, self).dispatch(*args, **kwargs)
return super().dispatch(*args, **kwargs)
def form_valid(self, *args, **kwargs):
for form in args:
@ -43,10 +43,10 @@ class ValidateCSRFMixin(object):
csrf_token_check(self.request, form)
if not form.is_valid():
return self.form_invalid(form)
return super(ValidateCSRFMixin, self).form_valid(*args, **kwargs)
return super().form_valid(*args, **kwargs)
class RedirectToNextURLViewMixin(object):
class RedirectToNextURLViewMixin:
def get_success_url(self):
if REDIRECT_FIELD_NAME in self.request.GET:
return self.request.GET[REDIRECT_FIELD_NAME]
@ -78,18 +78,18 @@ class NextURLViewMixin(RedirectToNextURLViewMixin):
},
status=303,
)
return super(NextURLViewMixin, self).dispatch(request, *args, **kwargs)
return super().dispatch(request, *args, **kwargs)
class TemplateNamesMixin(object):
class TemplateNamesMixin:
def get_template_names(self):
if hasattr(self, 'template_names'):
return self.template_names
return super(TemplateNamesMixin, self).get_template_names()
return super().get_template_names()
class HookMixin(object):
class HookMixin:
def get_form(self):
form = super(HookMixin, self).get_form()
form = super().get_form()
hooks.call_hooks('front_modify_form', self, form)
return form

View File

@ -18,7 +18,7 @@ try:
import lasso
except ImportError:
class MockLasso(object):
class MockLasso:
def __getattr__(self, key):
if key[0].isupper():
return ''

View File

@ -21,7 +21,7 @@ from . import app_settings, constants, utils
from .models import Service
class UserFederations(object):
class UserFederations:
'''Provide access to all federations of the current user'''
def __init__(self, request):
@ -42,7 +42,7 @@ class UserFederations(object):
d['provider'] = provider
d['links'].append(link)
return d
return super(UserFederations, self).__getattr__(name)
return super().__getattr__(name)
__AUTHENTIC2_DISTRIBUTION = None

View File

@ -14,7 +14,6 @@
# 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/>.
from __future__ import unicode_literals
import csv
import io
@ -74,7 +73,7 @@ def attrs(func=None, **kwargs):
return attr.s(func, **kwargs)
class UTF8Recoder(object):
class UTF8Recoder:
def __init__(self, fd):
self.fd = fd
@ -87,7 +86,7 @@ class UTF8Recoder(object):
next = __next__
class UnicodeReader(object):
class UnicodeReader:
def __init__(self, fd, dialect='excel', **kwargs):
self.reader = csv.reader(UTF8Recoder(fd), dialect=dialect, **kwargs)
@ -101,7 +100,7 @@ class UnicodeReader(object):
next = __next__
class CsvImporter(object):
class CsvImporter:
rows = None
error = None
error_description = None
@ -114,7 +113,7 @@ class CsvImporter(object):
input_fd = io.StringIO(fd_or_str)
elif not hasattr(fd_or_str, 'read1'):
try:
input_fd = io.open(fd_or_str.fileno(), closefd=False, mode='rb')
input_fd = open(fd_or_str.fileno(), closefd=False, mode='rb')
except Exception:
try:
fd_or_str.seek(0)
@ -152,7 +151,7 @@ class CsvImporter(object):
input_fd.seek(0)
if not hasattr(input_fd, 'readable'):
input_fd = io.open(input_fd.fileno(), 'rb', closefd=False)
input_fd = open(input_fd.fileno(), 'rb', closefd=False)
return io.TextIOWrapper(input_fd, encoding=encoding)
def parse_csv(input_fd):
@ -188,7 +187,7 @@ class CsvImporter(object):
@attrs
class CsvHeader(object):
class CsvHeader:
column = attrib()
name = attrib(default='')
field = attrib(default=False, converter=bool)
@ -215,7 +214,7 @@ class CsvHeader(object):
@attrs
class Error(object):
class Error:
code = attrib()
description = attrib(default='', cmp=False)
@ -240,7 +239,7 @@ class LineError(Error):
SOURCE_NAME = '_source_name'
SOURCE_ID = '_source_id'
SOURCE_COLUMNS = set([SOURCE_NAME, SOURCE_ID])
SOURCE_COLUMNS = {SOURCE_NAME, SOURCE_ID}
ROLE_NAME = '_role_name'
ROLE_SLUG = '_role_slug'
PASSWORD_HASH = 'password_hash'
@ -289,7 +288,7 @@ class ImportUserFormWithExternalId(ImportUserForm):
@attrs
class CsvRow(object):
class CsvRow:
line = attrib()
cells = attrib(default=[])
errors = attrib(default=[])
@ -328,7 +327,7 @@ class CsvRow(object):
@attrs
class CsvCell(object):
class CsvCell:
line = attrib()
header = attrib()
value = attrib(default=None)
@ -349,7 +348,7 @@ class CancelImport(Exception):
pass
class UserCsvImporter(object):
class UserCsvImporter:
csv_importer = None
errors = None
headers = None

View File

@ -14,7 +14,6 @@
# 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/>.
from __future__ import print_function, unicode_literals
import getpass

View File

@ -14,7 +14,6 @@
# 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/>.
from __future__ import print_function, unicode_literals
from django.core.management.base import BaseCommand

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import django.utils.timezone
from django.db import migrations, models

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations, models
@ -8,17 +5,15 @@ from django.db import migrations, models
class ThirdPartyAlterField(migrations.AlterField):
def __init__(self, *args, **kwargs):
self.app_label = kwargs.pop('app_label')
super(ThirdPartyAlterField, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
def state_forwards(self, app_label, state):
super(ThirdPartyAlterField, self).state_forwards(self.app_label, state)
super().state_forwards(self.app_label, state)
def database_forwards(self, app_label, schema_editor, from_state, to_state):
if hasattr(from_state, 'clear_delayed_apps_cache'):
from_state.clear_delayed_apps_cache()
super(ThirdPartyAlterField, self).database_forwards(
self.app_label, schema_editor, from_state, to_state
)
super().database_forwards(self.app_label, schema_editor, from_state, to_state)
def database_backwards(self, app_label, schema_editor, from_state, to_state):
self.database_forwards(app_label, schema_editor, from_state, to_state)

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations, models

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations, models

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import django.utils.timezone
from django.db import migrations, models

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import datetime
from django.db import migrations, models

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models

View File

@ -1,6 +1,4 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.12 on 2018-09-25 09:07
from __future__ import unicode_literals
from django.db import migrations, models

View File

@ -1,6 +1,4 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.18 on 2020-03-05 15:45
from __future__ import unicode_literals
from django.db import migrations, models

View File

@ -1,6 +1,4 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.18 on 2020-03-17 14:16
from __future__ import unicode_literals
from django.db import migrations, models

View File

@ -1,6 +1,4 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.29 on 2020-04-21 13:38
from __future__ import unicode_literals
from django.db import migrations, models

View File

@ -1,6 +1,4 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.29 on 2020-11-02 21:52
from __future__ import unicode_literals
from django.contrib.auth.models import AbstractUser
from django.db import migrations

View File

@ -1,6 +1,4 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.29 on 2021-02-09 09:37
from __future__ import unicode_literals
from django.db import migrations, models

View File

@ -1,4 +1,3 @@
# coding: utf-8
# authentic2 - versatile identity manager
# Copyright (C) 2010-2019 Entr'ouvert
#
@ -15,7 +14,6 @@
# 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/>.
from __future__ import unicode_literals
import base64
import datetime
@ -60,7 +58,7 @@ def iter_attributes():
yield value
class Attributes(object):
class Attributes:
def __init__(self, owner, verified=None):
self.__dict__['owner'] = owner
self.__dict__['verified'] = verified
@ -112,7 +110,7 @@ class Attributes(object):
return None
class AttributesDescriptor(object):
class AttributesDescriptor:
def __init__(self, verified=None):
self.verified = verified
@ -120,7 +118,7 @@ class AttributesDescriptor(object):
return Attributes(obj, verified=self.verified)
class IsVerified(object):
class IsVerified:
def __init__(self, user):
self.user = user
@ -129,7 +127,7 @@ class IsVerified(object):
return v is not None and v == getattr(self.user.verified_attributes, name, None)
class IsVerifiedDescriptor(object):
class IsVerifiedDescriptor:
def __get__(self, obj, objtype):
return IsVerified(obj)
@ -249,7 +247,7 @@ class User(AbstractBaseUser, PermissionMixin):
errors = {}
with errorcollector(errors):
super(User, self).validate_unique(exclude=exclude)
super().validate_unique(exclude=exclude)
exclude = exclude or []
@ -335,8 +333,8 @@ class User(AbstractBaseUser, PermissionMixin):
def save(self, *args, **kwargs):
update_fields = kwargs.get('update_fields')
rc = super(User, self).save(*args, **kwargs)
if not update_fields or not set(update_fields).isdisjoint(set(['first_name', 'last_name'])):
rc = super().save(*args, **kwargs)
if not update_fields or not set(update_fields).isdisjoint({'first_name', 'last_name'}):
try:
self.attributes.first_name
except AttributeError:
@ -359,7 +357,7 @@ class User(AbstractBaseUser, PermissionMixin):
def refresh_from_db(self, *args, **kwargs):
if hasattr(self, '_a2_attributes_cache'):
del self._a2_attributes_cache
return super(User, self).refresh_from_db(*args, **kwargs)
return super().refresh_from_db(*args, **kwargs)
def mark_as_active(self):
self.is_active = True

View File

@ -14,7 +14,6 @@
# 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/>.
from __future__ import unicode_literals
import uuid
from functools import wraps
@ -68,7 +67,7 @@ def update_model(obj, d):
obj.save()
class ExportContext(object):
class ExportContext:
_role_qs = None
_ou_qs = None
export_roles = None
@ -130,7 +129,7 @@ def search_role(role_d, ou=None):
return role
class ImportContext(object):
class ImportContext:
"""Holds information on how to perform the import.
ou_delete_orphans: if True any existing ou that is not found in the export will
@ -172,7 +171,7 @@ class ImportContext(object):
self.set_ou = set_ou
class RoleDeserializer(object):
class RoleDeserializer:
def __init__(self, d, import_context):
self._import_context = import_context
self._obj = None
@ -316,7 +315,7 @@ class RoleDeserializer(object):
return created, deleted
class ImportResult(object):
class ImportResult:
def __init__(self):
self.roles = {'created': [], 'updated': []}
self.ous = {'created': [], 'updated': []}

View File

@ -125,7 +125,7 @@ def _wrap_instance__resolve(wrapping_functions, instance):
return instance
class CacheDecoratorBase(object):
class CacheDecoratorBase:
"""Base class to build cache decorators.
It helps for building keys from function arguments.
@ -140,7 +140,7 @@ class CacheDecoratorBase(object):
if args:
# Case of a decorator used directly
return cls(**kwargs)(args[0])
return super(CacheDecoratorBase, cls).__new__(cls)
return super().__new__(cls)
def __init__(self, timeout=None, hostname_vary=True, args=None, kwargs=None):
self.timeout = timeout
@ -199,11 +199,11 @@ class CacheDecoratorBase(object):
for kw, arg in sorted(kwargs.items(), key=lambda x: x[0]):
if kw not in self.kwargs:
continue
parts.append(u'%s-%s' % (str(kw), str(arg)))
parts.append('%s-%s' % (str(kw), str(arg)))
return '|'.join(parts)
class SimpleDictionnaryCacheMixin(object):
class SimpleDictionnaryCacheMixin:
"""Default implementations of set, get and delete for a cache implemented
using a dictionary. The dictionnary must be returned by a property named
'cache'.
@ -226,7 +226,7 @@ class SimpleDictionnaryCacheMixin(object):
class GlobalCache(SimpleDictionnaryCacheMixin, CacheDecoratorBase):
def __init__(self, *args, **kwargs):
self.cache = {}
super(GlobalCache, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
class RequestCache(SimpleDictionnaryCacheMixin, CacheDecoratorBase):
@ -252,14 +252,14 @@ class DjangoCache(SimpleDictionnaryCacheMixin, CacheDecoratorBase):
self.delete(key)
class PickleCacheMixin(object):
class PickleCacheMixin:
def set(self, key, value):
value, tstamp = value
value = base64.b64encode(pickle.dumps(value)).decode('ascii')
super(PickleCacheMixin, self).set(key, (value, tstamp))
super().set(key, (value, tstamp))
def get(self, key):
value = super(PickleCacheMixin, self).get(key)
value = super().get(key)
if value[0] is not None:
value, tstamp = value
try:
@ -283,13 +283,13 @@ class SessionCache(PickleCacheMixin, SimpleDictionnaryCacheMixin, CacheDecorator
request = middleware.StoreRequestMiddleware.get_request()
if request:
request.session.modified = True
return super(SessionCache, self).set(key, value)
return super().set(key, value)
def clear(self):
request = middleware.StoreRequestMiddleware.get_request()
if request:
request.session.modified = True
return super(SessionCache, self).clear()
return super().clear()
@contextmanager

View File

@ -21,7 +21,7 @@ import time
from django.core.cache import cache
class ExponentialRetryTimeout(object):
class ExponentialRetryTimeout:
FACTOR = 1.8
DURATION = 0.8
MAX_DURATION = 3600 # max 1 hour
@ -66,7 +66,7 @@ class ExponentialRetryTimeout(object):
if not self.duration:
return
cache.delete(key)
self.logger.debug(u'success for %s', keys)
self.logger.debug('success for %s', keys)
def failure(self, *keys):
"""Signal an action failure, augment the exponential backoff one level."""
@ -83,4 +83,4 @@ class ExponentialRetryTimeout(object):
duration = min(self.duration * self.factor ** level, self.max_duration)
next_time += duration
cache.set(key, (level, next_time), self.cache_duration)
self.logger.debug(u'failure for %s, level: %s, next_time: %s', keys, level, next_time)
self.logger.debug('failure for %s, level: %s, next_time: %s', keys, level, next_time)

View File

@ -51,7 +51,7 @@ class AuthenticationForm(auth_forms.AuthenticationForm):
def __init__(self, *args, **kwargs):
preferred_ous = kwargs.pop('preferred_ous', [])
super(AuthenticationForm, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
self.exponential_backoff = ExponentialRetryTimeout(
key_prefix='login-exp-backoff-',
@ -132,7 +132,7 @@ class AuthenticationForm(auth_forms.AuthenticationForm):
@property
def media(self):
media = super(AuthenticationForm, self).media
media = super().media
media = media + Media(js=['authentic2/js/js_seconds_until.js'])
if app_settings.A2_LOGIN_FORM_OU_SELECTOR:
media = media + Media(js=['authentic2/js/ou_selector.js'])

View File

@ -45,7 +45,7 @@ class NewPasswordField(CharField):
def __init__(self, *args, **kwargs):
kwargs['help_text'] = password_help_text()
super(NewPasswordField, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
class CheckPasswordField(CharField):
@ -63,7 +63,7 @@ class CheckPasswordField(CharField):
'match': _('Passwords match.'),
'nomatch': _('Passwords do not match.'),
}
super(CheckPasswordField, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
class ProfileImageField(FileField):
@ -75,16 +75,16 @@ class ProfileImageField(FileField):
def clean(self, data, initial=None):
if data is FILE_INPUT_CONTRADICTION or data is False or data is None:
return super(ProfileImageField, self).clean(data, initial=initial)
return super().clean(data, initial=initial)
# we have a file
try:
with warnings.catch_warnings():
image = PIL.Image.open(io.BytesIO(data.read()))
except (IOError, PIL.Image.DecompressionBombWarning):
except (OSError, PIL.Image.DecompressionBombWarning):
raise ValidationError(_('The image is not valid'))
image = self.normalize_image(image)
new_data = self.file_from_image(image, data.name)
return super(ProfileImageField, self).clean(new_data, initial=initial)
return super().clean(new_data, initial=initial)
def file_from_image(self, image, name=None):
output = io.BytesIO()

View File

@ -20,9 +20,9 @@ from django import forms
from django.utils.translation import ugettext as _
class LockedFieldFormMixin(object):
class LockedFieldFormMixin:
def __init__(self, *args, **kwargs):
super(LockedFieldFormMixin, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
self.__lock_fields()
def __lock_fields(self):

View File

@ -87,7 +87,7 @@ class PasswordResetForm(HoneypotForm):
logger.info('password reset failed for user "%r": account is disabled', user)
utils.send_templated_mail(user, ['authentic2/password_reset_refused'])
if not self.users.exists() and email:
logger.info(u'password reset request for "%s", no user found', email)
logger.info('password reset request for "%s", no user found', email)
if getattr(settings, 'REGISTRATION_OPEN', True):
ctx = {
'registration_url': utils.make_url('registration_register', absolute=True),
@ -103,7 +103,7 @@ class PasswordResetMixin(Form):
successfully changed."""
def save(self, commit=True):
ret = super(PasswordResetMixin, self).save(commit=commit)
ret = super().save(commit=commit)
if commit:
models.PasswordReset.objects.filter(user=self.user).delete()
else:
@ -118,9 +118,9 @@ class PasswordResetMixin(Form):
return ret
class NotifyOfPasswordChange(object):
class NotifyOfPasswordChange:
def save(self, commit=True):
user = super(NotifyOfPasswordChange, self).save(commit=commit)
user = super().save(commit=commit)
if user.email:
ctx = {
'user': user,

View File

@ -33,7 +33,7 @@ class DeleteAccountForm(forms.Form):
def __init__(self, *args, **kwargs):
self.user = kwargs.pop('user')
super(DeleteAccountForm, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
def clean_password(self):
password = self.cleaned_data.get('password')
@ -47,7 +47,7 @@ class EmailChangeFormNoPassword(forms.Form):
def __init__(self, user, *args, **kwargs):
self.user = user
super(EmailChangeFormNoPassword, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
class EmailChangeForm(EmailChangeFormNoPassword):
@ -93,7 +93,7 @@ class BaseUserForm(LockedFieldFormMixin, forms.ModelForm):
# helper data for LockedFieldFormMixin
if atv.verified:
self.locked_fields.add(name)
super(BaseUserForm, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
def is_field_locked(self, name):
# helper method for LockedFieldFormMixin
@ -111,7 +111,7 @@ class BaseUserForm(LockedFieldFormMixin, forms.ModelForm):
setattr(self.instance.attributes, name, value)
def save(self, commit=True):
result = super(BaseUserForm, self).save(commit=commit)
result = super().save(commit=commit)
if commit:
self.save_attributes()
else:

View File

@ -41,7 +41,7 @@ class RegistrationForm(HoneypotForm):
email = ValidatedEmailField(label=_('Email'))
def __init__(self, *args, **kwargs):
super(RegistrationForm, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
attributes = {a.name: a for a in models.Attribute.objects.all()}
for field in app_settings.A2_PRE_REGISTRATION_FIELDS:
if field in ('first_name', 'last_name'):
@ -127,7 +127,7 @@ class RegistrationCompletionFormNoPassword(profile_forms.BaseUserForm):
def save(self, commit=True):
self.instance.email_verified = True
self.instance.is_active = True
user = super(RegistrationCompletionFormNoPassword, self).save(commit=commit)
user = super().save(commit=commit)
if commit and app_settings.A2_REGISTRATION_GROUPS:
groups = []
for name in app_settings.A2_REGISTRATION_GROUPS:

View File

@ -28,6 +28,6 @@ class NextUrlFormMixin(forms.Form):
request = StoreRequestMiddleware.get_request()
if not next_url and request:
next_url = request.GET.get(REDIRECT_FIELD_NAME)
super(NextUrlFormMixin, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
if next_url:
self.fields['next_url'].initial = next_url

View File

@ -101,7 +101,7 @@ BOOTSTRAP_DATE_INPUT_TEMPLATE = """
CLEAR_BTN_TEMPLATE = """<span class="add-on"><i class="icon-remove"></i></span>"""
class PickerWidgetMixin(object):
class PickerWidgetMixin:
class Media:
css = {
'all': ('css/datetimepicker.css',),
@ -134,7 +134,7 @@ class PickerWidgetMixin(object):
lambda x: DATE_FORMAT_JS_PY_MAPPING[x.group()], date_format
)
super(PickerWidgetMixin, self).__init__(attrs, format=self.format)
super().__init__(attrs, format=self.format)
def get_format(self):
format = get_format(self.format_name)[0]
@ -146,9 +146,7 @@ class PickerWidgetMixin(object):
attrs = attrs or {}
final_attrs = self.build_attrs(attrs)
final_attrs['class'] = "controls input-append date"
rendered_widget = super(PickerWidgetMixin, self).render(
name, value, attrs=final_attrs, renderer=renderer
)
rendered_widget = super().render(name, value, attrs=final_attrs, renderer=renderer)
# if not set, autoclose have to be true.
self.options.setdefault('autoclose', True)
@ -198,7 +196,7 @@ class DateTimeWidget(PickerWidgetMixin, DateTimeInput):
# Set the default options to show only the datepicker object
options['format'] = options.get('format', self.get_format())
super(DateTimeWidget, self).__init__(attrs, options, usel10n)
super().__init__(attrs, options, usel10n)
class DateWidget(PickerWidgetMixin, DateInput):
@ -222,7 +220,7 @@ class DateWidget(PickerWidgetMixin, DateInput):
options['minView'] = options.get('minView', 2)
options['format'] = options.get('format', self.get_format())
super(DateWidget, self).__init__(attrs, options, usel10n)
super().__init__(attrs, options, usel10n)
def format_value(self, value):
if value is not None:
@ -251,7 +249,7 @@ class TimeWidget(PickerWidgetMixin, TimeInput):
options['maxView'] = options.get('maxView', 1)
options['format'] = options.get('format', self.get_format())
super(TimeWidget, self).__init__(attrs, options, usel10n)
super().__init__(attrs, options, usel10n)
class PasswordInput(BasePasswordInput):
@ -263,7 +261,7 @@ class PasswordInput(BasePasswordInput):
css = {'all': ('authentic2/css/password.css',)}
def render(self, name, value, attrs=None, renderer=None):
output = super(PasswordInput, self).render(name, value, attrs=attrs, renderer=renderer)
output = super().render(name, value, attrs=attrs, renderer=renderer)
if attrs and app_settings.A2_PASSWORD_POLICY_SHOW_LAST_CHAR:
_id = attrs.get('id')
if _id:
@ -276,7 +274,7 @@ class NewPasswordInput(PasswordInput):
if attrs is None:
attrs = {}
attrs['autocomplete'] = 'new-password'
output = super(NewPasswordInput, self).render(name, value, attrs=attrs, renderer=renderer)
output = super().render(name, value, attrs=attrs, renderer=renderer)
if attrs:
_id = attrs.get('id')
if _id:
@ -291,7 +289,7 @@ class CheckPasswordInput(PasswordInput):
if attrs is None:
attrs = {}
attrs['autocomplete'] = 'new-password'
output = super(CheckPasswordInput, self).render(name, value, attrs=attrs, renderer=renderer)
output = super().render(name, value, attrs=attrs, renderer=renderer)
if attrs:
_id = attrs.get('id')
if _id and _id.endswith('2'):
@ -315,18 +313,18 @@ class ProfileImageInput(ClearableFileInput):
def __init__(self, *args, **kwargs):
attrs = kwargs.pop('attrs', {})
attrs['accept'] = 'image/*'
super(ProfileImageInput, self).__init__(*args, attrs=attrs, **kwargs)
super().__init__(*args, attrs=attrs, **kwargs)
class DatalistTextInput(TextInput):
def __init__(self, name='', data=(), attrs=None):
super(DatalistTextInput, self).__init__(attrs)
super().__init__(attrs)
self.data = data
self.name = 'list__%s' % name
self.attrs.update({'list': self.name})
def render(self, name, value, attrs=None, renderer=None):
output = super(DatalistTextInput, self).render(name, value, attrs=attrs, renderer=renderer)
output = super().render(name, value, attrs=attrs, renderer=renderer)
datalist = '<datalist id="%s">' % self.name
for element in self.data:
datalist += '<option value="%s">' % element
@ -354,7 +352,7 @@ class EmailInput(BaseEmailInput):
)
def get_context(self, *args, **kwargs):
context = super(EmailInput, self).get_context(*args, **kwargs)
context = super().get_context(*args, **kwargs)
if app_settings.A2_SUGGESTED_EMAIL_DOMAINS:
context['widget']['attrs']['data-suggested-domains'] = ':'.join(
app_settings.A2_SUGGESTED_EMAIL_DOMAINS

View File

@ -56,7 +56,7 @@ def call_hooks(hook_name, *args, **kwargs):
except Exception:
if getattr(settings, 'A2_HOOKS_PROPAGATE_EXCEPTIONS', False):
raise
logger.exception(u'exception while calling hook %s', hook)
logger.exception('exception while calling hook %s', hook)
def call_hooks_first_result(hook_name, *args, **kwargs):
@ -71,4 +71,4 @@ def call_hooks_first_result(hook_name, *args, **kwargs):
except Exception:
if getattr(settings, 'A2_HOOKS_PROPAGATE_EXCEPTIONS', False):
raise
logger.exception(u'exception while calling hook %s', hook)
logger.exception('exception while calling hook %s', hook)

View File

@ -1 +0,0 @@

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models

Some files were not shown because too many files have changed in this diff Show More