diff --git a/axes/tests/test_utils.py b/axes/tests/test_utils.py index ff895d2..2b5f4d3 100644 --- a/axes/tests/test_utils.py +++ b/axes/tests/test_utils.py @@ -245,6 +245,18 @@ class UtilsTestCase(TestCase): with self.assertRaises(TypeError): get_client_username(HttpRequest(), {}) + @override_settings(AXES_USERNAME_CALLABLE=True) + def test_get_client_username_not_callable(self): + with self.assertRaises(TypeError): + get_client_username(HttpRequest(), {}) + + @override_settings(AXES_USERNAME_CALLABLE='axes.tests.test_utils.get_username') + def test_get_client_username_str(self): + self.assertEqual( + get_client_username(HttpRequest(), {}), + 'username', + ) + class LockoutResponseTestCase(TestCase): def setUp(self): diff --git a/axes/utils.py b/axes/utils.py index 28daab0..1fc4b7f 100644 --- a/axes/utils.py +++ b/axes/utils.py @@ -6,6 +6,7 @@ from socket import error, inet_pton, AF_INET6 from django.core.cache import caches, BaseCache from django.http import HttpResponse, HttpResponseRedirect, HttpRequest, JsonResponse from django.shortcuts import render +from django.utils.module_loading import import_string import ipware.ip2 @@ -85,14 +86,19 @@ def get_client_username(request: HttpRequest, credentials: dict = None) -> str: """ if settings.AXES_USERNAME_CALLABLE: - logger.debug('Using AXES_USERNAME_CALLABLE to get username') - return settings.AXES_USERNAME_CALLABLE(request, credentials) + logger.debug('Using settings.AXES_USERNAME_CALLABLE to get username') + + if callable(settings.AXES_USERNAME_CALLABLE): + return settings.AXES_USERNAME_CALLABLE(request, credentials) + if isinstance(settings.AXES_USERNAME_CALLABLE, str): + return import_string(settings.AXES_USERNAME_CALLABLE)(request, credentials) + raise TypeError('settings.AXES_USERNAME_CALLABLE needs to be a string, callable, or None.') if credentials: - logger.debug('Using `credentials` to get username with key AXES_USERNAME_FORM_FIELD') + logger.debug('Using parameter credentials to get username with key settings.AXES_USERNAME_FORM_FIELD') return credentials.get(settings.AXES_USERNAME_FORM_FIELD, None) - logger.debug('Using `request.POST` to get username with key AXES_USERNAME_FORM_FIELD') + logger.debug('Using parameter request.POST to get username with key settings.AXES_USERNAME_FORM_FIELD') return request.POST.get(settings.AXES_USERNAME_FORM_FIELD, None)