Repository: jazzband/django-axes
Pull request #747 (2021-05-11 22:16:15)

Add AXES_CLIENT_STR_CALLABLE setting
Added new AXES_CLIENT_STR_CALLABLE setting for defining a new client str method due to #739 

codecov[bot]: # [Codecov](https://codecov.io/gh/jazzband/django-axes/pull/747?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=jazzband) Report
> Merging [#747](https://codecov.io/gh/jazzband/django-axes/pull/747?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=jazzband) (66263df) into [master](https://codecov.io/gh/jazzband/django-axes/commit/a9c38d0d0b5d33776f7586e11bd2cd613a9dea95?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=jazzband) (a9c38d0) will **decrease** coverage by `0.41%`.
> The diff coverage is `50.00%`.

[![Impacted file tree graph](https://codecov.io/gh/jazzband/django-axes/pull/747/graphs/tree.svg?width=650&height=150&src=pr&token=gcIvl2ZfVI&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=jazzband)](https://codecov.io/gh/jazzband/django-axes/pull/747?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=jazzband)

```diff
@@            Coverage Diff             @@
##           master     #747      +/-   ##
==========================================
- Coverage   97.93%   97.52%   -0.42%     
==========================================
  Files          31       31              
  Lines         920      928       +8     
  Branches      125      128       +3     
==========================================
+ Hits          901      905       +4     
- Misses         16       18       +2     
- Partials        3        5       +2     
```


| [Impacted Files](https://codecov.io/gh/jazzband/django-axes/pull/747?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=jazzband) | Coverage Δ | |
|---|---|---|
| [axes/helpers.py](https://codecov.io/gh/jazzband/django-axes/pull/747/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=jazzband#diff-YXhlcy9oZWxwZXJzLnB5) | `97.18% <42.85%> (-1.85%)` | :arrow_down: |
| [axes/conf.py](https://codecov.io/gh/jazzband/django-axes/pull/747/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=jazzband#diff-YXhlcy9jb25mLnB5) | `100.00% <100.00%> (ø)` | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/jazzband/django-axes/pull/747?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=jazzband).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=jazzband)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/jazzband/django-axes/pull/747?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=jazzband). Last update [a9c38d0...66263df](https://codecov.io/gh/jazzband/django-axes/pull/747?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=jazzband). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=jazzband).

aleksihakli: Thank you for the PR and feature @smtydn!

Patch:
diff --git a/axes/conf.py b/axes/conf.py
index d2ffe65..4747f1b 100644
--- a/axes/conf.py
+++ b/axes/conf.py
@@ -125,3 +125,7 @@ settings.AXES_SENSITIVE_PARAMETERS = getattr(
     "AXES_SENSITIVE_PARAMETERS",
     [],
 )
+
+# set the callable for the readable string that can be used in
+# e.g. logging to distinguish client requests
+settings.AXES_CLIENT_STR_CALLABLE = getattr(settings, "AXES_CLIENT_STR_CALLABLE", None)
diff --git a/axes/helpers.py b/axes/helpers.py
index d92a80e..dff7f18 100644
--- a/axes/helpers.py
+++ b/axes/helpers.py
@@ -250,6 +250,21 @@ def get_client_str(
     ``{username: "example", ip_address: "127.0.0.1", path_info: "/example/"}``
     """
 
+    if settings.AXES_CLIENT_STR_CALLABLE:
+        log.debug("Using settings.AXES_CLIENT_STR_CALLABLE to get client string.")
+
+        if callable(settings.AXES_CLIENT_STR_CALLABLE):
+            return settings.AXES_CLIENT_STR_CALLABLE(
+                username, ip_address, user_agent, path_info
+            )
+        if isinstance(settings.AXES_CLIENT_STR_CALLABLE, str):
+            return import_string(settings.AXES_CLIENT_STR_CALLABLE)(
+                username, ip_address, user_agent, path_info
+            )
+        raise TypeError(
+            "settings.AXES_CLIENT_STR_CALLABLE needs to be a string, callable or None."
+        )
+
     client_dict = dict()
 
     if settings.AXES_VERBOSE:


Test patch:
diff --git a/tests/test_helpers.py b/tests/test_helpers.py
index 14cb557..d2f02af 100644
--- a/tests/test_helpers.py
+++ b/tests/test_helpers.py
@@ -225,6 +225,16 @@ class ClientStringTestCase(AxesTestCase):
 
         self.assertEqual(expected, actual)
 
+    @override_settings(AXES_CLIENT_STR_CALLABLE="tests.test_helpers.get_dummy_client_str")
+    def test_get_client_str_callable(self):
+        self.assertEqual(
+            get_client_str("username", "ip_address", "user_agent", "path_info"),
+            "client string"
+        )
+
+def get_dummy_client_str(username, ip_address, user_agent, path_info):
+    return "client string"
+
 
 class ClientParametersTestCase(AxesTestCase):
     @override_settings(AXES_ONLY_USER_FAILURES=True)