Merge pull request #69 from ynerant/master

Add Django 3.1 and Python 3.9 support
This commit is contained in:
Valentin Samir 2021-06-19 16:03:46 +02:00 committed by GitHub
commit 956bec1178
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 175 additions and 181 deletions

View file

@ -2,7 +2,7 @@ before_script:
- pip install tox setuptools - pip install tox setuptools
flake8: flake8:
image: "python:2.7" image: "python:3.9"
cache: cache:
key: flake8 key: flake8
paths: paths:
@ -11,7 +11,7 @@ flake8:
- tox -e flake8 - tox -e flake8
check_rst: check_rst:
image: "python:2.7" image: "python:3.9"
cache: cache:
key: check_rst key: check_rst
paths: paths:
@ -19,107 +19,98 @@ check_rst:
script: script:
- tox -e check_rst - tox -e check_rst
py27-django17: py27-django111:
image: "python:2.7" image: "python:2.7"
cache: cache:
key: py27-django17 key: py27-django111
paths: paths:
- .tox/py27-django17 - .tox/py27-django111
script: script:
- tox -e py27-django17 - tox -e py27-django111
py27-django18: py35-django111:
image: "python:2.7"
cache:
key: py27-django18
paths:
- .tox/py27-django18
script:
- tox -e py27-django18
py27-django19:
image: "python:2.7"
cache:
key: py27-django19
paths:
- .tox/py27-django19
script:
- tox -e py27-django19
py27-django110:
image: "python:2.7"
cache:
key: py27-django110
paths:
- .tox/py27-django110
script:
- tox -e py27-django110
py34-django17:
image: "python:3.4"
cache:
key: py34-django17
paths:
- .tox/py34-django17
script:
- tox -e py34-django17
py34-django18:
image: "python:3.4"
cache:
key: py34-django18
paths:
- .tox/py34-django18
script:
- tox -e py34-django18
py34-django19:
image: "python:3.4"
cache:
key: py34-django19
paths:
- .tox/py34-django19
script:
- tox -e py34-django19
py34-django110:
image: "python:3.4"
cache:
key: py34-django110
paths:
- .tox/py34-django110
script:
- tox -e py34-django110
py35-django18:
image: "python:3.5" image: "python:3.5"
cache: cache:
key: py35-django18 key: py35-django111
paths: paths:
- .tox/py35-django18 - .tox/py35-django111
script: script:
- tox -e py35-django18 - tox -e py35-django111
py35-django19: py36-django111:
image: "python:3.5" image: "python:3.6"
cache: cache:
key: py35-django19 key: py36-django111
paths: paths:
- .tox/py35-django19 - .tox/py36-django111
script: script:
- tox -e py35-django19 - tox -e py36-django111
py35-django110: py37-django22:
image: "python:3.5" image: "python:3.7"
cache: cache:
key: py35-django110 key: py37-django22
paths: paths:
- .tox/py35-django110 - .tox/py37-django22
script: script:
- tox -e py35-django110 - tox -e py37-django22
py38-django22:
image: "python:3.8"
cache:
key: py38-django22
paths:
- .tox/py38-django22
script:
- tox -e py38-django22
py38-django30:
image: "python:3.8"
cache:
key: py38-django30
paths:
- .tox/py38-django30
script:
- tox -e py38-django30
py38-django31:
image: "python:3.8"
cache:
key: py38-django31
paths:
- .tox/py38-django31
script:
- tox -e py38-django31
py39-django22:
image: "python:3.9"
cache:
key: py39-django22
paths:
- .tox/py39-django22
script:
- tox -e py39-django22
py39-django30:
image: "python:3.9"
cache:
key: py39-django30
paths:
- .tox/py39-django30
script:
- tox -e py39-django30
py39-django31:
image: "python:3.9"
cache:
key: py39-django31
paths:
- .tox/py39-django31
script:
- tox -e py39-django31
coverage: coverage:
image: "python:2.7" image: "python:3.9"
cache: cache:
key: coverage key: coverage
paths: paths:

View file

@ -1,9 +1,9 @@
language: python language: python
matrix: matrix:
include: include:
- python: "3.8" - python: "3.9"
env: TOX_ENV=flake8 env: TOX_ENV=flake8
- python: "3.8" - python: "3.9"
env: TOX_ENV=check_rst env: TOX_ENV=check_rst
- python: "2.7" - python: "2.7"
env: TOX_ENV=py27-django111 env: TOX_ENV=py27-django111
@ -11,14 +11,6 @@ matrix:
env: TOX_ENV=py35-django111 env: TOX_ENV=py35-django111
- python: "3.6" - python: "3.6"
env: TOX_ENV=py36-django111 env: TOX_ENV=py36-django111
- python: "3.5"
env: TOX_ENV=py35-django20
- python: "3.6"
env: TOX_ENV=py36-django20
- python: "3.5"
env: TOX_ENV=py35-django21
- python: "3.6"
env: TOX_ENV=py36-django21
- python: "3.7" - python: "3.7"
env: TOX_ENV=py37-django22 env: TOX_ENV=py37-django22
- python: "3.8" - python: "3.8"
@ -26,6 +18,14 @@ matrix:
- python: "3.8" - python: "3.8"
env: TOX_ENV=py38-django30 env: TOX_ENV=py38-django30
- python: "3.8" - python: "3.8"
env: TOX_ENV=py38-django31
- python: "3.9"
env: TOX_ENV=py39-django22
- python: "3.9"
env: TOX_ENV=py39-django30
- python: "3.9"
env: TOX_ENV=py39-django31
- python: "3.9"
env: TOX_ENV=coverage env: TOX_ENV=coverage
- python: "3.8" - python: "3.8"
env: TOX_ENV=flake8 env: TOX_ENV=flake8

View file

@ -21,7 +21,7 @@ Features
* Possibility to rename/rewrite attributes per service * Possibility to rename/rewrite attributes per service
* Possibility to require some attribute values per service * Possibility to require some attribute values per service
* Federated mode between multiple CAS * Federated mode between multiple CAS
* Supports Django 1.11, 2.2 and 3.0 * Supports Django 1.11, 2.2 and 3.1
* Supports Python 2.7, 3.5+ * Supports Python 2.7, 3.5+
Dependencies Dependencies
@ -29,7 +29,7 @@ Dependencies
``django-cas-server`` depends on the following python packages: ``django-cas-server`` depends on the following python packages:
* Django >= 1.11 < 3.1 * Django >= 1.11 < 3.2
* requests >= 2.4 * requests >= 2.4
* requests_futures >= 0.9.5 * requests_futures >= 0.9.5
* lxml >= 3.4 * lxml >= 3.4

View file

@ -13,10 +13,20 @@ Including another URLconf
1. Import the include() function: from django.conf.urls import url, include, include 1. Import the include() function: from django.conf.urls import url, include, include
2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
""" """
import django
if django.VERSION < (2,):
from django.conf.urls import url
re_path = url
else:
from django.urls import re_path
from django.conf.urls import url, include from django.conf.urls import url, include
from django.contrib import admin from django.contrib import admin
urlpatterns = [ urlpatterns = [
url(r'^admin/', admin.site.urls), re_path(r'^admin/', admin.site.urls),
url(r'^', include('cas_server.urls', namespace='cas_server')), re_path(r'^', include('cas_server.urls', namespace='cas_server')),
] ]

View file

@ -10,6 +10,16 @@
# #
# (c) 2015-2016 Valentin Samir # (c) 2015-2016 Valentin Samir
"""urls for the app""" """urls for the app"""
import django
if django.VERSION < (2,):
from django.conf.urls import url
re_path = url
else:
from django.urls import re_path
from django.conf.urls import url from django.conf.urls import url
from django.views.generic import RedirectView from django.views.generic import RedirectView
from django.views.decorators.debug import sensitive_post_parameters, sensitive_variables from django.views.decorators.debug import sensitive_post_parameters, sensitive_variables
@ -19,42 +29,42 @@ from cas_server import views
app_name = "cas_server" app_name = "cas_server"
urlpatterns = [ urlpatterns = [
url( re_path(
r'^$', r'^$',
RedirectView.as_view(pattern_name="cas_server:login", permanent=False, query_string=True) RedirectView.as_view(pattern_name="cas_server:login", permanent=False, query_string=True)
), ),
url( re_path(
'^login$', '^login$',
sensitive_post_parameters('password')( sensitive_post_parameters('password')(
views.LoginView.as_view() views.LoginView.as_view()
), ),
name='login' name='login'
), ),
url('^logout$', views.LogoutView.as_view(), name='logout'), re_path('^logout$', views.LogoutView.as_view(), name='logout'),
url('^validate$', views.Validate.as_view(), name='validate'), re_path('^validate$', views.Validate.as_view(), name='validate'),
url( re_path(
'^serviceValidate$', '^serviceValidate$',
views.ValidateService.as_view(allow_proxy_ticket=False), views.ValidateService.as_view(allow_proxy_ticket=False),
name='serviceValidate' name='serviceValidate'
), ),
url( re_path(
'^proxyValidate$', '^proxyValidate$',
views.ValidateService.as_view(allow_proxy_ticket=True), views.ValidateService.as_view(allow_proxy_ticket=True),
name='proxyValidate' name='proxyValidate'
), ),
url('^proxy$', views.Proxy.as_view(), name='proxy'), re_path('^proxy$', views.Proxy.as_view(), name='proxy'),
url( re_path(
'^p3/serviceValidate$', '^p3/serviceValidate$',
views.ValidateService.as_view(allow_proxy_ticket=False), views.ValidateService.as_view(allow_proxy_ticket=False),
name='p3_serviceValidate' name='p3_serviceValidate'
), ),
url( re_path(
'^p3/proxyValidate$', '^p3/proxyValidate$',
views.ValidateService.as_view(allow_proxy_ticket=True), views.ValidateService.as_view(allow_proxy_ticket=True),
name='p3_proxyValidate' name='p3_proxyValidate'
), ),
url('^samlValidate$', views.SamlValidate.as_view(), name='samlValidate'), re_path('^samlValidate$', views.SamlValidate.as_view(), name='samlValidate'),
url( re_path(
'^auth$', '^auth$',
sensitive_variables('password', 'secret')( sensitive_variables('password', 'secret')(
sensitive_post_parameters('password', 'secret')( sensitive_post_parameters('password', 'secret')(
@ -63,5 +73,6 @@ urlpatterns = [
), ),
name='auth' name='auth'
), ),
url("^federate(?:/(?P<provider>([^/]+)))?$", views.FederateAuth.as_view(), name='federateAuth'), re_path("^federate(?:/(?P<provider>([^/]+)))?$",
views.FederateAuth.as_view(), name='federateAuth'),
] ]

View file

@ -409,7 +409,10 @@ def crypt_salt_is_valid(salt):
if '$' not in salt[1:]: if '$' not in salt[1:]:
return False return False
else: else:
hashed = crypt.crypt("", salt) try:
hashed = crypt.crypt("", salt)
except OSError:
return False
if not hashed or '$' not in hashed[1:]: if not hashed or '$' not in hashed[1:]:
return False return False
else: else:

View file

@ -288,7 +288,8 @@ class FederateAuth(CsrfExemptView):
# else, a User is trying to log in using an identity provider # else, a User is trying to log in using an identity provider
except FederatedIendityProvider.DoesNotExist: except FederatedIendityProvider.DoesNotExist:
# Manually checking for csrf to protect the code below # Manually checking for csrf to protect the code below
reason = CsrfViewMiddleware().process_view(request, None, (), {}) reason = CsrfViewMiddleware(lambda request: HttpResponse()) \
.process_view(request, None, (), {})
if reason is not None: # pragma: no cover (csrf checks are disabled during tests) if reason is not None: # pragma: no cover (csrf checks are disabled during tests)
return reason # Failed the test, stop here. return reason # Failed the test, stop here.
form = forms.FederateSelect(request.POST) form = forms.FederateSelect(request.POST)

View file

@ -36,6 +36,7 @@ if __name__ == '__main__':
'Framework :: Django :: 2.1', 'Framework :: Django :: 2.1',
'Framework :: Django :: 2.2', 'Framework :: Django :: 2.2',
'Framework :: Django :: 3.0', 'Framework :: Django :: 3.0',
'Framework :: Django :: 3.1',
'Intended Audience :: Developers', 'Intended Audience :: Developers',
'Intended Audience :: System Administrators', 'Intended Audience :: System Administrators',
'License :: OSI Approved :: GNU General Public License v3 (GPLv3)', 'License :: OSI Approved :: GNU General Public License v3 (GPLv3)',
@ -48,6 +49,7 @@ if __name__ == '__main__':
'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
'Topic :: Software Development :: Libraries :: Python Modules', 'Topic :: Software Development :: Libraries :: Python Modules',
'Topic :: Internet :: WWW/HTTP', 'Topic :: Internet :: WWW/HTTP',
'Topic :: Internet :: WWW/HTTP :: Dynamic Content', 'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
@ -62,7 +64,7 @@ if __name__ == '__main__':
}, },
keywords=['django', 'cas', 'cas3', 'server', 'sso', 'single sign-on', 'authentication', 'auth'], keywords=['django', 'cas', 'cas3', 'server', 'sso', 'single sign-on', 'authentication', 'auth'],
install_requires=[ install_requires=[
'Django >= 1.11,<3.1', 'requests >= 2.4', 'requests_futures >= 0.9.5', 'Django >= 1.11,<3.2', 'requests >= 2.4', 'requests_futures >= 0.9.5',
'lxml >= 3.4', 'six >= 1' 'lxml >= 3.4', 'six >= 1'
], ],
url="https://github.com/nitmir/django-cas-server", url="https://github.com/nitmir/django-cas-server",

112
tox.ini
View file

@ -9,9 +9,15 @@ envlist=
py36-django22, py36-django22,
py37-django22, py37-django22,
py38-django22, py38-django22,
py39-django22,
py36-django30, py36-django30,
py37-django30, py37-django30,
py38-django30, py38-django30,
py39-django30,
py36-django31,
py37-django31,
py38-django31,
py39-django31,
[flake8] [flake8]
max-line-length=100 max-line-length=100
@ -37,54 +43,12 @@ commands=
{[post_cmd]commands} {[post_cmd]commands}
whitelist_externals={[post_cmd]whitelist_externals} whitelist_externals={[post_cmd]whitelist_externals}
[testenv:py27-django17]
basepython=python2.7
deps =
Django>=1.7,<1.8
{[base]deps}
[testenv:py27-django18]
basepython=python2.7
deps =
Django>=1.8,<1.9
{[base]deps}
[testenv:py27-django19]
basepython=python2.7
deps =
Django>=1.9,<1.10
{[base]deps}
[testenv:py27-django110]
basepython=python2.7
deps =
Django>=1.10,<1.11
{[base]deps}
[testenv:py27-django111] [testenv:py27-django111]
basepython=python2.7 basepython=python2.7
deps = deps =
Django>=1.11,<1.12 Django>=1.11,<1.12
{[base]deps} {[base]deps}
[testenv:py34-django17]
basepython=python3.4
deps =
Django>=1.7,<1.8
{[base]deps}
[testenv:py34-django18]
basepython=python3.4
deps =
Django>=1.8,<1.9
{[base]deps}
[testenv:py35-django110]
basepython=python3.5
deps =
Django>=1.10,<1.11
{[base]deps}
[testenv:py35-django111] [testenv:py35-django111]
basepython=python3.5 basepython=python3.5
deps = deps =
@ -97,34 +61,10 @@ deps =
Django>=1.11,<1.12 Django>=1.11,<1.12
{[base]deps} {[base]deps}
[testenv:py35-django20] [testenv:py37-django111]
basepython=python3.5
deps =
Django>=2.0,<2.1
{[base]deps}
[testenv:py36-django20]
basepython=python3.6
deps =
Django>=2.0,<2.1
{[base]deps}
[testenv:py35-django21]
basepython=python3.5
deps =
Django>=2.1,<2.2
{[base]deps}
[testenv:py36-django21]
basepython=python3.6
deps =
Django>=2.1,<2.2
{[base]deps}
[testenv:py37-django21]
basepython=python3.7 basepython=python3.7
deps = deps =
Django>=2.1,<2.2 Django>=1.11,<1.12
{[base]deps} {[base]deps}
[testenv:py36-django22] [testenv:py36-django22]
@ -145,6 +85,12 @@ deps =
Django>=2.2,<3.0 Django>=2.2,<3.0
{[base]deps} {[base]deps}
[testenv:py39-django22]
basepython=python3.9
deps =
Django>=2.2,<3.0
{[base]deps}
[testenv:py36-django30] [testenv:py36-django30]
basepython=python3.6 basepython=python3.6
deps = deps =
@ -163,6 +109,36 @@ deps =
Django>=3.0,<3.1 Django>=3.0,<3.1
{[base]deps} {[base]deps}
[testenv:py39-django30]
basepython=python3.9
deps =
Django>=3.0,<3.1
{[base]deps}
[testenv:py36-django31]
basepython=python3.6
deps =
Django>=3.1,<3.2
{[base]deps}
[testenv:py37-django31]
basepython=python3.7
deps =
Django>=3.1,<3.2
{[base]deps}
[testenv:py38-django31]
basepython=python3.8
deps =
Django>=3.1,<3.2
{[base]deps}
[testenv:py39-django31]
basepython=python3.9
deps =
Django>=3.1,<3.2
{[base]deps}
[testenv:flake8] [testenv:flake8]
basepython=python3 basepython=python3