From 8660d0ce75955836ae5aeb177d679af3b327f5ae Mon Sep 17 00:00:00 2001 From: kjg Date: Sun, 1 Jun 2025 10:45:08 +0000 Subject: [PATCH 1/4] [IPv6ULA] add the update function --- ipv6ula/forms.py | 50 ++++++++++++++++++++++++- ipv6ula/models.py | 27 ++++++++++++- ipv6ula/templates/ipv6ula/base.html | 8 ++++ ipv6ula/templates/ipv6ula/ula_form.html | 10 +++++ ipv6ula/urls.py | 2 + ipv6ula/views.py | 21 +++++++++++ 6 files changed, 114 insertions(+), 4 deletions(-) diff --git a/ipv6ula/forms.py b/ipv6ula/forms.py index 0800a9f..2569abc 100644 --- a/ipv6ula/forms.py +++ b/ipv6ula/forms.py @@ -1,6 +1,7 @@ from django import forms - -from .models import validate_ula_prefix, ULA +import ipaddress +from .models import validate_ula_prefix, ULA, validate_owner_ula_prefix +from django.core.exceptions import ValidationError class ULAForm(forms.ModelForm): class Meta: @@ -17,3 +18,48 @@ class ULAGenerateForm(forms.ModelForm): class Meta: model = ULA fields = [ 'name', 'organization', 'website' ] + +class ULAUpdateForm(forms.ModelForm): + def __init__(self, *args, **kwargs): + self.owner = kwargs.pop('owner', None) + super().__init__(*args, **kwargs) + + class Meta: + model = ULA + fields = [ 'prefix', 'name', 'organization', 'website' ] + + def clean_prefix(self): + prefix = self.cleaned_data.get("prefix") + if not prefix or not self.owner: + return prefix + + net_str = f"{prefix}/48" + net = ipaddress.IPv6Network(net_str, strict=False) + normalized_prefix = str(net[0]) + self.cleaned_data['prefix'] = normalized_prefix + + qs = ULA.objects.filter(prefix=normalized_prefix) + if self.instance.pk: + qs = qs.exclude(pk=self.instance.pk) + + if qs.exists(): + existing = qs.first() + if existing.owner != self.owner: + raise ValidationError("This prefix is already registered by another user.") + else: + self.instance = existing + return normalized_prefix + + +class ULADeleteForm(forms.ModelForm): + class Meta: + model = ULA + fields = [ 'prefix' ] + + def clean_prefix(self): + prefix = self.cleaned_data['prefix'] + validate_ula_prefix(prefix) + validate_owner_ula_prefix(prefix) + + return prefix + diff --git a/ipv6ula/models.py b/ipv6ula/models.py index d7232ed..9b791f5 100644 --- a/ipv6ula/models.py +++ b/ipv6ula/models.py @@ -31,6 +31,30 @@ def validate_ula_prefix(prefix): params = {'prefix': net } ) +def validate_owner_ula_prefix(prefix): + ula_net = ipaddress.IPv6Network("fd00::/8") + net_str = f"{prefix}/48" + net = ipaddress.IPv6Network(net_str, strict=False) + + if not net.subnet_of(ula_net): + raise ValidationError( + _(f"Prefix {net} is not within ULA range ({ula_net})"), + code='invalid', + params = {'prefix': net } + ) + + + try: + ULA.objects.get(prefix=str(net[0])) + except ULA.DoesNotExist: + raise ValidationError( + _(f"Prefix {net} is not your prefix"), + code='invalid', + params = {'prefix': net } + ) + else: + pass + class User(AbstractUser): pass @@ -41,7 +65,7 @@ class ULA(models.Model): on_delete=models.CASCADE ) - prefix = models.GenericIPAddressField(protocol='IPv6', unique=True, validators=[validate_ula_prefix]) + prefix = models.GenericIPAddressField(protocol='IPv6', unique=True) name = models.CharField(max_length=256) organization = models.CharField(max_length=256) website = models.URLField() @@ -54,7 +78,6 @@ class ULA(models.Model): net_str = f"{self.prefix}/48" net = ipaddress.IPv6Network(net_str, strict=False) self.prefix = str(net[0]) - super().save(*args, **kwargs) def __str__(self): diff --git a/ipv6ula/templates/ipv6ula/base.html b/ipv6ula/templates/ipv6ula/base.html index a005058..d9d6fb2 100644 --- a/ipv6ula/templates/ipv6ula/base.html +++ b/ipv6ula/templates/ipv6ula/base.html @@ -33,6 +33,14 @@ Submit existing prefix + + {% if user.is_authenticated %} Logged in as {{ user }}.