misc: apply pyupgrade (#55519)
This commit is contained in:
parent
7408e493a2
commit
7bc0fcadff
|
@ -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
|
||||||
|
|
2
setup.py
2
setup.py
|
@ -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(
|
||||||
|
|
|
@ -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):
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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()
|
||||||
|
|
||||||
|
|
|
@ -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')},
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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(),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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')},
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -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')},
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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):
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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'))
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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',
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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'
|
||||||
|
|
|
@ -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__]
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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=()):
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 ''
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
from django.db import migrations
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
from django.db import migrations
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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': []}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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'])
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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):
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
Loading…
Reference in New Issue