2024-03-31 00:37:39 +00:00
|
|
|
from django.conf import settings
|
2023-01-04 14:05:32 +00:00
|
|
|
from django.contrib.auth import get_user_model
|
2014-02-07 19:59:16 +00:00
|
|
|
|
2022-12-23 14:09:32 +00:00
|
|
|
from auditlog.cid import set_cid
|
2025-11-19 08:46:43 +00:00
|
|
|
from auditlog.context import set_extra_data
|
2016-08-17 20:45:02 +00:00
|
|
|
|
2013-10-20 13:25:48 +00:00
|
|
|
|
2022-05-24 07:33:54 +00:00
|
|
|
class AuditlogMiddleware:
|
2013-10-20 13:25:48 +00:00
|
|
|
"""
|
2022-06-18 16:20:25 +00:00
|
|
|
Middleware to couple the request's user to log items. This is accomplished by currying the
|
|
|
|
|
signal receiver with the user from the request (or None if the user is not authenticated).
|
2013-10-20 13:25:48 +00:00
|
|
|
"""
|
|
|
|
|
|
2022-05-24 07:33:54 +00:00
|
|
|
def __init__(self, get_response=None):
|
|
|
|
|
self.get_response = get_response
|
2024-03-31 00:37:39 +00:00
|
|
|
if not isinstance(settings.AUDITLOG_DISABLE_REMOTE_ADDR, bool):
|
|
|
|
|
raise TypeError("Setting 'AUDITLOG_DISABLE_REMOTE_ADDR' must be a boolean")
|
2022-05-24 07:33:54 +00:00
|
|
|
|
2022-08-16 21:29:45 +00:00
|
|
|
@staticmethod
|
|
|
|
|
def _get_remote_addr(request):
|
2024-03-31 00:37:39 +00:00
|
|
|
if settings.AUDITLOG_DISABLE_REMOTE_ADDR:
|
|
|
|
|
return None
|
|
|
|
|
|
2022-11-22 07:44:59 +00:00
|
|
|
# In case there is no proxy, return the original address
|
|
|
|
|
if not request.headers.get("X-Forwarded-For"):
|
2022-08-16 21:29:45 +00:00
|
|
|
return request.META.get("REMOTE_ADDR")
|
|
|
|
|
|
2022-11-22 07:44:59 +00:00
|
|
|
# In case of proxy, set 'original' address
|
|
|
|
|
remote_addr: str = request.headers.get("X-Forwarded-For").split(",")[0]
|
|
|
|
|
|
|
|
|
|
# Remove port number from remote_addr
|
|
|
|
|
if "." in remote_addr and ":" in remote_addr: # IPv4 with port (`x.x.x.x:x`)
|
|
|
|
|
remote_addr = remote_addr.split(":")[0]
|
|
|
|
|
elif "[" in remote_addr: # IPv6 with port (`[:::]:x`)
|
|
|
|
|
remote_addr = remote_addr[1:].split("]")[0]
|
|
|
|
|
|
|
|
|
|
return remote_addr
|
|
|
|
|
|
2024-10-07 13:52:34 +00:00
|
|
|
@staticmethod
|
2025-10-17 15:51:53 +00:00
|
|
|
def _get_remote_port(request) -> int | None:
|
2024-10-07 13:52:34 +00:00
|
|
|
remote_port = request.headers.get("X-Forwarded-Port", "")
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
remote_port = int(remote_port)
|
|
|
|
|
except ValueError:
|
|
|
|
|
remote_port = None
|
|
|
|
|
|
|
|
|
|
return remote_port
|
|
|
|
|
|
2023-01-04 14:05:32 +00:00
|
|
|
@staticmethod
|
|
|
|
|
def _get_actor(request):
|
|
|
|
|
user = getattr(request, "user", None)
|
|
|
|
|
if isinstance(user, get_user_model()) and user.is_authenticated:
|
|
|
|
|
return user
|
|
|
|
|
return None
|
|
|
|
|
|
2025-11-19 08:46:43 +00:00
|
|
|
def get_extra_data(self, request):
|
|
|
|
|
context_data = {}
|
|
|
|
|
context_data["remote_addr"] = self._get_remote_addr(request)
|
|
|
|
|
context_data["remote_port"] = self._get_remote_port(request)
|
|
|
|
|
|
|
|
|
|
context_data["actor"] = self._get_actor(request)
|
2015-06-03 14:29:40 +00:00
|
|
|
|
2025-11-19 08:46:43 +00:00
|
|
|
return context_data
|
|
|
|
|
|
|
|
|
|
def __call__(self, request):
|
2022-12-23 14:09:32 +00:00
|
|
|
set_cid(request)
|
|
|
|
|
|
2025-11-19 08:46:43 +00:00
|
|
|
with set_extra_data(context_data=self.get_extra_data(request)):
|
2022-05-24 07:33:54 +00:00
|
|
|
return self.get_response(request)
|