From b5bac68f907b126e2d3c25758eb57ee517463767 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Dlouh=C3=BD?= Date: Mon, 13 Sep 2021 17:35:56 +0200 Subject: [PATCH] fix duplicated AccessAttempts --- ...007_alter_accessattempt_unique_together.py | 38 +++++++++++++++++++ axes/models.py | 1 + 2 files changed, 39 insertions(+) create mode 100644 axes/migrations/0007_alter_accessattempt_unique_together.py diff --git a/axes/migrations/0007_alter_accessattempt_unique_together.py b/axes/migrations/0007_alter_accessattempt_unique_together.py new file mode 100644 index 0000000..d84e3fb --- /dev/null +++ b/axes/migrations/0007_alter_accessattempt_unique_together.py @@ -0,0 +1,38 @@ +# Generated by Django 3.2.7 on 2021-09-13 15:16 + +from django.db import migrations +from django.db.models import Count + + +def deduplicate_attempts(apps, schema_editor): + AccessAttempt = apps.get_model("axes", "AccessAttempt") + duplicated_attempts = ( + AccessAttempt.objects.values("username", "user_agent", "ip_address") + .annotate(Count("id")) + .order_by() + .filter(id__count__gt=1) + ) + + for attempt in duplicated_attempts: + redundant_attempts = AccessAttempt.objects.filter( + username=attempt["username"], + user_agent=attempt["user_agent"], + ip_address=attempt["ip_address"], + )[1:] + for redundant_attempt in redundant_attempts: + redundant_attempt.delete() + + +class Migration(migrations.Migration): + + dependencies = [ + ("axes", "0006_remove_accesslog_trusted"), + ] + + operations = [ + migrations.RunPython(deduplicate_attempts), + migrations.AlterUniqueTogether( + name="accessattempt", + unique_together={("username", "ip_address", "user_agent")}, + ), + ] diff --git a/axes/models.py b/axes/models.py index a5a807c..14f13a2 100644 --- a/axes/models.py +++ b/axes/models.py @@ -34,6 +34,7 @@ class AccessAttempt(AccessBase): class Meta: verbose_name = _("access attempt") verbose_name_plural = _("access attempts") + unique_together = [["username", "ip_address", "user_agent"]] class AccessLog(AccessBase):