Skip to content

Commit df32f5f

Browse files
authored
[feat] Implement a setting to disable the exception handler. (#345)
* [FEAT] Implement a setting to disable the exception handler. * Some fixes and improvements
1 parent cba317c commit df32f5f

File tree

4 files changed

+40
-3
lines changed

4 files changed

+40
-3
lines changed

AUTHORS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,4 @@ an issue.
6060
- [Greg Wong](https://github.com/gregorywong)
6161
- [Michael V. Battista](https://github.com/mvbattista)
6262
- [William Abbott](https://github.com/wrabit)
63+
- [Henry Harutyunyan](https://github.com/henryh9n) (Revolut)

README.md

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ python setup.py install
207207
'ACCEPTED_TIME_DIFF': None, # Accepted time difference between your server and the Identity Provider
208208
'ALLOWED_REDIRECT_HOSTS': ["https://myfrontendclient.com"], # Allowed hosts to redirect to using the ?next parameter
209209
'TOKEN_REQUIRED': True, # Whether or not to require the token parameter in the SAML assertion
210+
'DISABLE_EXCEPTION_HANDLER': True, # Whether the custom exception handler should be used
210211
}
211212

212213
```
@@ -231,7 +232,7 @@ Some of the following settings are related to how this module operates. The rest
231232
<summary>Click to see the module settings</summary>
232233

233234
| **Field name** | **Description** | **Data type(s)** | **Default value(s)** | **Example** |
234-
| ------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
235+
|---------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------|------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------|
235236
| **METADATA\_AUTO\_CONF\_URL** | Auto SAML2 metadata configuration URL | `str` | `None` | `https://ORG.okta.com/app/APP-ID/sso/saml/metadata` |
236237
| **METADATA\_LOCAL\_FILE\_PATH** | SAML2 metadata configuration file path | `str` | `None` | `/path/to/the/metadata.xml` |
237238
| **KEY_FILE** | SAML2 private key file path. Required for AUTHN\_REQUESTS\_SIGNED | `str` | `None` | `/path/to/the/key.pem` |
@@ -273,6 +274,7 @@ Some of the following settings are related to how this module operates. The rest
273274
| **WANT\_RESPONSE\_SIGNED** | Set this to `False` if you don't want your provider to sign the response. | `bool` | `True` | |
274275
| **ACCEPTED\_TIME\_DIFF** | Sets the [accepted time diff](https://pysaml2.readthedocs.io/en/latest/howto/config.html#accepted-time-diff) in seconds | `int` or `None` | `None` | |
275276
| **ALLOWED\_REDIRECT\_HOSTS** | Allowed hosts to redirect to using the `?next=` parameter | `list` | `[]` | `['https://app.example.com', 'https://api.exmaple.com']` |
277+
| **DISABLE\_EXCEPTION\_HANDLER** | Set this to `True` if you want to disable the exception handler. Make sure to handle the `SAMLAuthError`s and other exceptions. | `bool` | `False` | |
276278

277279
### Triggers
278280

@@ -349,11 +351,21 @@ def get_custom_token_query(refresh):
349351

350352
```
351353

352-
## Customize Error Messages
354+
## Exception Handling
355+
This library implements an exception handler that returns an error response with a default error template. See the
356+
section below if you want to implement a custom error template.
357+
358+
If you want to disable error handling, set `DISABLE_EXCEPTION_HANDLER` to `True`. In this case the library will raise
359+
`SAMLAuthError` when an error happens and you might need to implement an exception handler. This might come in handy if
360+
you are using the library for an API.
361+
362+
## Customize Error Messages and Templates
353363

354364
The default permission `denied`, `error` and user `welcome` page can be overridden.
355365

356366
To override these pages put a template named 'django\_saml2\_auth/error.html', 'django\_saml2\_auth/welcome.html' or 'django\_saml2\_auth/denied.html' in your project's template folder.
367+
> [!Note]
368+
> If you set `DISABLE_EXCEPTION_HANDLER` to `True`, the custom error pages will not be displayed.
357369

358370
If a 'django\_saml2\_auth/welcome.html' template exists, that page will be shown to the user upon login instead of the user being redirected to the previous visited page. This welcome page can contain some first-visit notes and welcome words. The [Django user object](https://docs.djangoproject.com/en/1.9/ref/contrib/auth/#django.contrib.auth.models.User) is available within the template as the `user` template variable.
359371

django_saml2_auth/tests/test_utils.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
import pytest
66
from django.http import HttpRequest, HttpResponse
77
from django.urls import NoReverseMatch
8+
from pytest_django.fixtures import SettingsWrapper
9+
810
from django_saml2_auth.exceptions import SAMLAuthError
911
from django_saml2_auth.utils import (
1012
exception_handler,
@@ -39,7 +41,7 @@ def hello(_: HttpRequest) -> HttpResponse:
3941
return HttpResponse(content="Hello, world!")
4042

4143

42-
def goodbye(_: HttpRequest) -> None:
44+
def goodbye(_: HttpRequest) -> HttpResponse:
4345
"""Simple view function for testing exception_handler
4446
4547
Args:
@@ -139,6 +141,25 @@ def test_exception_handler_handle_exception():
139141
assert "Reason: Internal world error!" in contents
140142

141143

144+
def test_exception_handler_diabled_success(settings: SettingsWrapper):
145+
"""Test exception_handler decorator in disabled state with a valid function."""
146+
settings.SAML2_AUTH["DISABLE_EXCEPTION_HANDLER"] = True
147+
148+
decorated_hello = exception_handler(hello)
149+
result = decorated_hello(HttpRequest())
150+
assert result.content.decode("utf-8") == "Hello, world!"
151+
152+
153+
def test_exception_handler_disabled_on_exception(settings: SettingsWrapper):
154+
"""Test exception_handler decorator in a disabled state to make sure it raises the
155+
exception."""
156+
settings.SAML2_AUTH["DISABLE_EXCEPTION_HANDLER"] = True
157+
158+
decorated_goodbye = exception_handler(goodbye)
159+
with pytest.raises(SAMLAuthError):
160+
decorated_goodbye(HttpRequest())
161+
162+
142163
def test_jwt_well_formed():
143164
"""Test if passed RelayState is a well formed JWT"""
144165
token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiI0MjQyIiwibmFtZSI6Ikplc3NpY2EgVGVtcG9yYWwiLCJuaWNrbmFtZSI6Ikplc3MifQ.EDkUUxaM439gWLsQ8a8mJWIvQtgZe0et3O3z4Fd_J8o" # noqa

django_saml2_auth/utils.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,9 @@ def exception_handler(
166166
Decorated view function with exception handling
167167
"""
168168

169+
if dictor(settings.SAML2_AUTH, "DISABLE_EXCEPTION_HANDLER", False):
170+
return function
171+
169172
def handle_exception(exc: Exception, request: HttpRequest) -> HttpResponse:
170173
"""Render page with exception details
171174

0 commit comments

Comments
 (0)