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

View File

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

View File

@ -26,7 +26,7 @@ class RoleParentInline(admin.TabularInline):
fields = ['parent'] fields = ['parent']
def get_queryset(self, request): 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): class RoleChildInline(admin.TabularInline):
@ -35,7 +35,7 @@ class RoleChildInline(admin.TabularInline):
fields = ['child'] fields = ['child']
def get_queryset(self, request): 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): class RoleAttributeInline(admin.TabularInline):

View File

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

View File

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

View File

@ -29,7 +29,7 @@ def update_ou_admin_roles(ou):
Role = get_role_model() Role = get_role_model()
if app_settings.MANAGED_CONTENT_TYPES == (): 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: else:
ou_admin_role = ou.get_admin_role() 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.conf import settings
from django.db import migrations, models from django.db import migrations, models
@ -210,14 +207,14 @@ class Migration(migrations.Migration):
), ),
migrations.AlterUniqueTogether( migrations.AlterUniqueTogether(
name='organizationalunit', name='organizationalunit',
unique_together=set([('name',), ('slug',)]), unique_together={('name',), ('slug',)},
), ),
migrations.AlterUniqueTogether( migrations.AlterUniqueTogether(
name='roleattribute', name='roleattribute',
unique_together=set([('role', 'name', 'kind', 'value')]), unique_together={('role', 'name', 'kind', 'value')},
), ),
migrations.AlterUniqueTogether( migrations.AlterUniqueTogether(
name='role', 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 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 django.db import migrations, models
from authentic2.migrations import CreatePartialIndexes 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 from django.db import migrations, models
@ -21,6 +18,6 @@ class Migration(migrations.Migration):
), ),
migrations.AlterUniqueTogether( migrations.AlterUniqueTogether(
name='role', 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 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 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.conf import settings
from django.db import migrations, models 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 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 django.db import migrations, models
from authentic2.migrations import CreatePartialIndexes from authentic2.migrations import CreatePartialIndexes

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from collections import defaultdict from collections import defaultdict
from django.db import migrations from django.db import migrations
@ -26,8 +23,8 @@ def deduplicate_admin_roles(apps, schema_editor):
children = set() children = set()
for role in duplicates: for role in duplicates:
members |= set(role.members.all()) members |= set(role.members.all())
parents |= set(rp.parent for rp in RoleParenting.objects.filter(child=role, direct=True)) parents |= {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)) children |= {rp.child for rp in RoleParenting.objects.filter(parent=role, direct=True)}
duplicates[0].members = members duplicates[0].members = members
for parent in parents: for parent in parents:
RoleParenting.objects.get_or_crate(parent=parent, child=duplicates[0], direct=True) 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 from django.db import migrations, models
@ -13,6 +10,6 @@ class Migration(migrations.Migration):
operations = [ operations = [
migrations.AlterUniqueTogether( migrations.AlterUniqueTogether(
name='role', 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 from django.db import migrations, models
@ -13,10 +10,10 @@ class Migration(migrations.Migration):
operations = [ operations = [
migrations.AlterUniqueTogether( migrations.AlterUniqueTogether(
name='roleparenting', name='roleparenting',
unique_together=set([('parent', 'child', 'direct')]), unique_together={('parent', 'child', 'direct')},
), ),
migrations.AlterIndexTogether( migrations.AlterIndexTogether(
name='roleparenting', 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 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 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 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 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 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 # Generated by Django 1.11.18 on 2019-03-08 10:22
from __future__ import unicode_literals
from django.db import migrations, models 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 django.db import migrations, models
from authentic2.migrations import CreatePartialIndexes 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 # Generated by Django 1.11.18 on 2020-03-17 14:14
from __future__ import unicode_literals
from django.db import migrations, models 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 # Generated by Django 1.11.18 on 2020-04-02 09:01
from __future__ import unicode_literals
import django.core.validators import django.core.validators
from django.db import migrations, models 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 # Generated by Django 1.11.18 on 2020-05-27 13:22
from __future__ import unicode_literals
from django.db import migrations, models 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 # Generated by Django 1.11.18 on 2020-05-12 08:58
from __future__ import unicode_literals
from django.db import migrations 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 and self.clean_unused_accounts_alert >= self.clean_unused_accounts_deletion
): ):
raise ValidationError(_('Deletion alert delay must be less than actual deletion delay.')) raise ValidationError(_('Deletion alert delay must be less than actual deletion delay.'))
super(OrganizationalUnit, self).clean() super().clean()
def get_admin_role(self): def get_admin_role(self):
"""Get or create the generic admin role for this organizational """Get or create the generic admin role for this organizational
unit. unit.
""" """
name = _('Managers of "{ou}"').format(ou=self) 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( return Role.objects.get_admin_role(
instance=self, instance=self,
name=name, name=name,
@ -256,7 +256,7 @@ class Role(RoleAbstractBase):
admin_role = self.__class__.objects.get_admin_role( admin_role = self.__class__.objects.get_admin_role(
self, self,
name=_('Managers of role "{role}"').format(role=str(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,), permissions=(view_user_perm,),
self_administered=True, self_administered=True,
update_name=True, update_name=True,
@ -270,7 +270,7 @@ class Role(RoleAbstractBase):
errors = {} errors = {}
with errorcollector(errors): with errorcollector(errors):
super(Role, self).validate_unique(exclude=exclude) super().validate_unique(exclude=exclude)
exclude = exclude or [] exclude = exclude or []
@ -295,7 +295,7 @@ class Role(RoleAbstractBase):
# Service roles can only be part of the same ou as the service # Service roles can only be part of the same ou as the service
if self.service: if self.service:
self.ou = self.service.ou self.ou = self.service.ou
result = super(Role, self).save(*args, **kwargs) result = super().save(*args, **kwargs)
self.get_admin_role(create=False) self.get_admin_role(create=False)
return result return result
@ -402,7 +402,7 @@ class RoleParenting(RoleParentingAbstractBase):
verbose_name_plural = _('role parenting relations') verbose_name_plural = _('role parenting relations')
def __str__(self): 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): class RoleAttribute(models.Model):

View File

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

View File

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

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.conf import settings from django.conf import settings
from django.db import migrations, models 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.conf import settings
from django.db import migrations, models 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 django.db import migrations, models

View File

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

View File

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

View File

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

View File

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

View File

@ -18,9 +18,9 @@ from django.core.exceptions import ImproperlyConfigured
from ...decorators import to_list 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' UNEXPECTED_KEYS_ERROR = '{0}: unexpected key(s) {1} in configuration'
MISSING_KEYS_ERROR = '{0}: missing 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/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
class Plugin(object): class Plugin:
def get_apps(self): def get_apps(self):
return [__name__] return [__name__]

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models 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.conf import settings
from django.db import migrations, models 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 # Generated by Django 1.11.20 on 2019-06-14 12:38
from __future__ import unicode_literals
from django.db import migrations 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.core import validators
from django.db import migrations, models from django.db import migrations, models
from django.utils import timezone from django.utils import timezone

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import django.core.validators import django.core.validators
from django.db import migrations, models 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.conf import settings
from django.db import migrations 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.core.validators
import django.utils.timezone import django.utils.timezone
from django.db import migrations, models 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.contrib.auth.models
import django.core.validators import django.core.validators
from django.db import migrations, models 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 from authentic2_idp_oidc.models import OIDCClient
class OIDCUser(object): class OIDCUser:
"""Fake user class to return in case OIDC authentication""" """Fake user class to return in case OIDC authentication"""
def __init__(self, oidc_client): def __init__(self, oidc_client):
@ -68,12 +68,7 @@ class Authentic2Authentication(BasicAuthentication):
except OIDCClient.DoesNotExist: except OIDCClient.DoesNotExist:
pass pass
# try BasicAuthentication # try BasicAuthentication
if ( if 'request' in inspect.signature(super().authenticate_credentials).parameters:
'request'
in inspect.signature(super(Authentic2Authentication, self).authenticate_credentials).parameters
):
# compatibility with DRF 3.4 # compatibility with DRF 3.4
return super(Authentic2Authentication, self).authenticate_credentials( return super().authenticate_credentials(userid, password, request=request)
userid, password, request=request return super().authenticate_credentials(userid, password)
)
return super(Authentic2Authentication, self).authenticate_credentials(userid, password)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -14,7 +14,6 @@
# 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 __future__ import print_function, unicode_literals
from django.core.management.base import BaseCommand 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 import django.utils.timezone
from django.db import migrations, models 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.conf import settings
from django.db import migrations, models from django.db import migrations, models
@ -8,17 +5,15 @@ from django.db import migrations, models
class ThirdPartyAlterField(migrations.AlterField): class ThirdPartyAlterField(migrations.AlterField):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.app_label = kwargs.pop('app_label') self.app_label = kwargs.pop('app_label')
super(ThirdPartyAlterField, self).__init__(*args, **kwargs) super().__init__(*args, **kwargs)
def state_forwards(self, app_label, state): 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): def database_forwards(self, app_label, schema_editor, from_state, to_state):
if hasattr(from_state, 'clear_delayed_apps_cache'): if hasattr(from_state, 'clear_delayed_apps_cache'):
from_state.clear_delayed_apps_cache() from_state.clear_delayed_apps_cache()
super(ThirdPartyAlterField, self).database_forwards( super().database_forwards(self.app_label, schema_editor, from_state, to_state)
self.app_label, schema_editor, from_state, to_state
)
def database_backwards(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) 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 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.conf import settings
from django.db import migrations, models 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.conf import settings
from django.db import migrations, models 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 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 django.db import migrations, models

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import django.utils.timezone import django.utils.timezone
from django.db import migrations, models 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 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 django.db import migrations, models

View File

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

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import datetime import datetime
from django.db import migrations, models 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 django.db import migrations, models

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations 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 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 # Generated by Django 1.11.12 on 2018-09-25 09:07
from __future__ import unicode_literals
from django.db import migrations, models 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 # Generated by Django 1.11.18 on 2020-03-05 15:45
from __future__ import unicode_literals
from django.db import migrations, models 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 # Generated by Django 1.11.18 on 2020-03-17 14:16
from __future__ import unicode_literals
from django.db import migrations, models 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 # Generated by Django 1.11.29 on 2020-04-21 13:38
from __future__ import unicode_literals
from django.db import migrations, models 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 # 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.contrib.auth.models import AbstractUser
from django.db import migrations 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 # Generated by Django 1.11.29 on 2021-02-09 09:37
from __future__ import unicode_literals
from django.db import migrations, models from django.db import migrations, models

View File

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

View File

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

View File

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

View File

@ -21,7 +21,7 @@ import time
from django.core.cache import cache from django.core.cache import cache
class ExponentialRetryTimeout(object): class ExponentialRetryTimeout:
FACTOR = 1.8 FACTOR = 1.8
DURATION = 0.8 DURATION = 0.8
MAX_DURATION = 3600 # max 1 hour MAX_DURATION = 3600 # max 1 hour
@ -66,7 +66,7 @@ class ExponentialRetryTimeout(object):
if not self.duration: if not self.duration:
return return
cache.delete(key) cache.delete(key)
self.logger.debug(u'success for %s', keys) self.logger.debug('success for %s', keys)
def failure(self, *keys): def failure(self, *keys):
"""Signal an action failure, augment the exponential backoff one level.""" """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) duration = min(self.duration * self.factor ** level, self.max_duration)
next_time += duration next_time += duration
cache.set(key, (level, next_time), self.cache_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): def __init__(self, *args, **kwargs):
preferred_ous = kwargs.pop('preferred_ous', []) preferred_ous = kwargs.pop('preferred_ous', [])
super(AuthenticationForm, self).__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.exponential_backoff = ExponentialRetryTimeout( self.exponential_backoff = ExponentialRetryTimeout(
key_prefix='login-exp-backoff-', key_prefix='login-exp-backoff-',
@ -132,7 +132,7 @@ class AuthenticationForm(auth_forms.AuthenticationForm):
@property @property
def media(self): def media(self):
media = super(AuthenticationForm, self).media media = super().media
media = media + Media(js=['authentic2/js/js_seconds_until.js']) media = media + Media(js=['authentic2/js/js_seconds_until.js'])
if app_settings.A2_LOGIN_FORM_OU_SELECTOR: if app_settings.A2_LOGIN_FORM_OU_SELECTOR:
media = media + Media(js=['authentic2/js/ou_selector.js']) media = media + Media(js=['authentic2/js/ou_selector.js'])

View File

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

View File

@ -20,9 +20,9 @@ from django import forms
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
class LockedFieldFormMixin(object): class LockedFieldFormMixin:
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(LockedFieldFormMixin, self).__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.__lock_fields() self.__lock_fields()
def __lock_fields(self): 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) logger.info('password reset failed for user "%r": account is disabled', user)
utils.send_templated_mail(user, ['authentic2/password_reset_refused']) utils.send_templated_mail(user, ['authentic2/password_reset_refused'])
if not self.users.exists() and email: 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): if getattr(settings, 'REGISTRATION_OPEN', True):
ctx = { ctx = {
'registration_url': utils.make_url('registration_register', absolute=True), 'registration_url': utils.make_url('registration_register', absolute=True),
@ -103,7 +103,7 @@ class PasswordResetMixin(Form):
successfully changed.""" successfully changed."""
def save(self, commit=True): def save(self, commit=True):
ret = super(PasswordResetMixin, self).save(commit=commit) ret = super().save(commit=commit)
if commit: if commit:
models.PasswordReset.objects.filter(user=self.user).delete() models.PasswordReset.objects.filter(user=self.user).delete()
else: else:
@ -118,9 +118,9 @@ class PasswordResetMixin(Form):
return ret return ret
class NotifyOfPasswordChange(object): class NotifyOfPasswordChange:
def save(self, commit=True): def save(self, commit=True):
user = super(NotifyOfPasswordChange, self).save(commit=commit) user = super().save(commit=commit)
if user.email: if user.email:
ctx = { ctx = {
'user': user, 'user': user,

View File

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

View File

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

View File

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

View File

@ -56,7 +56,7 @@ def call_hooks(hook_name, *args, **kwargs):
except Exception: except Exception:
if getattr(settings, 'A2_HOOKS_PROPAGATE_EXCEPTIONS', False): if getattr(settings, 'A2_HOOKS_PROPAGATE_EXCEPTIONS', False):
raise 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): def call_hooks_first_result(hook_name, *args, **kwargs):
@ -71,4 +71,4 @@ def call_hooks_first_result(hook_name, *args, **kwargs):
except Exception: except Exception:
if getattr(settings, 'A2_HOOKS_PROPAGATE_EXCEPTIONS', False): if getattr(settings, 'A2_HOOKS_PROPAGATE_EXCEPTIONS', False):
raise 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 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 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 django.db import migrations, models

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