mirror of
https://github.com/jazzband/django-auditlog.git
synced 2026-03-16 22:20:26 +00:00
Added remote port (#671)
This commit is contained in:
parent
22dcbc4d06
commit
4c3ee0b36d
7 changed files with 56 additions and 3 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -80,3 +80,4 @@ venv.bak/
|
|||
|
||||
### JetBrains
|
||||
.idea/
|
||||
.vscode/
|
||||
|
|
|
|||
|
|
@ -2,6 +2,9 @@
|
|||
|
||||
## Next Release
|
||||
|
||||
#### Improvements
|
||||
- feat: Added `LogEntry.remote_port` field. ([#671](https://github.com/jazzband/django-auditlog/pull/671))
|
||||
|
||||
#### Fixes
|
||||
|
||||
- Fixed a problem when setting `Value(None)` in `JSONField` ([#646](https://github.com/jazzband/django-auditlog/pull/646))
|
||||
|
|
|
|||
|
|
@ -13,12 +13,13 @@ auditlog_disabled = ContextVar("auditlog_disabled", default=False)
|
|||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def set_actor(actor, remote_addr=None):
|
||||
def set_actor(actor, remote_addr=None, remote_port=None):
|
||||
"""Connect a signal receiver with current user attached."""
|
||||
# Initialize thread local storage
|
||||
context_data = {
|
||||
"signal_duid": ("set_actor", time.time()),
|
||||
"remote_addr": remote_addr,
|
||||
"remote_port": remote_port,
|
||||
}
|
||||
auditlog_value.set(context_data)
|
||||
|
||||
|
|
@ -63,6 +64,7 @@ def _set_actor(user, sender, instance, signal_duid, **kwargs):
|
|||
instance.actor = user
|
||||
|
||||
instance.remote_addr = auditlog["remote_addr"]
|
||||
instance.remote_port = auditlog["remote_port"]
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
from typing import Optional
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib.auth import get_user_model
|
||||
|
||||
|
|
@ -36,6 +38,17 @@ class AuditlogMiddleware:
|
|||
|
||||
return remote_addr
|
||||
|
||||
@staticmethod
|
||||
def _get_remote_port(request) -> Optional[int]:
|
||||
remote_port = request.headers.get("X-Forwarded-Port", "")
|
||||
|
||||
try:
|
||||
remote_port = int(remote_port)
|
||||
except ValueError:
|
||||
remote_port = None
|
||||
|
||||
return remote_port
|
||||
|
||||
@staticmethod
|
||||
def _get_actor(request):
|
||||
user = getattr(request, "user", None)
|
||||
|
|
@ -45,9 +58,10 @@ class AuditlogMiddleware:
|
|||
|
||||
def __call__(self, request):
|
||||
remote_addr = self._get_remote_addr(request)
|
||||
remote_port = self._get_remote_port(request)
|
||||
user = self._get_actor(request)
|
||||
|
||||
set_cid(request)
|
||||
|
||||
with set_actor(actor=user, remote_addr=remote_addr):
|
||||
with set_actor(actor=user, remote_addr=remote_addr, remote_port=remote_port):
|
||||
return self.get_response(request)
|
||||
|
|
|
|||
17
auditlog/migrations/0016_logentry_remote_port.py
Normal file
17
auditlog/migrations/0016_logentry_remote_port.py
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
("auditlog", "0015_alter_logentry_changes"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="logentry",
|
||||
name="remote_port",
|
||||
field=models.PositiveIntegerField(
|
||||
blank=True, null=True, verbose_name="remote port"
|
||||
),
|
||||
),
|
||||
]
|
||||
|
|
@ -373,6 +373,9 @@ class LogEntry(models.Model):
|
|||
remote_addr = models.GenericIPAddressField(
|
||||
blank=True, null=True, verbose_name=_("remote address")
|
||||
)
|
||||
remote_port = models.PositiveIntegerField(
|
||||
blank=True, null=True, verbose_name=_("remote port")
|
||||
)
|
||||
timestamp = models.DateTimeField(
|
||||
default=django_timezone.now,
|
||||
db_index=True,
|
||||
|
|
|
|||
|
|
@ -585,6 +585,13 @@ class MiddlewareTest(TestCase):
|
|||
self.middleware._get_remote_addr(request), expected_remote_addr
|
||||
)
|
||||
|
||||
def test_get_remote_port(self):
|
||||
headers = {
|
||||
"HTTP_X_FORWARDED_PORT": "12345",
|
||||
}
|
||||
request = self.factory.get("/", **headers)
|
||||
self.assertEqual(self.middleware._get_remote_port(request), 12345)
|
||||
|
||||
def test_cid(self):
|
||||
header = str(settings.AUDITLOG_CID_HEADER).lstrip("HTTP_").replace("_", "-")
|
||||
header_meta = "HTTP_" + header.upper().replace("-", "_")
|
||||
|
|
@ -622,9 +629,10 @@ class MiddlewareTest(TestCase):
|
|||
The remote address will be set even when there is no actor
|
||||
"""
|
||||
remote_addr = "123.213.145.99"
|
||||
remote_port = 12345
|
||||
actor = None
|
||||
|
||||
with set_actor(actor=actor, remote_addr=remote_addr):
|
||||
with set_actor(actor=actor, remote_addr=remote_addr, remote_port=remote_port):
|
||||
obj = SimpleModel.objects.create(text="I am not difficult.")
|
||||
|
||||
history = obj.history.get()
|
||||
|
|
@ -633,6 +641,11 @@ class MiddlewareTest(TestCase):
|
|||
remote_addr,
|
||||
msg=f"Remote address is {remote_addr}",
|
||||
)
|
||||
self.assertEqual(
|
||||
history.remote_port,
|
||||
remote_port,
|
||||
msg=f"Remote port is {remote_port}",
|
||||
)
|
||||
self.assertIsNone(history.actor, msg="Actor is `None` for anonymous user")
|
||||
|
||||
def test_get_actor(self):
|
||||
|
|
|
|||
Loading…
Reference in a new issue