[IPv6ULA] add the update function

This commit is contained in:
kjg 2025-06-01 10:45:08 +00:00
commit 8660d0ce75
6 changed files with 114 additions and 4 deletions

View file

@ -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

View file

@ -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):

View file

@ -33,6 +33,14 @@
<a class="nav-link" href="/submit/">Submit existing
prefix</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/update/">Update existing
prefix</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/delete/">Delete existing
prefix</a>
</li>
{% if user.is_authenticated %}
<span class="navbar-text">Logged in as {{ user }}.</span>
<li class="nav-item">

View file

@ -20,6 +20,16 @@
<p>
A new random prefix will be generated for you.
</p>
{% elif method == 'update' %}
<h1>Update existing prefix</h1>
<p>
You update your existing prefix.
</p>
{% elif method == 'delete' %}
<h1>Delete existing prefix</h1>
<p>
You delete your existing prefix.
</p>
{% endif %}
<p>

View file

@ -28,4 +28,6 @@ urlpatterns = [
path('login/', views.LoginView.as_view(), name='login'),
path('logout/', views.logout_view, name='logout'),
path('admin/', admin.site.urls),
path('update/', views.UpdateView.as_view(), name='update'),
path('delete/', views.DeleteView.as_view(), name='delete'),
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

View file

@ -73,6 +73,27 @@ class SubmitView(GenerateSubmitView):
class LoginView(auth_views.LoginView):
template_name = 'ipv6ula/login.html'
class UpdateView(GenerateSubmitView):
form_class = ULAUpdateForm
gen_method = "update"
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs['owner'] = self.request.user
return kwargs
def form_valid(self, form):
form.instance.owner = self.request.user
return super().form_valid(form)
class DeleteView(GenerateSubmitView):
form_class = ULADeleteForm
gen_method = "delete"
def form_valid(self, form):
form.instance.owner = self.request.user
return super().form_valid(form)
def logout_view(request):
logout(request)
return redirect("/")