From 61a25d90f42316f778f75a14750748a6c9777a21 Mon Sep 17 00:00:00 2001 From: hamed Date: Wed, 1 Nov 2023 14:33:24 +0300 Subject: [PATCH] add actor email --- CHANGELOG.md | 1 + auditlog/context.py | 7 ++++++- auditlog/migrations/0017_add_actor_email.py | 20 ++++++++++++++++++++ auditlog/models.py | 1 + auditlog_tests/tests.py | 6 ++++++ 5 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 auditlog/migrations/0017_add_actor_email.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e9cfe0c..21ed9081 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ #### Improvements +- feat: Added 'LogEntry.actor_email` field. ([#641](https://github.com/jazzband/django-auditlog/pull/641)) - Add Python 3.13 support. ([#671](https://github.com/jazzband/django-auditlog/pull/671)) - feat: Added `LogEntry.remote_port` field. ([#671](https://github.com/jazzband/django-auditlog/pull/671)) - feat: Added `truncate` option to `auditlogflush` management command. ([#681](https://github.com/jazzband/django-auditlog/pull/681)) diff --git a/auditlog/context.py b/auditlog/context.py index ecb034c7..a5f916c3 100644 --- a/auditlog/context.py +++ b/auditlog/context.py @@ -24,7 +24,11 @@ def set_actor(actor, remote_addr=None, remote_port=None): auditlog_value.set(context_data) # Connect signal for automatic logging - set_actor = partial(_set_actor, user=actor, signal_duid=context_data["signal_duid"]) + set_actor = partial( + _set_actor, + user=actor, + signal_duid=context_data["signal_duid"], + ) pre_save.connect( set_actor, sender=LogEntry, @@ -62,6 +66,7 @@ def _set_actor(user, sender, instance, signal_duid, **kwargs): and instance.actor is None ): instance.actor = user + instance.actor_email = hasattr(user, "email") and user.email or None instance.remote_addr = auditlog["remote_addr"] instance.remote_port = auditlog["remote_port"] diff --git a/auditlog/migrations/0017_add_actor_email.py b/auditlog/migrations/0017_add_actor_email.py new file mode 100644 index 00000000..2ed96bde --- /dev/null +++ b/auditlog/migrations/0017_add_actor_email.py @@ -0,0 +1,20 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("auditlog", "0016_logentry_remote_port"), + ] + + operations = [ + migrations.AddField( + model_name="logentry", + name="actor_email", + field=models.CharField( + null=True, + verbose_name="actor email", + blank=True, + max_length=254, + ), + ), + ] diff --git a/auditlog/models.py b/auditlog/models.py index 49e7aba6..45e0d7f0 100644 --- a/auditlog/models.py +++ b/auditlog/models.py @@ -384,6 +384,7 @@ class Action: additional_data = models.JSONField( blank=True, null=True, verbose_name=_("additional data") ) + actor_email = models.CharField(blank=True, null=True, max_length=254) objects = LogEntryManager() diff --git a/auditlog_tests/tests.py b/auditlog_tests/tests.py index f043de01..53e9f361 100644 --- a/auditlog_tests/tests.py +++ b/auditlog_tests/tests.py @@ -262,7 +262,10 @@ def setUp(self): super().setUp() def tearDown(self): + user_email = self.user.email self.user.delete() + auditlog_entries = LogEntry.objects.filter(actor_email=user_email).all() + self.assertIsNotNone(auditlog_entries, msg="All auditlog entries are deleted.") super().tearDown() def make_object(self): @@ -272,6 +275,7 @@ def make_object(self): def check_create_log_entry(self, obj, log_entry): super().check_create_log_entry(obj, log_entry) self.assertEqual(log_entry.actor, self.user) + self.assertEqual(log_entry.actor_email, self.user.email) def update(self, obj): with set_actor(self.user): @@ -280,6 +284,7 @@ def update(self, obj): def check_update_log_entry(self, obj, log_entry): super().check_update_log_entry(obj, log_entry) self.assertEqual(log_entry.actor, self.user) + self.assertEqual(log_entry.actor_email, self.user.email) def delete(self, obj): with set_actor(self.user): @@ -288,6 +293,7 @@ def delete(self, obj): def check_delete_log_entry(self, obj, log_entry): super().check_delete_log_entry(obj, log_entry) self.assertEqual(log_entry.actor, self.user) + self.assertEqual(log_entry.actor_email, self.user.email) class AltPrimaryKeyModelBase(SimpleModelTest):