Skip to content

Commit dc02454

Browse files
committed
Move use_jwt block below login block
1 parent 801bdb2 commit dc02454

File tree

2 files changed

+98
-18
lines changed

2 files changed

+98
-18
lines changed

django_saml2_auth/tests/test_saml.py

+79
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from django.urls import NoReverseMatch
1414
from saml2 import BINDING_HTTP_POST
1515

16+
from django_saml2_auth.errors import INACTIVE_USER
1617
from django_saml2_auth.exceptions import SAMLAuthError
1718
from django_saml2_auth.saml import (
1819
decode_saml_response,
@@ -771,3 +772,81 @@ def test_get_metadata_success_with_custom_trigger(settings: SettingsWrapper):
771772
get_metadata(domain="not-mapped-example.com")
772773

773774
assert str(exc_info.value) == "Domain not-mapped-example.com not mapped!"
775+
776+
777+
@pytest.mark.django_db
778+
@responses.activate
779+
def test_acs_view_when_use_jwt_set_redirects_user(
780+
settings: SettingsWrapper,
781+
monkeypatch: "MonkeyPatch", # type: ignore # noqa: F821
782+
):
783+
"""Test Acs view when USE_JWT is set that the user is correctly redirected"""
784+
responses.add(responses.GET, METADATA_URL1, body=METADATA1)
785+
settings.SAML2_AUTH = {
786+
"DEFAULT_NEXT_URL": "default_next_url",
787+
"USE_JWT": True,
788+
"JWT_SECRET": "JWT_SECRET",
789+
"JWT_ALGORITHM": "HS256",
790+
"FRONTEND_URL": "https://app.example.com/account/login/saml",
791+
"TRIGGER": {
792+
"BEFORE_LOGIN": None,
793+
"AFTER_LOGIN": None,
794+
"GET_METADATA_AUTO_CONF_URLS": GET_METADATA_AUTO_CONF_URLS,
795+
},
796+
}
797+
post_request = RequestFactory().post(METADATA_URL1, {"SAMLResponse": "SAML RESPONSE"})
798+
monkeypatch.setattr(
799+
Saml2Client, "parse_authn_request_response", mock_parse_authn_request_response
800+
)
801+
created, mock_user = user.get_or_create_user(
802+
{"username": "[email protected]", "first_name": "John", "last_name": "Doe"}
803+
)
804+
monkeypatch.setattr(user, "get_or_create_user", (created, mock_user))
805+
806+
middleware = SessionMiddleware(MagicMock())
807+
middleware.process_request(post_request)
808+
post_request.session.save()
809+
810+
result = acs(post_request)
811+
assert result.status_code == 302
812+
assert "https://app.example.com/account/login/saml?token=eyJ" in result.url
813+
814+
815+
@pytest.mark.django_db
816+
@responses.activate
817+
def test_acs_view_use_jwt_set_inactive_user(
818+
settings: SettingsWrapper,
819+
monkeypatch: "MonkeyPatch", # type: ignore # noqa: F821
820+
):
821+
"""Test Acs view when USE_JWT is set that inactive users can not log in"""
822+
responses.add(responses.GET, METADATA_URL1, body=METADATA1)
823+
settings.SAML2_AUTH = {
824+
"DEFAULT_NEXT_URL": "default_next_url",
825+
"USE_JWT": True,
826+
"JWT_SECRET": "JWT_SECRET",
827+
"JWT_ALGORITHM": "HS256",
828+
"FRONTEND_URL": "https://app.example.com/account/login/saml",
829+
"TRIGGER": {
830+
"BEFORE_LOGIN": None,
831+
"AFTER_LOGIN": None,
832+
"GET_METADATA_AUTO_CONF_URLS": GET_METADATA_AUTO_CONF_URLS,
833+
},
834+
}
835+
post_request = RequestFactory().post(METADATA_URL1, {"SAMLResponse": "SAML RESPONSE"})
836+
monkeypatch.setattr(
837+
Saml2Client, "parse_authn_request_response", mock_parse_authn_request_response
838+
)
839+
created, mock_user = user.get_or_create_user(
840+
{"username": "[email protected]", "first_name": "John", "last_name": "Doe"}
841+
)
842+
mock_user.is_active = False
843+
mock_user.save()
844+
monkeypatch.setattr(user, "get_or_create_user", (created, mock_user))
845+
846+
middleware = SessionMiddleware(MagicMock())
847+
middleware.process_request(post_request)
848+
post_request.session.save()
849+
850+
result = acs(post_request)
851+
assert result.status_code == 500
852+
assert f"Error code: {INACTIVE_USER}" in result.content.decode()

django_saml2_auth/views.py

+19-18
Original file line numberDiff line numberDiff line change
@@ -149,24 +149,6 @@ def acs(request: HttpRequest):
149149

150150
request.session.flush()
151151

152-
use_jwt = dictor(saml2_auth_settings, "USE_JWT", False)
153-
if use_jwt and target_user.is_active:
154-
# Create a new JWT token for IdP-initiated login (acs)
155-
jwt_token = create_custom_or_default_jwt(target_user)
156-
custom_token_query_trigger = dictor(saml2_auth_settings, "TRIGGER.CUSTOM_TOKEN_QUERY")
157-
if custom_token_query_trigger:
158-
query = run_hook(custom_token_query_trigger, jwt_token)
159-
else:
160-
query = f"?token={jwt_token}"
161-
162-
# Use JWT auth to send token to frontend
163-
frontend_url = dictor(saml2_auth_settings, "FRONTEND_URL", next_url)
164-
custom_frontend_url_trigger = dictor(saml2_auth_settings, "TRIGGER.GET_CUSTOM_FRONTEND_URL")
165-
if custom_frontend_url_trigger:
166-
frontend_url = run_hook(custom_frontend_url_trigger, relay_state) # type: ignore
167-
168-
return HttpResponseRedirect(frontend_url + query)
169-
170152
if target_user.is_active:
171153
# Try to load from the `AUTHENTICATION_BACKENDS` setting in settings.py
172154
if hasattr(settings, "AUTHENTICATION_BACKENDS") and settings.AUTHENTICATION_BACKENDS:
@@ -190,6 +172,25 @@ def acs(request: HttpRequest):
190172
},
191173
)
192174

175+
use_jwt = dictor(saml2_auth_settings, "USE_JWT", False)
176+
if use_jwt:
177+
# Create a new JWT token for IdP-initiated login (acs)
178+
jwt_token = create_custom_or_default_jwt(target_user)
179+
custom_token_query_trigger = dictor(saml2_auth_settings, "TRIGGER.CUSTOM_TOKEN_QUERY")
180+
if custom_token_query_trigger:
181+
query = run_hook(custom_token_query_trigger, jwt_token)
182+
else:
183+
query = f"?token={jwt_token}"
184+
185+
# Use JWT auth to send token to frontend
186+
frontend_url = dictor(saml2_auth_settings, "FRONTEND_URL", next_url)
187+
custom_frontend_url_trigger = dictor(saml2_auth_settings, "TRIGGER.GET_CUSTOM_FRONTEND_URL")
188+
if custom_frontend_url_trigger:
189+
frontend_url = run_hook(custom_frontend_url_trigger, relay_state) # type: ignore
190+
191+
return HttpResponseRedirect(frontend_url + query)
192+
193+
193194
def redirect(redirect_url: Optional[str] = None) -> HttpResponseRedirect:
194195
"""Redirect to the redirect_url or the root page.
195196

0 commit comments

Comments
 (0)