You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

136 lines
4.0 KiB

from django import forms
#from crispy_forms.helper import FormHelper
#from crispy_forms.layout import Submit, Layout
#from django.urls import reverse
from .models import Maintainer, Contact, InetNum
import re
import ipaddress
class WhoisObjectMixin(object):
def __init__(self, user, *args, **kwargs):
super(WhoisObjectMixin, self).__init__(*args, **kwargs)
self._user = user
instance = getattr(self, 'instance', None)
if instance and instance.pk:
self.fields['handle'].widget.attrs['readonly'] = True
def clean_handle(self):
instance = getattr(self, 'instance', None)
if instance and instance.pk:
return instance.handle
else:
return self.cleaned_data['handle']
def clean(self):
cleaned_data = super(WhoisObjectMixin, self).clean()
if cleaned_data.get("handle") == "AUTO" and not self.errors:
cleaned_data['handle'] = self._meta.model.genGenericHandle(cleaned_data.get("name"))
return cleaned_data
class MntForm(forms.ModelForm):
class Meta:
model = Maintainer
fields = ['handle', 'description', 'admin_c']
def __init__(self, user, *args, **kwargs):
super(MntForm, self).__init__(*args, **kwargs)
self._user = user
if 'admin_c' in self.fields:
self.fields['admin_c'].queryset = Contact.objects.filter(mnt_by=user.maintainer_set.all())
class MntInitialForm(MntForm):
class Meta:
model = Maintainer
fields = ['handle', 'description']
class ContactForm(WhoisObjectMixin, forms.ModelForm):
class Meta:
model = Contact
fields = ['type', 'handle', 'name', 'mnt_by']
def __init__(self, *args, **kwargs):
super(ContactForm, self).__init__(*args, **kwargs)
class ContactInitialForm(ContactForm):
class Meta:
model = Contact
fields = ['handle', 'name']
class InetNumForm(WhoisObjectMixin, forms.ModelForm):
prefix = forms.CharField()
protectedFields = ['handle', 'protocol', 'parent_range', 'mnt_by', 'prefix']
class Meta:
model = InetNum
fields = ['handle', 'protocol', 'parent_range', 'prefix', 'name', 'description', 'mnt_by', 'mnt_lower']
def __init__(self, lower=False, *args, **kwargs):
super(InetNumForm, self).__init__(*args, **kwargs)
print("args", args, kwargs)
self._editLower = lower
if 'admin_c' in self.fields:
self.fields['admin_c'].queryset = Contact.objects.filter(mnt_by__in=self.user.maintainer_set.all())
if self._editLower:
for key in self.protectedFields:
self.fields[key].disabled = True
self.fields[key].widget.attrs['readonly'] = False
def clean_prefix(self):
# make sure this is a subnet we're getting
print("HALLO")
net = self.cleaned_data['prefix']
if not re.match(r"[0-9:.]+/[0-9]+", net):
raise forms.ValidationError("Address needs to be a subnet in the format of ip/cidr")
try:
net = ipaddress.ip_network(net)
except ValueError as e:
raise forms.ValidationError(str(e))
return net
def clean(self):
# FIXME: Reset certain field sto instance:
cleaned_data = super(InetNumForm, self).clean()
if self._editLower:
# reset some fields, just in case
#for key in self.protectedFields:
# cleaned_data[key] = getattr(self.instance, key)
pass
else:
if all(x in cleaned_data for x in ('prefix', 'parent_range', 'protocol')):
prefix = cleaned_data['prefix']
parent = cleaned_data['parent_range']
parentNet = parent.getNetwork()
if cleaned_data['protocol'] != parent.protocol:
raise forms.ValidationError("Protocol type for prefix must be same as parent network")
# check if in parent block
if prefix.network_address not in parentNet or prefix.prefixlen < parentNet.prefixlen:
raise forms.ValidationError("Prefix must be inside parent network range")
# check if parent block has net that overlaps with us
for otherNet in parent.inetnum_set.all():
if self.instance and self.instance.pk == otherNet.pk:
continue
if otherNet.getNetwork().overlaps(prefix):
raise forms.ValidationError("The given prefix overlaps with network %s" % otherNet.handle)
self.instance.address = str(prefix.network_address)
self.instance.netmask = prefix.prefixlen
return cleaned_data