0001-misc-remove-six-module-usage-52503.patch
debian/control | ||
---|---|---|
29 | 29 |
python3-djangorestframework (<< 3.10), |
30 | 30 |
python3-markdown (>= 2.1), |
31 | 31 |
python3-ldap (>= 2.4), |
32 |
python3-six (>= 1.0), |
|
33 | 32 |
python3-jwcrypto (>= 0.3.1), |
34 | 33 |
python3-cryptography (>= 1.3.4), |
35 | 34 |
python3-django-filters (>= 1), |
debian/py3dist-overrides | ||
---|---|---|
9 | 9 |
XStatic_jquery_ui python3-xstatic-jquery-ui |
10 | 10 |
django-import-export python3-django-import-export |
11 | 11 |
django-sekizai python3-django-sekizai |
12 |
six python3-six |
|
13 | 12 |
pycryptodome python3-pycryptodome |
14 | 13 |
ldaptools python3-ldaptools |
15 | 14 |
django-mellon python3-django-mellon |
doc/installation_modes.rst | ||
---|---|---|
23 | 23 |
- gadjo>=0.6 |
24 | 24 |
- django-import-export>=0.2.7,<=0.4.5 |
25 | 25 |
- djangorestframework>=3.3 |
26 |
- six>=1.9 |
|
27 | 26 |
- Markdown>=2.5 |
28 | 27 |
- python-ldap |
29 | 28 |
setup.py | ||
---|---|---|
129 | 129 |
'gadjo>=0.53', |
130 | 130 |
'django-import-export>=1,<2', |
131 | 131 |
'djangorestframework>=3.3,<3.10', |
132 |
'six>=1', |
|
133 | 132 |
'Markdown>=2.1', |
134 | 133 |
'python-ldap', |
135 | 134 |
'django-filter>1,<2.3', |
src/authentic2/a2_rbac/admin.py | ||
---|---|---|
15 | 15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | 16 | |
17 | 17 |
from django.contrib import admin |
18 |
from django.utils import six |
|
19 | 18 |
from django.utils.translation import ugettext_lazy as _ |
20 | 19 | |
21 | 20 |
from . import models |
... | ... | |
90 | 89 |
list_select_related = True |
91 | 90 | |
92 | 91 |
def name(self, obj): |
93 |
return six.text_type(obj)
|
|
92 |
return str(obj)
|
|
94 | 93 | |
95 | 94 |
name.short_description = _('name') |
96 | 95 |
src/authentic2/a2_rbac/management.py | ||
---|---|---|
15 | 15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | 16 | |
17 | 17 |
from django.contrib.contenttypes.models import ContentType |
18 |
from django.utils import six |
|
19 | 18 |
from django.utils.text import slugify |
20 | 19 |
from django.utils.translation import ugettext |
21 | 20 |
from django.utils.translation import ugettext_lazy as _ |
... | ... | |
41 | 40 |
# do not create scoped admin roles if the model is not scopable |
42 | 41 |
if not ou_model: |
43 | 42 |
continue |
44 |
name = six.text_type(MANAGED_CT[key]['name'])
|
|
43 |
name = str(MANAGED_CT[key]['name'])
|
|
45 | 44 |
slug = '_a2-' + slugify(name) |
46 |
scoped_name = six.text_type(MANAGED_CT[key]['scoped_name'])
|
|
45 |
scoped_name = str(MANAGED_CT[key]['scoped_name'])
|
|
47 | 46 |
name = scoped_name.format(ou=ou) |
48 | 47 |
ou_slug = slug + '-' + ou.slug |
49 | 48 |
if app_settings.MANAGED_CONTENT_TYPES == (): |
... | ... | |
123 | 122 |
if ct_tuple not in MANAGED_CT: |
124 | 123 |
continue |
125 | 124 |
# General admin role |
126 |
name = six.text_type(MANAGED_CT[ct_tuple]['name'])
|
|
125 |
name = str(MANAGED_CT[ct_tuple]['name'])
|
|
127 | 126 |
slug = '_a2-' + slugify(name) |
128 | 127 |
if ( |
129 | 128 |
app_settings.MANAGED_CONTENT_TYPES is not None |
src/authentic2/a2_rbac/migrations/0024_fix_self_admin_perm.py | ||
---|---|---|
3 | 3 |
from __future__ import unicode_literals |
4 | 4 | |
5 | 5 |
from django.db import migrations |
6 |
from django.utils.six import text_type |
|
7 | 6 | |
8 | 7 |
from authentic2.a2_rbac.models import MANAGE_MEMBERS_OP |
9 | 8 |
from django_rbac.models import CHANGE_OP |
... | ... | |
14 | 13 |
Permission = apps.get_model('a2_rbac', 'Permission') |
15 | 14 |
Operation = apps.get_model('django_rbac', 'Operation') |
16 | 15 |
ContentType = apps.get_model('contenttypes', 'ContentType') |
17 |
change_op, _ = Operation.objects.get_or_create(slug=text_type(CHANGE_OP.slug))
|
|
18 |
manage_members_op, _ = Operation.objects.get_or_create(slug=text_type(MANAGE_MEMBERS_OP.slug))
|
|
16 |
change_op, _ = Operation.objects.get_or_create(slug=str(CHANGE_OP.slug))
|
|
17 |
manage_members_op, _ = Operation.objects.get_or_create(slug=str(MANAGE_MEMBERS_OP.slug))
|
|
19 | 18 |
ct = ContentType.objects.get_for_model(Role) |
20 | 19 |
perms_to_delete = [] |
21 | 20 |
for role in Role.objects.all(): |
src/authentic2/a2_rbac/models.py | ||
---|---|---|
20 | 20 |
from django.core.exceptions import ValidationError |
21 | 21 |
from django.core.validators import MinValueValidator |
22 | 22 |
from django.db import models |
23 |
from django.utils import six |
|
24 | 23 |
from django.utils.text import slugify |
25 | 24 |
from django.utils.translation import pgettext_lazy |
26 | 25 |
from django.utils.translation import ugettext_lazy as _ |
... | ... | |
248 | 247 | |
249 | 248 |
admin_role = self.__class__.objects.get_admin_role( |
250 | 249 |
self, |
251 |
name=_('Managers of role "{role}"').format(role=six.text_type(self)),
|
|
252 |
slug='_a2-managers-of-role-{role}'.format(role=slugify(six.text_type(self))),
|
|
250 |
name=_('Managers of role "{role}"').format(role=str(self)),
|
|
251 |
slug='_a2-managers-of-role-{role}'.format(role=slugify(str(self))),
|
|
253 | 252 |
permissions=(view_user_perm,), |
254 | 253 |
self_administered=True, |
255 | 254 |
update_name=True, |
src/authentic2/app_settings.py | ||
---|---|---|
16 | 16 | |
17 | 17 |
import sys |
18 | 18 | |
19 |
import six |
|
20 | 19 |
from django.core.exceptions import ImproperlyConfigured |
21 | 20 |
from django.utils.translation import ugettext_lazy as _ |
22 | 21 | |
... | ... | |
26 | 25 | |
27 | 26 |
def __init__(self, default=SENTINEL, definition='', names=None): |
28 | 27 |
self.names = names or [] |
29 |
if isinstance(self.names, six.string_types):
|
|
28 |
if isinstance(self.names, str):
|
|
30 | 29 |
self.names = [self.names] |
31 | 30 |
self.names = set(self.names) |
32 | 31 |
self.default = default |
src/authentic2/attribute_kinds.py | ||
---|---|---|
28 | 28 |
from django.core.validators import RegexValidator |
29 | 29 |
from django.db.models import query |
30 | 30 |
from django.urls import reverse |
31 |
from django.utils import formats, html, six
|
|
31 |
from django.utils import formats, html |
|
32 | 32 |
from django.utils.functional import keep_lazy |
33 | 33 |
from django.utils.translation import pgettext_lazy |
34 | 34 |
from django.utils.translation import ugettext_lazy as _ |
... | ... | |
42 | 42 |
from .plugins import collect_from_plugins |
43 | 43 | |
44 | 44 | |
45 |
@keep_lazy(six.text_type)
|
|
45 |
@keep_lazy(str)
|
|
46 | 46 |
def capfirst(value): |
47 | 47 |
return value and value[0].upper() + value[1:] |
48 | 48 | |
... | ... | |
75 | 75 |
# Test for the empty string here so that it does not get validated, |
76 | 76 |
# and so that subclasses do not need to handle it explicitly |
77 | 77 |
# inside the `to_internal_value()` method. |
78 |
if data == '' or (self.trim_whitespace and six.text_type(data).strip() == ''):
|
|
78 |
if data == '' or (self.trim_whitespace and str(data).strip() == ''):
|
|
79 | 79 |
if not self.allow_blank: |
80 | 80 |
self.fail('blank') |
81 | 81 |
return '' |
src/authentic2/attributes_ng/sources/__init__.py | ||
---|---|---|
16 | 16 | |
17 | 17 |
import abc |
18 | 18 | |
19 |
from django.utils import six |
|
20 | 19 | |
21 | ||
22 |
@six.add_metaclass(abc.ABCMeta) |
|
23 |
class BaseAttributeSource(object): |
|
20 |
class BaseAttributeSource(object, metaclass=abc.ABCMeta): |
|
24 | 21 |
""" |
25 | 22 |
Base class for attribute sources |
26 | 23 |
""" |
src/authentic2/attributes_ng/sources/django_user.py | ||
---|---|---|
15 | 15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | 16 | |
17 | 17 |
from django.contrib.auth import get_user_model |
18 |
from django.utils import six |
|
19 | 18 |
from django.utils.translation import ugettext_lazy as _ |
20 | 19 | |
21 | 20 |
from django_rbac.utils import get_role_model |
... | ... | |
91 | 90 |
ctx['django_user_' + str(av.attribute.name)] = serialized |
92 | 91 |
ctx['django_user_' + str(av.attribute.name) + ':verified'] = av.verified |
93 | 92 |
ctx['django_user_groups'] = [group for group in user.groups.all()] |
94 |
ctx['django_user_group_names'] = [six.text_type(group) for group in user.groups.all()]
|
|
93 |
ctx['django_user_group_names'] = [str(group) for group in user.groups.all()]
|
|
95 | 94 |
if user.username: |
96 | 95 |
splitted = user.username.rsplit('@', 1) |
97 | 96 |
ctx['django_user_domain'] = splitted[1] if '@' in user.username else '' |
src/authentic2/attributes_ng/sources/format.py | ||
---|---|---|
14 | 14 |
# You should have received a copy of the GNU Affero General Public License |
15 | 15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | 16 | |
17 |
import six |
|
18 | 17 |
from django.core.exceptions import ImproperlyConfigured |
19 | 18 | |
20 | 19 |
from ...decorators import to_list |
... | ... | |
62 | 61 |
config_error(UNEXPECTED_KEYS_ERROR, unexpected) |
63 | 62 |
if 'name' not in keys or 'template' not in keys: |
64 | 63 |
config_error(BAD_CONFIG_ERROR) |
65 |
if not isinstance(d['template'], six.string_types):
|
|
64 |
if not isinstance(d['template'], str):
|
|
66 | 65 |
config_error(TYPE_ERROR) |
67 | 66 |
yield d |
68 | 67 |
src/authentic2/authentication.py | ||
---|---|---|
16 | 16 | |
17 | 17 |
import inspect |
18 | 18 | |
19 |
from django.utils import six |
|
20 | ||
21 | 19 |
try: |
22 | 20 |
from django.utils.deprecation import CallableTrue |
23 | 21 |
except ImportError: |
... | ... | |
71 | 69 |
pass |
72 | 70 |
# try BasicAuthentication |
73 | 71 |
if ( |
74 |
six.PY3 |
|
75 |
and 'request' |
|
72 |
'request' |
|
76 | 73 |
in inspect.signature(super(Authentic2Authentication, self).authenticate_credentials).parameters |
77 | 74 |
): |
78 | 75 |
# compatibility with DRF 3.4 |
src/authentic2/backends/ldap_backend.py | ||
---|---|---|
15 | 15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | 16 | |
17 | 17 |
import hashlib |
18 |
import urllib.parse |
|
18 | 19 | |
19 | 20 |
try: |
20 | 21 |
import ldap |
... | ... | |
36 | 37 |
import os |
37 | 38 |
import random |
38 | 39 |
import time |
40 |
import urllib.parse |
|
39 | 41 | |
40 | 42 |
from django.conf import settings |
41 | 43 |
from django.contrib import messages |
... | ... | |
43 | 45 |
from django.contrib.auth.models import Group |
44 | 46 |
from django.core.cache import cache |
45 | 47 |
from django.core.exceptions import ImproperlyConfigured |
46 |
from django.utils import six |
|
47 | 48 |
from django.utils.encoding import force_bytes, force_text |
48 |
from django.utils.six.moves.urllib import parse as urlparse |
|
49 | 49 |
from django.utils.translation import ngettext |
50 | 50 |
from django.utils.translation import ugettext as _ |
51 | 51 | |
... | ... | |
290 | 290 |
def map_text(d): |
291 | 291 |
if d is None: |
292 | 292 |
return d |
293 |
elif isinstance(d, six.string_types):
|
|
293 |
elif isinstance(d, str):
|
|
294 | 294 |
return force_text(d) |
295 | 295 |
elif isinstance(d, (list, tuple)): |
296 | 296 |
return d.__class__(map_text(x) for x in d) |
... | ... | |
1031 | 1031 |
'''Obtain a Django role''' |
1032 | 1032 |
kwargs = {} |
1033 | 1033 |
slug = None |
1034 |
if isinstance(role_id, six.string_types):
|
|
1034 |
if isinstance(role_id, str):
|
|
1035 | 1035 |
slug = role_id |
1036 | 1036 |
elif isinstance(role_id, (tuple, list)): |
1037 | 1037 |
try: |
... | ... | |
1302 | 1302 |
attribute, param = attribute.split(':') |
1303 | 1303 |
quote = 'noquote' not in param.split(',') |
1304 | 1304 |
if quote: |
1305 |
decoded.append((attribute, urlparse.unquote(value))) |
|
1305 |
decoded.append((attribute, urllib.parse.unquote(value)))
|
|
1306 | 1306 |
else: |
1307 | 1307 |
decoded.append((attribute, force_text(value))) |
1308 | 1308 |
filters = [filter_format(u'(%s=%s)', (a, b)) for a, b in decoded] |
... | ... | |
1322 | 1322 |
if isinstance(part, list): |
1323 | 1323 |
part = part[0] |
1324 | 1324 |
if quote: |
1325 |
part = urlparse.quote(part.encode('utf-8')) |
|
1325 |
part = urllib.parse.quote(part.encode('utf-8'))
|
|
1326 | 1326 |
parts.append(part) |
1327 | 1327 |
return ' '.join(part for part in parts) |
1328 | 1328 | |
... | ... | |
1676 | 1676 | |
1677 | 1677 |
# convert string to list of strings for settings accepting it |
1678 | 1678 |
for i in cls._TO_ITERABLE: |
1679 |
if i in block and isinstance(block[i], six.string_types):
|
|
1679 |
if i in block and isinstance(block[i], str):
|
|
1680 | 1680 |
block[i] = (block[i],) |
1681 | 1681 | |
1682 | 1682 |
for d in cls._DEFAULTS: |
... | ... | |
1685 | 1685 |
if d == 'user_filter' and app_settings.A2_ACCEPT_EMAIL_AUTHENTICATION: |
1686 | 1686 |
block[d] = '(|(mail=%s)(uid=%s))' |
1687 | 1687 |
else: |
1688 |
if isinstance(cls._DEFAULTS[d], six.string_types):
|
|
1689 |
if not isinstance(block[d], six.string_types):
|
|
1688 |
if isinstance(cls._DEFAULTS[d], str):
|
|
1689 |
if not isinstance(block[d], str):
|
|
1690 | 1690 |
raise ImproperlyConfigured('LDAP_AUTH_SETTINGS: attribute %r must be a string' % d) |
1691 | 1691 |
try: |
1692 | 1692 |
block[d] = force_text(block[d]) |
... | ... | |
1710 | 1710 |
for key in cls._TO_LOWERCASE: |
1711 | 1711 |
# we handle strings, list of strings and list of list or tuple whose first element is a |
1712 | 1712 |
# string |
1713 |
if isinstance(block[key], six.string_types):
|
|
1713 |
if isinstance(block[key], str):
|
|
1714 | 1714 |
block[key] = force_text(block[key]).lower() |
1715 | 1715 |
elif isinstance(block[key], (list, tuple)): |
1716 | 1716 |
new_seq = [] |
src/authentic2/backends/models_backend.py | ||
---|---|---|
16 | 16 | |
17 | 17 |
from __future__ import unicode_literals |
18 | 18 | |
19 |
import functools |
|
20 | ||
19 | 21 |
from django.contrib.auth import get_user_model |
20 | 22 |
from django.contrib.auth.backends import ModelBackend |
21 | 23 |
from django.db import models |
22 |
from django.utils import six |
|
23 | 24 | |
24 | 25 |
from authentic2.backends import get_user_queryset |
25 | 26 |
from authentic2.user_login_failure import user_login_failure, user_login_success |
... | ... | |
58 | 59 |
queries.append(models.Q(**{username_field: upn(username, realm)})) |
59 | 60 |
else: |
60 | 61 |
queries.append(models.Q(**{username_field: upn(username, realm)})) |
61 |
queries = six.moves.reduce(models.Q.__or__, queries)
|
|
62 |
queries = functools.reduce(models.Q.__or__, queries)
|
|
62 | 63 |
if ou: |
63 | 64 |
queries &= models.Q(ou=ou) |
64 | 65 |
return queries |
src/authentic2/cors.py | ||
---|---|---|
15 | 15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | 16 | |
17 | 17 | |
18 |
import urllib.parse |
|
19 | ||
18 | 20 |
from django.conf import settings |
19 |
from django.utils.six.moves.urllib import parse as urlparse |
|
20 | 21 | |
21 | 22 |
from . import app_settings, plugins |
22 | 23 |
from .decorators import SessionCache |
... | ... | |
24 | 25 | |
25 | 26 |
def make_origin(url): |
26 | 27 |
'''Build origin of an URL''' |
27 |
parsed = urlparse.urlparse(url) |
|
28 |
parsed = urllib.parse.urlparse(url)
|
|
28 | 29 |
if ':' in parsed.netloc: |
29 | 30 |
host, port = parsed.netloc.split(':', 1) |
30 | 31 |
if parsed.scheme == 'http' and port == 80: |
src/authentic2/crypto.py | ||
---|---|---|
26 | 26 |
from Cryptodome.Protocol.KDF import PBKDF2 |
27 | 27 |
from django.utils.crypto import constant_time_compare |
28 | 28 |
from django.utils.encoding import force_bytes |
29 |
from django.utils.six import text_type |
|
30 | 29 | |
31 | 30 | |
32 | 31 |
class DecryptionError(Exception): |
... | ... | |
123 | 122 |
key_size = 16 |
124 | 123 |
hmac_size = key_size |
125 | 124 | |
126 |
if isinstance(salt, text_type):
|
|
125 |
if isinstance(salt, str):
|
|
127 | 126 |
salt = force_bytes(salt) |
128 | 127 |
iv = hashmod.new(salt).digest() |
129 | 128 | |
... | ... | |
174 | 173 |
if not crypted or not hmac or prf(key, crypted)[:hmac_size] != hmac: |
175 | 174 |
raise DecryptionError('invalid HMAC') |
176 | 175 | |
177 |
if isinstance(salt, text_type):
|
|
176 |
if isinstance(salt, str):
|
|
178 | 177 |
salt = force_bytes(salt) |
179 | 178 |
iv = hashmod.new(salt).digest() |
180 | 179 |
src/authentic2/csv_import.py | ||
---|---|---|
27 | 27 |
from django.core.validators import RegexValidator |
28 | 28 |
from django.db import IntegrityError, models |
29 | 29 |
from django.db.transaction import atomic |
30 |
from django.utils import six |
|
31 | 30 |
from django.utils.encoding import force_bytes, force_text |
32 | 31 |
from django.utils.translation import ugettext as _ |
33 | 32 | |
... | ... | |
109 | 108 |
encoding = None |
110 | 109 | |
111 | 110 |
def run(self, fd_or_str, encoding): |
112 |
if isinstance(fd_or_str, six.binary_type):
|
|
111 |
if isinstance(fd_or_str, bytes):
|
|
113 | 112 |
input_fd = io.BytesIO(fd_or_str) |
114 |
elif isinstance(fd_or_str, six.text_type):
|
|
113 |
elif isinstance(fd_or_str, str):
|
|
115 | 114 |
input_fd = io.StringIO(fd_or_str) |
116 | 115 |
elif not hasattr(fd_or_str, 'read1'): |
117 | 116 |
try: |
... | ... | |
122 | 121 |
except Exception: |
123 | 122 |
pass |
124 | 123 |
content = fd_or_str.read() |
125 |
if isinstance(content, six.text_type):
|
|
124 |
if isinstance(content, str):
|
|
126 | 125 |
input_fd = io.StringIO(content) |
127 | 126 |
else: |
128 | 127 |
input_fd = io.BytesIO(content) |
... | ... | |
539 | 538 |
form.is_valid() |
540 | 539 | |
541 | 540 |
def get_form_errors(form, name): |
542 |
return [Error('data-error', six.text_type(value)) for value in form.errors.get(name, [])]
|
|
541 |
return [Error('data-error', str(value)) for value in form.errors.get(name, [])]
|
|
543 | 542 | |
544 | 543 |
cells = [ |
545 | 544 |
CsvCell( |
src/authentic2/custom_user/models.py | ||
---|---|---|
24 | 24 |
from django.core.exceptions import MultipleObjectsReturned, ValidationError |
25 | 25 |
from django.core.mail import send_mail |
26 | 26 |
from django.db import models, transaction |
27 |
from django.utils import six, timezone
|
|
27 |
from django.utils import timezone |
|
28 | 28 |
from django.utils.translation import ugettext_lazy as _ |
29 | 29 | |
30 | 30 |
try: |
... | ... | |
233 | 233 |
return '%s (%s)' % (human_name, short_id) |
234 | 234 | |
235 | 235 |
def __repr__(self): |
236 |
return '<User: %r>' % six.text_type(self)
|
|
236 |
return '<User: %r>' % str(self)
|
|
237 | 237 | |
238 | 238 |
def clean(self): |
239 | 239 |
if not (self.username or self.email or (self.first_name and self.last_name)): |
src/authentic2/decorators.py | ||
---|---|---|
25 | 25 |
from django.core.cache import cache as django_cache |
26 | 26 |
from django.core.exceptions import ValidationError |
27 | 27 |
from django.http import Http404, HttpResponse, HttpResponseBadRequest, HttpResponseForbidden |
28 |
from django.utils import six |
|
29 | 28 |
from django.views.debug import technical_404_response |
30 | 29 | |
31 | 30 |
from . import app_settings, middleware |
... | ... | |
195 | 194 |
for i, arg in enumerate(args): |
196 | 195 |
if self.args and i not in self.args: |
197 | 196 |
continue |
198 |
parts.append(six.text_type(arg))
|
|
197 |
parts.append(str(arg))
|
|
199 | 198 | |
200 | 199 |
for kw, arg in sorted(kwargs.items(), key=lambda x: x[0]): |
201 | 200 |
if kw not in self.kwargs: |
202 | 201 |
continue |
203 |
parts.append(u'%s-%s' % (six.text_type(kw), six.text_type(arg)))
|
|
202 |
parts.append(u'%s-%s' % (str(kw), str(arg)))
|
|
204 | 203 |
return u'|'.join(parts) |
205 | 204 | |
206 | 205 |
src/authentic2/disco_service/disco_responder.py | ||
---|---|---|
23 | 23 | |
24 | 24 | |
25 | 25 |
import logging |
26 |
import urllib.parse |
|
26 | 27 |
from xml.dom.minidom import parseString |
27 | 28 | |
28 | 29 |
from django.conf.urls import url |
29 | 30 |
from django.http import HttpResponseRedirect |
30 | 31 |
from django.urls import reverse |
31 | 32 |
from django.utils.http import urlquote |
32 |
from django.utils.six.moves.urllib import parse as urlparse |
|
33 | 33 |
from django.utils.translation import ugettext as _ |
34 | 34 | |
35 | 35 |
from authentic2 import settings |
... | ... | |
117 | 117 | |
118 | 118 | |
119 | 119 |
def is_param_id_in_return_url(return_url, returnIDParam): |
120 |
url = urlparse.urlparse(return_url) |
|
121 |
if url.query and returnIDParam in urlparse.parse_qs(url.query): |
|
120 |
url = urllib.parse.urlparse(return_url)
|
|
121 |
if url.query and returnIDParam in urllib.parse.parse_qs(url.query):
|
|
122 | 122 |
return True |
123 | 123 |
return False |
124 | 124 | |
125 | 125 | |
126 | 126 |
def add_param_to_url(url, param_name, value): |
127 |
scheme, netloc, path, params, query, fragment = urlparse.urlparse(url) |
|
127 |
scheme, netloc, path, params, query, fragment = urllib.parse.urlparse(url)
|
|
128 | 128 |
if query: |
129 |
qs = urlparse.parse_qs(query) |
|
129 |
qs = urllib.parse.parse_qs(query)
|
|
130 | 130 |
qs[param_name] = [value] |
131 | 131 |
query = urlparse.urlencode(qs) |
132 | 132 |
else: |
133 | 133 |
query = '%s=%s' % (param_name, value) |
134 |
return urlparse.urlunparse((scheme, netloc, path, params, query, fragment)) |
|
134 |
return urllib.parse.urlunparse((scheme, netloc, path, params, query, fragment))
|
|
135 | 135 | |
136 | 136 | |
137 | 137 |
def disco(request): |
src/authentic2/exponential_retry_timeout.py | ||
---|---|---|
19 | 19 |
import time |
20 | 20 | |
21 | 21 |
from django.core.cache import cache |
22 |
from django.utils import six |
|
23 | 22 | |
24 | 23 | |
25 | 24 |
class ExponentialRetryTimeout(object): |
... | ... | |
45 | 44 |
self.key_prefix = key_prefix |
46 | 45 | |
47 | 46 |
def key(self, keys): |
48 |
key = u'-'.join(six.text_type(key) for key in keys)
|
|
47 |
key = u'-'.join(str(key) for key in keys)
|
|
49 | 48 |
key = key.encode('utf-8') |
50 | 49 |
return '%s%s' % (self.key_prefix or self.KEY_PREFIX, hashlib.md5(key).hexdigest()) |
51 | 50 |
src/authentic2/idp/saml/backend.py | ||
---|---|---|
14 | 14 |
# You should have received a copy of the GNU Affero General Public License |
15 | 15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | 16 | |
17 |
import functools |
|
17 | 18 |
import logging |
18 | 19 |
import operator |
19 | 20 |
import random |
21 |
from urllib.parse import quote |
|
20 | 22 | |
21 | 23 |
from django.db.models import Q |
22 | 24 |
from django.template.loader import render_to_string |
23 | 25 |
from django.urls import reverse |
24 |
from django.utils import six |
|
25 |
from django.utils.six.moves.urllib.parse import quote |
|
26 | 26 |
from django.utils.translation import ugettext as _ |
27 | 27 | |
28 | 28 |
import authentic2.idp.saml.saml2_endpoints as saml2_endpoints |
... | ... | |
68 | 68 |
queries.append( |
69 | 69 |
q.filter(sp_options_policy__isnull=True, liberty_provider__entity_id__in=sessions_eids) |
70 | 70 |
) |
71 |
qs = six.moves.reduce(operator.__or__, queries)
|
|
71 |
qs = functools.reduce(operator.__or__, queries)
|
|
72 | 72 |
# do some prefetching |
73 | 73 |
qs = qs.prefetch_related('liberty_provider') |
74 | 74 |
qs = qs.select_related('sp_options_policy') |
src/authentic2/idp/saml/saml2_endpoints.py | ||
---|---|---|
41 | 41 |
import string |
42 | 42 |
import xml.etree.cElementTree as ctree |
43 | 43 |
from functools import wraps |
44 |
from urllib.parse import quote, urlencode |
|
44 | 45 | |
45 | 46 |
from django.conf import settings |
46 | 47 |
from django.contrib import messages |
... | ... | |
50 | 51 |
from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseForbidden, HttpResponseRedirect |
51 | 52 |
from django.shortcuts import redirect, render |
52 | 53 |
from django.urls import reverse |
53 |
from django.utils import six |
|
54 | 54 |
from django.utils.encoding import force_bytes, force_str, force_text |
55 |
from django.utils.six.moves.urllib.parse import quote, urlencode |
|
56 | 55 |
from django.utils.translation import ugettext as _ |
57 | 56 |
from django.utils.translation import ugettext_noop as N_ |
58 | 57 |
from django.views.decorators.cache import never_cache |
... | ... | |
821 | 820 |
if not access_granted: |
822 | 821 |
logger.debug('access denied, return answer to the requester') |
823 | 822 |
set_saml2_response_responder_status_code( |
824 |
login.response, lasso.SAML2_STATUS_CODE_REQUEST_DENIED, msg=six.text_type(dic['message'])
|
|
823 |
login.response, lasso.SAML2_STATUS_CODE_REQUEST_DENIED, msg=str(dic['message'])
|
|
825 | 824 |
) |
826 | 825 |
return finish_sso(request, login) |
827 | 826 |
src/authentic2/log_filters.py | ||
---|---|---|
16 | 16 | |
17 | 17 |
import logging |
18 | 18 | |
19 |
from django.utils import six |
|
20 | ||
21 | 19 | |
22 | 20 |
class RequestContextFilter(logging.Filter): |
23 | 21 |
DEFAULT_USERNAME = '-' |
... | ... | |
45 | 43 | |
46 | 44 |
if not hasattr(record, 'user'): |
47 | 45 |
if hasattr(request, 'user') and request.user.is_authenticated: |
48 |
record.user = six.text_type(request.user)
|
|
46 |
record.user = str(request.user)
|
|
49 | 47 |
else: |
50 | 48 |
record.user = self.DEFAULT_USERNAME |
51 | 49 |
src/authentic2/management/commands/check-and-repair.py | ||
---|---|---|
27 | 27 |
from django.db.models import Count, Q |
28 | 28 |
from django.db.models.functions import Lower |
29 | 29 |
from django.db.transaction import atomic |
30 |
from django.utils.six.moves import input |
|
31 | 30 |
from django.utils.timezone import localtime |
32 | 31 | |
33 | 32 |
from authentic2 import app_settings |
src/authentic2/management/commands/clean-unused-accounts.py | ||
---|---|---|
17 | 17 |
from __future__ import print_function |
18 | 18 | |
19 | 19 |
import logging |
20 |
import urllib.parse |
|
20 | 21 |
from datetime import timedelta |
21 | 22 | |
22 | 23 |
from django.conf import settings |
... | ... | |
25 | 26 |
from django.db import transaction |
26 | 27 |
from django.db.models import F |
27 | 28 |
from django.utils import timezone, translation |
28 |
from django.utils.six.moves.urllib import parse as urlparse |
|
29 | 29 | |
30 | 30 |
from authentic2.backends.ldap_backend import LDAPBackend |
31 | 31 |
from authentic2.utils import send_templated_mail |
... | ... | |
110 | 110 |
ctx = { |
111 | 111 |
'user': user, |
112 | 112 |
'days_to_deletion': days_to_deletion, |
113 |
'login_url': urlparse.urljoin(settings.SITE_BASE_URL, settings.LOGIN_URL), |
|
113 |
'login_url': urllib.parse.urljoin(settings.SITE_BASE_URL, settings.LOGIN_URL),
|
|
114 | 114 |
} |
115 | 115 |
with transaction.atomic(): |
116 | 116 |
if not self.fake: |
src/authentic2/management/commands/slapd-shell.py | ||
---|---|---|
16 | 16 | |
17 | 17 |
from __future__ import print_function |
18 | 18 | |
19 |
import io |
|
19 | 20 |
import logging |
20 | 21 |
import re |
21 | 22 |
import sys |
22 | 23 | |
23 | 24 |
from django.contrib.auth import get_user_model |
24 | 25 |
from django.core.management.base import BaseCommand |
25 |
from django.utils import six |
|
26 | 26 |
from ldap.dn import escape_dn_chars |
27 | 27 |
from ldif import LDIFWriter |
28 | 28 | |
... | ... | |
48 | 48 |
def ldap(self, command, attrs): |
49 | 49 |
self.logger.debug('received command %s %s', command, attrs) |
50 | 50 |
if command == 'SEARCH': |
51 |
out = six.BytesIO()
|
|
51 |
out = io.BytesIO()
|
|
52 | 52 |
ldif_writer = LDIFWriter(out) |
53 | 53 |
qs = get_user_model().objects.all() |
54 | 54 |
if attrs['filter'] != '(objectClass=*)': |
... | ... | |
85 | 85 |
for user in qs: |
86 | 86 |
o = {} |
87 | 87 |
for user_attribute, ldap_attribute in MAPPING.items(): |
88 |
o[ldap_attribute] = [six.text_type(getattr(user, user_attribute)).encode('utf-8')]
|
|
88 |
o[ldap_attribute] = [str(getattr(user, user_attribute)).encode('utf-8')]
|
|
89 | 89 |
o['objectClass'] = ['inetOrgPerson'] |
90 | 90 |
dn = 'uid=%s,%s' % (escape_dn_chars(o['uid'][0]), attrs['suffix']) |
91 | 91 |
self.logger.debug(u'sending entry %s %s', dn, o) |
src/authentic2/manager/forms.py | ||
---|---|---|
23 | 23 |
from django.contrib.auth import get_user_model |
24 | 24 |
from django.contrib.contenttypes.models import ContentType |
25 | 25 |
from django.core.exceptions import ValidationError |
26 |
from django.utils import six |
|
27 | 26 |
from django.utils.text import slugify |
28 | 27 |
from django.utils.translation import pgettext, ugettext |
29 | 28 |
from django.utils.translation import ugettext_lazy as _ |
... | ... | |
67 | 66 |
def save(self, commit=True): |
68 | 67 |
instance = self.instance |
69 | 68 |
if not instance.slug: |
70 |
instance.slug = slugify(six.text_type(instance.name)).lstrip('_')
|
|
69 |
instance.slug = slugify(str(instance.name)).lstrip('_')
|
|
71 | 70 |
qs = instance.__class__.objects.all() |
72 | 71 |
if instance.pk: |
73 | 72 |
qs = qs.exclude(pk=instance.pk) |
... | ... | |
441 | 440 |
if self.show_all_ou and (len(self.ou_qs) > 1 or self.search_all_ous): |
442 | 441 |
choices.append(('all', all_ou_label)) |
443 | 442 |
for ou in self.ou_qs: |
444 |
choices.append((str(ou.pk), six.text_type(ou)))
|
|
443 |
choices.append((str(ou.pk), str(ou)))
|
|
445 | 444 |
if self.show_none_ou and self.search_all_ous: |
446 | 445 |
choices.append(('none', pgettext('organizational unit', 'None'))) |
447 | 446 | |
... | ... | |
703 | 702 |
@staticmethod |
704 | 703 |
def raise_validation_error(error_message): |
705 | 704 |
message_prefix = ugettext('Invalid import file') |
706 |
raise forms.ValidationError('%s : %s' % (message_prefix, six.text_type(error_message)))
|
|
705 |
raise forms.ValidationError('%s : %s' % (message_prefix, str(error_message)))
|
|
707 | 706 | |
708 | 707 | |
709 | 708 |
class UserNewImportForm(UserImportForm): |
src/authentic2/manager/ou_views.py | ||
---|---|---|
21 | 21 |
from django.db import transaction |
22 | 22 |
from django.http import HttpResponseRedirect |
23 | 23 |
from django.urls import reverse |
24 |
from django.utils import six |
|
25 | 24 |
from django.utils.translation import ugettext as _ |
26 | 25 |
from django.views.generic import FormView |
27 | 26 | |
... | ... | |
68 | 67 | |
69 | 68 |
@property |
70 | 69 |
def title(self): |
71 |
return six.text_type(self.object)
|
|
70 |
return str(self.object)
|
|
72 | 71 | |
73 | 72 |
def authorize(self, request, *args, **kwargs): |
74 | 73 |
super(OrganizationalUnitDetailView, self).authorize(request, *args, **kwargs) |
src/authentic2/manager/resources.py | ||
---|---|---|
15 | 15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | 16 | |
17 | 17 |
from django.contrib.auth import get_user_model |
18 |
from django.utils import six |
|
19 | 18 |
from import_export.fields import Field |
20 | 19 |
from import_export.resources import ModelResource |
21 | 20 |
from import_export.widgets import Widget |
... | ... | |
30 | 29 |
raise NotImplementedError |
31 | 30 | |
32 | 31 |
def render(self, value, object): |
33 |
return u', '.join(six.text_type(v) for v in value.all())
|
|
32 |
return u', '.join(str(v) for v in value.all())
|
|
34 | 33 | |
35 | 34 | |
36 | 35 |
class UserResource(ModelResource): |
... | ... | |
42 | 41 |
result.add(role) |
43 | 42 |
for pr in role.parent_relation.all(): |
44 | 43 |
result.add(pr.parent) |
45 |
return ', '.join(six.text_type(x) for x in result)
|
|
44 |
return ', '.join(str(x) for x in result)
|
|
46 | 45 | |
47 | 46 |
class Meta: |
48 | 47 |
model = User |
src/authentic2/manager/service_views.py | ||
---|---|---|
15 | 15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | 16 | |
17 | 17 |
from django.contrib import messages |
18 |
from django.utils import six |
|
19 | 18 |
from django.utils.translation import ugettext as _ |
20 | 19 | |
21 | 20 |
from authentic2.models import Service |
... | ... | |
53 | 52 | |
54 | 53 |
@property |
55 | 54 |
def title(self): |
56 |
return six.text_type(self.object)
|
|
55 |
return str(self.object)
|
|
57 | 56 | |
58 | 57 |
def get_table_queryset(self): |
59 | 58 |
return self.object.authorized_roles.all() |
src/authentic2/manager/user_import.py | ||
---|---|---|
30 | 30 |
from django.conf import settings |
31 | 31 |
from django.core.files.storage import default_storage |
32 | 32 |
from django.db import connection |
33 |
from django.utils import six |
|
34 | 33 |
from django.utils.functional import cached_property |
35 | 34 |
from django.utils.timezone import utc |
36 | 35 |
from django.utils.translation import ugettext_lazy as _ |
... | ... | |
225 | 224 |
logger.exception('error during report %s:%s run', self.user_import.uuid, self.uuid) |
226 | 225 |
state = self.STATE_ERROR |
227 | 226 |
try: |
228 |
exception = six.text_type(e)
|
|
227 |
exception = str(e)
|
|
229 | 228 |
except Exception: |
230 | 229 |
exception = repr(repr(e)) |
231 | 230 |
else: |
src/authentic2/manager/views.py | ||
---|---|---|
26 | 26 |
from django.forms import MediaDefiningClass |
27 | 27 |
from django.http import Http404, HttpResponse |
28 | 28 |
from django.urls import reverse, reverse_lazy |
29 |
from django.utils import six |
|
30 | 29 |
from django.utils.encoding import force_text |
31 | 30 |
from django.utils.functional import cached_property |
32 | 31 |
from django.utils.timezone import now |
... | ... | |
62 | 61 |
return super(MultipleOUMixin, self).get_context_data(**kwargs) |
63 | 62 | |
64 | 63 | |
65 |
@six.add_metaclass(MediaMixinBase) |
|
66 |
class MediaMixin(object): |
|
64 |
class MediaMixin(object, metaclass=MediaMixinBase): |
|
67 | 65 |
'''Expose needed CSS and JS files as a media object''' |
68 | 66 | |
69 | 67 |
class Media: |
... | ... | |
401 | 399 | |
402 | 400 |
def get_instance_name(self): |
403 | 401 |
if hasattr(self, 'get_object'): |
404 |
return six.text_type(self.get_object())
|
|
402 |
return str(self.get_object())
|
|
405 | 403 |
return u'' |
406 | 404 | |
407 | 405 |
def get_context_data(self, **kwargs): |
... | ... | |
674 | 672 |
continue |
675 | 673 |
menu_entries.append( |
676 | 674 |
{ |
677 |
'label': six.text_type(entry['label']),
|
|
675 |
'label': str(entry['label']),
|
|
678 | 676 |
'slug': entry.get('slug', ''), |
679 |
'url': request.build_absolute_uri(six.text_type(entry['href'])),
|
|
677 |
'url': request.build_absolute_uri(str(entry['href'])),
|
|
680 | 678 |
} |
681 | 679 |
) |
682 | 680 |
return menu_entries |
src/authentic2/manager/widgets.py | ||
---|---|---|
15 | 15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | 16 | |
17 | 17 |
import base64 |
18 |
import functools |
|
18 | 19 |
import operator |
19 | 20 |
import pickle |
20 | 21 | |
21 | 22 |
from django.contrib.auth import get_user_model |
22 | 23 |
from django.core import signing |
23 |
from django.utils import six |
|
24 | 24 |
from django.utils.encoding import force_text |
25 | 25 |
from django_select2.forms import ModelSelect2MultipleWidget, ModelSelect2Widget |
26 | 26 | |
... | ... | |
43 | 43 |
queries = [] |
44 | 44 |
for term in term.split(): |
45 | 45 |
queries.append(super(SplitTermMixin, self).filter_queryset(term, queryset=qs)) |
46 |
qs = six.moves.reduce(self.split_term_operator, queries)
|
|
46 |
qs = functools.reduce(self.split_term_operator, queries)
|
|
47 | 47 |
return qs |
48 | 48 | |
49 | 49 | |
... | ... | |
101 | 101 |
] |
102 | 102 | |
103 | 103 |
def label_from_instance(self, obj): |
104 |
label = six.text_type(obj)
|
|
104 |
label = str(obj)
|
|
105 | 105 |
if obj.ou and utils.get_ou_count() > 1: |
106 | 106 |
label = u'{ou} - {obj}'.format(ou=obj.ou, obj=obj) |
107 | 107 |
return label |
src/authentic2/middleware.py | ||
---|---|---|
21 | 21 |
except ImportError: |
22 | 22 |
threading = None |
23 | 23 | |
24 |
import urllib.parse |
|
25 | ||
24 | 26 |
from django import http |
25 | 27 |
from django.conf import settings |
26 | 28 |
from django.contrib import messages |
27 | 29 |
from django.utils.deprecation import MiddlewareMixin |
28 | 30 |
from django.utils.functional import SimpleLazyObject |
29 |
from django.utils.six.moves.urllib import parse as urlparse |
|
30 | 31 |
from django.utils.translation import ugettext as _ |
31 | 32 | |
32 | 33 |
from . import app_settings, plugins, utils |
... | ... | |
162 | 163 |
return response |
163 | 164 |
if not getattr(response, 'display_message', True): |
164 | 165 |
return response |
165 |
parsed_url = urlparse.urlparse(url) |
|
166 |
parsed_url = urllib.parse.urlparse(url)
|
|
166 | 167 |
if not parsed_url.scheme and not parsed_url.netloc: |
167 | 168 |
return response |
168 |
parsed_request_url = urlparse.urlparse(request.build_absolute_uri()) |
|
169 |
parsed_request_url = urllib.parse.urlparse(request.build_absolute_uri())
|
|
169 | 170 |
if (parsed_request_url.scheme == parsed_url.scheme or not parsed_url.scheme) and ( |
170 | 171 |
parsed_request_url.netloc == parsed_url.netloc |
171 | 172 |
): |
src/authentic2/migrations/__init__.py | ||
---|---|---|
1 | 1 |
import itertools |
2 | 2 | |
3 | 3 |
from django.db.migrations.operations.base import Operation |
4 |
from django.utils import six |
|
5 | 4 | |
6 | 5 | |
7 | 6 |
class CreatePartialIndexes(Operation): |
... | ... | |
64 | 63 |
for clause in where: |
65 | 64 |
if isinstance(clause, tuple): |
66 | 65 |
clause, params = clause |
67 |
assert isinstance(clause, six.string_types)
|
|
66 |
assert isinstance(clause, str)
|
|
68 | 67 |
assert isinstance(params, tuple) |
69 | 68 |
clause = clause % tuple(schema_editor.quote_value(param) for param in params) |
70 |
assert isinstance(clause, six.string_types)
|
|
69 |
assert isinstance(clause, str)
|
|
71 | 70 |
clauses.append(clause) |
72 | 71 |
where_clause = ' AND '.join(clauses) |
73 | 72 |
# SQLite does not accept parameters in partial index creations, don't ask why :/ |
src/authentic2/models.py | ||
---|---|---|
16 | 16 | |
17 | 17 |
import datetime |
18 | 18 |
import time |
19 |
import urllib.parse |
|
19 | 20 |
import uuid |
20 | 21 | |
21 | 22 |
import django |
... | ... | |
27 | 28 |
from django.core.exceptions import ValidationError |
28 | 29 |
from django.db import models, transaction |
29 | 30 |
from django.db.models.query import Q |
30 |
from django.utils import six, timezone
|
|
31 |
from django.utils import timezone |
|
31 | 32 |
from django.utils.http import urlquote |
32 |
from django.utils.six.moves.urllib import parse as urlparse |
|
33 | 33 |
from django.utils.translation import ugettext_lazy as _ |
34 | 34 |
from model_utils.managers import QueryManager |
35 | 35 | |
... | ... | |
117 | 117 | |
118 | 118 |
def get_logout_url(self, request): |
119 | 119 |
ok_icon_url = ( |
120 |
request.build_absolute_uri(urlparse.urljoin(settings.STATIC_URL, 'authentic2/images/ok.png')) |
|
120 |
request.build_absolute_uri(urllib.parse.urljoin(settings.STATIC_URL, 'authentic2/images/ok.png'))
|
|
121 | 121 |
+ '?nonce=%s' % time.time() |
122 | 122 |
) |
123 | 123 |
return self.logout_url.format(urlquote(ok_icon_url)) |
... | ... | |
363 | 363 |
verbose_name_plural = _('password reset') |
364 | 364 | |
365 | 365 |
def __str__(self): |
366 |
return six.text_type(self.user)
|
|
366 |
return str(self.user)
|
|
367 | 367 | |
368 | 368 | |
369 | 369 |
class Service(models.Model): |
... | ... | |
418 | 418 |
return self.name |
419 | 419 | |
420 | 420 |
def __repr__(self): |
421 |
return '<%s %r>' % (self.__class__.__name__, six.text_type(self))
|
|
421 |
return '<%s %r>' % (self.__class__.__name__, str(self))
|
|
422 | 422 | |
423 | 423 |
def authorize(self, user): |
424 | 424 |
if not self.authorized_roles.exists(): |
... | ... | |
492 | 492 |
else: |
493 | 493 |
return _uuid |
494 | 494 | |
495 |
if isinstance(_uuid, six.text_type):
|
|
495 |
if isinstance(_uuid, str):
|
|
496 | 496 |
_uuid = _uuid.encode('ascii') |
497 | 497 |
_uuid = base64url_decode(_uuid) |
498 | 498 |
return uuid.UUID(bytes=_uuid) |
src/authentic2/passwords.py | ||
---|---|---|
20 | 20 |
import string |
21 | 21 | |
22 | 22 |
from django.core.exceptions import ValidationError |
23 |
from django.utils import six |
|
24 | 23 |
from django.utils.functional import lazy |
25 | 24 |
from django.utils.module_loading import import_string |
26 | 25 |
from django.utils.translation import ugettext as _ |
... | ... | |
50 | 49 |
return ''.join(new_password) |
51 | 50 | |
52 | 51 | |
53 |
@six.add_metaclass(abc.ABCMeta) |
|
54 |
class PasswordChecker(object): |
|
52 |
class PasswordChecker(object, metaclass=abc.ABCMeta): |
|
55 | 53 |
class Check(object): |
56 | 54 |
def __init__(self, label, result): |
57 | 55 |
self.label = label |
... | ... | |
134 | 132 |
return '' |
135 | 133 | |
136 | 134 | |
137 |
password_help_text = lazy(password_help_text, six.text_type) |
|
135 |
password_help_text = lazy(password_help_text, str) |
src/authentic2/saml/admin.py | ||
---|---|---|
22 | 22 |
from django.contrib import admin, messages |
23 | 23 |
from django.core.exceptions import ValidationError |
24 | 24 |
from django.forms import ModelForm |
25 |
from django.utils import six |
|
26 | 25 |
from django.utils.translation import ugettext as _ |
27 | 26 | |
28 | 27 |
try: |
... | ... | |
72 | 71 |
def render(self, name, value, attrs=None, **kwargs): |
73 | 72 |
if attrs is None: |
74 | 73 |
attrs = {} |
75 |
if isinstance(value, (str, six.text_type)):
|
|
74 |
if isinstance(value, (str, str)):
|
|
76 | 75 |
attrs['rows'] = value.count('\n') + 5 |
77 | 76 |
attrs['cols'] = min(max((len(x) for x in value.split('\n'))), 150) |
78 | 77 |
return super(TextAndFileWidget, self).render(name, value, attrs, **kwargs) |
src/authentic2/saml/common.py | ||
---|---|---|
15 | 15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | 16 | |
17 | 17 |
import datetime |
18 |
import functools |
|
18 | 19 |
import logging |
19 | 20 |
import os.path |
20 | 21 |
import re |
... | ... | |
25 | 26 |
from django.http import Http404, HttpResponse, HttpResponseRedirect |
26 | 27 |
from django.shortcuts import render |
27 | 28 |
from django.urls import reverse |
28 |
from django.utils import six |
|
29 | 29 |
from django.utils.encoding import force_text |
30 | 30 | |
31 | 31 |
from authentic2.compat_lasso import lasso |
... | ... | |
337 | 337 |
return None |
338 | 338 |
logger.debug('loaded %d bytes', len(metadata)) |
339 | 339 |
try: |
340 |
metadata = six.text_type(metadata, 'utf-8')
|
|
340 |
metadata = str(metadata, 'utf-8')
|
|
341 | 341 |
except UnicodeDecodeError: |
342 | 342 |
logging.error('SAML metadata autoload: retrieved metadata for entity id %s is not UTF-8', provider_id) |
343 | 343 |
return None |
... | ... | |
586 | 586 |
value, |
587 | 587 |
) |
588 | 588 |
if session_not_on_or_afters: |
589 |
return six.moves.reduce(min, session_not_on_or_afters)
|
|
589 |
return functools.reduce(min, session_not_on_or_afters)
|
|
590 | 590 |
return None |
src/authentic2/saml/fields.py | ||
---|---|---|
27 | 27 |
from django.core.exceptions import ValidationError |
28 | 28 |
from django.db import models |
29 | 29 |
from django.template.defaultfilters import pluralize |
30 |
from django.utils import six |
|
31 | 30 |
from django.utils.encoding import force_bytes, force_text |
32 | 31 |
from django.utils.text import capfirst |
33 | 32 | |
... | ... | |
56 | 55 |
# Initial author: Oliver Beattie |
57 | 56 | |
58 | 57 | |
59 |
class PickledObject(six.text_type):
|
|
58 |
class PickledObject(str):
|
|
60 | 59 |
"""A subclass of string so it can be told whether a string is |
61 | 60 |
a pickled object or not (if the object is an instance of this class |
62 | 61 |
then it must [well, should] be a pickled one).""" |
... | ... | |
161 | 160 |
return MultiSelectFormField(**defaults) |
162 | 161 | |
163 | 162 |
def get_db_prep_value(self, value, connection, prepared=False): |
164 |
if isinstance(value, six.string_types):
|
|
163 |
if isinstance(value, str):
|
|
165 | 164 |
return value |
166 | 165 |
elif isinstance(value, list): |
167 | 166 |
return ",".join(value) |
src/authentic2/saml/management/commands/sync-metadata.py | ||
---|---|---|
16 | 16 | |
17 | 17 |
from __future__ import print_function |
18 | 18 | |
19 |
import io |
|
19 | 20 |
import os |
20 | 21 |
import sys |
21 | 22 |
import warnings |
... | ... | |
26 | 27 |
from django.core.management.base import BaseCommand, CommandError |
27 | 28 |
from django.db.transaction import atomic |
28 | 29 |
from django.template.defaultfilters import slugify |
29 |
from django.utils import six |
|
30 | 30 |
from django.utils.translation import gettext as _ |
31 | 31 | |
32 | 32 |
from authentic2.compat_lasso import lasso |
... | ... | |
340 | 340 |
response = requests.get(metadata_file_path) |
341 | 341 |
if not response.ok: |
342 | 342 |
raise CommandError('Unable to open url %s' % metadata_file_path) |
343 |
metadata_file = six.BytesIO(response.content)
|
|
343 |
metadata_file = io.BytesIO(response.content)
|
|
344 | 344 |
else: |
345 | 345 |
try: |
346 | 346 |
with open(metadata_file_path, 'rb') as fd: |
347 |
metadata_file = six.BytesIO(fd.read())
|
|
347 |
metadata_file = io.BytesIO(fd.read())
|
|
348 | 348 |
except IOError: |
349 | 349 |
raise CommandError('Unable to open file %s' % metadata_file_path) |
350 | 350 |
src/authentic2/saml/models.py | ||
---|---|---|
25 | 25 |
from django.db import models |
26 | 26 |
from django.db.models import Q |
27 | 27 |
from django.db.models.query import QuerySet |
28 |
from django.utils import six |
|
29 | 28 |
from django.utils.encoding import force_str, force_text |
30 | 29 |
from django.utils.translation import ugettext_lazy as _ |
31 | 30 | |
... | ... | |
484 | 483 |
return (self.liberty_provider.slug,) |
485 | 484 | |
486 | 485 |
def __str__(self): |
487 |
return six.text_type(self.liberty_provider)
|
|
486 |
return str(self.liberty_provider)
|
|
488 | 487 | |
489 | 488 |
class Meta: |
490 | 489 |
verbose_name = _('SAML service provider') |
src/authentic2/saml/saml2utils.py | ||
---|---|---|
22 | 22 |
import time |
23 | 23 |
import xml.etree.ElementTree as etree |
24 | 24 | |
25 |
from django.utils import six |
|
26 | 25 |
from django.utils.encoding import force_text |
27 | 26 | |
28 | 27 |
from authentic2.compat_lasso import lasso |
... | ... | |
30 | 29 | |
31 | 30 | |
32 | 31 |
def filter_attribute_private_key(message): |
33 |
if isinstance(message, six.string_types):
|
|
32 |
if isinstance(message, str):
|
|
34 | 33 |
return re.sub(r' (\w+:)?(PrivateKey=")([&#;\w/ +-=])+(")', '', message) |
35 | 34 |
else: |
36 | 35 |
return message |
37 | 36 | |
38 | 37 | |
39 | 38 |
def filter_element_private_key(message): |
40 |
if isinstance(message, six.string_types):
|
|
39 |
if isinstance(message, str):
|
|
41 | 40 |
return re.sub( |
42 | 41 |
r'(<saml)(p)?(:PrivateKeyFile>-----BEGIN RSA PRIVATE KEY-----)' |
43 | 42 |
r'([&#;\w/+=\s])+' |
src/authentic2/saml/x509utils.py | ||
---|---|---|
19 | 19 |
import subprocess |
20 | 20 |
import tempfile |
21 | 21 | |
22 |
import six |
|
23 | ||
24 | 22 |
_openssl = 'openssl' |
25 | 23 | |
26 | 24 | |
27 | 25 |
def decapsulate_pem_file(file_or_string): |
28 | 26 |
'''Remove PEM header lines''' |
29 |
if not isinstance(file_or_string, six.string_types):
|
|
27 |
if not isinstance(file_or_string, str):
|
|
30 | 28 |
content = file_or_string.read() |
31 | 29 |
else: |
32 | 30 |
content = file_or_string |
src/authentic2/serializers.py | ||
---|---|---|
23 | 23 |
from django.core.serializers.json import Serializer as JSONSerializer |
24 | 24 |
from django.core.serializers.python import _get_model |
25 | 25 |
from django.db import DEFAULT_DB_ALIAS |
26 |
from django.utils import six |
|
27 | 26 | |
28 | 27 | |
29 | 28 |
class Serializer(JSONSerializer): |
... | ... | |
73 | 72 |
""" |
74 | 73 |
from django.core.serializers.python import Deserializer as PythonDeserializer |
75 | 74 | |
76 |
if not isinstance(stream_or_string, (bytes, six.string_types)):
|
|
75 |
if not isinstance(stream_or_string, (bytes, str)):
|
|
77 | 76 |
stream_or_string = stream_or_string.read() |
78 | 77 |
if isinstance(stream_or_string, bytes): |
79 | 78 |
stream_or_string = stream_or_string.decode('utf-8') |
... | ... | |
85 | 84 |
except GeneratorExit: |
86 | 85 |
raise |
87 | 86 |
except Exception as e: |
88 |
# Map to deserializer error |
|
89 |
six.reraise(DeserializationError, DeserializationError(e), sys.exc_info()[2]) |
|
87 |
raise DeserializationError(e) |
src/authentic2/utils/__init__.py | ||
---|---|---|
19 | 19 |
import logging |
20 | 20 |
import random |
21 | 21 |
import time |
22 |
import urllib.parse |
|
22 | 23 |
import uuid |
23 | 24 |
from functools import wraps |
24 | 25 |
from importlib import import_module |
... | ... | |
40 | 41 |
from django.template.context import make_context |
41 | 42 |
from django.template.loader import TemplateDoesNotExist, render_to_string, select_template |
42 | 43 |
from django.urls import reverse |
43 |
from django.utils import html, six, timezone
|
|
44 |
from django.utils import html, timezone |
|
44 | 45 |
from django.utils.encoding import iri_to_uri, uri_to_iri |
45 | 46 |
from django.utils.formats import localize |
46 |
from django.utils.six.moves.urllib import parse as urlparse |
|
47 | 47 |
from django.utils.translation import ungettext |
48 | 48 | |
49 | 49 |
try: |
... | ... | |
171 | 171 |
backends = [] |
172 | 172 |
for backend_path in getattr(app_settings, setting_name): |
173 | 173 |
kwargs = {} |
174 |
if not isinstance(backend_path, six.string_types):
|
|
174 |
if not isinstance(backend_path, str):
|
|
175 | 175 |
backend_path, kwargs = backend_path |
176 | 176 |
kwargs_settings = getattr(app_settings, setting_name + '_KWARGS', {}) |
177 | 177 |
backend = load_backend(backend_path, kwargs_settings) |
... | ... | |
232 | 232 | |
233 | 233 |
def add_arg(url, key, value=None): |
234 | 234 |
'''Add a parameter to an URL''' |
235 |
key = urlparse.quote(key) |
|
235 |
key = urllib.parse.quote(key)
|
|
236 | 236 |
if value is not None: |
237 |
add = '%s=%s' % (key, urlparse.quote(value)) |
|
237 |
add = '%s=%s' % (key, urllib.parse.quote(value))
|
|
238 | 238 |
else: |
239 | 239 |
add = key |
240 | 240 |
if '?' in url: |
... | ... | |
262 | 262 | |
263 | 263 |
def field_names(list_of_field_name_and_titles): |
264 | 264 |
for t in list_of_field_name_and_titles: |
265 |
if isinstance(t, six.string_types):
|
|
265 |
if isinstance(t, str):
|
|
266 | 266 |
yield t |
267 | 267 |
else: |
268 | 268 |
yield t[0] |
... | ... | |
270 | 270 | |
271 | 271 |
def is_valid_url(url): |
272 | 272 |
try: |
273 |
parsed = urlparse.urlparse(url) |
|
273 |
parsed = urllib.parse.urlparse(url)
|
|
274 | 274 |
if parsed.scheme in ('http', 'https', ''): |
275 | 275 |
return True |
276 | 276 |
except Exception: |
... | ... | |
307 | 307 |
else: |
308 | 308 |
url = to |
309 | 309 |
url = iri_to_uri(url) |
310 |
scheme, netloc, path, query_string, o_fragment = urlparse.urlsplit(url) |
|
311 |
url = uri_to_iri(urlparse.urlunsplit((scheme, netloc, path, '', ''))) |
|
310 |
scheme, netloc, path, query_string, o_fragment = urllib.parse.urlsplit(url)
|
|
311 |
url = uri_to_iri(urllib.parse.urlunsplit((scheme, netloc, path, '', '')))
|
|
312 | 312 |
fragment = fragment or o_fragment |
313 | 313 |
# Django < 1.6 compat, query_string is not optional |
314 | 314 |
url_params = QueryDict(query_string=query_string, mutable=True) |
... | ... | |
348 | 348 |
if request: |
349 | 349 |
url = request.build_absolute_uri(url) |
350 | 350 |
elif hasattr(settings, 'SITE_BASE_URL'): |
351 |
url = urlparse.urljoin(settings.SITE_BASE_URL, url) |
|
351 |
url = urllib.parse.urljoin(settings.SITE_BASE_URL, url)
|
|
352 | 352 |
else: |
353 | 353 |
raise TypeError('make_url() absolute cannot be used without request') |
354 | 354 |
# keep using unicode |
... | ... | |
426 | 426 |
# explicitly state that the session has been modified |
427 | 427 |
request.session.modified = True |
428 | 428 |
event = { |
429 |
'who': six.text_type(request.user),
|
|
429 |
'who': str(request.user),
|
|
430 | 430 |
'who_id': getattr(request.user, 'pk', None), |
431 | 431 |
'how': how, |
432 | 432 |
'when': int(time.time()), |
433 | 433 |
} |
434 | 434 |
kwargs = { |
435 |
'who': six.text_type(request.user)[:80],
|
|
435 |
'who': str(request.user)[:80],
|
|
436 | 436 |
'how': how, |
437 | 437 |
} |
438 | 438 |
nonce = nonce or get_nonce(request) |
... | ... | |
621 | 621 |
def normalize_attribute_values(values): |
622 | 622 |
'''Take a list of values or a single one and normalize it''' |
623 | 623 |
values_set = set() |
624 |
if isinstance(values, six.string_types) or not hasattr(values, '__iter__'):
|
|
624 |
if isinstance(values, str) or not hasattr(values, '__iter__'):
|
|
625 | 625 |
values = [values] |
626 | 626 |
for value in values: |
627 | 627 |
if isinstance(value, bool): |
628 | 628 |
value = str(value).lower() |
629 |
values_set.add(six.text_type(value))
|
|
629 |
values_set.add(str(value))
|
|
630 | 630 |
return values_set |
631 | 631 | |
632 | 632 | |
... | ... | |
682 | 682 |
""" |
683 | 683 |
from .. import middleware |
684 | 684 | |
685 |
if isinstance(template_names, six.string_types):
|
|
685 |
if isinstance(template_names, str):
|
|
686 | 686 |
template_names = [template_names] |
687 | 687 |
if per_ou_templates and getattr(user_or_email, 'ou', None): |
688 | 688 |
new_template_names = [] |
... | ... | |
1055 | 1055 |
if good_next_url(request, next_url): |
1056 | 1056 |
if replace: |
1057 | 1057 |
for key, value in replace.items(): |
1058 |
next_url = next_url.replace(key, urlparse.quote(value)) |
|
1058 |
next_url = next_url.replace(key, urllib.parse.quote(value))
|
|
1059 | 1059 |
return next_url |
1060 | 1060 |
return default |
1061 | 1061 | |
... | ... | |
1127 | 1127 |
If not scheme and not port are given, port compare is skipped. |
1128 | 1128 |
The last two rules allow authorizing complete domains easily. |
1129 | 1129 |
""" |
1130 |
p1, p2 = urlparse.urlparse(url1), urlparse.urlparse(url2)
|
|
1130 |
p1, p2 = urllib.parse.urlparse(url1), urllib.parse.urlparse(url2)
|
|
1131 | 1131 |
p1_host, p1_port = netloc_to_host_port(p1.netloc) |
1132 | 1132 |
p2_host, p2_port = netloc_to_host_port(p2.netloc) |
1133 | 1133 |
src/authentic2/utils/evaluate.py | ||
---|---|---|
25 | 25 | |
26 | 26 |
import ast |
27 | 27 | |
28 |
from django.utils import six |
|
29 | 28 |
from django.utils.translation import ugettext as _ |
30 | 29 | |
31 | 30 | |
... | ... | |
110 | 109 |
# set the nearer expr node as the node of the error |
111 | 110 |
if e.node is None and hasattr(node, 'col_offset'): |
112 | 111 |
e.set_node(node) |
113 |
six.reraise(*sys.exc_info())
|
|
112 |
raise e
|
|
114 | 113 | |
115 | 114 |
@lru_cache(maxsize=1024) |
116 | 115 |
def __call__(self, expression): |
... | ... | |
126 | 125 |
if e.text is None: |
127 | 126 |
e.text = expression |
128 | 127 |
e.params = {'expression': expression} |
129 |
six.reraise(*sys.exc_info())
|
|
128 |
raise e
|
|
130 | 129 |
return compile(tree, expression, mode='eval') |
131 | 130 | |
132 | 131 | |
... | ... | |
179 | 178 |
super(ConditionValidator, self).__init__( |
180 | 179 |
authorized_nodes=authorized_nodes, forbidden_nodes=forbidden_nodes |
181 | 180 |
) |
182 |
if six.PY3: |
|
183 |
self.authorized_nodes.append(ast.NameConstant) |
|
181 |
self.authorized_nodes.append(ast.NameConstant) |
|
184 | 182 | |
185 | 183 |
def check_Name(self, node): |
186 | 184 |
if node.id.startswith('_'): |
... | ... | |
225 | 223 |
raise ExpressionError( |
226 | 224 |
_('variable is not defined: %s') % e, code='undefined-variable', text=expression, column=0 |
227 | 225 |
) |
228 |
except Exception: |
|
226 |
except Exception as e:
|
|
229 | 227 |
if on_raise is not None: |
230 | 228 |
return on_raise |
231 |
six.reraise(*sys.exc_info()) |
|
229 |
raise e |
src/authentic2/utils/lazy.py | ||
---|---|---|
16 | 16 | |
17 | 17 |
from __future__ import unicode_literals |
18 | 18 | |
19 |
from django.utils import six |
|
20 | 19 |
from django.utils.encoding import force_text |
21 | 20 |
from django.utils.functional import keep_lazy |
22 | 21 |
from django.utils.text import format_lazy |
... | ... | |
30 | 29 |
return format_lazy(fstring, *args) |
31 | 30 | |
32 | 31 | |
33 |
@keep_lazy(six.text_type)
|
|
32 |
@keep_lazy(str)
|
|
34 | 33 |
def lazy_label(default, func): |
35 | 34 |
"""Allow using a getter for a label, with late binding. |
36 | 35 |
src/authentic2/views.py | ||
---|---|---|
42 | 42 |
from django.template import loader |
43 | 43 |
from django.template.loader import render_to_string |
44 | 44 |
from django.urls import reverse |
45 |
from django.utils import six, timezone
|
|
45 |
from django.utils import timezone |
|
46 | 46 |
from django.utils.translation import ugettext as _ |
47 | 47 |
from django.views.decorators.cache import never_cache |
48 | 48 |
from django.views.decorators.csrf import csrf_exempt, ensure_csrf_cookie |
... | ... | |
452 | 452 |
value = filter(None, value) |
453 | 453 |
value = [html_value(attribute, at_value) for at_value in value] |
454 | 454 |
if not title: |
455 |
title = six.text_type(attribute)
|
|
455 |
title = str(attribute)
|
|
456 | 456 |
else: |
457 | 457 |
# fallback to model attributes |
458 | 458 |
try: |
... | ... | |
471 | 471 |
if not isinstance(value, (list, tuple)): |
472 | 472 |
value = (value,) |
473 | 473 |
raw_value = value |
474 |
value = [six.text_type(v) for v in value]
|
|
474 |
value = [str(v) for v in value]
|
|
475 | 475 |
if value or app_settings.A2_PROFILE_DISPLAY_EMPTY_FIELDS: |
476 | 476 |
profile.append((title, value)) |
477 | 477 |
attributes.append({'attribute': attribute, 'values': raw_value}) |
src/authentic2_auth_fc/models.py | ||
---|---|---|
18 | 18 |
import hashlib |
19 | 19 |
import hmac |
20 | 20 |
import json |
21 |
import urllib.parse |
|
21 | 22 | |
22 | 23 |
from django.conf import settings |
23 | 24 |
from django.db import models |
24 | 25 |
from django.utils.encoding import force_bytes, force_text |
25 |
from django.utils.six.moves.urllib import parse as urlparse |
|
26 | 26 |
from django.utils.timezone import now |
27 | 27 |
from django.utils.translation import ugettext_lazy as _ |
28 | 28 | |
... | ... | |
66 | 66 |
return None, 'id_token is expired' |
67 | 67 | |
68 | 68 |
def check_issuer(): |
69 |
parsed = urlparse.urlparse(app_settings.authorize_url) |
|
69 |
parsed = urllib.parse.urlparse(app_settings.authorize_url)
|
|
70 | 70 |
if 'iss' not in payload: |
71 | 71 |
return False |
72 | 72 |
try: |
73 |
parsed_issuer = urlparse.urlparse(payload['iss']) |
|
73 |
parsed_issuer = urllib.parse.urlparse(payload['iss'])
|
|
74 | 74 |
except Exception: |
75 | 75 |
return False |
76 | 76 |
return parsed_issuer.scheme == parsed.scheme and parsed_issuer.netloc == parsed.netloc |
src/authentic2_auth_fc/views.py | ||
---|---|---|
16 | 16 | |
17 | 17 |
import json |
18 | 18 |
import logging |
19 |
import urllib.parse |
|
19 | 20 |
import uuid |
20 | 21 | |
21 | 22 |
import requests |
... | ... | |
31 | 32 |
from django.shortcuts import render, resolve_url |
32 | 33 |
from django.urls import reverse |
33 | 34 |
from django.utils.http import is_safe_url, urlencode |
34 |
from django.utils.six.moves.urllib import parse as urlparse |
|
35 | 35 |
from django.utils.translation import ugettext as _ |
36 | 36 |
from django.views.generic import FormView, View |
37 | 37 |
from requests_oauthlib import OAuth2Session |
... | ... | |
509 | 509 |
redirect_to = resolve_url(settings.LOGIN_REDIRECT_URL) |
510 | 510 | |
511 | 511 |
# Prevent errors when redirect_to does not contain fc-login-or-link view |
512 |
parsed_redirect_to = urlparse.urlparse(redirect_to) |
|
512 |
parsed_redirect_to = urllib.parse.urlparse(redirect_to)
|
|
513 | 513 |
if parsed_redirect_to.path == reverse('fc-login-or-link'): |
514 |
redirect_to = urlparse.parse_qs(parsed_redirect_to.query).get( |
|
514 |
redirect_to = urllib.parse.parse_qs(parsed_redirect_to.query).get(
|
|
515 | 515 |
REDIRECT_FIELD_NAME, [a2_utils.make_url('auth_homepage')] |
516 | 516 |
)[0] |
517 | 517 |
params = { |
src/authentic2_auth_oidc/backends.py | ||
---|---|---|
20 | 20 |
import requests |
21 | 21 |
from django.contrib.auth import get_user_model |
22 | 22 |
from django.contrib.auth.backends import ModelBackend |
23 |
from django.utils import six |
|
24 | 23 |
from django.utils.timezone import now |
25 | 24 |
from jwcrypto.jwk import JWK |
26 | 25 |
from jwcrypto.jwt import JWT |
... | ... | |
88 | 87 |
jwt = JWT(jwt=original_id_token, key=key_or_keyset, check_claims={}, algs=algs) |
89 | 88 |
jwt.claims |
90 | 89 | |
91 |
if isinstance(id_token.aud, six.text_type) and provider.client_id != id_token.aud:
|
|
90 |
if isinstance(id_token.aud, str) and provider.client_id != id_token.aud:
|
|
92 | 91 |
logger.warning( |
93 | 92 |
'auth_oidc: invalid id_token audience %s != provider client_id %s', |
94 | 93 |
id_token.aud, |
src/authentic2_auth_oidc/utils.py | ||
---|---|---|
15 | 15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | 16 | |
17 | 17 |
import datetime |
18 |
import urllib.parse |
|
18 | 19 | |
19 | 20 |
import requests |
20 | 21 |
from django.shortcuts import get_object_or_404 |
21 |
from django.utils import six |
|
22 |
from django.utils.six.moves.urllib import parse as urlparse |
|
23 | 22 |
from django.utils.timezone import utc |
24 | 23 |
from django.utils.translation import ugettext as _ |
25 | 24 |
from jwcrypto.common import JWException, base64url_encode, json_decode |
... | ... | |
93 | 92 | |
94 | 93 |
REQUIRED_ID_TOKEN_KEYS = set(['iss', 'sub', 'aud', 'exp', 'iat']) |
95 | 94 |
KEY_TYPES = { |
96 |
'iss': six.text_type,
|
|
97 |
'sub': six.text_type,
|
|
95 |
'iss': str,
|
|
96 |
'sub': str,
|
|
98 | 97 |
'exp': int, |
99 | 98 |
'iat': int, |
100 | 99 |
'auth_time': int, |
101 |
'nonce': six.text_type,
|
|
102 |
'acr': six.text_type,
|
|
103 |
'azp': six.text_type,
|
|
100 |
'nonce': str,
|
|
101 |
'acr': str,
|
|
102 |
'azp': str,
|
|
104 | 103 |
# aud and amr havec specific checks |
105 | 104 |
} |
106 | 105 | |
... | ... | |
120 | 119 |
nonce = None |
121 | 120 | |
122 | 121 |
def __init__(self, encoded): |
123 |
if not isinstance(encoded, (six.binary_type, six.string_types)):
|
|
122 |
if not isinstance(encoded, (bytes, str)):
|
|
124 | 123 |
raise IDTokenError(_('Encoded ID Token must be either binary or string data')) |
125 | 124 |
self._encoded = encoded |
126 | 125 | |
... | ... | |
139 | 138 |
if key == 'amr': |
140 | 139 |
if not isinstance(decoded['amr'], list): |
141 | 140 |
raise IDTokenError(_('invalid amr value: %s') % decoded['amr']) |
142 |
if not all(isinstance(v, six.text_type) for v in decoded['amr']):
|
|
141 |
if not all(isinstance(v, str) for v in decoded['amr']):
|
|
143 | 142 |
raise IDTokenError(_('invalid amr value: %s') % decoded['amr']) |
144 | 143 |
elif key in KEY_TYPES: |
145 | 144 |
if not isinstance(decoded[key], KEY_TYPES[key]): |
... | ... | |
197 | 196 | |
198 | 197 | |
199 | 198 |
def check_https(url): |
200 |
return urlparse.urlparse(url).scheme == 'https' |
|
199 |
return urllib.parse.urlparse(url).scheme == 'https'
|
|
201 | 200 | |
202 | 201 | |
203 | 202 |
def register_issuer(name, issuer=None, openid_configuration=None, verify=True, timeout=None, ou=None): |
... | ... | |
293 | 292 | |
294 | 293 | |
295 | 294 |
def get_openid_configuration_url(issuer): |
296 |
parsed = urlparse.urlparse(issuer) |
|
295 |
parsed = urllib.parse.urlparse(issuer)
|
|
297 | 296 |
if parsed.query or parsed.fragment or parsed.scheme != 'https': |
298 | 297 |
raise ValueError( |
299 | 298 |
_('invalid issuer URL, it must use the https:// scheme and not have a ' 'query or fragment') |
300 | 299 |
) |
301 |
issuer = urlparse.urlunparse((parsed.scheme, parsed.netloc, parsed.path.rstrip('/'), None, None, None)) |
|
300 |
issuer = urllib.parse.urlunparse( |
|
301 |
(parsed.scheme, parsed.netloc, parsed.path.rstrip('/'), None, None, None) |
|
302 |
) |
|
302 | 303 |
return issuer + '/.well-known/openid-configuration' |
src/authentic2_auth_saml/adapters.py | ||
---|---|---|
21 | 21 |
from django.contrib import messages |
22 | 22 |
from django.core.exceptions import MultipleObjectsReturned |
23 | 23 |
from django.db.transaction import atomic |
24 |
from django.utils import six |
|
25 | 24 |
from django.utils.translation import ugettext as _ |
26 | 25 |
from mellon.adapters import DefaultAdapter, UserCreationError |
27 | 26 |
from mellon.utils import get_setting |
... | ... | |
44 | 43 |
super(MappingError, self).__init__(message) |
45 | 44 | |
46 | 45 |
def __str__(self): |
47 |
s = six.text_type(self.args[0])
|
|
46 |
s = str(self.args[0])
|
|
48 | 47 |
if self.details: |
49 | 48 |
s += ' ' + repr(self.details) |
50 | 49 |
return s |
... | ... | |
127 | 126 |
action = mapping.get('action', 'set-attribute') |
128 | 127 |
mandatory = mapping.get('mandatory', False) is True |
129 | 128 |
method = None |
130 |
if isinstance(action, six.string_types):
|
|
129 |
if isinstance(action, str):
|
|
131 | 130 |
try: |
132 | 131 |
method = getattr(self, 'action_' + action.replace('-', '_')) |
133 | 132 |
except AttributeError: |
... | ... | |
149 | 148 | |
150 | 149 |
def action_rename(self, user, idp, saml_attributes, mapping): |
151 | 150 |
from_name = mapping.get('from') |
152 |
if not from_name or not isinstance(from_name, six.string_types):
|
|
151 |
if not from_name or not isinstance(from_name, str):
|
|
153 | 152 |
raise MappingError('missing from in rename') |
154 | 153 |
to_name = mapping.get('to') |
155 |
if not to_name or not isinstance(to_name, six.string_types):
|
|
154 |
if not to_name or not isinstance(to_name, str):
|
|
156 | 155 |
raise MappingError('missing to in rename') |
157 | 156 |
if from_name in saml_attributes: |
158 | 157 |
saml_attributes[to_name] = saml_attributes[from_name] |
159 | 158 | |
160 | 159 |
def action_set_attribute(self, user, idp, saml_attributes, mapping): |
161 | 160 |
attribute = mapping.get('attribute') |
162 |
if not attribute or not isinstance(attribute, six.string_types):
|
|
161 |
if not attribute or not isinstance(attribute, str):
|
|
163 | 162 |
raise MappingError('missing attribute key') |
164 | 163 | |
165 | 164 |
saml_attribute = mapping.get('saml_attribute') |
166 |
if not saml_attribute or not isinstance(saml_attribute, six.string_types):
|
|
165 |
if not saml_attribute or not isinstance(saml_attribute, str):
|
|
167 | 166 |
raise MappingError('missing saml_attribute key') |
168 | 167 | |
169 | 168 |
if saml_attribute not in saml_attributes: |
... | ... | |
199 | 198 |
slug = ou_desc.get('slug') |
200 | 199 |
name = ou_desc.get('name') |
201 | 200 |
if slug: |
202 |
if not isinstance(slug, six.string_types):
|
|
201 |
if not isinstance(slug, str):
|
|
203 | 202 |
raise MappingError('invalid ou.slug in ou description') |
204 | 203 |
try: |
205 | 204 |
return OU.objects.get(slug=slug) |
206 | 205 |
except OU.DoesNotExist: |
207 | 206 |
raise MappingError('unknown ou', details={'slug': slug}) |
208 | 207 |
elif name: |
209 |
if not isinstance(name, six.string_types):
|
|
208 |
if not isinstance(name, str):
|
|
210 | 209 |
raise MappingError('invalid ou.slug in ou description') |
211 | 210 |
try: |
212 | 211 |
return OU.objects.get(name=name) |
... | ... | |
228 | 227 |
kwargs['ou'] = ou |
229 | 228 | |
230 | 229 |
if slug: |
231 |
if not isinstance(slug, six.string_types):
|
|
230 |
if not isinstance(slug, str):
|
|
232 | 231 |
raise MappingError('invalid role slug', details={'slug': slug}) |
233 | 232 |
kwargs['slug'] = slug |
234 | 233 |
elif name: |
235 |
if not isinstance(name, six.string_types):
|
|
234 |
if not isinstance(name, str):
|
|
236 | 235 |
raise MappingError('invalid role name', details={'name': name}) |
237 | 236 |
kwargs['name'] = name |
238 | 237 |
else: |
... | ... | |
249 | 248 |
condition = mapping.get('condition') |
250 | 249 |
if condition is None: |
251 | 250 |
return True |
252 |
if not isinstance(condition, six.string_types):
|
|
251 |
if not isinstance(condition, str):
|
|
253 | 252 |
raise MappingError('invalid condition') |
254 | 253 |
try: |
255 | 254 |
# use a proxy to simplify condition expressions as subscript is forbidden |
... | ... | |
258 | 257 |
logger.debug('auth_saml: condition %r is %s', condition, value, extra={'user': user}) |
259 | 258 |
return value |
260 | 259 |
except Exception as e: |
261 |
raise MappingError('condition evaluation failed', details={'error': six.text_type(e)})
|
|
260 |
raise MappingError('condition evaluation failed', details={'error': str(e)})
|
|
262 | 261 | |
263 | 262 |
def action_add_role(self, user, idp, saml_attributes, mapping): |
264 | 263 |
role = self.get_role(mapping) |
src/authentic2_idp_cas/managers.py | ||
---|---|---|
14 | 14 |
# You should have received a copy of the GNU Affero General Public License |
15 | 15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | 16 | |
17 |
import urllib.parse |
|
17 | 18 |
from datetime import timedelta |
18 | 19 | |
19 | 20 |
from django.db import models |
20 | 21 |
from django.db.models import query |
21 |
from django.utils.six.moves.urllib import parse as urlparse |
|
22 | 22 |
from django.utils.timezone import now |
23 | 23 | |
24 | 24 | |
... | ... | |
37 | 37 |
class ServiceQuerySet(query.QuerySet): |
38 | 38 |
def for_service(self, service): |
39 | 39 |
'''Find service with the longest match''' |
40 |
parsed = urlparse.urlparse(service) |
|
40 |
parsed = urllib.parse.urlparse(service)
|
|
41 | 41 |
matches = [] |
42 | 42 |
for match in self.filter(urls__contains=parsed.netloc): |
43 | 43 |
urls = match.get_urls() |
src/authentic2_idp_cas/views.py | ||
---|---|---|
21 | 21 | |
22 | 22 |
import requests |
23 | 23 |
from django.http import HttpResponse, HttpResponseBadRequest |
24 |
from django.utils import six |
|
25 | 24 |
from django.utils.timezone import now |
26 | 25 |
from django.views.generic.base import View |
27 | 26 | |
... | ... | |
262 | 261 |
if st.service.identifier_attribute not in attributes: |
263 | 262 |
self.logger.error( |
264 | 263 |
'unable to compute an identifier for user %r and service %s', |
265 |
six.text_type(st.user),
|
|
264 |
str(st.user),
|
|
266 | 265 |
st.service_url, |
267 | 266 |
) |
268 | 267 |
return self.validation_failure(request, service, INTERNAL_ERROR) |
... | ... | |
299 | 298 |
'validation success service: %r ticket: %s user: %r identifier: %r', |
300 | 299 |
st.service_url, |
301 | 300 |
st.ticket_id, |
302 |
six.text_type(st.user),
|
|
301 |
str(st.user),
|
|
303 | 302 |
identifier, |
304 | 303 |
) |
305 | 304 |
return self.real_validation_success(request, st, identifier) |
... | ... | |
327 | 326 |
root = ET.Element(SERVICE_RESPONSE_ELT) |
328 | 327 |
success = ET.SubElement(root, AUTHENTICATION_SUCCESS_ELT) |
329 | 328 |
user = ET.SubElement(success, USER_ELT) |
330 |
user.text = six.text_type(identifier)
|
|
329 |
user.text = str(identifier)
|
|
331 | 330 |
self.provision_pgt(request, st, success) |
332 | 331 |
self.provision_attributes(request, st, success) |
333 | 332 |
return HttpResponse(ET.tostring(root, encoding='utf-8'), content_type='text/xml') |
... | ... | |
349 | 348 |
for key, values in values.items(): |
350 | 349 |
for value in values: |
351 | 350 |
attribute_elt = ET.SubElement(attributes_elt, '{%s}%s' % (CAS_NAMESPACE, key)) |
352 |
attribute_elt.text = six.text_type(value)
|
|
351 |
attribute_elt.text = str(value)
|
|
353 | 352 | |
354 | 353 |
def provision_pgt(self, request, st, success): |
355 | 354 |
"""Provision a PGT ticket if requested""" |
src/authentic2_idp_oidc/models.py | ||
---|---|---|
14 | 14 |
# You should have received a copy of the GNU Affero General Public License |
15 | 15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | 16 | |
17 |
import urllib.parse |
|
17 | 18 |
import uuid |
18 | 19 |
from importlib import import_module |
19 | 20 | |
... | ... | |
22 | 23 |
from django.core.exceptions import ImproperlyConfigured, ValidationError |
23 | 24 |
from django.core.validators import URLValidator |
24 | 25 |
from django.db import models |
25 |
from django.utils import six |
|
26 |
from django.utils.six.moves.urllib import parse as urlparse |
|
27 | 26 |
from django.utils.timezone import now |
28 | 27 |
from django.utils.translation import ugettext_lazy as _ |
29 | 28 | |
... | ... | |
34 | 33 | |
35 | 34 | |
36 | 35 |
def generate_uuid(): |
37 |
return six.text_type(uuid.uuid4())
|
|
36 |
return str(uuid.uuid4())
|
|
38 | 37 | |
39 | 38 | |
40 | 39 |
def validate_https_url(data): |
... | ... | |
173 | 172 |
if len(redirect_uri) > app_settings.REDIRECT_URI_MAX_LENGTH: |
174 | 173 |
raise ValueError('redirect_uri length > %s' % app_settings.REDIRECT_URI_MAX_LENGTH) |
175 | 174 | |
176 |
parsed_uri = urlparse.urlparse(redirect_uri) |
|
175 |
parsed_uri = urllib.parse.urlparse(redirect_uri)
|
|
177 | 176 |
for valid_redirect_uri in self.redirect_uris.split(): |
178 |
parsed_valid_uri = urlparse.urlparse(valid_redirect_uri) |
|
177 |
parsed_valid_uri = urllib.parse.urlparse(valid_redirect_uri)
|
|
179 | 178 |
if parsed_uri.scheme != parsed_valid_uri.scheme: |
180 | 179 |
continue |
181 | 180 |
if parsed_valid_uri.netloc.startswith('*'): |
... | ... | |
257 | 256 | |
258 | 257 |
def __repr__(self): |
259 | 258 |
return '<OIDCAuthorization client:%r user:%r scopes:%r>' % ( |
260 |
self.client_id and six.text_type(self.client),
|
|
261 |
self.user_id and six.text_type(self.user),
|
|
259 |
self.client_id and str(self.client),
|
|
260 |
self.user_id and str(self.user),
|
|
262 | 261 |
self.scopes, |
263 | 262 |
) |
264 | 263 | |
... | ... | |
324 | 323 |
def __repr__(self): |
325 | 324 |
return '<OIDCCode uuid:%s client:%s user:%s expired:%s scopes:%s>' % ( |
326 | 325 |
self.uuid, |
327 |
self.client_id and six.text_type(self.client),
|
|
328 |
self.user_id and six.text_type(self.user),
|
|
326 |
self.client_id and str(self.client),
|
|
327 |
self.user_id and str(self.user),
|
|
329 | 328 |
self.expired, |
330 | 329 |
self.scopes, |
331 | 330 |
) |
... | ... | |
362 | 361 |
def __repr__(self): |
363 | 362 |
return '<OIDCAccessToken uuid:%s client:%s user:%s expired:%s scopes:%s>' % ( |
364 | 363 |
self.uuid, |
365 |
self.client_id and six.text_type(self.client),
|
|
366 |
self.user_id and six.text_type(self.user),
|
|
364 |
self.client_id and str(self.client),
|
|
365 |
self.user_id and str(self.user),
|
|
367 | 366 |
self.expired, |
368 | 367 |
self.scopes, |
369 | 368 |
) |
src/authentic2_idp_oidc/utils.py | ||
---|---|---|
17 | 17 |
import base64 |
18 | 18 |
import hashlib |
19 | 19 |
import json |
20 |
import urllib.parse |
|
20 | 21 |
import uuid |
21 | 22 | |
22 | 23 |
from django.conf import settings |
23 | 24 |
from django.core.exceptions import ImproperlyConfigured |
24 |
from django.utils import six |
|
25 | 25 |
from django.utils.encoding import force_bytes, force_text |
26 |
from django.utils.six.moves.urllib import parse as urlparse |
|
27 | 26 |
from jwcrypto.jwk import JWK, InvalidJWKValue, JWKSet |
28 | 27 |
from jwcrypto.jwt import JWT |
29 | 28 | |
... | ... | |
107 | 106 | |
108 | 107 | |
109 | 108 |
def url_domain(url): |
110 |
return urlparse.urlparse(url).netloc.split(':')[0] |
|
109 |
return urllib.parse.urlparse(url).netloc.split(':')[0]
|
|
111 | 110 | |
112 | 111 | |
113 | 112 |
def make_sub(client, user): |
... | ... | |
165 | 164 | |
166 | 165 |
def normalize_claim_values(values): |
167 | 166 |
values_list = [] |
168 |
if isinstance(values, six.string_types) or not hasattr(values, '__iter__'):
|
|
167 |
if isinstance(values, str) or not hasattr(values, '__iter__'):
|
|
169 | 168 |
return values |
170 | 169 |
for value in values: |
171 | 170 |
if isinstance(value, bool): |
src/authentic2_idp_oidc/views.py | ||
---|---|---|
36 | 36 |
from django.http import HttpResponse, HttpResponseNotAllowed, JsonResponse |
37 | 37 |
from django.shortcuts import render |
38 | 38 |
from django.urls import reverse |
39 |
from django.utils import six |
|
40 | 39 |
from django.utils.encoding import force_text |
41 | 40 |
from django.utils.http import urlencode |
42 | 41 |
from django.utils.timezone import now, utc |
... | ... | |
423 | 422 |
'idp_oidc: sending code %s for scopes %s for service %s', code.uuid, ' '.join(scopes), client |
424 | 423 |
) |
425 | 424 |
params = { |
426 |
'code': six.text_type(code.uuid),
|
|
425 |
'code': str(code.uuid),
|
|
427 | 426 |
} |
428 | 427 |
if state is not None: |
429 | 428 |
params['state'] = state |
... | ... | |
664 | 663 |
) |
665 | 664 |
return JsonResponse( |
666 | 665 |
{ |
667 |
'access_token': six.text_type(access_token.uuid),
|
|
666 |
'access_token': str(access_token.uuid),
|
|
668 | 667 |
'token_type': 'Bearer', |
669 | 668 |
'expires_in': int(expires_in.total_seconds()), |
670 | 669 |
'id_token': utils.make_idtoken(client, id_token), |
... | ... | |
726 | 725 |
id_token['nonce'] = oidc_code.nonce |
727 | 726 |
return JsonResponse( |
728 | 727 |
{ |
729 |
'access_token': six.text_type(access_token.uuid),
|
|
728 |
'access_token': str(access_token.uuid),
|
|
730 | 729 |
'token_type': 'Bearer', |
731 | 730 |
'expires_in': int(expires_in.total_seconds()), |
732 | 731 |
'id_token': utils.make_idtoken(client, id_token), |
src/django_rbac/backends.py | ||
---|---|---|
1 | 1 |
import copy |
2 |
import functools |
|
2 | 3 | |
3 | 4 |
from django.conf import settings |
4 | 5 |
from django.contrib.contenttypes.models import ContentType |
5 | 6 |
from django.db.models.query import Q |
6 |
from django.utils import six |
|
7 | 7 | |
8 | 8 |
try: |
9 | 9 |
from django.core.exceptions import FieldDoesNotExist |
... | ... | |
145 | 145 |
return False |
146 | 146 |
if user_obj.is_superuser: |
147 | 147 |
return True |
148 |
if isinstance(perm_or_perms, six.string_types):
|
|
148 |
if isinstance(perm_or_perms, str):
|
|
149 | 149 |
perm_or_perms = [perm_or_perms] |
150 | 150 |
perm_or_perms = set(perm_or_perms) |
151 | 151 |
cache = self.get_permission_cache(user_obj) |
... | ... | |
174 | 174 |
return False |
175 | 175 |
if user_obj.is_superuser: |
176 | 176 |
return True |
177 |
if isinstance(perm_or_perms, six.string_types):
|
|
177 |
if isinstance(perm_or_perms, str):
|
|
178 | 178 |
perm_or_perms = [perm_or_perms] |
179 | 179 |
perm_or_perms = set(perm_or_perms) |
180 | 180 |
cache = self.get_permission_cache(user_obj) |
... | ... | |
197 | 197 |
ct_id, fk = key.split('.') |
198 | 198 |
q.append(Q(pk=int(fk))) |
199 | 199 |
if q: |
200 |
return six.moves.reduce(Q.__or__, q)
|
|
200 |
return functools.reduce(Q.__or__, q)
|
|
201 | 201 |
return False |
202 | 202 | |
203 | 203 |
def filter_by_perm(self, user_obj, perm_or_perms, qs): |
src/django_rbac/managers.py | ||
---|---|---|
1 | 1 |
import contextlib |
2 |
import functools |
|
2 | 3 |
import threading |
3 | 4 | |
4 | 5 |
from django.contrib.auth import get_user_model |
... | ... | |
6 | 7 |
from django.db import models |
7 | 8 |
from django.db.models import query |
8 | 9 |
from django.db.models.query import Prefetch, Q |
9 |
from django.utils import six |
|
10 | 10 | |
11 | 11 |
from . import utils |
12 | 12 | |
... | ... | |
210 | 210 |
obsolete = old - add |
211 | 211 |
if obsolete: |
212 | 212 |
queries = (query.Q(parent_id=a, child_id=b, direct=False) for a, b in obsolete) |
213 |
self.model.objects.filter(six.moves.reduce(query.Q.__or__, queries)).delete()
|
|
213 |
self.model.objects.filter(functools.reduce(query.Q.__or__, queries)).delete()
|
|
214 | 214 | |
215 | 215 | |
216 | 216 |
@contextlib.contextmanager |
src/django_rbac/models.py | ||
---|---|---|
1 |
import functools |
|
1 | 2 |
import hashlib |
2 | 3 |
import operator |
3 | 4 | |
4 | 5 |
from django.conf import settings |
5 | 6 |
from django.db import models |
6 | 7 |
from django.db.models.query import Prefetch, Q |
7 |
from django.utils import six |
|
8 | 8 |
from django.utils.text import slugify |
9 | 9 |
from django.utils.translation import ugettext_lazy as _ |
10 | 10 | |
... | ... | |
45 | 45 |
def save(self, *args, **kwargs): |
46 | 46 |
# truncate slug and add a hash if it's too long |
47 | 47 |
if not self.slug: |
48 |
self.slug = slugify(six.text_type(self.name)).lstrip('_')
|
|
48 |
self.slug = slugify(str(self.name)).lstrip('_')
|
|
49 | 49 |
if len(self.slug) > 256: |
50 | 50 |
self.slug = self.slug[:252] + hashlib.md5(self.slug).hexdigest()[:4] |
51 | 51 |
if not self.uuid: |
... | ... | |
373 | 373 |
if hasattr(backend, "filter_by_perm"): |
374 | 374 |
results.append(backend.filter_by_perm(self, perm_or_perms, qs)) |
375 | 375 |
if results: |
376 |
return six.moves.reduce(operator.__or__, results)
|
|
376 |
return functools.reduce(operator.__or__, results)
|
|
377 | 377 |
else: |
378 | 378 |
return qs |
379 | 379 |
tests/auth_fc/conftest.py | ||
---|---|---|
18 | 18 |
import contextlib |
19 | 19 |
import datetime |
20 | 20 |
import json |
21 |
import urllib.parse as urlparse
|
|
21 |
import urllib.parse |
|
22 | 22 |
import uuid |
23 | 23 | |
24 | 24 |
import httmock |
... | ... | |
60 | 60 | |
61 | 61 |
def handle_authorization(self, app, url, **kwargs): |
62 | 62 |
assert url.startswith('https://fcp.integ01') |
63 |
parsed_url = urlparse.urlparse(url) |
|
63 |
parsed_url = urllib.parse.urlparse(url)
|
|
64 | 64 |
query = QueryDict(parsed_url.query) |
65 | 65 |
assert_equals_url(query['redirect_uri'], self.callback_url) |
66 | 66 |
assert query['client_id'] == self.client_id |
... | ... | |
90 | 90 |
app.session.flush() |
91 | 91 |
response = app.get(path) |
92 | 92 |
self.callback_params = { |
93 |
k: v for k, v in QueryDict(urlparse.urlparse(response.location).query).items() |
|
93 |
k: v for k, v in QueryDict(urllib.parse.urlparse(response.location).query).items()
|
|
94 | 94 |
} |
95 | 95 |
response = response.follow() |
96 | 96 |
response = response.click(href='callback') |
... | ... | |
142 | 142 | |
143 | 143 |
def handle_logout(self, app, url): |
144 | 144 |
assert url.startswith('https://fcp.integ01.dev-franceconnect.fr/api/v1/logout') |
145 |
parsed_url = urlparse.urlparse(url) |
|
145 |
parsed_url = urllib.parse.urlparse(url)
|
|
146 | 146 |
query = QueryDict(parsed_url.query) |
147 | 147 |
assert_equals_url(query['post_logout_redirect_uri'], 'http://testserver' + reverse('fc-logout')) |
148 | 148 |
assert query['state'] |
tests/auth_fc/test_auth_fc.py | ||
---|---|---|
16 | 16 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 | 17 | |
18 | 18 |
import datetime |
19 |
import urllib.parse |
|
19 | 20 | |
20 | 21 |
import mock |
21 | 22 |
import requests |
22 | 23 |
from django.contrib.auth import get_user_model |
23 | 24 |
from django.urls import reverse |
24 |
from django.utils.six.moves.urllib import parse as urlparse |
|
25 | 25 |
from django.utils.timezone import now |
26 | 26 | |
27 | 27 |
from authentic2.custom_user.models import DeletedUser |
... | ... | |
34 | 34 | |
35 | 35 | |
36 | 36 |
def path(url): |
37 |
return urlparse.urlparse(url).path |
|
37 |
return urllib.parse.urlparse(url).path
|
|
38 | 38 | |
39 | 39 | |
40 | 40 |
def test_login_redirect(app, franceconnect): |
tests/conftest.py | ||
---|---|---|
16 | 16 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 | 17 | |
18 | 18 | |
19 |
import urllib.parse |
|
20 | ||
19 | 21 |
import django |
20 | 22 |
import django_webtest |
21 | 23 |
import mock |
... | ... | |
25 | 27 |
from django.core.management import call_command |
26 | 28 |
from django.db import connection |
27 | 29 |
from django.db.migrations.executor import MigrationExecutor |
28 |
from django.utils.six.moves.urllib import parse as urlparse |
|
29 | 30 |
from pytest_django.migrations import DisableMigrations |
30 | 31 | |
31 | 32 |
from authentic2 import hooks as a2_hooks |
... | ... | |
458 | 459 |
else: |
459 | 460 | |
460 | 461 |
def check_location(response, default_return): |
461 |
assert urlparse.urljoin('http://testserver/', default_return).endswith(response['Location']) |
|
462 |
assert urllib.parse.urljoin('http://testserver/', default_return).endswith(response['Location'])
|
|
462 | 463 | |
463 | 464 |
return check_location |
464 | 465 |
tests/test_admin.py | ||
---|---|---|
17 | 17 | |
18 | 18 |
from __future__ import unicode_literals |
19 | 19 | |
20 |
from django.utils.six.moves.urllib.parse import urlparse
|
|
20 |
from urllib.parse import urlparse |
|
21 | 21 | |
22 | 22 |
from authentic2.custom_user.models import User |
23 | 23 |
from authentic2.models import Attribute |
tests/test_all.py | ||
---|---|---|
17 | 17 | |
18 | 18 |
import base64 |
19 | 19 |
import json |
20 |
import urllib.parse |
|
20 | 21 | |
21 | 22 |
import pytest |
22 | 23 |
from django.contrib.auth import get_user_model |
... | ... | |
29 | 30 |
from django.test.utils import override_settings |
30 | 31 |
from django.urls import reverse |
31 | 32 |
from django.utils.encoding import force_text |
32 |
from django.utils.six import text_type |
|
33 |
from django.utils.six.moves.urllib import parse as urlparse |
|
34 | 33 |
from django.utils.translation import ugettext as _ |
35 | 34 |
from rest_framework import status, test |
36 | 35 | |
... | ... | |
203 | 202 |
response = login_require(request, login_hint=['backoffice']) |
204 | 203 |
self.assertEqualsURL(response['Location'].split('?', 1)[0], '/login/') |
205 | 204 |
self.assertEqualsURL( |
206 |
urlparse.parse_qs(response['Location'].split('?', 1)[1])['next'][0], '/coin?nonce=xxx&next=/zob/' |
|
205 |
urllib.parse.parse_qs(response['Location'].split('?', 1)[1])['next'][0], |
|
206 |
'/coin?nonce=xxx&next=/zob/', |
|
207 | 207 |
) |
208 | 208 |
self.assertEqual(request.session['login-hint'], ['backoffice']) |
209 | 209 | |
... | ... | |
385 | 385 |
for i, name in enumerate(attribute_kinds.get_attribute_kinds()): |
386 | 386 |
fields['field_%d' % i] = attribute_kinds.get_form_field(name) |
387 | 387 |
AttributeKindForm = type('AttributeKindForm', (forms.Form,), fields) |
388 |
text_type(AttributeKindForm().as_p())
|
|
388 |
str(AttributeKindForm().as_p())
|
|
389 | 389 | |
390 | 390 | |
391 | 391 |
class APITest(TestCase): |
tests/test_auth_oidc.py | ||
---|---|---|
21 | 21 |
import random |
22 | 22 |
import re |
23 | 23 |
import time |
24 |
import urllib.parse |
|
24 | 25 | |
25 | 26 |
import pytest |
26 | 27 |
from django.contrib.auth import get_user_model |
... | ... | |
28 | 29 |
from django.http import QueryDict |
29 | 30 |
from django.urls import reverse |
30 | 31 |
from django.utils.encoding import force_str, force_text |
31 |
from django.utils.six.moves.urllib import parse as urlparse |
|
32 | 32 |
from django.utils.timezone import now, utc |
33 | 33 |
from httmock import HTTMock, urlmatch |
34 | 34 |
from jwcrypto.common import base64url_decode, base64url_encode, json_encode |
... | ... | |
248 | 248 |
provides_kid_header=False, |
249 | 249 |
kid=None, |
250 | 250 |
): |
251 |
token_endpoint = urlparse.urlparse(oidc_provider.token_endpoint) |
|
252 |
userinfo_endpoint = urlparse.urlparse(oidc_provider.userinfo_endpoint) |
|
253 |
token_revocation_endpoint = urlparse.urlparse(oidc_provider.token_revocation_endpoint) |
|
251 |
token_endpoint = urllib.parse.urlparse(oidc_provider.token_endpoint)
|
|
252 |
userinfo_endpoint = urllib.parse.urlparse(oidc_provider.userinfo_endpoint)
|
|
253 |
token_revocation_endpoint = urllib.parse.urlparse(oidc_provider.token_revocation_endpoint)
|
|
254 | 254 | |
255 | 255 |
@urlmatch(netloc=token_endpoint.netloc, path=token_endpoint.path) |
256 | 256 |
def token_endpoint_mock(url, request): |
257 |
if urlparse.parse_qs(request.body).get('code') == [code]: |
|
257 |
if urllib.parse.parse_qs(request.body).get('code') == [code]:
|
|
258 | 258 |
exp = now() + datetime.timedelta(seconds=10) |
259 | 259 |
id_token = { |
260 | 260 |
'iss': oidc_provider.issuer, |
... | ... | |
341 | 341 | |
342 | 342 |
@urlmatch(netloc=token_revocation_endpoint.netloc, path=token_revocation_endpoint.path) |
343 | 343 |
def token_revocation_endpoint_mock(url, request): |
344 |
query = urlparse.parse_qs(request.body) |
|
344 |
query = urllib.parse.parse_qs(request.body)
|
|
345 | 345 |
assert 'token' in query |
346 | 346 |
return { |
347 | 347 |
'status_code': 200, |
... | ... | |
458 | 458 |
response = app.get('/admin/').maybe_follow() |
459 | 459 |
assert oidc_provider.name in response.text |
460 | 460 |
response = response.click(oidc_provider.name) |
461 |
location = urlparse.urlparse(response.location) |
|
462 |
endpoint = urlparse.urlparse(oidc_provider.authorization_endpoint) |
|
461 |
location = urllib.parse.urlparse(response.location)
|
|
462 |
endpoint = urllib.parse.urlparse(oidc_provider.authorization_endpoint)
|
|
463 | 463 |
assert location.scheme == endpoint.scheme |
464 | 464 |
assert location.netloc == endpoint.netloc |
465 | 465 |
assert location.path == endpoint.path |
... | ... | |
510 | 510 |
assert set(hooks.auth_oidc_backend_modify_user[0]['kwargs']) >= set( |
511 | 511 |
['user', 'provider', 'user_info', 'id_token', 'access_token'] |
512 | 512 |
) |
513 |
assert urlparse.urlparse(response['Location']).path == '/admin/' |
|
513 |
assert urllib.parse.urlparse(response['Location']).path == '/admin/'
|
|
514 | 514 |
assert User.objects.count() == 1 |
515 | 515 |
user = User.objects.get() |
516 | 516 |
assert user.ou == get_default_ou() |
... | ... | |
588 | 588 |
response = app.get('/').maybe_follow() |
589 | 589 |
assert oidc_provider.name in response.text |
590 | 590 |
response = response.click(oidc_provider.name) |
591 |
location = urlparse.urlparse(response.location) |
|
591 |
location = urllib.parse.urlparse(response.location)
|
|
592 | 592 |
query = QueryDict(location.query) |
593 | 593 |
state = query['state'] |
594 | 594 |
nonce = query['nonce'] |
... | ... | |
603 | 603 |
with oidc_provider_mock(oidc_provider, oidc_provider_jwkset, code, sub=simple_user.uuid, nonce=nonce): |
604 | 604 |
response = app.get(login_callback_url(oidc_provider), params={'code': code, 'state': state}) |
605 | 605 | |
606 |
assert urlparse.urlparse(response['Location']).path == '/' |
|
606 |
assert urllib.parse.urlparse(response['Location']).path == '/'
|
|
607 | 607 |
assert User.objects.count() == 1 |
608 | 608 |
user = User.objects.get() |
609 | 609 |
# verify user was not modified |
... | ... | |
630 | 630 |
response = app.get('/').maybe_follow() |
631 | 631 |
assert oidc_provider.name in response.text |
632 | 632 |
response = response.click(oidc_provider.name) |
633 |
location = urlparse.urlparse(response.location) |
|
633 |
location = urllib.parse.urlparse(response.location)
|
|
634 | 634 |
query = QueryDict(location.query) |
635 | 635 |
state = query['state'] |
636 | 636 |
nonce = query['nonce'] |
... | ... | |
658 | 658 |
config_file = os.path.join(config_dir, 'openid_configuration.json') |
659 | 659 |
with open(config_file) as f: |
660 | 660 |
oidc_conf = json.load(f) |
661 |
jwks_uri = urlparse.urlparse(oidc_conf['jwks_uri']) |
|
661 |
jwks_uri = urllib.parse.urlparse(oidc_conf['jwks_uri'])
|
|
662 | 662 | |
663 | 663 |
@urlmatch(netloc=jwks_uri.netloc, path=jwks_uri.path) |
664 | 664 |
def jwks_mock(url, request): |
... | ... | |
705 | 705 |
response = app.get('/').maybe_follow() |
706 | 706 |
assert oidc_provider_rsa.name in response.text |
707 | 707 |
response = response.click(oidc_provider_rsa.name) |
708 |
location = urlparse.urlparse(response.location) |
|
708 |
location = urllib.parse.urlparse(response.location)
|
|
709 | 709 |
query = QueryDict(location.query) |
710 | 710 |
state = query['state'] |
711 | 711 |
nonce = query['nonce'] |
... | ... | |
771 | 771 | |
772 | 772 |
response = app.get('/').maybe_follow() |
773 | 773 |
response = response.click(oidc_provider.name) |
774 |
location = urlparse.urlparse(response.location) |
|
774 |
location = urllib.parse.urlparse(response.location)
|
|
775 | 775 |
query = QueryDict(location.query) |
776 | 776 |
state = query['state'] |
777 | 777 |
nonce = query['nonce'] |
... | ... | |
799 | 799 |
# As the oidc-state is used during a redirect from a third-party, we need |
800 | 800 |
# it to be lax. |
801 | 801 |
assert re.search('Set-Cookie.* oidc-state=.*SameSite=Lax', str(response)) |
802 |
qs = urlparse.parse_qs(urlparse.urlparse(response.location).query)
|
|
802 |
qs = urllib.parse.parse_qs(urllib.parse.urlparse(response.location).query)
|
|
803 | 803 |
state = qs['state'] |
804 | 804 | |
805 | 805 |
# reset the session to forget the state |
... | ... | |
858 | 858 |
response = app.get('/').maybe_follow() |
859 | 859 |
assert oidc_provider.name in response.text |
860 | 860 |
response = response.click(oidc_provider.name) |
861 |
location = urlparse.urlparse(response.location) |
|
861 |
location = urllib.parse.urlparse(response.location)
|
|
862 | 862 |
query = QueryDict(location.query) |
863 | 863 |
state = query['state'] |
864 | 864 |
nonce = query['nonce'] |
... | ... | |
877 | 877 |
response = app.get('/').maybe_follow() |
878 | 878 |
assert oidc_provider.name in response.text |
879 | 879 |
response = response.click(oidc_provider.name) |
880 |
location = urlparse.urlparse(response.location) |
|
880 |
location = urllib.parse.urlparse(response.location)
|
|
881 | 881 |
query = QueryDict(location.query) |
882 | 882 |
state = query['state'] |
883 | 883 |
nonce = query['nonce'] |
tests/test_idp_cas.py | ||
---|---|---|
14 | 14 |
# You should have received a copy of the GNU Affero General Public License |
15 | 15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | 16 | |
17 |
import urllib.parse |
|
18 | ||
17 | 19 |
from django.contrib.auth import get_user_model |
18 | 20 |
from django.test.client import Client, RequestFactory |
19 | 21 |
from django.test.utils import override_settings |
20 | 22 |
from django.utils.encoding import force_text |
21 |
from django.utils.six.moves.urllib import parse as urlparse |
|
22 | 23 | |
23 | 24 |
from authentic2.a2_rbac.utils import get_default_ou |
24 | 25 |
from authentic2.constants import AUTHENTICATION_EVENTS_SESSION_KEY, NONCE_FIELD_NAME |
... | ... | |
132 | 133 |
assert service.authorized_roles.exists() is True |
133 | 134 |
response = client.get('/idp/cas/login', {constants.SERVICE_PARAM: self.URL}) |
134 | 135 |
location = response['Location'] |
135 |
query = urlparse.parse_qs(location.split('?')[1]) |
|
136 |
query = urllib.parse.parse_qs(location.split('?')[1])
|
|
136 | 137 |
next_url, next_url_query = query['next'][0].split('?') |
137 |
next_url_query = urlparse.parse_qs(next_url_query) |
|
138 |
next_url_query = urllib.parse.parse_qs(next_url_query)
|
|
138 | 139 |
response = client.get(location) |
139 | 140 |
response = client.post( |
140 | 141 |
location, |
... | ... | |
152 | 153 |
assert service.authorized_roles.exists() is True |
153 | 154 |
response = client.get('/idp/cas/login', {constants.SERVICE_PARAM: self.URL}) |
154 | 155 |
location = response['Location'] |
155 |
query = urlparse.parse_qs(location.split('?')[1]) |
|
156 |
query = urllib.parse.parse_qs(location.split('?')[1])
|
|
156 | 157 |
next_url, next_url_query = query['next'][0].split('?') |
157 |
next_url_query = urlparse.parse_qs(next_url_query) |
|
158 |
next_url_query = urllib.parse.parse_qs(next_url_query)
|
|
158 | 159 |
response = client.get(location) |
159 | 160 |
response = client.post( |
160 | 161 |
location, |
... | ... | |
163 | 164 |
) |
164 | 165 |
response = client.get(response.url) |
165 | 166 |
client = Client() |
166 |
ticket_id = urlparse.parse_qs(response.url.split('?')[1])[constants.TICKET_PARAM][0] |
|
167 |
ticket_id = urllib.parse.parse_qs(response.url.split('?')[1])[constants.TICKET_PARAM][0]
|
|
167 | 168 |
response = client.get( |
168 | 169 |
'/idp/cas/validate', {constants.TICKET_PARAM: ticket_id, constants.SERVICE_PARAM: self.URL} |
169 | 170 |
) |
... | ... | |
174 | 175 |
ticket = Ticket.objects.get() |
175 | 176 |
location = response['Location'] |
176 | 177 |
url = location.split('?')[0] |
177 |
query = urlparse.parse_qs(location.split('?')[1]) |
|
178 |
query = urllib.parse.parse_qs(location.split('?')[1])
|
|
178 | 179 |
self.assertTrue(url.endswith('/login/')) |
179 | 180 |
self.assertIn('nonce', query) |
180 | 181 |
self.assertIn('next', query) |
181 | 182 |
self.assertEqual(query['nonce'], [ticket.ticket_id]) |
182 | 183 |
next_url, next_url_query = query['next'][0].split('?') |
183 |
next_url_query = urlparse.parse_qs(next_url_query) |
|
184 |
next_url_query = urllib.parse.parse_qs(next_url_query)
|
|
184 | 185 |
self.assertEqual(next_url, '/idp/cas/continue/') |
185 | 186 |
self.assertEqual(set(next_url_query.keys()), set([constants.SERVICE_PARAM, NONCE_FIELD_NAME])) |
186 | 187 |
self.assertEqual(next_url_query[constants.SERVICE_PARAM], [self.URL]) |
... | ... | |
214 | 215 |
# Do not the same client for direct calls from the CAS service provider |
215 | 216 |
# to prevent use of the user session |
216 | 217 |
client = Client() |
217 |
ticket_id = urlparse.parse_qs(response.url.split('?')[1])[constants.TICKET_PARAM][0] |
|
218 |
ticket_id = urllib.parse.parse_qs(response.url.split('?')[1])[constants.TICKET_PARAM][0]
|
|
218 | 219 |
response = client.get( |
219 | 220 |
'/idp/cas/validate', {constants.TICKET_PARAM: ticket_id, constants.SERVICE_PARAM: self.URL} |
220 | 221 |
) |
... | ... | |
231 | 232 |
ticket = Ticket.objects.get() |
232 | 233 |
location = response['Location'] |
233 | 234 |
url = location.split('?')[0] |
234 |
query = urlparse.parse_qs(location.split('?')[1]) |
|
235 |
query = urllib.parse.parse_qs(location.split('?')[1])
|
|
235 | 236 |
self.assertTrue(url.endswith('/login/')) |
236 | 237 |
self.assertIn('nonce', query) |
237 | 238 |
self.assertIn('next', query) |
238 | 239 |
self.assertEqual(query['nonce'], [ticket.ticket_id]) |
239 | 240 |
next_url, next_url_query = query['next'][0].split('?') |
240 |
next_url_query = urlparse.parse_qs(next_url_query) |
|
241 |
next_url_query = urllib.parse.parse_qs(next_url_query)
|
|
241 | 242 |
self.assertEqual(next_url, '/idp/cas/continue/') |
242 | 243 |
self.assertEqual(set(next_url_query.keys()), set([constants.SERVICE_PARAM, NONCE_FIELD_NAME])) |
243 | 244 |
self.assertEqual(next_url_query[constants.SERVICE_PARAM], [self.URL]) |
... | ... | |
271 | 272 |
# Do not the same client for direct calls from the CAS service provider |
272 | 273 |
# to prevent use of the user session |
273 | 274 |
client = Client() |
274 |
ticket_id = urlparse.parse_qs(response.url.split('?')[1])[constants.TICKET_PARAM][0] |
|
275 |
ticket_id = urllib.parse.parse_qs(response.url.split('?')[1])[constants.TICKET_PARAM][0]
|
|
275 | 276 |
response = client.get( |
276 | 277 |
'/idp/cas/serviceValidate', {constants.TICKET_PARAM: ticket_id, constants.SERVICE_PARAM: self.URL} |
277 | 278 |
) |
... | ... | |
292 | 293 |
ticket = Ticket.objects.get() |
293 | 294 |
location = response['Location'] |
294 | 295 |
url = location.split('?')[0] |
295 |
query = urlparse.parse_qs(location.split('?')[1]) |
|
296 |
query = urllib.parse.parse_qs(location.split('?')[1])
|
|
296 | 297 |
self.assertTrue(url.endswith('/login/')) |
297 | 298 |
self.assertIn('nonce', query) |
298 | 299 |
self.assertIn('next', query) |
299 | 300 |
self.assertEqual(query['nonce'], [ticket.ticket_id]) |
300 | 301 |
next_url, next_url_query = query['next'][0].split('?') |
301 |
next_url_query = urlparse.parse_qs(next_url_query) |
|
302 |
next_url_query = urllib.parse.parse_qs(next_url_query)
|
|
302 | 303 |
self.assertEqual(next_url, '/idp/cas/continue/') |
303 | 304 |
self.assertEqual(set(next_url_query.keys()), set([constants.SERVICE_PARAM, NONCE_FIELD_NAME])) |
304 | 305 |
self.assertEqual(next_url_query[constants.SERVICE_PARAM], [self.URL]) |
... | ... | |
332 | 333 |
# Do not the same client for direct calls from the CAS service provider |
333 | 334 |
# to prevent use of the user session |
334 | 335 |
client = Client() |
335 |
ticket_id = urlparse.parse_qs(response.url.split('?')[1])[constants.TICKET_PARAM][0] |
|
336 |
ticket_id = urllib.parse.parse_qs(response.url.split('?')[1])[constants.TICKET_PARAM][0]
|
|
336 | 337 |
response = client.get( |
337 | 338 |
'/idp/cas/serviceValidate', |
338 | 339 |
{constants.TICKET_PARAM: ticket_id, constants.SERVICE_PARAM: self.URL, constants.RENEW_PARAM: ''}, |
... | ... | |
351 | 352 |
ticket = Ticket.objects.get() |
352 | 353 |
location = response['Location'] |
353 | 354 |
url = location.split('?')[0] |
354 |
query = urlparse.parse_qs(location.split('?')[1]) |
|
355 |
query = urllib.parse.parse_qs(location.split('?')[1])
|
|
355 | 356 |
self.assertTrue(url.endswith('/login/')) |
356 | 357 |
self.assertIn('nonce', query) |
357 | 358 |
self.assertIn('next', query) |
358 | 359 |
self.assertEqual(query['nonce'], [ticket.ticket_id]) |
359 | 360 |
next_url, next_url_query = query['next'][0].split('?') |
360 |
next_url_query = urlparse.parse_qs(next_url_query) |
|
361 |
next_url_query = urllib.parse.parse_qs(next_url_query)
|
|
361 | 362 |
self.assertEqual(next_url, '/idp/cas/continue/') |
362 | 363 |
self.assertEqual(set(next_url_query.keys()), set([constants.SERVICE_PARAM, NONCE_FIELD_NAME])) |
363 | 364 |
self.assertEqual(next_url_query[constants.SERVICE_PARAM], [self.URL]) |
... | ... | |
391 | 392 |
# Do not the same client for direct calls from the CAS service provider |
392 | 393 |
# to prevent use of the user session |
393 | 394 |
client = Client() |
394 |
ticket_id = urlparse.parse_qs(response.url.split('?')[1])[constants.TICKET_PARAM][0] |
|
395 |
ticket_id = urllib.parse.parse_qs(response.url.split('?')[1])[constants.TICKET_PARAM][0]
|
|
395 | 396 |
response = client.get( |
396 | 397 |
'/idp/cas/proxyValidate', {constants.TICKET_PARAM: ticket_id, constants.SERVICE_PARAM: self.URL} |
397 | 398 |
) |
... | ... | |
413 | 414 |
ticket = Ticket.objects.get() |
414 | 415 |
location = response['Location'] |
415 | 416 |
url = location.split('?')[0] |
416 |
query = urlparse.parse_qs(location.split('?')[1]) |
|
417 |
query = urllib.parse.parse_qs(location.split('?')[1])
|
|
417 | 418 |
self.assertTrue(url.endswith('/login/')) |
418 | 419 |
self.assertIn('nonce', query) |
419 | 420 |
self.assertIn('next', query) |
420 | 421 |
self.assertEqual(query['nonce'], [ticket.ticket_id]) |
421 | 422 |
next_url, next_url_query = query['next'][0].split('?') |
422 |
next_url_query = urlparse.parse_qs(next_url_query) |
|
423 |
next_url_query = urllib.parse.parse_qs(next_url_query)
|
|
423 | 424 |
self.assertEqual(next_url, '/idp/cas/continue/') |
424 | 425 |
self.assertEqual(set(next_url_query.keys()), set([constants.SERVICE_PARAM, NONCE_FIELD_NAME])) |
425 | 426 |
self.assertEqual(next_url_query[constants.SERVICE_PARAM], [self.URL]) |
... | ... | |
453 | 454 |
# Do not the same client for direct calls from the CAS service provider |
454 | 455 |
# to prevent use of the user session |
455 | 456 |
client = Client() |
456 |
ticket_id = urlparse.parse_qs(response.url.split('?')[1])[constants.TICKET_PARAM][0] |
|
457 |
ticket_id = urllib.parse.parse_qs(response.url.split('?')[1])[constants.TICKET_PARAM][0]
|
|
457 | 458 |
response = client.get( |
458 | 459 |
'/idp/cas/serviceValidate', |
459 | 460 |
{ |
tests/test_idp_oidc.py | ||
---|---|---|
18 | 18 |
import datetime |
19 | 19 |
import functools |
20 | 20 |
import json |
21 |
import urllib.parse |
|
21 | 22 |
from importlib import import_module |
22 | 23 | |
23 | 24 |
import pytest |
... | ... | |
28 | 29 |
from django.test.utils import override_settings |
29 | 30 |
from django.urls import reverse |
30 | 31 |
from django.utils.encoding import force_text |
31 |
from django.utils.six.moves.urllib import parse as urlparse |
|
32 | 32 |
from django.utils.timezone import now |
33 | 33 |
from jwcrypto.jwk import JWK, JWKSet |
34 | 34 |
from jwcrypto.jwt import JWT |
... | ... | |
301 | 301 |
assert code.auth_time <= now() |
302 | 302 |
assert code.expired >= now() |
303 | 303 |
assert response['Location'].startswith(redirect_uri) |
304 |
location = urlparse.urlparse(response['Location']) |
|
304 |
location = urllib.parse.urlparse(response['Location'])
|
|
305 | 305 |
if oidc_client.authorization_flow == oidc_client.FLOW_AUTHORIZATION_CODE: |
306 |
query = urlparse.parse_qs(location.query) |
|
306 |
query = urllib.parse.parse_qs(location.query)
|
|
307 | 307 |
assert set(query.keys()) == set(['code', 'state']) |
308 | 308 |
assert query['code'] == [code.uuid] |
309 | 309 |
code = query['code'][0] |
... | ... | |
328 | 328 |
id_token = response.json['id_token'] |
329 | 329 |
elif oidc_client.authorization_flow == oidc_client.FLOW_IMPLICIT: |
330 | 330 |
assert location.fragment |
331 |
query = urlparse.parse_qs(location.fragment) |
|
331 |
query = urllib.parse.parse_qs(location.fragment)
|
|
332 | 332 |
assert OIDCAccessToken.objects.count() == 1 |
333 | 333 |
access_token = OIDCAccessToken.objects.get() |
334 | 334 |
assert set(query.keys()) == set(['access_token', 'token_type', 'expires_in', 'id_token', 'state']) |
... | ... | |
434 | 434 |
): |
435 | 435 |
# check next_url qs |
436 | 436 |
if message: |
437 |
location = urlparse.urlparse(response.location) |
|
437 |
location = urllib.parse.urlparse(response.location)
|
|
438 | 438 |
assert location.path == '/continue/' |
439 | 439 |
if check_next: |
440 | 440 |
location_qs = QueryDict(location.query or '') |
441 | 441 |
assert 'next' in location_qs |
442 | 442 |
assert location_qs['next'].startswith(redirect_uri) |
443 |
next_url = urlparse.urlparse(location_qs['next']) |
|
443 |
next_url = urllib.parse.urlparse(location_qs['next'])
|
|
444 | 444 |
next_url_qs = QueryDict(next_url.fragment if fragment else next_url.query) |
445 | 445 |
assert next_url_qs['error'] == error |
446 | 446 |
assert next_url_qs['error_description'] == error_description |
... | ... | |
449 | 449 |
assert error_description in continue_response.pyquery('.error').text() |
450 | 450 |
elif check_next: |
451 | 451 |
assert response.location.startswith(redirect_uri) |
452 |
location = urlparse.urlparse(response.location) |
|
452 |
location = urllib.parse.urlparse(response.location)
|
|
453 | 453 |
location_qs = QueryDict(location.fragment if fragment else location.query) |
454 | 454 |
assert location_qs['error'] == error |
455 | 455 |
assert location_qs['error_description'] == error_description |
... | ... | |
466 | 466 | |
467 | 467 | |
468 | 468 |
def assert_authorization_response(response, fragment=False, **kwargs): |
469 |
location = urlparse.urlparse(response.location) |
|
469 |
location = urllib.parse.urlparse(response.location)
|
|
470 | 470 |
location_qs = QueryDict(location.fragment if fragment else location.query) |
471 | 471 |
assert set(location_qs) == set(kwargs) |
472 | 472 |
for key, value in kwargs.items(): |
... | ... | |
769 | 769 |
}, |
770 | 770 |
) |
771 | 771 |
response = app.get(authorize_url) |
772 |
assert urlparse.urlparse(response['Location']).path == reverse('auth_login') |
|
772 |
assert urllib.parse.urlparse(response['Location']).path == reverse('auth_login')
|
|
773 | 773 | |
774 | 774 |
if oidc_client.authorization_mode != oidc_client.AUTHORIZATION_MODE_NONE: |
775 | 775 |
# prompt is none, but consent is required |
... | ... | |
873 | 873 |
code.expired = now() - datetime.timedelta(seconds=120) |
874 | 874 |
assert not code.is_valid() |
875 | 875 |
code.save() |
876 |
location = urlparse.urlparse(response['Location']) |
|
877 |
query = urlparse.parse_qs(location.query) |
|
876 |
location = urllib.parse.urlparse(response['Location'])
|
|
877 |
query = urllib.parse.parse_qs(location.query)
|
|
878 | 878 |
assert set(query.keys()) == set(['code']) |
879 | 879 |
assert query['code'] == [code.uuid] |
880 | 880 |
code = query['code'][0] |
... | ... | |
1000 | 1000 |
authorize_url = make_url('oidc-authorize', params=params) |
1001 | 1001 |
response = app.get(authorize_url) |
1002 | 1002 |
response = response.form.submit('accept') |
1003 |
location = urlparse.urlparse(response['Location']) |
|
1004 |
query = urlparse.parse_qs(location.query) |
|
1003 |
location = urllib.parse.urlparse(response['Location'])
|
|
1004 |
query = urllib.parse.parse_qs(location.query)
|
|
1005 | 1005 |
code = query['code'][0] |
1006 | 1006 |
token_url = make_url('oidc-token') |
1007 | 1007 |
response = app.post( |
... | ... | |
1067 | 1067 |
assert OIDCAuthorization.objects.get() |
1068 | 1068 |
if oidc_client.authorization_flow == oidc_client.FLOW_AUTHORIZATION_CODE: |
1069 | 1069 |
code = OIDCCode.objects.get() |
1070 |
location = urlparse.urlparse(response['Location']) |
|
1070 |
location = urllib.parse.urlparse(response['Location'])
|
|
1071 | 1071 |
if oidc_client.authorization_flow == oidc_client.FLOW_AUTHORIZATION_CODE: |
1072 |
query = urlparse.parse_qs(location.query) |
|
1072 |
query = urllib.parse.parse_qs(location.query)
|
|
1073 | 1073 |
code = query['code'][0] |
1074 | 1074 |
token_url = make_url('oidc-token') |
1075 | 1075 |
response = app.post( |
... | ... | |
1083 | 1083 |
) |
1084 | 1084 |
id_token = response.json['id_token'] |
1085 | 1085 |
elif oidc_client.authorization_flow == oidc_client.FLOW_IMPLICIT: |
1086 |
query = urlparse.parse_qs(location.fragment) |
|
1086 |
query = urllib.parse.parse_qs(location.fragment)
|
|
1087 | 1087 |
id_token = query['id_token'][0] |
1088 | 1088 | |
1089 | 1089 |
if oidc_client.idtoken_algo in (oidc_client.ALGO_RSA, oidc_client.ALGO_EC): |
... | ... | |
1118 | 1118 |
authorize_url = make_url('oidc-authorize', params=params) |
1119 | 1119 |
response = app.get(authorize_url) |
1120 | 1120 | |
1121 |
location = urlparse.urlparse(response['Location']) |
|
1122 |
query = urlparse.parse_qs(location.query) |
|
1121 |
location = urllib.parse.urlparse(response['Location'])
|
|
1122 |
query = urllib.parse.parse_qs(location.query)
|
|
1123 | 1123 |
assert query['service'] == ['default client'] |
1124 | 1124 |
response = response.follow().click('Register') |
1125 |
location = urlparse.urlparse(response.request.url) |
|
1126 |
query = urlparse.parse_qs(location.query) |
|
1125 |
location = urllib.parse.urlparse(response.request.url)
|
|
1126 |
query = urllib.parse.parse_qs(location.query)
|
|
1127 | 1127 |
assert query['service'] == ['default client'] |
1128 | 1128 | |
1129 | 1129 |
response.form.set('email', 'john.doe@example.com') |
... | ... | |
1317 | 1317 |
authorize_url = make_url('oidc-authorize', params=params) |
1318 | 1318 | |
1319 | 1319 |
response = app.get(authorize_url) |
1320 |
location = urlparse.urlparse(response['Location']) |
|
1321 |
query = urlparse.parse_qs(location.query) |
|
1320 |
location = urllib.parse.urlparse(response['Location'])
|
|
1321 |
query = urllib.parse.parse_qs(location.query)
|
|
1322 | 1322 |
code = query['code'][0] |
1323 | 1323 | |
1324 | 1324 |
token_url = make_url('oidc-token') |
... | ... | |
1420 | 1420 |
authorize_url = make_url('oidc-authorize', params=params) |
1421 | 1421 | |
1422 | 1422 |
response = app.get(authorize_url) |
1423 |
location = urlparse.urlparse(response['Location']) |
|
1424 |
query = urlparse.parse_qs(location.query) |
|
1423 |
location = urllib.parse.urlparse(response['Location'])
|
|
1424 |
query = urllib.parse.parse_qs(location.query)
|
|
1425 | 1425 |
code = query['code'][0] |
1426 | 1426 | |
1427 | 1427 |
token_url = make_url('oidc-token') |
tests/test_idp_saml2.py | ||
---|---|---|
21 | 21 |
import datetime |
22 | 22 |
import hashlib |
23 | 23 |
import re |
24 |
import urllib.parse |
|
24 | 25 |
import xml.etree.ElementTree as ET |
25 | 26 | |
26 | 27 |
import lasso |
... | ... | |
31 | 32 |
from django.template import Context, Template |
32 | 33 |
from django.urls import reverse |
33 | 34 |
from django.utils.encoding import force_bytes, force_str, force_text |
34 |
from django.utils.six.moves.urllib import parse as urlparse |
|
35 | 35 |
from django.utils.translation import gettext as _ |
36 | 36 | |
37 | 37 |
from authentic2.a2_rbac.models import OrganizationalUnit, Role |
... | ... | |
272 | 272 |
), |
273 | 273 |
) |
274 | 274 |
login.buildAuthnRequestMsg() |
275 |
url_parsed = urlparse.urlparse(login.msgUrl) |
|
275 |
url_parsed = urllib.parse.urlparse(login.msgUrl)
|
|
276 | 276 |
assert url_parsed.path == reverse('a2-idp-saml-sso'), 'msgUrl should target the sso endpoint' |
277 | 277 |
if self.keys: |
278 | 278 |
assert 'rsa-sha256' in login.msgUrl |
... | ... | |
288 | 288 |
if response.location: |
289 | 289 |
method = lasso.HTTP_METHOD_ARTIFACT_GET |
290 | 290 |
query_string = response.location.split('?', 1)[1] |
291 |
parsed_query_string = urlparse.parse_qs(query_string) |
|
291 |
parsed_query_string = urllib.parse.parse_qs(query_string)
|
|
292 | 292 |
self.relay_state = parsed_query_string.get('RelayState') |
293 | 293 |
login.msgRelayState = force_str(self.relay_state) |
294 | 294 |
else: # lasso.HTTP_METHOD_ARTIFACT_POST, never happens |
... | ... | |
334 | 334 |
REDIRECT_FIELD_NAME: make_url('a2-idp-saml-continue', params={NONCE_FIELD_NAME: request_id}), |
335 | 335 |
}, |
336 | 336 |
) |
337 |
self.nonce = urlparse.parse_qs(urlparse.urlparse(response['Location']).query)['nonce'][0]
|
|
337 |
self.nonce = urllib.parse.parse_qs(urllib.parse.urlparse(response['Location']).query)['nonce'][0]
|
|
338 | 338 |
url = response['Location'] |
339 | 339 |
response = self.app.get(url) |
340 | 340 |
assert response.status_code == 200 |
tests/test_import_export_site_cmd.py | ||
---|---|---|
14 | 14 |
# You should have received a copy of the GNU Affero General Public License |
15 | 15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | 16 | |
17 |
import builtins as __builtin__ |
|
17 | 18 |
import json |
18 | 19 |
import random |
19 | 20 | |
... | ... | |
21 | 22 |
from django import VERSION |
22 | 23 |
from django.core import management |
23 | 24 |
from django.core.exceptions import ValidationError |
24 |
from django.utils.six.moves import builtins as __builtin__ |
|
25 | 25 | |
26 | 26 |
from django_rbac.utils import get_role_model |
27 | 27 |
tests/test_ldap.py | ||
---|---|---|
18 | 18 |
import json |
19 | 19 |
import os |
20 | 20 |
import time |
21 |
import urllib.parse |
|
21 | 22 | |
22 | 23 |
import ldap |
23 | 24 |
import mock |
... | ... | |
27 | 28 |
from django.core.exceptions import ImproperlyConfigured |
28 | 29 |
from django.utils import timezone |
29 | 30 |
from django.utils.encoding import force_bytes, force_text |
30 |
from django.utils.six.moves.urllib import parse as urlparse |
|
31 | 31 |
from ldap.dn import escape_dn_chars |
32 | 32 |
from ldaptools.slapd import Slapd, has_slapd |
33 | 33 | |
... | ... | |
1479 | 1479 |
assert all( |
1480 | 1480 |
[ |
1481 | 1481 |
user.userexternalid_set.first().external_id |
1482 |
== urlparse.quote(user.username.split('@')[0].encode('utf-8')) |
|
1482 |
== urllib.parse.quote(user.username.split('@')[0].encode('utf-8'))
|
|
1483 | 1483 |
for user in User.objects.all() |
1484 | 1484 |
] |
1485 | 1485 |
) |
tests/test_login.py | ||
---|---|---|
14 | 14 |
# You should have received a copy of the GNU Affero General Public License |
15 | 15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | 16 | |
17 |
from urllib.parse import quote |
|
18 | ||
17 | 19 |
import pytest |
18 | 20 |
from django.contrib.auth import get_user_model |
19 |
from django.utils.six.moves.urllib.parse import quote |
|
20 | 21 | |
21 | 22 |
from authentic2 import models |
22 | 23 |
tests/test_manager.py | ||
---|---|---|
18 | 18 |
from __future__ import unicode_literals |
19 | 19 | |
20 | 20 |
import json |
21 |
from urllib.parse import urlparse |
|
21 | 22 | |
22 | 23 |
import pytest |
23 | 24 |
from django.contrib.auth import get_user_model |
... | ... | |
25 | 26 |
from django.core import mail |
26 | 27 |
from django.urls import reverse |
27 | 28 |
from django.utils.encoding import force_bytes, force_str |
28 |
from django.utils.six.moves.urllib.parse import urlparse |
|
29 | 29 |
from webtest import Upload |
30 | 30 | |
31 | 31 |
from authentic2.a2_rbac.models import MANAGE_MEMBERS_OP |
tests/test_registration.py | ||
---|---|---|
16 | 16 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 | 17 | |
18 | 18 |
from datetime import date |
19 |
from urllib.parse import urlparse |
|
19 | 20 | |
20 | 21 |
from django.contrib.auth import REDIRECT_FIELD_NAME, get_user_model |
21 | 22 |
from django.urls import reverse |
22 | 23 |
from django.utils.http import urlquote |
23 |
from django.utils.six.moves.urllib.parse import urlparse |
|
24 | 24 | |
25 | 25 |
from authentic2 import models, utils |
26 | 26 |
from authentic2.apps.journal.models import Event |
tests/test_user_manager.py | ||
---|---|---|
27 | 27 |
from django.contrib.auth import get_user_model |
28 | 28 |
from django.contrib.contenttypes.models import ContentType |
29 | 29 |
from django.urls import reverse |
30 |
from django.utils.six import text_type |
|
31 | 30 |
from webtest import Upload |
32 | 31 | |
33 | 32 |
from authentic2.a2_rbac.utils import get_default_ou, get_view_user_perm |
... | ... | |
230 | 229 |
response = login( |
231 | 230 |
app, |
232 | 231 |
superuser_or_admin, |
233 |
reverse('a2-manager-user-by-uuid-detail', kwargs={'slug': text_type(simple_user.uuid)}),
|
|
232 |
reverse('a2-manager-user-by-uuid-detail', kwargs={'slug': str(simple_user.uuid)}),
|
|
234 | 233 |
) |
235 | 234 |
assert 'Change user email' in response.text |
236 | 235 |
# cannot click it's a submit button :/ |
237 | 236 |
response = app.get( |
238 |
reverse('a2-manager-user-by-uuid-change-email', kwargs={'slug': text_type(simple_user.uuid)})
|
|
237 |
reverse('a2-manager-user-by-uuid-change-email', kwargs={'slug': str(simple_user.uuid)})
|
|
239 | 238 |
) |
240 | 239 |
assert response.form['new_email'].value == simple_user.email |
241 | 240 |
response.form.set('new_email', NEW_EMAIL) |
... | ... | |
270 | 269 |
response = login( |
271 | 270 |
app, |
272 | 271 |
superuser_or_admin, |
273 |
reverse('a2-manager-user-by-uuid-detail', kwargs={'slug': text_type(simple_user.uuid)}),
|
|
272 |
reverse('a2-manager-user-by-uuid-detail', kwargs={'slug': str(simple_user.uuid)}),
|
|
274 | 273 |
) |
275 | 274 |
assert 'Change user email' in response.text |
276 | 275 |
# cannot click it's a submit button :/ |
277 | 276 |
response = app.get( |
278 |
reverse('a2-manager-user-by-uuid-change-email', kwargs={'slug': text_type(simple_user.uuid)})
|
|
277 |
reverse('a2-manager-user-by-uuid-change-email', kwargs={'slug': str(simple_user.uuid)})
|
|
279 | 278 |
) |
280 | 279 |
assert response.form['new_email'].value == simple_user.email |
281 | 280 |
assert len(mailoutbox) == 0 |
tests/test_views.py | ||
---|---|---|
16 | 16 |
# authentic2 |
17 | 17 | |
18 | 18 |
import datetime |
19 |
from urllib.parse import urlparse |
|
19 | 20 | |
20 | 21 |
import pytest |
21 | 22 |
from django.urls import reverse |
22 | 23 |
from django.utils.html import escape |
23 |
from django.utils.six.moves.urllib.parse import urlparse |
|
24 | 24 | |
25 | 25 |
from authentic2.custom_user.models import DeletedUser, User |
26 | 26 |
tests/utils.py | ||
---|---|---|
18 | 18 |
import base64 |
19 | 19 |
import re |
20 | 20 |
import socket |
21 |
import urllib.parse |
|
21 | 22 |
from contextlib import closing, contextmanager |
22 | 23 | |
23 | 24 |
import httmock |
... | ... | |
25 | 26 |
from django.shortcuts import resolve_url |
26 | 27 |
from django.test import TestCase |
27 | 28 |
from django.urls import reverse |
28 |
from django.utils import six |
|
29 | 29 |
from django.utils.encoding import force_text, iri_to_uri |
30 |
from django.utils.six.moves.urllib import parse as urlparse |
|
31 | 30 |
from lxml import etree |
32 | 31 | |
33 | 32 |
from authentic2 import models, utils |
... | ... | |
98 | 97 |
value. |
99 | 98 |
""" |
100 | 99 |
url1 = iri_to_uri(utils.make_url(url1, params=None)) |
101 |
splitted1 = urlparse.urlsplit(url1) |
|
100 |
splitted1 = urllib.parse.urlsplit(url1)
|
|
102 | 101 |
url2 = iri_to_uri(utils.make_url(url2, params=kwargs)) |
103 |
splitted2 = urlparse.urlsplit(url2) |
|
102 |
splitted2 = urllib.parse.urlsplit(url2)
|
|
104 | 103 |
for i, (elt1, elt2) in enumerate(zip(splitted1, splitted2)): |
105 | 104 |
if i == 3: |
106 |
elt1 = urlparse.parse_qs(elt1, True) |
|
107 |
elt2 = urlparse.parse_qs(elt2, True) |
|
105 |
elt1 = urllib.parse.parse_qs(elt1, True)
|
|
106 |
elt2 = urllib.parse.parse_qs(elt2, True)
|
|
108 | 107 |
for k, v in elt1.items(): |
109 | 108 |
elt1[k] = set(v) |
110 | 109 |
for k, v in elt2.items(): |
... | ... | |
117 | 116 | |
118 | 117 |
def assert_redirects_complex(response, expected_url, **kwargs): |
119 | 118 |
assert response.status_code == 302, 'code should be 302' |
120 |
scheme, netloc, path, query, fragment = urlparse.urlsplit(response.url) |
|
121 |
e_scheme, e_netloc, e_path, e_query, e_fragment = urlparse.urlsplit(expected_url) |
|
119 |
scheme, netloc, path, query, fragment = urllib.parse.urlsplit(response.url)
|
|
120 |
e_scheme, e_netloc, e_path, e_query, e_fragment = urllib.parse.urlsplit(expected_url)
|
|
122 | 121 |
e_scheme = e_scheme if e_scheme else scheme |
123 | 122 |
e_netloc = e_netloc if e_netloc else netloc |
124 |
expected_url = urlparse.urlunsplit((e_scheme, e_netloc, e_path, e_query, e_fragment)) |
|
123 |
expected_url = urllib.parse.urlunsplit((e_scheme, e_netloc, e_path, e_query, e_fragment))
|
|
125 | 124 |
assert_equals_url(response['Location'], expected_url, **kwargs) |
126 | 125 | |
127 | 126 | |
... | ... | |
132 | 131 |
for xpath, content in constraints: |
133 | 132 |
nodes = doc.xpath(xpath, namespaces=namespaces) |
134 | 133 |
assert len(nodes) > 0, 'xpath %s not found' % xpath |
135 |
if isinstance(content, six.string_types):
|
|
134 |
if isinstance(content, str):
|
|
136 | 135 |
for node in nodes: |
137 | 136 |
if hasattr(node, 'text'): |
138 | 137 |
assert node.text == content, 'xpath %s does not contain %s but %s' % ( |
139 |
- |