diff --git a/ipv6ula/migrations/0003_auto_20201204_2201.py b/ipv6ula/migrations/0003_auto_20201204_2201.py new file mode 100644 index 0000000..239e74b --- /dev/null +++ b/ipv6ula/migrations/0003_auto_20201204_2201.py @@ -0,0 +1,19 @@ +# Generated by Django 3.1.4 on 2020-12-04 22:01 + +from django.db import migrations, models +import ipv6ula.models + + +class Migration(migrations.Migration): + + dependencies = [ + ('ipv6ula', '0002_auto_20201204_2019'), + ] + + operations = [ + migrations.AlterField( + model_name='ula', + name='prefix', + field=models.GenericIPAddressField(protocol='IPv6', unique=True, validators=[ipv6ula.models.validate_ula_prefix]), + ), + ] diff --git a/ipv6ula/models.py b/ipv6ula/models.py index bda2f46..b408796 100644 --- a/ipv6ula/models.py +++ b/ipv6ula/models.py @@ -2,8 +2,22 @@ from django.contrib.auth.models import AbstractUser from django.contrib.auth import get_user_model from django.db import models from django.core.exceptions import ValidationError +from django.utils.translation import gettext_lazy as _ +import ipaddress + +def validate_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 {prefix} is not within ULA range ({ula_net})"), + code='invalid', + params = {'prefix': prefix } + ) class User(AbstractUser): @@ -15,17 +29,21 @@ class ULA(models.Model): on_delete=models.CASCADE ) - prefix = models.GenericIPAddressField(protocol='IPv6', unique=True) + prefix = models.GenericIPAddressField(protocol='IPv6', unique=True, validators=[validate_ula_prefix]) name = models.CharField(max_length=256) organization = models.CharField(max_length=256) website = models.URLField() - # def save(self, *args, **kwargs): - # """ - # Ensure we only save the first IPv6 address of the network - # """ + def save(self, *args, **kwargs): + """ + Ensure we only save the first IPv6 address of the network + """ - # super().save(*args, **kwargs) + 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): return f"{self.prefix}" diff --git a/ipv6ula/templates/ipv6ula/ula_form.html b/ipv6ula/templates/ipv6ula/ula_form.html index 8eeae74..20d6abd 100644 --- a/ipv6ula/templates/ipv6ula/ula_form.html +++ b/ipv6ula/templates/ipv6ula/ula_form.html @@ -6,11 +6,17 @@
+ All ULA prefixes are /48 networks. Simply add the first IP address + (without any netmask, for instance fd23:2323:2323::). + + You can choose the name of your liking and an optional + organization name. +
++ ULA prefixes must be part of the fd00::/8 network. +
- You can choose the name of your liking and an optional - organization name.