diff --git a/accounts/apps.py b/accounts/apps.py index aae08f0..0c695dd 100644 --- a/accounts/apps.py +++ b/accounts/apps.py @@ -1,11 +1,18 @@ from django.apps import AppConfig from django.conf import settings from django.contrib.auth import signals +from django.db.models.signals import post_save from django.utils.text import capfirst from django.utils.translation import gettext_lazy as _ -def add_user_to_projects(sender, user, **kwargs): +def _on_user_logged_in(sender, user, **kwargs): + event_model = user.events.model + event_model.objects.create( + user=user, + action=event_model.Action.USER_LOGGED_IN, + ) + project_model = user.projects.model domain = user.email.rsplit("@")[-1] if domain in settings.STAFF_EMAIL_DOMAINS: @@ -18,6 +25,20 @@ def add_user_to_projects(sender, user, **kwargs): ).exclude(users=user): if domain in project.email_domains: project.users.add(user) + event_model.objects.create( + user=user, + action=event_model.Action.PROJECT_ACCESS_GRANTED, + project=project, + ) + + +def _on_user_post_save(sender, instance, created, **kwargs): + if created: + event_model = instance.events.model + event_model.objects.create( + user=instance, + action=event_model.Action.USER_CREATED, + ) class AccountsConfig(AppConfig): @@ -26,4 +47,5 @@ class AccountsConfig(AppConfig): verbose_name = capfirst(_("Authentication")) def ready(self): - signals.user_logged_in.connect(add_user_to_projects) + signals.user_logged_in.connect(_on_user_logged_in) + post_save.connect(_on_user_post_save, sender=self.get_model("user")) diff --git a/projects/apps.py b/projects/apps.py index 572ee0e..7b256d2 100644 --- a/projects/apps.py +++ b/projects/apps.py @@ -1,9 +1,22 @@ from django.apps import AppConfig +from django.db.models.signals import post_save from django.utils.text import capfirst from django.utils.translation import gettext_lazy as _ +def _on_project_post_save(sender, instance, created, **kwargs): + if created: + event_model = instance.events.model + event_model.objects.create( + project=instance, + action=event_model.Action.PROJECT_CREATED, + ) + + class ProjectsConfig(AppConfig): default_auto_field = "django.db.models.BigAutoField" name = "projects" verbose_name = capfirst(_("projects")) + + def ready(self): + post_save.connect(_on_project_post_save, sender=self.get_model("project")) diff --git a/projects/migrations/0005_alter_event_action_alter_event_created_at.py b/projects/migrations/0005_alter_event_action_alter_event_created_at.py new file mode 100644 index 0000000..37d52d6 --- /dev/null +++ b/projects/migrations/0005_alter_event_action_alter_event_created_at.py @@ -0,0 +1,36 @@ +# Generated by Django 5.1b1 on 2024-07-18 17:23 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("projects", "0004_event"), + ] + + operations = [ + migrations.AlterField( + model_name="event", + name="action", + field=models.CharField( + choices=[ + ("user-logged-in", "user logged in"), + ("project-access-granted", "project access granted"), + ("catalog-created", "created catalog"), + ("catalog-updated", "updated catalog"), + ("catalog-submitted", "submitted catalog"), + ("catalog-replaced", "replaced catalog"), + ("catalog-deleted", "deleted catalog"), + ], + max_length=40, + verbose_name="action", + ), + ), + migrations.AlterField( + model_name="event", + name="created_at", + field=models.DateTimeField( + auto_now_add=True, db_index=True, verbose_name="created at" + ), + ), + ] diff --git a/projects/models.py b/projects/models.py index f0e1d2d..f928d57 100644 --- a/projects/models.py +++ b/projects/models.py @@ -170,13 +170,17 @@ def po(self): class Event(models.Model): class Action(models.TextChoices): + USER_CREATED = "user-created", _("user created") + USER_LOGGED_IN = "user-logged-in", _("user logged in") + PROJECT_CREATED = "project-created", _("created project") + PROJECT_ACCESS_GRANTED = "project-access-granted", _("project access granted") CATALOG_CREATED = "catalog-created", _("created catalog") CATALOG_UPDATED = "catalog-updated", _("updated catalog") CATALOG_SUBMITTED = "catalog-submitted", _("submitted catalog") CATALOG_REPLACED = "catalog-replaced", _("replaced catalog") CATALOG_DELETED = "catalog-deleted", _("deleted catalog") - created_at = models.DateTimeField(_("created at"), auto_now_add=True) + created_at = models.DateTimeField(_("created at"), auto_now_add=True, db_index=True) user = models.ForeignKey( settings.AUTH_USER_MODEL, blank=True, @@ -185,7 +189,7 @@ class Action(models.TextChoices): related_name="events", verbose_name=_("user"), ) - action = models.CharField(_("action"), max_length=20, choices=Action) + action = models.CharField(_("action"), max_length=40, choices=Action) project = models.ForeignKey( Project, diff --git a/projects/test_views.py b/projects/test_views.py index aaa6f2c..196412a 100644 --- a/projects/test_views.py +++ b/projects/test_views.py @@ -447,12 +447,7 @@ def test_fix_nls(self): def test_event_save(self): user = User.objects.create_superuser("admin@example.com", "admin") - p = Project.objects.create(name="test", slug="test") - c = p.catalogs.create( - language_code="fr", - domain="djangojs", - pofile="", - ) + p, c = self.create_project_and_catalog() p2 = Project.objects.create(name="test2", slug="test2") @@ -484,3 +479,24 @@ def test_event_save(self): project=p2, ) self.assertEqual(str(e), "created catalog") + + self.assertEqual( + list(Event.objects.values_list("action", flat=True)), + [ + "catalog-created", + "catalog-created", + "catalog-created", + "catalog-created", + "project-created", + "project-created", + "user-created", + ], + ) + + def test_event_log(self): + self.create_project_and_catalog() + + self.assertEqual( + list(Event.objects.values_list("action", flat=True)), + ["project-created"], + )