apply isort and pyupgrade (#55990)
This commit is contained in:
parent
2704f4feaa
commit
4729ef9a3b
|
@ -6,3 +6,13 @@ repos:
|
|||
hooks:
|
||||
- id: black
|
||||
args: ['--target-version', 'py37', '--skip-string-normalization', '--line-length', '110']
|
||||
- repo: https://github.com/PyCQA/isort
|
||||
rev: 5.7.0
|
||||
hooks:
|
||||
- id: isort
|
||||
args: ['--profile', 'black', '--line-length', '110']
|
||||
- repo: https://github.com/asottile/pyupgrade
|
||||
rev: v2.20.0
|
||||
hooks:
|
||||
- id: pyupgrade
|
||||
args: ['--keep-percent-format', '--py37-plus']
|
||||
|
|
14
README
14
README
|
@ -319,7 +319,7 @@ Unit tests are written using pytest and launched using tox, and can be run with:
|
|||
tox
|
||||
|
||||
Code Style
|
||||
----------
|
||||
==========
|
||||
|
||||
black is used to format the code, using thoses parameters:
|
||||
|
||||
|
@ -328,6 +328,18 @@ black is used to format the code, using thoses parameters:
|
|||
There is .pre-commit-config.yaml to use pre-commit to automatically run black
|
||||
before commits. (execute `pre-commit install` to install the git hook.)
|
||||
|
||||
isort is used to format the imports, using those parameter:
|
||||
|
||||
isort --profile black --line-length 110
|
||||
|
||||
pyupgrade is used to automatically upgrade syntax, using those parameters:
|
||||
|
||||
pyupgrade --keep-percent-format --py37-plus
|
||||
|
||||
There is .pre-commit-config.yaml to use pre-commit to automatically run black,
|
||||
isort and pyupgrade before commits. (execute `pre-commit install` to install
|
||||
the git hook.)
|
||||
|
||||
Remarks
|
||||
=======
|
||||
|
||||
|
|
|
@ -13,33 +13,29 @@
|
|||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from xml.etree import ElementTree as ET
|
||||
import hashlib
|
||||
|
||||
import logging
|
||||
import os
|
||||
import threading
|
||||
import time
|
||||
import uuid
|
||||
from xml.etree import ElementTree as ET
|
||||
|
||||
import lasso
|
||||
import requests
|
||||
import requests.exceptions
|
||||
from atomicwrites import atomic_write
|
||||
|
||||
from django.core.exceptions import PermissionDenied, FieldDoesNotExist
|
||||
from django.core.files.storage import default_storage
|
||||
from django.contrib import auth
|
||||
from django.contrib import auth, messages
|
||||
from django.contrib.auth.models import Group
|
||||
from django.contrib import messages
|
||||
from django.core.exceptions import FieldDoesNotExist, PermissionDenied
|
||||
from django.core.files.storage import default_storage
|
||||
from django.utils import six
|
||||
from django.utils.encoding import force_text
|
||||
from django.utils.six.moves.urllib.parse import urlparse
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
from . import utils, app_settings, models
|
||||
from . import app_settings, models, utils
|
||||
|
||||
User = auth.get_user_model()
|
||||
|
||||
|
@ -51,7 +47,7 @@ class UserCreationError(Exception):
|
|||
|
||||
|
||||
def display_truncated_list(l, max_length=10):
|
||||
s = '[' + ', '.join(map(six.text_type, l))
|
||||
s = '[' + ', '.join(map(str, l))
|
||||
if len(l) > max_length:
|
||||
s += '..truncated more than %d items (%d)]' % (max_length, len(l))
|
||||
else:
|
||||
|
@ -59,7 +55,7 @@ def display_truncated_list(l, max_length=10):
|
|||
return s
|
||||
|
||||
|
||||
class DefaultAdapter(object):
|
||||
class DefaultAdapter:
|
||||
def __init__(self, request=None):
|
||||
self.request = request
|
||||
|
||||
|
@ -153,7 +149,7 @@ class DefaultAdapter(object):
|
|||
idp['METADATA'] = fd.read()
|
||||
# use file cache mtime as last_update time, prevent too many loading from different workers
|
||||
last_update = max(last_update, os.stat(file_cache_path).st_mtime)
|
||||
except (IOError, OSError):
|
||||
except OSError:
|
||||
warning('metadata url %s : error when loading the file cache %s', url, file_cache_path)
|
||||
|
||||
# fresh cache, skip loading
|
||||
|
@ -305,7 +301,7 @@ class DefaultAdapter(object):
|
|||
if saml_attributes['name_id_format'] == lasso.SAML2_NAME_IDENTIFIER_FORMAT_TRANSIENT:
|
||||
if transient_federation_attribute and saml_attributes.get(transient_federation_attribute):
|
||||
name_id = saml_attributes[transient_federation_attribute]
|
||||
if not isinstance(name_id, six.string_types):
|
||||
if not isinstance(name_id, str):
|
||||
if len(name_id) == 1:
|
||||
name_id = name_id[0]
|
||||
else:
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import sys
|
||||
|
||||
|
||||
class AppSettings(object):
|
||||
class AppSettings:
|
||||
__PREFIX = 'MELLON_'
|
||||
__DEFAULTS = {
|
||||
'IDENTITY_PROVIDERS': [],
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import logging
|
||||
|
||||
from django.contrib.auth.backends import ModelBackend
|
||||
|
|
|
@ -13,12 +13,11 @@
|
|||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.utils.http import urlencode
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.utils.deprecation import MiddlewareMixin
|
||||
from django.urls import reverse
|
||||
from django.utils.deprecation import MiddlewareMixin
|
||||
from django.utils.http import urlencode
|
||||
|
||||
from . import app_settings, utils
|
||||
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
@ -40,6 +37,6 @@ class Migration(migrations.Migration):
|
|||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='usersamlidentifier',
|
||||
unique_together=set([('issuer', 'name_id')]),
|
||||
unique_together={('issuer', 'name_id')},
|
||||
),
|
||||
]
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# Generated by Django 2.2.12 on 2020-04-24 05:14
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
|
|
@ -13,13 +13,12 @@
|
|||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from importlib import import_module
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import models
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.conf import settings
|
||||
|
||||
|
||||
class UserSAMLIdentifier(models.Model):
|
||||
|
|
|
@ -29,10 +29,10 @@ class SessionStore(SessionStore):
|
|||
session_not_on_or_after = self.get_session_not_on_or_after()
|
||||
if session_not_on_or_after and 'expiry' not in kwargs:
|
||||
kwargs['expiry'] = session_not_on_or_after
|
||||
return super(SessionStore, self).get_expiry_age(**kwargs)
|
||||
return super().get_expiry_age(**kwargs)
|
||||
|
||||
def get_expiry_date(self, **kwargs):
|
||||
session_not_on_or_after = self.get_session_not_on_or_after()
|
||||
if session_not_on_or_after and 'expiry' not in kwargs:
|
||||
kwargs['expiry'] = session_not_on_or_after
|
||||
return super(SessionStore, self).get_expiry_date(**kwargs)
|
||||
return super().get_expiry_date(**kwargs)
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
from django.conf.urls import url
|
||||
import django
|
||||
from django.conf.urls import url
|
||||
|
||||
from . import views
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
url('login/$', views.login, name='mellon_login'),
|
||||
url('login/debug/$', views.debug_login, name='mellon_debug_login'),
|
||||
|
|
|
@ -13,23 +13,22 @@
|
|||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import logging
|
||||
import datetime
|
||||
import importlib
|
||||
import logging
|
||||
from functools import wraps
|
||||
import isodate
|
||||
from xml.parsers import expat
|
||||
|
||||
import isodate
|
||||
import lasso
|
||||
from django.conf import settings
|
||||
from django.contrib import auth
|
||||
from django.template.loader import render_to_string
|
||||
from django.urls import reverse
|
||||
from django.utils.encoding import force_text
|
||||
from django.utils.timezone import make_aware, now, make_naive, is_aware, get_default_timezone
|
||||
from django.conf import settings
|
||||
from django.utils.six.moves.urllib.parse import urlparse
|
||||
import lasso
|
||||
from django.utils.timezone import get_default_timezone, is_aware, make_aware, make_naive, now
|
||||
|
||||
from . import app_settings
|
||||
|
||||
|
@ -133,8 +132,7 @@ def get_idp(entity_id):
|
|||
def get_idps():
|
||||
for adapter in get_adapters():
|
||||
if hasattr(adapter, 'get_idps'):
|
||||
for idp in adapter.get_idps():
|
||||
yield idp
|
||||
yield from adapter.get_idps()
|
||||
|
||||
|
||||
def flatten_datetime(d):
|
||||
|
|
|
@ -13,55 +13,45 @@
|
|||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import logging
|
||||
import uuid
|
||||
import xml.etree.ElementTree as ET
|
||||
from contextlib import contextmanager, nullcontext
|
||||
from importlib import import_module
|
||||
from io import StringIO
|
||||
import logging
|
||||
import requests
|
||||
import lasso
|
||||
import uuid
|
||||
from requests.exceptions import RequestException
|
||||
from xml.sax.saxutils import escape
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
import django.http
|
||||
from django.views.generic import View
|
||||
from django.views.generic.base import RedirectView
|
||||
from django.http import HttpResponseRedirect, HttpResponse, HttpResponseForbidden
|
||||
from django.contrib import auth
|
||||
from django.contrib.auth import get_user_model
|
||||
import lasso
|
||||
import requests
|
||||
from django.conf import settings
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
from django.contrib import auth
|
||||
from django.contrib.auth import REDIRECT_FIELD_NAME, get_user_model
|
||||
from django.db import transaction
|
||||
from django.http import HttpResponse, HttpResponseForbidden, HttpResponseRedirect
|
||||
from django.shortcuts import render, resolve_url
|
||||
from django.urls import reverse
|
||||
from django.utils.http import urlencode
|
||||
from django.utils import six
|
||||
from django.utils.encoding import force_text, force_str
|
||||
from django.contrib.auth import REDIRECT_FIELD_NAME
|
||||
from django.db import transaction
|
||||
from django.utils.encoding import force_str, force_text
|
||||
from django.utils.http import urlencode
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
from django.views.generic import View
|
||||
from django.views.generic.base import RedirectView
|
||||
from requests.exceptions import RequestException
|
||||
|
||||
from . import app_settings, utils, models
|
||||
|
||||
from . import app_settings, models, utils
|
||||
|
||||
RETRY_LOGIN_COOKIE = 'MELLON_RETRY_LOGIN'
|
||||
|
||||
lasso.setFlag('thin-sessions')
|
||||
|
||||
if six.PY3:
|
||||
|
||||
def lasso_decode(x):
|
||||
def lasso_decode(x):
|
||||
return x
|
||||
|
||||
|
||||
else:
|
||||
|
||||
def lasso_decode(x):
|
||||
return x.decode('utf-8')
|
||||
|
||||
|
||||
EO_NS = 'https://www.entrouvert.com/'
|
||||
LOGIN_HINT = '{%s}login-hint' % EO_NS
|
||||
|
||||
|
@ -71,16 +61,16 @@ User = get_user_model()
|
|||
class HttpResponseBadRequest(django.http.HttpResponseBadRequest):
|
||||
def __init__(self, *args, **kwargs):
|
||||
kwargs['content_type'] = kwargs.get('content_type', 'text/plain')
|
||||
super(HttpResponseBadRequest, self).__init__(*args, **kwargs)
|
||||
super().__init__(*args, **kwargs)
|
||||
self['X-Content-Type-Options'] = 'nosniff'
|
||||
|
||||
|
||||
class LogMixin(object):
|
||||
class LogMixin:
|
||||
"""Initialize a module logger in new objects"""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.log = logging.getLogger(__name__)
|
||||
super(LogMixin, self).__init__(*args, **kwargs)
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
|
||||
def check_next_url(request, next_url):
|
||||
|
@ -101,7 +91,7 @@ def check_next_url(request, next_url):
|
|||
return next_url
|
||||
|
||||
|
||||
class ProfileMixin(object):
|
||||
class ProfileMixin:
|
||||
profile = None
|
||||
|
||||
def set_next_url(self, next_url):
|
||||
|
@ -507,7 +497,7 @@ class LoginView(ProfileMixin, LogMixin, View):
|
|||
# configure requested AuthnClassRef
|
||||
authn_classref = utils.get_setting(idp, 'AUTHN_CLASSREF')
|
||||
if authn_classref:
|
||||
authn_classref = tuple([str(x) for x in authn_classref])
|
||||
authn_classref = tuple(str(x) for x in authn_classref)
|
||||
req_authncontext = lasso.Samlp2RequestedAuthnContext()
|
||||
authn_request.requestedAuthnContext = req_authncontext
|
||||
req_authncontext.authnContextClassRef = authn_classref
|
||||
|
@ -550,7 +540,6 @@ class LoginView(ProfileMixin, LogMixin, View):
|
|||
assert hasattr(authn_request.extensions, 'any'), 'extension nodes need lasso > 2.5.1'
|
||||
serialized = ET.tostring(node, 'utf-8')
|
||||
# tostring return bytes in PY3, but lasso needs str
|
||||
if six.PY3:
|
||||
serialized = serialized.decode('utf-8')
|
||||
extension_content = authn_request.extensions.any or ()
|
||||
extension_content += (serialized,)
|
||||
|
@ -653,7 +642,7 @@ class LogoutView(ProfileMixin, LogMixin, View):
|
|||
return HttpResponseBadRequest('error processing logout request: %r' % e)
|
||||
|
||||
issuer = force_text(logout.remoteProviderId)
|
||||
session_indexes = set(force_text(sessionIndex) for sessionIndex in logout.request.sessionIndexes)
|
||||
session_indexes = {force_text(sessionIndex) for sessionIndex in logout.request.sessionIndexes}
|
||||
|
||||
saml_identifier = (
|
||||
models.UserSAMLIdentifier.objects.filter(
|
||||
|
|
12
setup.py
12
setup.py
|
@ -5,11 +5,12 @@
|
|||
|
||||
import os
|
||||
import subprocess
|
||||
from setuptools import setup, find_packages
|
||||
from setuptools.command.install_lib import install_lib as _install_lib
|
||||
from distutils.command.build import build as _build
|
||||
from setuptools.command.sdist import sdist as _sdist
|
||||
from distutils.cmd import Command
|
||||
from distutils.command.build import build as _build
|
||||
|
||||
from setuptools import find_packages, setup
|
||||
from setuptools.command.install_lib import install_lib as _install_lib
|
||||
from setuptools.command.sdist import sdist as _sdist
|
||||
|
||||
|
||||
class compile_translations(Command):
|
||||
|
@ -24,6 +25,7 @@ class compile_translations(Command):
|
|||
|
||||
def run(self):
|
||||
import os
|
||||
|
||||
from django.core.management import call_command
|
||||
|
||||
os.environ.pop('DJANGO_SETTINGS_MODULE', None)
|
||||
|
@ -68,7 +70,7 @@ def get_version():
|
|||
tag exists, take 0.0.0- and add the length of the commit log.
|
||||
"""
|
||||
if os.path.exists('VERSION'):
|
||||
with open('VERSION', 'r') as v:
|
||||
with open('VERSION') as v:
|
||||
return v.read()
|
||||
if os.path.exists('.git'):
|
||||
p = subprocess.Popen(
|
||||
|
|
|
@ -13,11 +13,11 @@
|
|||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import os
|
||||
import logging
|
||||
import os
|
||||
|
||||
import pytest
|
||||
import django_webtest
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
|
|
|
@ -13,24 +13,21 @@
|
|||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import datetime
|
||||
import re
|
||||
import lasso
|
||||
import time
|
||||
from multiprocessing.pool import ThreadPool
|
||||
from unittest import mock
|
||||
|
||||
import mock
|
||||
import lasso
|
||||
import pytest
|
||||
|
||||
from django.contrib import auth
|
||||
from django.db import connection
|
||||
|
||||
from mellon.adapters import DefaultAdapter
|
||||
from mellon.backends import SAMLBackend
|
||||
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
User = auth.get_user_model()
|
||||
|
@ -119,7 +116,7 @@ def test_lookup_user_transaction(transactional_db, concurrency, idp, saml_attrib
|
|||
users = p.map(f, range(concurrency))
|
||||
|
||||
assert len(users) == concurrency
|
||||
assert len(set(user.pk for user in users)) == 1
|
||||
assert len({user.pk for user in users}) == 1
|
||||
|
||||
|
||||
def test_provision_user_attributes(settings, django_user_model, idp, saml_attributes, caplog):
|
||||
|
|
|
@ -13,32 +13,29 @@
|
|||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import datetime
|
||||
from html import unescape
|
||||
import re
|
||||
import base64
|
||||
import zlib
|
||||
import datetime
|
||||
import re
|
||||
import xml.etree.ElementTree as ET
|
||||
import zlib
|
||||
from html import unescape
|
||||
|
||||
import lasso
|
||||
|
||||
import pytest
|
||||
from pytest import fixture
|
||||
|
||||
from django.contrib.sessions.models import Session
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.sessions.models import Session
|
||||
from django.urls import reverse
|
||||
from django.utils import six
|
||||
from django.utils.six.moves.urllib import parse as urlparse
|
||||
from django.utils.encoding import force_str
|
||||
from django.utils.six.moves.urllib import parse as urlparse
|
||||
from httmock import HTTMock, all_requests
|
||||
from httmock import response as mock_response
|
||||
from pytest import fixture
|
||||
|
||||
from mellon.utils import create_metadata
|
||||
from mellon.views import lasso_decode
|
||||
|
||||
from httmock import all_requests, HTTMock, response as mock_response
|
||||
|
||||
|
||||
@fixture
|
||||
def idp_metadata():
|
||||
|
@ -81,7 +78,7 @@ def sp_metadata(sp_settings, rf):
|
|||
return create_metadata(request)
|
||||
|
||||
|
||||
class MockIdp(object):
|
||||
class MockIdp:
|
||||
session_dump = None
|
||||
identity_dump = None
|
||||
|
||||
|
@ -240,10 +237,10 @@ def test_sso_slo(db, app, idp, caplog, sp_settings):
|
|||
assert 'created new user' in caplog.text
|
||||
assert 'logged in using SAML' in caplog.text
|
||||
assert urlparse.urlparse(response['Location']).path == '/whatever/'
|
||||
response = app.get(reverse('mellon_logout'), extra_environ={'HTTP_REFERER': str('/some/path')})
|
||||
response = app.get(reverse('mellon_logout'), extra_environ={'HTTP_REFERER': '/some/path'})
|
||||
assert urlparse.urlparse(response['Location']).path == '/singleLogout'
|
||||
# again, user is already logged out
|
||||
response = app.get(reverse('mellon_logout'), extra_environ={'HTTP_REFERER': str('/some/path')})
|
||||
response = app.get(reverse('mellon_logout'), extra_environ={'HTTP_REFERER': '/some/path'})
|
||||
assert urlparse.urlparse(response['Location']).path == '/some/path'
|
||||
|
||||
|
||||
|
@ -433,18 +430,11 @@ def test_sso_request_denied(db, app, idp, caplog, sp_settings):
|
|||
assert not relay_state
|
||||
assert url.endswith(reverse('mellon_login'))
|
||||
response = app.post(reverse('mellon_login'), params={'SAMLResponse': body, 'RelayState': relay_state})
|
||||
if six.PY3:
|
||||
assert (
|
||||
"status is not success codes: ['urn:oasis:names:tc:SAML:2.0:status:Responder',\
|
||||
'urn:oasis:names:tc:SAML:2.0:status:RequestDenied']"
|
||||
in caplog.text
|
||||
)
|
||||
else:
|
||||
assert (
|
||||
"status is not success codes: [u'urn:oasis:names:tc:SAML:2.0:status:Responder',\
|
||||
u'urn:oasis:names:tc:SAML:2.0:status:RequestDenied']"
|
||||
in caplog.text
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.urls('urls_tests_template_base')
|
||||
|
@ -663,7 +653,7 @@ def test_passive_auth_middleware_ok(db, app, idp, caplog, settings):
|
|||
settings.MELLON_OPENED_SESSION_COOKIE_NAME = 'IDP_SESSION'
|
||||
assert 'MELLON_PASSIVE_TRIED' not in app.cookies
|
||||
# webtest-lint is against unicode
|
||||
app.set_cookie(str('IDP_SESSION'), str('1'))
|
||||
app.set_cookie('IDP_SESSION', '1')
|
||||
response = app.get('/', headers={'Accept': force_str('text/html')}, status=302)
|
||||
assert urlparse.urlparse(response.location).path == '/login/'
|
||||
assert urlparse.parse_qs(urlparse.urlparse(response.location).query, keep_blank_values=True) == {
|
||||
|
@ -681,7 +671,7 @@ def test_passive_auth_middleware_ok(db, app, idp, caplog, settings):
|
|||
assert 'MELLON_PASSIVE_TRIED' not in app.cookies
|
||||
|
||||
# check passive authentication is tried again
|
||||
app.set_cookie(str('IDP_SESSION'), str('1'))
|
||||
app.set_cookie('IDP_SESSION', '1')
|
||||
response = app.get('/', headers={'Accept': force_str('text/html')}, status=302)
|
||||
assert urlparse.urlparse(response.location).path == '/login/'
|
||||
assert urlparse.parse_qs(urlparse.urlparse(response.location).query, keep_blank_values=True) == {
|
||||
|
@ -695,7 +685,7 @@ def test_passive_auth_middleware_no_passive_auth_parameter(db, app, idp, caplog,
|
|||
settings.MELLON_OPENED_SESSION_COOKIE_NAME = 'IDP_SESSION'
|
||||
assert 'MELLON_PASSIVE_TRIED' not in app.cookies
|
||||
# webtest-lint is against unicode
|
||||
app.set_cookie(str('IDP_SESSION'), str('1'))
|
||||
app.set_cookie('IDP_SESSION', '1')
|
||||
app.get('/?no-passive-auth', headers={'Accept': force_str('text/html')}, status=200)
|
||||
|
||||
|
||||
|
|
|
@ -13,17 +13,16 @@
|
|||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import datetime
|
||||
from unittest import mock
|
||||
|
||||
import mock
|
||||
import lasso
|
||||
|
||||
from mellon.utils import create_metadata, iso8601_to_datetime, flatten_datetime
|
||||
from mellon.views import check_next_url
|
||||
from xml_utils import assert_xml_constraints
|
||||
|
||||
from mellon.utils import create_metadata, flatten_datetime, iso8601_to_datetime
|
||||
from mellon.views import check_next_url
|
||||
|
||||
|
||||
def test_create_metadata(rf, private_settings, caplog):
|
||||
ns = {
|
||||
|
@ -144,17 +143,17 @@ def test_flatten_datetime():
|
|||
'y': 1,
|
||||
'z': 'u',
|
||||
}
|
||||
assert set(flatten_datetime(d).keys()) == set(['x', 'y', 'z'])
|
||||
assert set(flatten_datetime(d).keys()) == {'x', 'y', 'z'}
|
||||
assert flatten_datetime(d)['x'] == '2010-10-10T10:10:34'
|
||||
assert flatten_datetime(d)['y'] == 1
|
||||
assert flatten_datetime(d)['z'] == 'u'
|
||||
|
||||
|
||||
def test_check_next_url(rf):
|
||||
assert not check_next_url(rf.get('/'), u'')
|
||||
assert not check_next_url(rf.get('/'), '')
|
||||
assert not check_next_url(rf.get('/'), None)
|
||||
assert not check_next_url(rf.get('/'), u'\x00')
|
||||
assert not check_next_url(rf.get('/'), u'\u010e')
|
||||
assert not check_next_url(rf.get('/'), u'https://example.invalid/')
|
||||
assert not check_next_url(rf.get('/'), '\x00')
|
||||
assert not check_next_url(rf.get('/'), '\u010e')
|
||||
assert not check_next_url(rf.get('/'), 'https://example.invalid/')
|
||||
# default hostname is testserver
|
||||
assert check_next_url(rf.get('/'), u'http://testserver/ok/')
|
||||
assert check_next_url(rf.get('/'), 'http://testserver/ok/')
|
||||
|
|
|
@ -13,23 +13,20 @@
|
|||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import pytest
|
||||
import mock
|
||||
import lasso
|
||||
from django.utils.six.moves.urllib.parse import parse_qs, urlparse
|
||||
import base64
|
||||
import hashlib
|
||||
from httmock import HTTMock
|
||||
from unittest import mock
|
||||
|
||||
import lasso
|
||||
import pytest
|
||||
from django.urls import reverse
|
||||
from django.utils.encoding import force_text
|
||||
from django.utils.http import urlencode
|
||||
|
||||
from xml_utils import assert_xml_constraints
|
||||
|
||||
from django.utils.six.moves.urllib.parse import parse_qs, urlparse
|
||||
from httmock import HTTMock
|
||||
from utils import error_500, html_response
|
||||
from xml_utils import assert_xml_constraints
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
|
@ -207,7 +204,7 @@ def test_sp_initiated_login(private_settings, client):
|
|||
assert response.status_code == 302
|
||||
params = parse_qs(urlparse(response['Location']).query)
|
||||
assert response['Location'].startswith('http://idp5/singleSignOn?')
|
||||
assert set(params.keys()) == set(['SAMLRequest', 'RelayState'])
|
||||
assert set(params.keys()) == {'SAMLRequest', 'RelayState'}
|
||||
assert len(params['SAMLRequest']) == 1
|
||||
assert base64.b64decode(params['SAMLRequest'][0])
|
||||
assert client.session['mellon_next_url_%s' % params['RelayState'][0]] == '/whatever'
|
||||
|
@ -229,7 +226,7 @@ def test_sp_initiated_login_chosen(private_settings, client):
|
|||
assert response.status_code == 302
|
||||
params = parse_qs(urlparse(response['Location']).query)
|
||||
assert response['Location'].startswith('http://idp5/singleSignOn?')
|
||||
assert set(params.keys()) == set(['SAMLRequest', 'RelayState'])
|
||||
assert set(params.keys()) == {'SAMLRequest', 'RelayState'}
|
||||
assert len(params['SAMLRequest']) == 1
|
||||
assert base64.b64decode(params['SAMLRequest'][0])
|
||||
assert client.session['mellon_next_url_%s' % params['RelayState'][0]] == '/whatever'
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from django.conf.urls import url, include
|
||||
from django.conf.urls import include, url
|
||||
from django.http import HttpResponse
|
||||
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from django.conf.urls import url, include
|
||||
from django.conf.urls import include, url
|
||||
from django.http import HttpResponse
|
||||
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from django.conf.urls import url, include
|
||||
from django.conf.urls import include, url
|
||||
from django.http import HttpResponse
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import os
|
||||
|
||||
import django
|
||||
from django.conf import global_settings
|
||||
|
||||
|
|
6
tox.ini
6
tox.ini
|
@ -1,5 +1,5 @@
|
|||
[tox]
|
||||
envlist = black,py3-django22-coverage
|
||||
envlist = code-style,py3-django22-coverage
|
||||
toxworkdir = {env:TMPDIR:/tmp}/tox-{env:USER}/django-mellon/
|
||||
|
||||
[testenv]
|
||||
|
@ -55,12 +55,12 @@ commands =
|
|||
./getlasso3.sh
|
||||
django-admin {posargs:--help}
|
||||
|
||||
[testenv:black]
|
||||
[testenv:code-style]
|
||||
skip_install = true
|
||||
deps =
|
||||
pre-commit
|
||||
commands =
|
||||
pre-commit run black --all-files --show-diff-on-failure
|
||||
pre-commit run --all-files --show-diff-on-failure
|
||||
|
||||
[pytest]
|
||||
junit_family=legacy
|
||||
|
|
Loading…
Reference in New Issue