-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #773 from ae-utbm/taiste
SAS, Eboutic, Antispam, psycopg
- Loading branch information
Showing
69 changed files
with
1,978 additions
and
1,631 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
db.sqlite3 | ||
*.sqlite3 | ||
*.log | ||
*.pyc | ||
*.mo | ||
|
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
from django.contrib import admin | ||
|
||
from antispam.models import ToxicDomain | ||
|
||
|
||
@admin.register(ToxicDomain) | ||
class ToxicDomainAdmin(admin.ModelAdmin): | ||
list_display = ("domain", "is_externally_managed", "created") | ||
search_fields = ("domain", "is_externally_managed", "created") | ||
list_filter = ("is_externally_managed",) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
from django.apps import AppConfig | ||
|
||
|
||
class AntispamConfig(AppConfig): | ||
default_auto_field = "django.db.models.BigAutoField" | ||
verbose_name = "antispam" | ||
name = "antispam" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import re | ||
|
||
from django import forms | ||
from django.core.validators import EmailValidator | ||
from django.utils.translation import gettext_lazy as _ | ||
|
||
from antispam.models import ToxicDomain | ||
|
||
|
||
class AntiSpamEmailField(forms.EmailField): | ||
"""An email field that email addresses with a known toxic domain.""" | ||
|
||
def run_validators(self, value: str): | ||
super().run_validators(value) | ||
# Domain part should exist since email validation is guaranteed to run first | ||
domain = re.search(EmailValidator.domain_regex, value) | ||
if ToxicDomain.objects.filter(domain=domain[0]).exists(): | ||
raise forms.ValidationError(_("Email domain is not allowed.")) |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
import requests | ||
from django.conf import settings | ||
from django.core.management import BaseCommand | ||
from django.db.models import Max | ||
from django.utils import timezone | ||
|
||
from antispam.models import ToxicDomain | ||
|
||
|
||
class Command(BaseCommand): | ||
"""Update blocked ips/mails database""" | ||
|
||
help = "Update blocked ips/mails database" | ||
|
||
def add_arguments(self, parser): | ||
parser.add_argument( | ||
"--force", action="store_true", help="Force re-creation even if up to date" | ||
) | ||
|
||
def _should_update(self, *, force: bool = False) -> bool: | ||
if force: | ||
return True | ||
oldest = ToxicDomain.objects.filter(is_externally_managed=True).aggregate( | ||
res=Max("created") | ||
)["res"] | ||
return not (oldest and timezone.now() < (oldest + timezone.timedelta(days=1))) | ||
|
||
def _download_domains(self, providers: list[str]) -> set[str]: | ||
domains = set() | ||
for provider in providers: | ||
res = requests.get(provider) | ||
if not res.ok: | ||
self.stderr.write( | ||
f"Source {provider} responded with code {res.status_code}" | ||
) | ||
continue | ||
domains |= set(res.content.decode().splitlines()) | ||
return domains | ||
|
||
def _update_domains(self, domains: set[str]): | ||
# Cleanup database | ||
ToxicDomain.objects.filter(is_externally_managed=True).delete() | ||
|
||
# Create database | ||
ToxicDomain.objects.bulk_create( | ||
[ | ||
ToxicDomain(domain=domain, is_externally_managed=True) | ||
for domain in domains | ||
], | ||
ignore_conflicts=True, | ||
) | ||
self.stdout.write("Domain database updated") | ||
|
||
def handle(self, *args, **options): | ||
if not self._should_update(force=options["force"]): | ||
self.stdout.write("Domain database is up to date") | ||
return | ||
self.stdout.write("Updating domain database") | ||
|
||
domains = self._download_domains(settings.TOXIC_DOMAINS_PROVIDERS) | ||
|
||
if not domains: | ||
self.stderr.write( | ||
"No domains could be fetched from settings.TOXIC_DOMAINS_PROVIDERS. " | ||
"Please, have a look at your settings." | ||
) | ||
return | ||
|
||
self._update_domains(domains) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
# Generated by Django 4.2.14 on 2024-08-03 23:05 | ||
|
||
from django.db import migrations, models | ||
|
||
|
||
class Migration(migrations.Migration): | ||
initial = True | ||
|
||
dependencies = [] | ||
|
||
operations = [ | ||
migrations.CreateModel( | ||
name="ToxicDomain", | ||
fields=[ | ||
( | ||
"domain", | ||
models.URLField( | ||
max_length=253, | ||
primary_key=True, | ||
serialize=False, | ||
verbose_name="domain", | ||
), | ||
), | ||
("created", models.DateTimeField(auto_now_add=True)), | ||
( | ||
"is_externally_managed", | ||
models.BooleanField( | ||
default=False, | ||
help_text="True if kept up-to-date using external toxic domain providers, else False", | ||
verbose_name="is externally managed", | ||
), | ||
), | ||
], | ||
), | ||
] |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
from django.db import models | ||
from django.utils.translation import gettext_lazy as _ | ||
|
||
|
||
class ToxicDomain(models.Model): | ||
"""Domain marked as spam in public databases""" | ||
|
||
domain = models.URLField(_("domain"), max_length=253, primary_key=True) | ||
created = models.DateTimeField(auto_now_add=True) | ||
is_externally_managed = models.BooleanField( | ||
_("is externally managed"), | ||
default=False, | ||
help_text=_( | ||
"True if kept up-to-date using external toxic domain providers, else False" | ||
), | ||
) | ||
|
||
def __str__(self) -> str: | ||
return self.domain |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.