Skip to content

Commit 749c00e

Browse files
author
Giuseppe De Marco
authored
Merge pull request #337 from g-as/feature/django_4.1
Django 4.1 compat
2 parents 109fd9e + 27e2733 commit 749c00e

File tree

8 files changed

+69
-15
lines changed

8 files changed

+69
-15
lines changed

.github/workflows/python-package.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
strategy:
1717
matrix:
1818
python-version: ["3.8", "3.9", "3.10"]
19-
django-version: ["3.2", "4.0"]
19+
django-version: ["3.2", "4.0", "4.1"]
2020
include:
2121
- python-version: "3.7"
2222
django-version: "3.2"

.pre-commit-config.yaml

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ exclude: 'docs|migrations'
22

33
repos:
44
- repo: https://github.com/pre-commit/pre-commit-hooks
5-
rev: v4.1.0
5+
rev: v4.3.0
66
hooks:
77
- id: trailing-whitespace
88
- id: end-of-file-fixer
@@ -13,7 +13,7 @@ repos:
1313
- id: debug-statements
1414

1515
- repo: https://github.com/asottile/pyupgrade
16-
rev: v2.31.1
16+
rev: v2.34.0
1717
hooks:
1818
- id: pyupgrade
1919
args: [--py37-plus]
@@ -32,12 +32,12 @@ repos:
3232
args: ['--settings-path=pyproject.toml']
3333

3434
- repo: https://github.com/psf/black
35-
rev: 22.3.0
35+
rev: 22.6.0
3636
hooks:
3737
- id: black
3838

3939
- repo: https://github.com/adamchainz/django-upgrade
40-
rev: 1.4.0
40+
rev: 1.7.0
4141
hooks:
4242
- id: django-upgrade
4343
args: [--target-version, "3.2"]

djangosaml2/__init__.py

-1
Original file line numberDiff line numberDiff line change
@@ -1 +0,0 @@
1-
default_app_config = "djangosaml2.apps.DjangoSaml2Config"

djangosaml2/tests/__init__.py

+33
Original file line numberDiff line numberDiff line change
@@ -782,6 +782,39 @@ def test_logout_service_global(self):
782782
"Not a valid Response",
783783
)
784784

785+
@override_settings(LOGOUT_REDIRECT_URL="/dashboard/")
786+
def test_post_logout_redirection(self):
787+
settings.SAML_CONFIG = conf.create_conf(
788+
sp_host="sp.example.com",
789+
idp_hosts=["idp.example.com"],
790+
metadata_file="remote_metadata_one_idp.xml",
791+
)
792+
793+
self.do_login()
794+
795+
response = self.client.get(reverse("saml2_logout"))
796+
self.assertEqual(response.status_code, 302)
797+
798+
# now simulate a logout response sent by the idp
799+
expected_request = """<samlp:LogoutRequest xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" ID="XXXXXXXXXXXXXXXXXXXXXX" Version="2.0" Destination="https://idp.example.com/simplesaml/saml2/idp/SingleLogoutService.php" Reason=""><saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">http://sp.example.com/saml2/metadata/</saml:Issuer><saml:NameID SPNameQualifier="http://sp.example.com/saml2/metadata/" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient">1f87035b4c1325b296a53d92097e6b3fa36d7e30ee82e3fcb0680d60243c1f03</saml:NameID><samlp:SessionIndex>a0123456789abcdef0123456789abcdef</samlp:SessionIndex></samlp:LogoutRequest>"""
800+
801+
request_id = re.findall(r' ID="(.*?)" ', expected_request)[0]
802+
instant = datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%SZ")
803+
804+
saml_response = """<?xml version='1.0' encoding='UTF-8'?>
805+
<samlp:LogoutResponse xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Destination="http://sp.example.com/saml2/ls/" ID="a140848e7ce2bce834d7264ecdde0151" InResponseTo="{}" IssueInstant="{}" Version="2.0"><saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">https://idp.example.com/simplesaml/saml2/idp/metadata.php</saml:Issuer><samlp:Status><samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" /></samlp:Status></samlp:LogoutResponse>""".format(
806+
request_id, instant
807+
)
808+
809+
response = self.client.get(
810+
reverse("saml2_ls"),
811+
{
812+
"SAMLResponse": deflate_and_base64_encode(saml_response),
813+
},
814+
)
815+
self.assertRedirects(response, "/dashboard/")
816+
self.assertListEqual(list(self.client.session.keys()), [])
817+
785818
def test_incomplete_logout(self):
786819
settings.SAML_CONFIG = conf.create_conf(
787820
sp_host="sp.example.com", idp_hosts=["idp.example.com"]

djangosaml2/views.py

+23-7
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,18 @@
2626
HttpResponseRedirect,
2727
HttpResponseServerError,
2828
)
29-
from django.shortcuts import render
29+
from django.shortcuts import render, resolve_url
3030
from django.template import TemplateDoesNotExist
3131
from django.urls import reverse
3232
from django.utils.decorators import method_decorator
3333
from django.utils.module_loading import import_string
34+
from django.utils.translation import gettext_lazy as _
3435
from django.views.decorators.csrf import csrf_exempt
3536
from django.views.generic import View
3637

3738
from django.contrib import auth
3839
from django.contrib.auth.mixins import LoginRequiredMixin
39-
from django.contrib.auth.views import LogoutView as AuthLogoutView
40+
from django.contrib.sites.shortcuts import get_current_site
4041

4142
import saml2
4243
from saml2.client_base import LogoutError
@@ -787,14 +788,29 @@ def do_logout_service(self, request, data, binding):
787788
return HttpResponseBadRequest("No SAMLResponse or SAMLRequest parameter found")
788789

789790

790-
def finish_logout(request, response, next_page=None):
791+
def finish_logout(request, response):
791792
if getattr(settings, "SAML_IGNORE_LOGOUT_ERRORS", False) or (
792793
response and response.status_ok()
793794
):
794-
if not next_page:
795-
next_page = getattr(settings, "LOGOUT_REDIRECT_URL", "/")
796-
logger.debug("Performing django logout with a next_page of %s", next_page)
797-
return AuthLogoutView.as_view()(request, next_page=next_page)
795+
logger.debug("Performing django logout.")
796+
797+
auth.logout(request)
798+
799+
if settings.LOGOUT_REDIRECT_URL is not None:
800+
return HttpResponseRedirect(resolve_url(settings.LOGOUT_REDIRECT_URL))
801+
else:
802+
current_site = get_current_site(request)
803+
return render(
804+
request,
805+
"registration/logged_out.html",
806+
{
807+
"site": current_site,
808+
"site_name": current_site.name,
809+
"title": _("Logged out"),
810+
"subtitle": None,
811+
},
812+
)
813+
798814
logger.error("Unknown error during the logout")
799815
return render(request, "djangosaml2/logout_error.html", {})
800816

setup.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ def read(*rnames):
2727

2828
setup(
2929
name="djangosaml2",
30-
version="1.5.0",
30+
version="1.5.1",
3131
description="pysaml2 integration for Django",
3232
long_description=read("README.md"),
3333
long_description_content_type="text/markdown",
@@ -37,6 +37,7 @@ def read(*rnames):
3737
"Framework :: Django",
3838
"Framework :: Django :: 3.2",
3939
"Framework :: Django :: 4.0",
40+
"Framework :: Django :: 4.1",
4041
"Intended Audience :: Developers",
4142
"License :: OSI Approved :: Apache Software License",
4243
"Operating System :: OS Independent",

tests/settings.py

+4
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,10 @@
109109
USE_TZ = True
110110

111111

112+
# https://docs.djangoproject.com/en/dev/ref/settings/#default-auto-field
113+
DEFAULT_AUTO_FIELD = "django.db.models.AutoField"
114+
115+
112116
# Static files (CSS, JavaScript, Images)
113117
# https://docs.djangoproject.com/en/1.10/howto/static-files/
114118

tox.ini

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tox]
22
envlist =
3-
py{3.7,3.8,3.9,3.10}-django{3.2,4.0}
3+
py{3.7,3.8,3.9,3.10}-django{3.2,4.0,4.1}
44

55
[testenv]
66
commands =
@@ -10,6 +10,7 @@ commands =
1010
deps =
1111
django3.2: django~=3.2
1212
django4.0: django~=4.0
13+
django4.1: django==4.1b1
1314
djangomaster: https://github.com/django/django/archive/master.tar.gz
1415
.
1516

0 commit comments

Comments
 (0)