Skip to content

Commit 9fb0dae

Browse files
🐛 Robustify create_user to handle None value (#13572)
* 🐛 Robustify create_user to handle None value * fix * update * update according to review
1 parent d1e0dca commit 9fb0dae

4 files changed

Lines changed: 19 additions & 1 deletion

File tree

dojo/middleware.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,11 @@ def process_exception(self, request, exception):
9494
if isinstance(exception, AuthForbidden):
9595
messages.error(request, "You are not authorized to log in via this method. Please contact support or use the standard login.")
9696
return redirect("/login?force_login_form")
97+
if isinstance(exception, TypeError) and "'NoneType' object is not iterable" in str(exception):
98+
logger.warning("OIDC login error: NoneType is not iterable")
99+
messages.error(request, "An unexpected error occurred during social login. Please use the standard login.")
100+
return redirect("/login?force_login_form")
101+
logger.error(f"Unhandled exception during social login: {exception}")
97102
return super().process_exception(request, exception)
98103

99104

dojo/pipeline.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,5 +183,6 @@ def sanitize_username(username):
183183
def create_user(strategy, details, backend, user=None, *args, **kwargs):
184184
if not settings.SOCIAL_AUTH_CREATE_USER:
185185
return None
186-
details["username"] = sanitize_username(details.get("username"))
186+
username = details.get(settings.SOCIAL_AUTH_CREATE_USER_MAPPING)
187+
details["username"] = sanitize_username(username)
187188
return social_core.pipeline.user.create_user(strategy, details, backend, user, args, kwargs)

dojo/settings/settings.dist.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@
113113
DD_FORGOT_USERNAME=(bool, True), # do we show link "I forgot my username" on login screen
114114
DD_SOCIAL_AUTH_SHOW_LOGIN_FORM=(bool, True), # do we show user/pass input
115115
DD_SOCIAL_AUTH_CREATE_USER=(bool, True), # if True creates user at first login
116+
DD_SOCIAL_AUTH_CREATE_USER_MAPPING=(str, "username"), # could also be email or fullname
116117
DD_SOCIAL_LOGIN_AUTO_REDIRECT=(bool, False), # auto-redirect if there is only one social login method
117118
DD_SOCIAL_AUTH_TRAILING_SLASH=(bool, True),
118119
DD_SOCIAL_AUTH_OIDC_AUTH_ENABLED=(bool, False),
@@ -574,6 +575,7 @@ def generate_url(scheme, double_slashes, user, password, host, port, path, param
574575
SHOW_LOGIN_FORM = env("DD_SOCIAL_AUTH_SHOW_LOGIN_FORM")
575576
SOCIAL_LOGIN_AUTO_REDIRECT = env("DD_SOCIAL_LOGIN_AUTO_REDIRECT")
576577
SOCIAL_AUTH_CREATE_USER = env("DD_SOCIAL_AUTH_CREATE_USER")
578+
SOCIAL_AUTH_CREATE_USER_MAPPING = env("DD_SOCIAL_AUTH_CREATE_USER_MAPPING")
577579

578580
SOCIAL_AUTH_STRATEGY = "social_django.strategy.DjangoStrategy"
579581
SOCIAL_AUTH_STORAGE = "social_django.models.DjangoStorage"

unittests/test_social_auth_failure_handling.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,16 @@ def test_non_social_auth_path_redirects_on_auth_forbidden(self):
8383
storage = list(messages.get_messages(request))
8484
self.assertTrue(any("You are not authorized to log in via this method." in str(msg) for msg in storage))
8585

86+
def test_type_error_none_type_iterable_redirect(self):
87+
"""Ensure middleware catches 'NoneType' object is not iterable TypeError and redirects."""
88+
request = self._prepare_request("/login/oidc/")
89+
exception = TypeError("'NoneType' object is not iterable")
90+
response = self.middleware.process_exception(request, exception)
91+
self.assertEqual(response.status_code, 302)
92+
self.assertEqual(response.url, "/login?force_login_form")
93+
storage = list(messages.get_messages(request))
94+
self.assertTrue(any("An unexpected error occurred during social login." in str(msg) for msg in storage))
95+
8696

8797
@override_settings(
8898
AUTHENTICATION_BACKENDS=(

0 commit comments

Comments
 (0)