Compare commits
6 Commits
8a162acee3
...
a3b6209e0a
Author | SHA1 | Date |
---|---|---|
Sebastian Lohff | a3b6209e0a | |
Sebastian Lohff | c800f853ac | |
Sebastian Lohff | 39b65ceba0 | |
Sebastian Lohff | ef5afbfe3a | |
Sebastian Lohff | 8384311517 | |
Sebastian Lohff | a5e831ec21 |
192
api/dnshelper.py
192
api/dnshelper.py
|
@ -11,121 +11,121 @@ import dns.resolver
|
|||
# FIXME: DNS timeouts
|
||||
|
||||
def compareRecords(rrset, expected):
|
||||
result = {
|
||||
"nameMissing": [],
|
||||
"rrMissing": [],
|
||||
"rrExtra": [],
|
||||
}
|
||||
result = {
|
||||
"nameMissing": [],
|
||||
"rrMissing": [],
|
||||
"rrExtra": [],
|
||||
}
|
||||
|
||||
for domain, rrtype, content in expected:
|
||||
for rrrec in rrset:
|
||||
if domain == rrrec.name.to_text() and dns.rdatatype.from_text(rrtype) == rrrec.rdtype:
|
||||
for name in content:
|
||||
if name not in map(lambda _x: _x.to_text(), rrrec.items):
|
||||
# record missing
|
||||
result["rrMissing"].append((domain, rrtype, name))
|
||||
for domain, rrtype, content in expected:
|
||||
for rrrec in rrset:
|
||||
if domain == rrrec.name.to_text() and dns.rdatatype.from_text(rrtype) == rrrec.rdtype:
|
||||
for name in content:
|
||||
if name not in map(lambda _x: _x.to_text(), rrrec.items):
|
||||
# record missing
|
||||
result["rrMissing"].append((domain, rrtype, name))
|
||||
|
||||
for item in rrrec.items:
|
||||
if item.to_text() not in content:
|
||||
# superfluous record
|
||||
result["rrExtra"].append((domain, rrtype, item.to_text()))
|
||||
for item in rrrec.items:
|
||||
if item.to_text() not in content:
|
||||
# superfluous record
|
||||
result["rrExtra"].append((domain, rrtype, item.to_text()))
|
||||
|
||||
break
|
||||
else:
|
||||
# domain + rr nicht in nameserver
|
||||
result["nameMissing"].append((domain, rrtype))
|
||||
break
|
||||
else:
|
||||
# domain + rr nicht in nameserver
|
||||
result["nameMissing"].append((domain, rrtype))
|
||||
|
||||
success = not any(len(_x) > 0 for _x in result.values())
|
||||
success = not any(len(_x) > 0 for _x in result.values())
|
||||
|
||||
return success, result
|
||||
return success, result
|
||||
|
||||
|
||||
def dnsQuery(domain, rrType, nameserverIp):
|
||||
dname = dns.name.from_text(domain)
|
||||
req = dns.message.make_query(dname, dns.rdatatype.from_text(rrType))
|
||||
resp = dns.query.udp(req, nameserverIp, timeout=2.0)
|
||||
dname = dns.name.from_text(domain)
|
||||
req = dns.message.make_query(dname, dns.rdatatype.from_text(rrType))
|
||||
resp = dns.query.udp(req, nameserverIp, timeout=2.0)
|
||||
|
||||
if resp.rcode() != dns.rcode.NXDOMAIN:
|
||||
rrset = resp.answer + resp.authority + resp.additional
|
||||
return True, rrset
|
||||
else:
|
||||
return False, []
|
||||
if resp.rcode() != dns.rcode.NXDOMAIN:
|
||||
rrset = resp.answer + resp.authority + resp.additional
|
||||
return True, rrset
|
||||
else:
|
||||
return False, []
|
||||
|
||||
|
||||
def checkDomain(domain, tldNameserver, nameservers):
|
||||
result = []
|
||||
result = []
|
||||
|
||||
if nameservers.count() == 0:
|
||||
return [("err", "Domain %s has no nameservers attached to it, nothing to check" % domain)]
|
||||
if nameservers.count() == 0:
|
||||
return [("err", "Domain %s has no nameservers attached to it, nothing to check" % domain)]
|
||||
|
||||
# build record set
|
||||
nsRecords = [(domain, "NS", list(ns.name for ns in nameservers))]
|
||||
glueRecords = []
|
||||
for ns in nameservers:
|
||||
if ns.name.endswith("." + domain):
|
||||
if ns.glueIPv4 or ns.glueIPv6:
|
||||
if ns.glueIPv4:
|
||||
glueRecords.append((ns.name, "A", [ns.glueIPv4]))
|
||||
if ns.glueIPv6:
|
||||
glueRecords.append((ns.name, "AAAA", [ns.glueIPv6]))
|
||||
else:
|
||||
result.append(("err", "Nameserver %s is under domain %s, but has no glue entries." % (ns.name, domain)))
|
||||
# build record set
|
||||
nsRecords = [(domain, "NS", list(ns.name for ns in nameservers))]
|
||||
glueRecords = []
|
||||
for ns in nameservers:
|
||||
if ns.name.endswith("." + domain):
|
||||
if ns.glueIPv4 or ns.glueIPv6:
|
||||
if ns.glueIPv4:
|
||||
glueRecords.append((ns.name, "A", [ns.glueIPv4]))
|
||||
if ns.glueIPv6:
|
||||
glueRecords.append((ns.name, "AAAA", [ns.glueIPv6]))
|
||||
else:
|
||||
result.append(("err", "Nameserver %s is under domain %s, but has no glue entries." % (ns.name, domain)))
|
||||
|
||||
# 1. TLD nameserver
|
||||
try:
|
||||
found, rrset = dnsQuery(domain, "ANY", tldNameserver)
|
||||
if found:
|
||||
success, errors = compareRecords(rrset, nsRecords + glueRecords)
|
||||
if success:
|
||||
result.append(("succ", "All records present in TLD nameserver"))
|
||||
else:
|
||||
result.append(("err", "Record mismatch between TLD nameserver and WHOIS database", errors))
|
||||
else:
|
||||
result.append(("err", "Domain %s not found in TLD nameserver" % (domain,)))
|
||||
except (dns.exception.Timeout, OSError):
|
||||
result.append(("err", "TLD nameserver is currently not reachable"))
|
||||
# 1. TLD nameserver
|
||||
try:
|
||||
found, rrset = dnsQuery(domain, "ANY", tldNameserver)
|
||||
if found:
|
||||
success, errors = compareRecords(rrset, nsRecords + glueRecords)
|
||||
if success:
|
||||
result.append(("succ", "All records present in TLD nameserver"))
|
||||
else:
|
||||
result.append(("err", "Record mismatch between TLD nameserver and WHOIS database", errors))
|
||||
else:
|
||||
result.append(("err", "Domain %s not found in TLD nameserver" % (domain,)))
|
||||
except (dns.exception.Timeout, OSError):
|
||||
result.append(("err", "TLD nameserver is currently not reachable"))
|
||||
|
||||
# find other records...
|
||||
# find other records...
|
||||
|
||||
# 2. your nameservers
|
||||
for ns in nameservers:
|
||||
addr = None
|
||||
if ns.glueIPv4:
|
||||
addr = ns.glueIPv4
|
||||
elif ns.glueIPv6:
|
||||
addr = ns.glueIPv6
|
||||
else:
|
||||
for rrType in ("A", "AAAA"):
|
||||
try:
|
||||
r = dns.resolver.Resolver()
|
||||
r.timeout = 2.0
|
||||
q = r.query(ns.name, rdtype=dns.rdatatype.from_text(rrType))
|
||||
addr = q.response.answer[0].items[0].address
|
||||
except (dns.exception.DNSException, OSError):
|
||||
pass
|
||||
# 2. your nameservers
|
||||
for ns in nameservers:
|
||||
addr = None
|
||||
if ns.glueIPv4:
|
||||
addr = ns.glueIPv4
|
||||
elif ns.glueIPv6:
|
||||
addr = ns.glueIPv6
|
||||
else:
|
||||
for rrType in ("A", "AAAA"):
|
||||
try:
|
||||
r = dns.resolver.Resolver()
|
||||
r.timeout = 2.0
|
||||
q = r.query(ns.name, rdtype=dns.rdatatype.from_text(rrType))
|
||||
addr = q.response.answer[0].items[0].address
|
||||
except (dns.exception.DNSException, OSError):
|
||||
pass
|
||||
|
||||
if addr:
|
||||
err = False
|
||||
errDict = {"nameMissing": [], "rrMissing": [], "rrExtra": []}
|
||||
try:
|
||||
for rec in (nsRecords + glueRecords):
|
||||
found, rrset = dnsQuery(rec[0], rec[1], addr)
|
||||
if addr:
|
||||
err = False
|
||||
errDict = {"nameMissing": [], "rrMissing": [], "rrExtra": []}
|
||||
try:
|
||||
for rec in (nsRecords + glueRecords):
|
||||
found, rrset = dnsQuery(rec[0], rec[1], addr)
|
||||
|
||||
#success, errors = compareRecords(rrset, nsRecords + glueRecords)
|
||||
success, errors = compareRecords(rrset, [rec])
|
||||
if not success:
|
||||
err = True
|
||||
for k in errors.keys():
|
||||
errDict[k].extend(errors[k])
|
||||
#success, errors = compareRecords(rrset, nsRecords + glueRecords)
|
||||
success, errors = compareRecords(rrset, [rec])
|
||||
if not success:
|
||||
err = True
|
||||
for k in errors.keys():
|
||||
errDict[k].extend(errors[k])
|
||||
|
||||
if not err:
|
||||
result.append(("succ", "Nameserver %s is configured correctly" % ns.name))
|
||||
else:
|
||||
result.append(("err", "Nameserver %s (via %s) recordset does not match the database" % (ns.name, addr), errDict))
|
||||
except (dns.exception.DNSException, OSError):
|
||||
result.append(("err", "Nameserver %s is not reachable (via %s)" % (ns.name, addr)))
|
||||
if not err:
|
||||
result.append(("succ", "Nameserver %s is configured correctly" % ns.name))
|
||||
else:
|
||||
result.append(("err", "Nameserver %s (via %s) recordset does not match the database" % (ns.name, addr), errDict))
|
||||
except (dns.exception.DNSException, OSError):
|
||||
result.append(("err", "Nameserver %s is not reachable (via %s)" % (ns.name, addr)))
|
||||
|
||||
else:
|
||||
result.append(("err", "Can't resolv an ip address for nameserver %s" % ns.name))
|
||||
else:
|
||||
result.append(("err", "Can't resolv an ip address for nameserver %s" % ns.name))
|
||||
|
||||
return result
|
||||
return result
|
||||
|
|
12
api/urls.py
12
api/urls.py
|
@ -7,13 +7,13 @@ from django.conf.urls import url
|
|||
from . import views as api_views
|
||||
|
||||
urlpatterns = [
|
||||
url(r'asblock/free-as/$', api_views.asblockFreeAS, name='asblock-free-as'),
|
||||
url(r'asblock/free-subnet/$', api_views.freeSubnet, name='inetnum-free-subnet'),
|
||||
url(r'inetnum/get-subnet/$', api_views.getSubnet, name='inetnum-get-subnet'),
|
||||
url(r'asblock/free-as/$', api_views.asblockFreeAS, name='asblock-free-as'),
|
||||
url(r'asblock/free-subnet/$', api_views.freeSubnet, name='inetnum-free-subnet'),
|
||||
url(r'inetnum/get-subnet/$', api_views.getSubnet, name='inetnum-get-subnet'),
|
||||
|
||||
url(r'domain/check/$', api_views.checkDomain, name='domain-check'),
|
||||
url(r'rzone/check/$', api_views.checkRzone, name='reversezone-check'),
|
||||
url(r'domain/check/$', api_views.checkDomain, name='domain-check'),
|
||||
url(r'rzone/check/$', api_views.checkRzone, name='reversezone-check'),
|
||||
|
||||
url(r'roa/$', api_views.getROA, name='get-roa'),
|
||||
url(r'roa/$', api_views.getROA, name='get-roa'),
|
||||
|
||||
]
|
||||
|
|
336
api/views.py
336
api/views.py
|
@ -19,219 +19,219 @@ import ipaddress
|
|||
@login_required
|
||||
def asblockFreeAS(request):
|
||||
|
||||
ret = {
|
||||
"success": False,
|
||||
"errorMsg": None,
|
||||
"number": -1,
|
||||
}
|
||||
ret = {
|
||||
"success": False,
|
||||
"errorMsg": None,
|
||||
"number": -1,
|
||||
}
|
||||
|
||||
try:
|
||||
blockName = request.GET.get('block', None)
|
||||
if not blockName:
|
||||
raise ValidationError("No block given")
|
||||
try:
|
||||
blockName = request.GET.get('block', None)
|
||||
if not blockName:
|
||||
raise ValidationError("No block given")
|
||||
|
||||
try:
|
||||
mnts = request.user.maintainer_set.all()
|
||||
block = ASBlock.objects.filter(Q(mnt_by__in=mnts) | Q(mnt_lower__in=mnts)).distinct().get(handle=blockName)
|
||||
if block.asblock_set.count() > 0:
|
||||
raise ValidationError("AS Block already has sub AS Blocks")
|
||||
if block.asnumber_set.count() > 0:
|
||||
num = block.asnumber_set.order_by("-number")[0].number + 1
|
||||
if num > block.asEnd:
|
||||
num = None
|
||||
for n in range(block.asBegin, block.asEnd + 1):
|
||||
try:
|
||||
ASNumber.objects.get(number=n)
|
||||
except ASNumber.DoesNotExist:
|
||||
num = n
|
||||
break
|
||||
if not num:
|
||||
raise ValidationError("No free AS Number in block")
|
||||
ret["number"] = num
|
||||
else:
|
||||
ret["number"] = block.asBegin
|
||||
except ASBlock.DoesNotExist:
|
||||
raise ValidationError("Could not get AS Block")
|
||||
try:
|
||||
mnts = request.user.maintainer_set.all()
|
||||
block = ASBlock.objects.filter(Q(mnt_by__in=mnts) | Q(mnt_lower__in=mnts)).distinct().get(handle=blockName)
|
||||
if block.asblock_set.count() > 0:
|
||||
raise ValidationError("AS Block already has sub AS Blocks")
|
||||
if block.asnumber_set.count() > 0:
|
||||
num = block.asnumber_set.order_by("-number")[0].number + 1
|
||||
if num > block.asEnd:
|
||||
num = None
|
||||
for n in range(block.asBegin, block.asEnd + 1):
|
||||
try:
|
||||
ASNumber.objects.get(number=n)
|
||||
except ASNumber.DoesNotExist:
|
||||
num = n
|
||||
break
|
||||
if not num:
|
||||
raise ValidationError("No free AS Number in block")
|
||||
ret["number"] = num
|
||||
else:
|
||||
ret["number"] = block.asBegin
|
||||
except ASBlock.DoesNotExist:
|
||||
raise ValidationError("Could not get AS Block")
|
||||
|
||||
ret["success"] = True
|
||||
except ValidationError as e:
|
||||
ret["errorMsg"] = e.message
|
||||
return JsonResponse(ret)
|
||||
ret["success"] = True
|
||||
except ValidationError as e:
|
||||
ret["errorMsg"] = e.message
|
||||
return JsonResponse(ret)
|
||||
|
||||
|
||||
@login_required
|
||||
def freeSubnet(request):
|
||||
|
||||
ret = {
|
||||
"success": False,
|
||||
"errorMsg": None,
|
||||
"network": None,
|
||||
}
|
||||
ret = {
|
||||
"success": False,
|
||||
"errorMsg": None,
|
||||
"network": None,
|
||||
}
|
||||
|
||||
try:
|
||||
parentRangeName = request.GET.get('parentRange', None)
|
||||
if not parentRangeName:
|
||||
raise ValidationError("No subnet given")
|
||||
try:
|
||||
parentRangeName = request.GET.get('parentRange', None)
|
||||
if not parentRangeName:
|
||||
raise ValidationError("No subnet given")
|
||||
|
||||
parentRange = None
|
||||
try:
|
||||
mnts = request.user.maintainer_set.all()
|
||||
parentRange = InetNum.objects.filter(Q(mnt_by__in=mnts) | Q(mnt_lower__in=mnts)).distinct().get(handle=parentRangeName)
|
||||
except InetNum.DoesNotExist:
|
||||
raise ValidationError("Parent range does not exist / is not maintained by you")
|
||||
parentRange = None
|
||||
try:
|
||||
mnts = request.user.maintainer_set.all()
|
||||
parentRange = InetNum.objects.filter(Q(mnt_by__in=mnts) | Q(mnt_lower__in=mnts)).distinct().get(handle=parentRangeName)
|
||||
except InetNum.DoesNotExist:
|
||||
raise ValidationError("Parent range does not exist / is not maintained by you")
|
||||
|
||||
prefixLen = 0
|
||||
try:
|
||||
prefixLen = request.GET.get("prefixLen", None)
|
||||
if not prefixLen:
|
||||
if parentRange.protocol == InetNum.IPv4:
|
||||
prefixLen = 27
|
||||
else:
|
||||
prefixLen = 60
|
||||
prefixLen = int(prefixLen)
|
||||
prefixLen = 0
|
||||
try:
|
||||
prefixLen = request.GET.get("prefixLen", None)
|
||||
if not prefixLen:
|
||||
if parentRange.protocol == InetNum.IPv4:
|
||||
prefixLen = 27
|
||||
else:
|
||||
prefixLen = 60
|
||||
prefixLen = int(prefixLen)
|
||||
|
||||
if prefixLen < 8 or \
|
||||
(parentRange.protocol == InetNum.IPv4 and prefixLen > 32) or \
|
||||
(parentRange.protocol == InetNum.IPv6 and prefixLen > 128):
|
||||
raise ValidationError("Given prefix length is out of range")
|
||||
except ValueError:
|
||||
raise ValidationError("PrefixLen is not a number")
|
||||
if prefixLen < 8 or \
|
||||
(parentRange.protocol == InetNum.IPv4 and prefixLen > 32) or \
|
||||
(parentRange.protocol == InetNum.IPv6 and prefixLen > 128):
|
||||
raise ValidationError("Given prefix length is out of range")
|
||||
except ValueError:
|
||||
raise ValidationError("PrefixLen is not a number")
|
||||
|
||||
usableNet = None
|
||||
# FIXME: use first biggest usable netblock...
|
||||
#biggestNet = parentRange.inetnum_set.order_by("-address")
|
||||
#if biggestNet
|
||||
# candidateNet =
|
||||
# and (biggestNet.getNetwork().broadcast_address.:
|
||||
usableNet = None
|
||||
# FIXME: use first biggest usable netblock...
|
||||
#biggestNet = parentRange.inetnum_set.order_by("-address")
|
||||
#if biggestNet
|
||||
# candidateNet =
|
||||
# and (biggestNet.getNetwork().broadcast_address.:
|
||||
|
||||
# try using next network in range
|
||||
# ordering does not work, as order_by sorts alphabetically
|
||||
# ==> the set is short, we can iterate through all. no sense in unpacking the SQL magic
|
||||
#biggestNets = parentRange.inetnum_set.order_by("-address")
|
||||
biggestNet = None
|
||||
for ipRange in parentRange.inetnum_set.all():
|
||||
if not biggestNet or ipRange.getNetwork() > biggestNet:
|
||||
biggestNet = ipRange.getNetwork()
|
||||
# try using next network in range
|
||||
# ordering does not work, as order_by sorts alphabetically
|
||||
# ==> the set is short, we can iterate through all. no sense in unpacking the SQL magic
|
||||
#biggestNets = parentRange.inetnum_set.order_by("-address")
|
||||
biggestNet = None
|
||||
for ipRange in parentRange.inetnum_set.all():
|
||||
if not biggestNet or ipRange.getNetwork() > biggestNet:
|
||||
biggestNet = ipRange.getNetwork()
|
||||
|
||||
if biggestNet:
|
||||
candidateNet = ipaddress.ip_network("%s/%s" % (biggestNet.broadcast_address + 1, biggestNet.prefixlen))
|
||||
print("biggest net", biggestNet, "candidate", candidateNet)
|
||||
if candidateNet.network_address in parentRange.getNetwork():
|
||||
usableNet = candidateNet
|
||||
if biggestNet:
|
||||
candidateNet = ipaddress.ip_network("%s/%s" % (biggestNet.broadcast_address + 1, biggestNet.prefixlen))
|
||||
print("biggest net", biggestNet, "candidate", candidateNet)
|
||||
if candidateNet.network_address in parentRange.getNetwork():
|
||||
usableNet = candidateNet
|
||||
|
||||
# check if there are still networks left in range
|
||||
if not usableNet:
|
||||
# search for free network
|
||||
nets = list(parentRange.getNetwork().subnets())
|
||||
for subRange in parentRange.inetnum_set.all():
|
||||
newNet = None
|
||||
for net in nets:
|
||||
if subRange.getNetwork().network_address in net:
|
||||
newNet = net
|
||||
if not newNet:
|
||||
# critical error, we want a 500 here
|
||||
raise ValueError("Subnet not in range")
|
||||
# check if there are still networks left in range
|
||||
if not usableNet:
|
||||
# search for free network
|
||||
nets = list(parentRange.getNetwork().subnets())
|
||||
for subRange in parentRange.inetnum_set.all():
|
||||
newNet = None
|
||||
for net in nets:
|
||||
if subRange.getNetwork().network_address in net:
|
||||
newNet = net
|
||||
if not newNet:
|
||||
# critical error, we want a 500 here
|
||||
raise ValueError("Subnet not in range")
|
||||
|
||||
nets.remove(newNet)
|
||||
nets.extend(newNet.address_exclude(subRange.getNetwork()))
|
||||
nets.remove(newNet)
|
||||
nets.extend(newNet.address_exclude(subRange.getNetwork()))
|
||||
|
||||
nets = sorted(nets)
|
||||
for net in nets:
|
||||
if net.prefixlen <= prefixLen:
|
||||
usableNet = net
|
||||
break
|
||||
nets = sorted(nets)
|
||||
for net in nets:
|
||||
if net.prefixlen <= prefixLen:
|
||||
usableNet = net
|
||||
break
|
||||
|
||||
if not usableNet:
|
||||
raise ValidationError("No space left in given range")
|
||||
if not usableNet:
|
||||
raise ValidationError("No space left in given range")
|
||||
|
||||
ret["network"] = "%s/%s" % (usableNet.network_address, prefixLen)
|
||||
ret["success"] = True
|
||||
except ValidationError as e:
|
||||
ret["errorMsg"] = e.message
|
||||
ret["network"] = "%s/%s" % (usableNet.network_address, prefixLen)
|
||||
ret["success"] = True
|
||||
except ValidationError as e:
|
||||
ret["errorMsg"] = e.message
|
||||
|
||||
return JsonResponse(ret)
|
||||
return JsonResponse(ret)
|
||||
|
||||
|
||||
@login_required
|
||||
def getSubnet(request):
|
||||
|
||||
ret = {
|
||||
"success": False,
|
||||
"errorMsg": None,
|
||||
"network": None,
|
||||
}
|
||||
ret = {
|
||||
"success": False,
|
||||
"errorMsg": None,
|
||||
"network": None,
|
||||
}
|
||||
|
||||
try:
|
||||
netName = request.GET.get('net', None)
|
||||
mnts = request.user.maintainer_set.all()
|
||||
nets = InetNum.objects.filter(Q(mnt_by__in=mnts) | Q(mnt_lower__in=mnts)).distinct()
|
||||
net = nets.get(handle=netName)
|
||||
try:
|
||||
netName = request.GET.get('net', None)
|
||||
mnts = request.user.maintainer_set.all()
|
||||
nets = InetNum.objects.filter(Q(mnt_by__in=mnts) | Q(mnt_lower__in=mnts)).distinct()
|
||||
net = nets.get(handle=netName)
|
||||
|
||||
ret["success"] = True
|
||||
ret["network"] = net.prefix()
|
||||
except InetNum.DoesNotExist:
|
||||
ret["errorMsg"] = "Chosen network does not exist"
|
||||
ret["success"] = True
|
||||
ret["network"] = net.prefix()
|
||||
except InetNum.DoesNotExist:
|
||||
ret["errorMsg"] = "Chosen network does not exist"
|
||||
|
||||
return JsonResponse(ret)
|
||||
return JsonResponse(ret)
|
||||
|
||||
|
||||
@login_required
|
||||
def checkDomain(request):
|
||||
ret = {
|
||||
"success": False,
|
||||
"errorMsg": None,
|
||||
"domain": None,
|
||||
"result": None,
|
||||
}
|
||||
ret = {
|
||||
"success": False,
|
||||
"errorMsg": None,
|
||||
"domain": None,
|
||||
"result": None,
|
||||
}
|
||||
|
||||
try:
|
||||
domainName = Domain.fixName(request.GET.get('domain', ''))
|
||||
domain = Domain.objects.get(name=domainName)
|
||||
#if not domain.canEdit(request.user):
|
||||
# raise Domain.DoesNotExist()
|
||||
try:
|
||||
domainName = Domain.fixName(request.GET.get('domain', ''))
|
||||
domain = Domain.objects.get(name=domainName)
|
||||
#if not domain.canEdit(request.user):
|
||||
# raise Domain.DoesNotExist()
|
||||
|
||||
ret["success"] = True
|
||||
ret["domain"] = domain.name
|
||||
# FIXME: change this if we ever have more than one...
|
||||
ret["result"] = helperCheckDomain(domain.name, TLD_NAMESERVERS[0], domain.nameservers.all())
|
||||
except Domain.DoesNotExist:
|
||||
ret["errorMsg"] = "Domain does not exist"
|
||||
ret["success"] = True
|
||||
ret["domain"] = domain.name
|
||||
# FIXME: change this if we ever have more than one...
|
||||
ret["result"] = helperCheckDomain(domain.name, TLD_NAMESERVERS[0], domain.nameservers.all())
|
||||
except Domain.DoesNotExist:
|
||||
ret["errorMsg"] = "Domain does not exist"
|
||||
|
||||
return JsonResponse(ret)
|
||||
return JsonResponse(ret)
|
||||
|
||||
|
||||
@login_required
|
||||
def checkRzone(request):
|
||||
ret = {
|
||||
"success": False,
|
||||
"errorMsg": None,
|
||||
"domain": None,
|
||||
"result": None,
|
||||
}
|
||||
ret = {
|
||||
"success": False,
|
||||
"errorMsg": None,
|
||||
"domain": None,
|
||||
"result": None,
|
||||
}
|
||||
|
||||
try:
|
||||
rzonePk = int(request.GET.get('domain', ''))
|
||||
rzone = ReverseZone.objects.get(pk=rzonePk)
|
||||
#if not rzone.canEdit(request.user):
|
||||
# raise ReverseZone.DoesNotExist()
|
||||
try:
|
||||
rzonePk = int(request.GET.get('domain', ''))
|
||||
rzone = ReverseZone.objects.get(pk=rzonePk)
|
||||
#if not rzone.canEdit(request.user):
|
||||
# raise ReverseZone.DoesNotExist()
|
||||
|
||||
ret["success"] = True
|
||||
# FIXME: change this if we ever have more than one...
|
||||
ret["result"] = helperCheckDomain(rzone.getZone(), TLD_NAMESERVERS[0], rzone.nameservers.all())
|
||||
except (ReverseZone.DoesNotExist, ValueError):
|
||||
ret["errorMsg"] = "ReverseZone does not exist"
|
||||
ret["success"] = True
|
||||
# FIXME: change this if we ever have more than one...
|
||||
ret["result"] = helperCheckDomain(rzone.getZone(), TLD_NAMESERVERS[0], rzone.nameservers.all())
|
||||
except (ReverseZone.DoesNotExist, ValueError):
|
||||
ret["errorMsg"] = "ReverseZone does not exist"
|
||||
|
||||
return JsonResponse(ret)
|
||||
return JsonResponse(ret)
|
||||
|
||||
|
||||
def getROA(request):
|
||||
roa = {}
|
||||
for asn in ASNumber.objects.all():
|
||||
nets = []
|
||||
for net in asn.inetnum_set.all():
|
||||
nets.append(net.prefix())
|
||||
roa = {}
|
||||
for asn in ASNumber.objects.all():
|
||||
nets = []
|
||||
for net in asn.inetnum_set.all():
|
||||
nets.append(net.prefix())
|
||||
|
||||
if nets:
|
||||
roa[asn.number] = nets
|
||||
if nets:
|
||||
roa[asn.number] = nets
|
||||
|
||||
return JsonResponse(roa)
|
||||
return JsonResponse(roa)
|
||||
|
|
268
bin/dns-sync
268
bin/dns-sync
|
@ -25,179 +25,181 @@ __VERSION__ = '0.1'
|
|||
|
||||
|
||||
def _parser():
|
||||
parser = argparse.ArgumentParser(
|
||||
#prog='foo',
|
||||
#description='do some awesome foo',
|
||||
)
|
||||
parser = argparse.ArgumentParser()
|
||||
|
||||
parser.add_argument("--pdns-host", default="127.0.0.1", help="PDNS host")
|
||||
parser.add_argument("--pdns-port", default=8081, help="PDNS port")
|
||||
parser.add_argument("-c", "--config", default=None, type=argparse.FileType("r"), help="Path to config file (default path: ./dns-sync.conf, /etc/dns-sync.conf)")
|
||||
parser.add_argument("--api-key", default=None, help="PDNS API key")
|
||||
parser.add_argument("--version", action="version", version="%(prog)s " + __VERSION__)
|
||||
parser.add_argument("--pdns-host", default="127.0.0.1", help="PDNS host")
|
||||
parser.add_argument("--pdns-port", default=8081, help="PDNS port")
|
||||
parser.add_argument("-c", "--config", default=None, type=argparse.FileType("r"), help="Path to config file (default path: ./dns-sync.conf, /etc/dns-sync.conf)")
|
||||
parser.add_argument("--api-key", default=None, help="PDNS API key")
|
||||
parser.add_argument("--version", action="version", version="%(prog)s " + __VERSION__)
|
||||
|
||||
return parser
|
||||
|
||||
return parser
|
||||
|
||||
def mergeDomains(zoneData, pdnsData):
|
||||
rrAdd = []
|
||||
rrData = pdnsData['rrsets']
|
||||
rrAdd = []
|
||||
rrData = pdnsData['rrsets']
|
||||
|
||||
for domain, rrType, records in zoneData:
|
||||
found = False
|
||||
pdnsDom = list(filter(lambda _x: _x['name'] == domain and _x['type'] == rrType, rrData))
|
||||
if len(pdnsDom) > 0:
|
||||
rrSet = set(_x['content'] for _x in pdnsDom[0]['records'])
|
||||
if rrSet == set(records):
|
||||
found = True
|
||||
for domain, rrType, records in zoneData:
|
||||
found = False
|
||||
pdnsDom = list(filter(lambda _x: _x['name'] == domain and _x['type'] == rrType, rrData))
|
||||
if len(pdnsDom) > 0:
|
||||
rrSet = set(_x['content'].lower() for _x in pdnsDom[0]['records'])
|
||||
if rrSet == set(record.lower() for record in records):
|
||||
found = True
|
||||
|
||||
if not found:
|
||||
# new domain!
|
||||
rrAdd.append({
|
||||
"name": domain,
|
||||
"type": rrType,
|
||||
"ttl": 60*60,
|
||||
"changetype": "REPLACE",
|
||||
"records": [{"content": record, "disabled": False} for record in records],
|
||||
})
|
||||
if not found:
|
||||
# new domain!
|
||||
rrAdd.append({
|
||||
"name": domain,
|
||||
"type": rrType,
|
||||
"ttl": 60*60,
|
||||
"changetype": "REPLACE",
|
||||
"records": [{"content": record, "disabled": False} for record in records],
|
||||
})
|
||||
|
||||
return rrAdd
|
||||
return rrAdd
|
||||
|
||||
|
||||
def removeOldDomains(zoneData, pdnsData):
|
||||
rrDel = []
|
||||
rrDel = []
|
||||
|
||||
#print("zone data", zoneData)
|
||||
#print("pdnsData", pdnsData)
|
||||
for entry in pdnsData['rrsets']:
|
||||
# search for name/type in domain dict. if non-existtant mark for deletion
|
||||
# this could be much more efficient with a dict! name: [rrset...]
|
||||
if not any(entry['name'] == _x[0] and entry['type'] == _x[1] for _x in zoneData):
|
||||
rrDel.append({
|
||||
"changetype": "DELETE",
|
||||
"name": entry["name"],
|
||||
"type": entry["type"],
|
||||
})
|
||||
#print("zone data", zoneData)
|
||||
#print("pdnsData", pdnsData)
|
||||
for entry in pdnsData['rrsets']:
|
||||
# search for name/type in domain dict. if non-existtant mark for deletion
|
||||
# this could be much more efficient with a dict! name: [rrset...]
|
||||
if not any(entry['name'] == _x[0] and entry['type'] == _x[1] for _x in zoneData):
|
||||
rrDel.append({
|
||||
"changetype": "DELETE",
|
||||
"name": entry["name"],
|
||||
"type": entry["type"],
|
||||
})
|
||||
|
||||
return rrDel
|
||||
|
||||
return rrDel
|
||||
|
||||
def handleNameserver(ns, servers, usedNameservers, domains):
|
||||
servers.append(ns.name)
|
||||
servers.append(ns.name)
|
||||
|
||||
if ns.name not in usedNameservers and (ns.glueIPv4 or ns.glueIPv6):
|
||||
usedNameservers.append(ns.name)
|
||||
if ns.glueIPv4:
|
||||
domains.append((ns.name, "A", [ns.glueIPv4]))
|
||||
if ns.glueIPv6:
|
||||
domains.append((ns.name, "AAAA", [ns.glueIPv6]))
|
||||
if ns.name not in usedNameservers and (ns.glueIPv4 or ns.glueIPv6):
|
||||
usedNameservers.append(ns.name)
|
||||
if ns.glueIPv4:
|
||||
domains.append((ns.name, "A", [ns.glueIPv4]))
|
||||
if ns.glueIPv6:
|
||||
domains.append((ns.name, "AAAA", [ns.glueIPv6]))
|
||||
|
||||
|
||||
def getDomainsFromQueryset(qs, zone, glueRecords, usedNameservers, v4reverse=False):
|
||||
for domain in qs:
|
||||
servers = []
|
||||
for ns in domain.nameservers.all():
|
||||
servers.append(ns.name)
|
||||
for domain in qs:
|
||||
servers = []
|
||||
for ns in domain.nameservers.all():
|
||||
servers.append(ns.name)
|
||||
|
||||
if ns.name not in usedNameservers and (ns.glueIPv4 or ns.glueIPv6):
|
||||
usedNameservers.append(ns.name)
|
||||
if ns.glueIPv4:
|
||||
glueRecords.append((ns.name, "A", [ns.glueIPv4]))
|
||||
if ns.glueIPv6:
|
||||
glueRecords.append((ns.name, "AAAA", [ns.glueIPv6]))
|
||||
if ns.name not in usedNameservers and (ns.glueIPv4 or ns.glueIPv6):
|
||||
usedNameservers.append(ns.name)
|
||||
if ns.glueIPv4:
|
||||
glueRecords.append((ns.name, "A", [ns.glueIPv4]))
|
||||
if ns.glueIPv6:
|
||||
glueRecords.append((ns.name, "AAAA", [ns.glueIPv6]))
|
||||
|
||||
zone.append((domain.getZone(), "NS", servers))
|
||||
zone.append((domain.getZone(), "NS", servers))
|
||||
|
||||
if v4reverse:
|
||||
# for ipv4 reverse we have to do some extra work in case of classless delegations
|
||||
# see RFC2317
|
||||
net = domain.parentNet.getNetwork()
|
||||
if net.prefixlen % 8 != 0:
|
||||
revZone = domain.getZone()
|
||||
parts = str(net.network_address).split(".")
|
||||
baseZone = ".".join(reversed(parts[:net.prefixlen // 8])) + ".in-addr.arpa."
|
||||
startNo = int(parts[net.prefixlen // 8])
|
||||
lenExp = 8 - (net.prefixlen % 8)
|
||||
if domain.ds_records:
|
||||
zone.append((domain.getZone(), "DS", domain.ds_records.split("\n")))
|
||||
|
||||
if v4reverse:
|
||||
# for ipv4 reverse we have to do some extra work in case of classless delegations
|
||||
# see RFC2317
|
||||
net = domain.parentNet.getNetwork()
|
||||
if net.prefixlen % 8 != 0:
|
||||
revZone = domain.getZone()
|
||||
parts = str(net.network_address).split(".")
|
||||
baseZone = ".".join(reversed(parts[:net.prefixlen // 8])) + ".in-addr.arpa."
|
||||
startNo = int(parts[net.prefixlen // 8])
|
||||
lenExp = 8 - (net.prefixlen % 8)
|
||||
|
||||
for i in range(2 ** lenExp):
|
||||
no = startNo + i
|
||||
zone.append(("%d.%s" % (no, baseZone), "CNAME", ["%d.%s" % (no, revZone)]))
|
||||
|
||||
for i in range(2 ** lenExp):
|
||||
no = startNo + i
|
||||
zone.append(("%d.%s" % (no, baseZone), "CNAME", ["%d.%s" % (no, revZone)]))
|
||||
|
||||
def mergeDomainsWithPdns(s, args, zone, zoneData, protectedRecords=[]):
|
||||
url = "http://%s:%s/api/v1/servers/localhost/zones/%s" % (args.pdns_host, args.pdns_port, zone,)
|
||||
pdnsData = s.get(url).json()
|
||||
url = "http://%s:%s/api/v1/servers/localhost/zones/%s" % (args.pdns_host, args.pdns_port, zone,)
|
||||
pdnsData = s.get(url).json()
|
||||
|
||||
baseProtectedRecords = [
|
||||
(zone, "NS", []),
|
||||
(zone, "SOA", []),
|
||||
]
|
||||
baseProtectedRecords = [
|
||||
(zone, "NS", []),
|
||||
(zone, "SOA", []),
|
||||
]
|
||||
|
||||
# add dn. (NS + glue Nameservers)
|
||||
newDomains = mergeDomains(zoneData, pdnsData)
|
||||
print("Add/replace", newDomains)
|
||||
# add dn. (NS + glue Nameservers)
|
||||
newDomains = mergeDomains(zoneData, pdnsData)
|
||||
print("Add/replace", newDomains)
|
||||
|
||||
if len(newDomains) > 0:
|
||||
r = s.patch(url, data=json.dumps({'rrsets': newDomains}))
|
||||
if r.status_code != 204:
|
||||
raise RuntimeError("Could not update records in powerdns, API returned %d" % r.status_code)
|
||||
if len(newDomains) > 0:
|
||||
r = s.patch(url, data=json.dumps({'rrsets': newDomains}))
|
||||
if r.status_code != 204:
|
||||
raise RuntimeError("Could not update records in powerdns, API returned %d" % r.status_code)
|
||||
|
||||
delDomains = removeOldDomains(zoneData + protectedRecords + baseProtectedRecords, pdnsData)
|
||||
print("Del", delDomains)
|
||||
r = s.patch(url, data=json.dumps({'rrsets': delDomains}))
|
||||
if r.status_code != 204:
|
||||
raise RuntimeError("Could not update records in powerdns, API returned %d" % r.status_code)
|
||||
delDomains = removeOldDomains(zoneData + protectedRecords + baseProtectedRecords, pdnsData)
|
||||
print("Del", delDomains)
|
||||
r = s.patch(url, data=json.dumps({'rrsets': delDomains}))
|
||||
if r.status_code != 204:
|
||||
raise RuntimeError("Could not update records in powerdns, API returned %d" % r.status_code)
|
||||
|
||||
|
||||
def main():
|
||||
parser = _parser()
|
||||
args = parser.parse_args()
|
||||
parser = _parser()
|
||||
args = parser.parse_args()
|
||||
|
||||
config = configparser.ConfigParser()
|
||||
if args.config:
|
||||
config.read_file(args.config)
|
||||
else:
|
||||
config.read([os.path.join(os.path.abspath(__file__), "dns-sync.conf"), "/etc/dns-sync.conf"])
|
||||
#print(config)
|
||||
#print(config.get("DEFAULT", "api-key"))
|
||||
#print(config.has_section("DEFAULT"), config.has_option("DEFAULT", "api-key"))
|
||||
config = configparser.ConfigParser()
|
||||
if args.config:
|
||||
config.read_file(args.config)
|
||||
else:
|
||||
config.read([os.path.join(os.path.abspath(__file__), "dns-sync.conf"), "/etc/dns-sync.conf"])
|
||||
#print(config)
|
||||
#print(config.get("DEFAULT", "api-key"))
|
||||
#print(config.has_section("DEFAULT"), config.has_option("DEFAULT", "api-key"))
|
||||
|
||||
if args.api_key:
|
||||
config["DEFAULT"]["api-key"] = args.api_key
|
||||
if args.api_key:
|
||||
config["DEFAULT"]["api-key"] = args.api_key
|
||||
|
||||
if not config.has_option("DEFAULT", "api-key"):
|
||||
print("Error: Could not find api-key (not present in config under [DEFAULT]; not given via command line)", file=sys.stderr)
|
||||
sys.exit(2)
|
||||
if not config.has_option("DEFAULT", "api-key"):
|
||||
print("Error: Could not find api-key (not present in config under [DEFAULT]; not given via command line)", file=sys.stderr)
|
||||
sys.exit(2)
|
||||
|
||||
s = requests.Session()
|
||||
s.headers = {
|
||||
'X-API-Key': config.get("DEFAULT", "api-key"),
|
||||
'Accept': 'application/json'
|
||||
}
|
||||
s = requests.Session()
|
||||
s.headers = {
|
||||
'X-API-Key': config.get("DEFAULT", "api-key"),
|
||||
'Accept': 'application/json'
|
||||
}
|
||||
|
||||
domains = []
|
||||
rzone4 = []
|
||||
rzone6 = []
|
||||
usedNameservers = []
|
||||
domains = []
|
||||
rzone4 = []
|
||||
rzone6 = []
|
||||
usedNameservers = []
|
||||
|
||||
# assenble domain data
|
||||
# dn.
|
||||
qs = Domain.objects.annotate(nsCount=Count('nameservers')).filter(nsCount__gt=0).order_by("name")
|
||||
getDomainsFromQueryset(qs, domains, domains, usedNameservers)
|
||||
# assenble domain data
|
||||
# dn.
|
||||
qs = Domain.objects.annotate(nsCount=Count('nameservers')).filter(nsCount__gt=0).order_by("name")
|
||||
getDomainsFromQueryset(qs, domains, domains, usedNameservers)
|
||||
|
||||
# reverse zones
|
||||
qs = ReverseZone.objects.annotate(nsCount=Count('nameservers')).filter(nsCount__gt=0).order_by("parentNet__address")
|
||||
qs4 = filter(lambda _revz: _revz.getNetwork().version == 4, qs)
|
||||
qs6 = filter(lambda _revz: _revz.getNetwork().version == 6, qs)
|
||||
getDomainsFromQueryset(qs4, rzone4, domains, usedNameservers, v4reverse=True)
|
||||
getDomainsFromQueryset(qs6, rzone6, domains, usedNameservers)
|
||||
# reverse zones
|
||||
qs = ReverseZone.objects.annotate(nsCount=Count('nameservers')).filter(nsCount__gt=0).order_by("parentNet__address")
|
||||
qs4 = filter(lambda _revz: _revz.getNetwork().version == 4, qs)
|
||||
qs6 = filter(lambda _revz: _revz.getNetwork().version == 6, qs)
|
||||
getDomainsFromQueryset(qs4, rzone4, domains, usedNameservers, v4reverse=True)
|
||||
getDomainsFromQueryset(qs6, rzone6, domains, usedNameservers)
|
||||
|
||||
#print("dn.", domains)
|
||||
#print("v4", rzone4)
|
||||
#print("v6", rzone6)
|
||||
|
||||
mergeDomainsWithPdns(s, args, "dn.", domains)
|
||||
mergeDomainsWithPdns(s, args, "10.in-addr.arpa.", rzone4)
|
||||
mergeDomainsWithPdns(s, args, "3.2.7.c.3.a.d.f.ip6.arpa.", rzone6)
|
||||
#print("dn.", domains)
|
||||
#print("v4", rzone4)
|
||||
#print("v6", rzone6)
|
||||
|
||||
mergeDomainsWithPdns(s, args, "dn.", domains)
|
||||
mergeDomainsWithPdns(s, args, "10.in-addr.arpa.", rzone4)
|
||||
mergeDomainsWithPdns(s, args, "3.2.7.c.3.a.d.f.ip6.arpa.", rzone6)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
main()
|
||||
|
|
170
bin/import-data
170
bin/import-data
|
@ -24,107 +24,107 @@ from whoisdb.models import ASBlock, ASNumber, Contact, Maintainer, InetNum
|
|||
__VERSION__ = '0.1'
|
||||
|
||||
def _parser():
|
||||
parser = argparse.ArgumentParser(
|
||||
#prog='foo',
|
||||
#description='do some awesome foo',
|
||||
)
|
||||
parser = argparse.ArgumentParser(
|
||||
#prog='foo',
|
||||
#description='do some awesome foo',
|
||||
)
|
||||
|
||||
#parser.add_argument("-p", "--port", default=2323, type=int, help="Your port")
|
||||
#parser.add_argument("-v", "--verbose", default=False, action="store_true", help="Be more verbose")
|
||||
parser.add_argument("-j", "--json", type=argparse.FileType('r'), required=True, help="Path to json file")
|
||||
#parser.add_argument("-p", "--port", default=2323, type=int, help="Your port")
|
||||
#parser.add_argument("-v", "--verbose", default=False, action="store_true", help="Be more verbose")
|
||||
parser.add_argument("-j", "--json", type=argparse.FileType('r'), required=True, help="Path to json file")
|
||||
|
||||
parser.add_argument("--version", action="version", version="%(prog)s " + __VERSION__)
|
||||
parser.add_argument("--version", action="version", version="%(prog)s " + __VERSION__)
|
||||
|
||||
return parser
|
||||
return parser
|
||||
|
||||
def main():
|
||||
parser = _parser()
|
||||
args = parser.parse_args()
|
||||
parser = _parser()
|
||||
args = parser.parse_args()
|
||||
|
||||
defContact = Contact.objects.get(handle="UNKNOWN-DN")
|
||||
defMnt = Maintainer.objects.get(handle="DARKNET-MNT")
|
||||
blocks = [
|
||||
ASBlock.objects.get(handle="TRA1-ASB"),
|
||||
ASBlock.objects.get(handle="UAB1-ASB")
|
||||
]
|
||||
ranges = [
|
||||
InetNum.objects.get(handle="TRA1-NET"),
|
||||
InetNum.objects.get(handle="DEF4-NET"),
|
||||
InetNum.objects.get(handle="DEF6-NET"),
|
||||
InetNum.objects.get(handle="MISC6-NET"),
|
||||
InetNum.objects.get(handle="LTRA1-NET"),
|
||||
InetNum.objects.get(handle="MAIN4-NET"),
|
||||
]
|
||||
defContact = Contact.objects.get(handle="UNKNOWN-DN")
|
||||
defMnt = Maintainer.objects.get(handle="DARKNET-MNT")
|
||||
blocks = [
|
||||
ASBlock.objects.get(handle="TRA1-ASB"),
|
||||
ASBlock.objects.get(handle="UAB1-ASB")
|
||||
]
|
||||
ranges = [
|
||||
InetNum.objects.get(handle="TRA1-NET"),
|
||||
InetNum.objects.get(handle="DEF4-NET"),
|
||||
InetNum.objects.get(handle="DEF6-NET"),
|
||||
InetNum.objects.get(handle="MISC6-NET"),
|
||||
InetNum.objects.get(handle="LTRA1-NET"),
|
||||
InetNum.objects.get(handle="MAIN4-NET"),
|
||||
]
|
||||
|
||||
|
||||
data = json.load(args.json)
|
||||
print(data.keys())
|
||||
for k, v in data["handles"].items():
|
||||
print(k, v["person"])
|
||||
for asn in data["as"]:
|
||||
print(asn)
|
||||
if ASNumber.objects.filter(number=asn["number"]).count() > 0:
|
||||
continue
|
||||
data = json.load(args.json)
|
||||
print(data.keys())
|
||||
for k, v in data["handles"].items():
|
||||
print(k, v["person"])
|
||||
for asn in data["as"]:
|
||||
print(asn)
|
||||
if ASNumber.objects.filter(number=asn["number"]).count() > 0:
|
||||
continue
|
||||
|
||||
obj = ASNumber(number=asn["number"])
|
||||
block = None
|
||||
for block in blocks:
|
||||
if obj.number >= block.asBegin and obj.number <= block.asEnd:
|
||||
obj.asblock = block
|
||||
break
|
||||
else:
|
||||
raise ValueError("AS %d does not fit a block" % asn["number"])
|
||||
obj = ASNumber(number=asn["number"])
|
||||
block = None
|
||||
for block in blocks:
|
||||
if obj.number >= block.asBegin and obj.number <= block.asEnd:
|
||||
obj.asblock = block
|
||||
break
|
||||
else:
|
||||
raise ValueError("AS %d does not fit a block" % asn["number"])
|
||||
|
||||
if len(asn['admin_c']) >= 1:
|
||||
name = data["handles"][asn["admin_c"][0]]["person"]
|
||||
obj.name = "Imported AS of %s" % name
|
||||
obj.handle = ASNumber.genGenericHandle(re.sub("[^a-zA-Z0-9 ]", "", name))
|
||||
else:
|
||||
obj.name = "Imported AS without admin info"
|
||||
obj.handle = ASNumber.genGenericHandle("Unknown Imported AS")
|
||||
obj.description = "Object has been imported from old DB and has not yet been edited"
|
||||
obj.save()
|
||||
obj.mnt_by.add(defMnt)
|
||||
obj.admin_c.add(defContact)
|
||||
obj.save()
|
||||
if len(asn['admin_c']) >= 1:
|
||||
name = data["handles"][asn["admin_c"][0]]["person"]
|
||||
obj.name = "Imported AS of %s" % name
|
||||
obj.handle = ASNumber.genGenericHandle(re.sub("[^a-zA-Z0-9 ]", "", name))
|
||||
else:
|
||||
obj.name = "Imported AS without admin info"
|
||||
obj.handle = ASNumber.genGenericHandle("Unknown Imported AS")
|
||||
obj.description = "Object has been imported from old DB and has not yet been edited"
|
||||
obj.save()
|
||||
obj.mnt_by.add(defMnt)
|
||||
obj.admin_c.add(defContact)
|
||||
obj.save()
|
||||
|
||||
for net in data["network"]:
|
||||
print(net)
|
||||
network = ipaddress.ip_network(net["prefix"])
|
||||
for net in data["network"]:
|
||||
print(net)
|
||||
network = ipaddress.ip_network(net["prefix"])
|
||||
|
||||
if InetNum.objects.filter(address=str(network.network_address), netmask=network.prefixlen).count() > 0:
|
||||
continue
|
||||
if InetNum.objects.filter(address=str(network.network_address), netmask=network.prefixlen).count() > 0:
|
||||
continue
|
||||
|
||||
origin = None
|
||||
if net["origin"]:
|
||||
origin = ASNumber.objects.get(number=net["origin"])
|
||||
obj = InetNum(address=str(network.network_address), netmask=network.prefixlen)
|
||||
obj.protocol = InetNum.IPv4 if network.version == 4 else InetNum.IPv6
|
||||
origin = None
|
||||
if net["origin"]:
|
||||
origin = ASNumber.objects.get(number=net["origin"])
|
||||
obj = InetNum(address=str(network.network_address), netmask=network.prefixlen)
|
||||
obj.protocol = InetNum.IPv4 if network.version == 4 else InetNum.IPv6
|
||||
|
||||
x = list(filter(lambda _x: _x['number'] == net["origin"], data["as"]))
|
||||
if len(x) > 0 and x[0]["admin_c"]:
|
||||
name = data["handles"][x[0]["admin_c"][0]]["person"]
|
||||
obj.name = "Imported Network of %s" % name
|
||||
obj.handle = InetNum.genGenericHandle(re.sub("[^a-zA-Z0-9 ]", "", name))
|
||||
else:
|
||||
obj.name = "Imported Network without admin info"
|
||||
obj.handle = InetNum.genGenericHandle("Unknown Imported Network")
|
||||
obj.description = "Object has been imported from old DB and has not yet been edited"
|
||||
x = list(filter(lambda _x: _x['number'] == net["origin"], data["as"]))
|
||||
if len(x) > 0 and x[0]["admin_c"]:
|
||||
name = data["handles"][x[0]["admin_c"][0]]["person"]
|
||||
obj.name = "Imported Network of %s" % name
|
||||
obj.handle = InetNum.genGenericHandle(re.sub("[^a-zA-Z0-9 ]", "", name))
|
||||
else:
|
||||
obj.name = "Imported Network without admin info"
|
||||
obj.handle = InetNum.genGenericHandle("Unknown Imported Network")
|
||||
obj.description = "Object has been imported from old DB and has not yet been edited"
|
||||
|
||||
for r in ranges:
|
||||
if network.network_address in r.getNetwork():
|
||||
obj.parent_range = r
|
||||
break
|
||||
else:
|
||||
raise ValueError("%s did not fit in any netblock" % network)
|
||||
for r in ranges:
|
||||
if network.network_address in r.getNetwork():
|
||||
obj.parent_range = r
|
||||
break
|
||||
else:
|
||||
raise ValueError("%s did not fit in any netblock" % network)
|
||||
|
||||
obj.save()
|
||||
obj.save()
|
||||
|
||||
obj.mnt_by.add(defMnt)
|
||||
obj.admin_c.add(defContact)
|
||||
if origin:
|
||||
obj.origin_as.add(origin)
|
||||
obj.save()
|
||||
obj.mnt_by.add(defMnt)
|
||||
obj.admin_c.add(defContact)
|
||||
if origin:
|
||||
obj.origin_as.add(origin)
|
||||
obj.save()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
main()
|
||||
|
|
|
@ -12,11 +12,11 @@ import os
|
|||
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
files = [
|
||||
("templates/help/faq.md", "templates/help/faq.html"),
|
||||
("templates/help/faq.md", "templates/help/faq.html"),
|
||||
]
|
||||
|
||||
for srcFile, dstFile in files:
|
||||
srcFile = os.path.join(BASE_DIR, srcFile)
|
||||
dstFile = os.path.join(BASE_DIR, dstFile)
|
||||
markdown.markdownFromFile(open(srcFile, "rb"), open(dstFile, "wb"), extensions=[TocExtension(baselevel=1, permalink=True)])
|
||||
srcFile = os.path.join(BASE_DIR, srcFile)
|
||||
dstFile = os.path.join(BASE_DIR, dstFile)
|
||||
markdown.markdownFromFile(open(srcFile, "rb"), open(dstFile, "wb"), extensions=[TocExtension(baselevel=1, permalink=True)])
|
||||
|
||||
|
|
|
@ -22,26 +22,26 @@ from whoisdb.models import ASNumber
|
|||
__VERSION__ = '0.1'
|
||||
|
||||
def _parser():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser = argparse.ArgumentParser()
|
||||
|
||||
parser.add_argument("--version", action="version", version="%(prog)s " + __VERSION__)
|
||||
parser.add_argument("--version", action="version", version="%(prog)s " + __VERSION__)
|
||||
|
||||
return parser
|
||||
return parser
|
||||
|
||||
def main():
|
||||
parser = _parser()
|
||||
parser.parse_args()
|
||||
parser = _parser()
|
||||
parser.parse_args()
|
||||
|
||||
roa = {}
|
||||
for asn in ASNumber.objects.all():
|
||||
nets = []
|
||||
for net in asn.inetnum_set.all():
|
||||
nets.append(net.prefix())
|
||||
roa = {}
|
||||
for asn in ASNumber.objects.all():
|
||||
nets = []
|
||||
for net in asn.inetnum_set.all():
|
||||
nets.append(net.prefix())
|
||||
|
||||
if nets:
|
||||
roa[asn.number] = nets
|
||||
if nets:
|
||||
roa[asn.number] = nets
|
||||
|
||||
print(json.dumps(roa))
|
||||
print(json.dumps(roa))
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
main()
|
||||
|
|
118
bin/whoisd
118
bin/whoisd
|
@ -24,84 +24,84 @@ log = logging.getLogger("whoisd")
|
|||
__VERSION__ = '0.1'
|
||||
|
||||
class WhoisHandler(socketserver.BaseRequestHandler):
|
||||
header = "% This is the DARKNET database query service.\n" \
|
||||
"% The objects should be in something like RPSL format.\n" \
|
||||
"%\n" \
|
||||
"% The DARKNET database is subject to terms and conditions.\n" \
|
||||
"% Mostly these are \"be nice\" and \"don't knowingly break things\".\n" \
|
||||
"\n"
|
||||
header = "% This is the DARKNET database query service.\n" \
|
||||
"% The objects should be in something like RPSL format.\n" \
|
||||
"%\n" \
|
||||
"% The DARKNET database is subject to terms and conditions.\n" \
|
||||
"% Mostly these are \"be nice\" and \"don't knowingly break things\".\n" \
|
||||
"\n"
|
||||
|
||||
def handle(self):
|
||||
self.request.sendall(self.header.encode())
|
||||
line = self.request.recv(1024)
|
||||
line = line.split(b"\n", 2)[0].strip()
|
||||
print("Request object is %s" % line)
|
||||
log.info("Request by %s for %s" % (self.request.getpeername()[0], line))
|
||||
self.request.send(b"\n")
|
||||
def handle(self):
|
||||
self.request.sendall(self.header.encode())
|
||||
line = self.request.recv(1024)
|
||||
line = line.split(b"\n", 2)[0].strip()
|
||||
print("Request object is %s" % line)
|
||||
log.info("Request by %s for %s" % (self.request.getpeername()[0], line))
|
||||
self.request.send(b"\n")
|
||||
|
||||
objs = findInDatabase(line.decode())
|
||||
if len(objs) > 0:
|
||||
self.request.sendall(("%% %d result%s\n" % (len(objs), "" if len(objs)==1 else "s")).encode())
|
||||
for obj in objs:
|
||||
self.sendObject(obj)
|
||||
else:
|
||||
self.request.sendall(b"%% NOT FOUND\n\n")
|
||||
objs = findInDatabase(line.decode())
|
||||
if len(objs) > 0:
|
||||
self.request.sendall(("%% %d result%s\n" % (len(objs), "" if len(objs)==1 else "s")).encode())
|
||||
for obj in objs:
|
||||
self.sendObject(obj)
|
||||
else:
|
||||
self.request.sendall(b"%% NOT FOUND\n\n")
|
||||
|
||||
def sendObject(self, obj):
|
||||
result = [
|
||||
"",
|
||||
"%% Object %s (%s)" % (obj, obj.getClassName()),
|
||||
""
|
||||
]
|
||||
def sendObject(self, obj):
|
||||
result = [
|
||||
"",
|
||||
"%% Object %s (%s)" % (obj, obj.getClassName()),
|
||||
""
|
||||
]
|
||||
|
||||
for field, value in getWhoisObjectFields(obj, False):
|
||||
fieldName = field.lower().replace(" ", "-") + ":"
|
||||
if not value:
|
||||
value = ""
|
||||
for field, value in getWhoisObjectFields(obj, False):
|
||||
fieldName = field.lower().replace(" ", "-") + ":"
|
||||
if not value:
|
||||
value = ""
|
||||
|
||||
if hasattr(value, "through"):
|
||||
for v in value.all():
|
||||
result.append("%-16s %s" % (fieldName, v))
|
||||
else:
|
||||
result.append("%-16s %s" % (fieldName, value))
|
||||
result.extend(["", ""])
|
||||
if hasattr(value, "through"):
|
||||
for v in value.all():
|
||||
result.append("%-16s %s" % (fieldName, v))
|
||||
else:
|
||||
result.append("%-16s %s" % (fieldName, value))
|
||||
result.extend(["", ""])
|
||||
|
||||
self.request.sendall("\n".join(result).encode())
|
||||
self.request.sendall("\n".join(result).encode())
|
||||
|
||||
class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
|
||||
allow_reuse_address = True
|
||||
allow_reuse_address = True
|
||||
|
||||
|
||||
def _parser():
|
||||
parser = argparse.ArgumentParser(
|
||||
#prog='foo',
|
||||
#description='do some awesome foo',
|
||||
)
|
||||
parser = argparse.ArgumentParser(
|
||||
#prog='foo',
|
||||
#description='do some awesome foo',
|
||||
)
|
||||
|
||||
parser.add_argument("-p", "--port", default=43, type=int, help="whoisd port")
|
||||
#parser.add_argument("-v", "--verbose", default=False, action="store_true", help="Be more verbose")
|
||||
parser.add_argument("-p", "--port", default=43, type=int, help="whoisd port")
|
||||
#parser.add_argument("-v", "--verbose", default=False, action="store_true", help="Be more verbose")
|
||||
|
||||
parser.add_argument("--version", action="version", version="%(prog)s " + __VERSION__)
|
||||
parser.add_argument("--version", action="version", version="%(prog)s " + __VERSION__)
|
||||
|
||||
return parser
|
||||
return parser
|
||||
|
||||
def main():
|
||||
parser = _parser()
|
||||
args = parser.parse_args()
|
||||
parser = _parser()
|
||||
args = parser.parse_args()
|
||||
|
||||
server = ThreadedTCPServer(('', args.port), WhoisHandler)
|
||||
server = ThreadedTCPServer(('', args.port), WhoisHandler)
|
||||
|
||||
while True:
|
||||
try:
|
||||
server.serve_forever()
|
||||
except select.error as e:
|
||||
log.exception(e)
|
||||
except KeyboardInterrupt:
|
||||
log.info("^c hit, quitting.")
|
||||
break
|
||||
while True:
|
||||
try:
|
||||
server.serve_forever()
|
||||
except select.error as e:
|
||||
log.exception(e)
|
||||
except KeyboardInterrupt:
|
||||
log.info("^c hit, quitting.")
|
||||
break
|
||||
|
||||
server.server_close()
|
||||
server.server_close()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
main()
|
||||
|
|
|
@ -7,6 +7,6 @@ from .models import User
|
|||
|
||||
|
||||
class CustomUserCreationForm(UserCreationForm):
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ("username",)
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ("username",)
|
||||
|
|
|
@ -7,4 +7,4 @@ from django.db import models
|
|||
from django.contrib.auth.models import AbstractUser
|
||||
|
||||
class User(AbstractUser):
|
||||
pass
|
||||
pass
|
||||
|
|
|
@ -8,10 +8,10 @@ from django.contrib.auth import views as auth_views
|
|||
from . import views as dncore_views
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^$', dncore_views.dashboard, name='dashboard'),
|
||||
url(r'^$', dncore_views.dashboard, name='dashboard'),
|
||||
|
||||
url(r'^login/$', auth_views.login, name='login'),
|
||||
url(r'^register/$', dncore_views.RegisterUser.as_view(), name='register'),
|
||||
url(r'^logout/$', auth_views.logout, {'next_page': '/'}, name='logout'),
|
||||
url(r'^profile/$', dncore_views.profile, name='profile'),
|
||||
url(r'^login/$', auth_views.login, name='login'),
|
||||
url(r'^register/$', dncore_views.RegisterUser.as_view(), name='register'),
|
||||
url(r'^logout/$', auth_views.logout, {'next_page': '/'}, name='logout'),
|
||||
url(r'^profile/$', dncore_views.profile, name='profile'),
|
||||
]
|
||||
|
|
|
@ -22,54 +22,54 @@ from .forms import CustomUserCreationForm
|
|||
|
||||
@login_required
|
||||
def profile(request):
|
||||
pwForm = None
|
||||
pwForm = None
|
||||
|
||||
if request.method == "POST":
|
||||
if request.POST.get("submit", None) == "pwchange":
|
||||
pwForm = PasswordChangeForm(user=request.user, data=request.POST)
|
||||
if pwForm.is_valid():
|
||||
pwForm.save()
|
||||
auth_login(request, pwForm.user)
|
||||
messages.success(request, "Password changed")
|
||||
if request.method == "POST":
|
||||
if request.POST.get("submit", None) == "pwchange":
|
||||
pwForm = PasswordChangeForm(user=request.user, data=request.POST)
|
||||
if pwForm.is_valid():
|
||||
pwForm.save()
|
||||
auth_login(request, pwForm.user)
|
||||
messages.success(request, "Password changed")
|
||||
|
||||
return HttpResponseRedirect(reverse("user:profile"))
|
||||
return HttpResponseRedirect(reverse("user:profile"))
|
||||
|
||||
if not pwForm:
|
||||
pwForm = PasswordChangeForm(user=request.user)
|
||||
if not pwForm:
|
||||
pwForm = PasswordChangeForm(user=request.user)
|
||||
|
||||
return render(request, "registration/profile.html", {'pwForm': pwForm})
|
||||
return render(request, "registration/profile.html", {'pwForm': pwForm})
|
||||
|
||||
|
||||
@login_required
|
||||
def dashboard(request):
|
||||
mnts = request.user.maintainer_set.all()
|
||||
ownMnts = request.user.maintainer_set.filter(rir=False, lir=False).all().distinct()
|
||||
# if account only has rir/lir objects, show them
|
||||
if ownMnts.count() == 0:
|
||||
ownMnts = mnts
|
||||
mnts = request.user.maintainer_set.all()
|
||||
ownMnts = request.user.maintainer_set.filter(rir=False, lir=False).all().distinct()
|
||||
# if account only has rir/lir objects, show them
|
||||
if ownMnts.count() == 0:
|
||||
ownMnts = mnts
|
||||
|
||||
asns = ASNumber.objects.filter(Q(mnt_by__in=ownMnts) | Q(mnt_lower__in=ownMnts)).distinct()
|
||||
inetnums = InetNum.objects.filter(Q(mnt_by__in=ownMnts) | Q(mnt_lower__in=ownMnts)).distinct()
|
||||
domains = Domain.objects.filter(mnt_by__in=mnts).distinct()
|
||||
rrequests = Request.objects.filter((Q(provider__in=mnts) | Q(applicant__in=mnts)) & Q(status=Request.STATE_OPEN)).distinct()
|
||||
asns = ASNumber.objects.filter(Q(mnt_by__in=ownMnts) | Q(mnt_lower__in=ownMnts)).distinct()
|
||||
inetnums = InetNum.objects.filter(Q(mnt_by__in=ownMnts) | Q(mnt_lower__in=ownMnts)).distinct()
|
||||
domains = Domain.objects.filter(mnt_by__in=mnts).distinct()
|
||||
rrequests = Request.objects.filter((Q(provider__in=mnts) | Q(applicant__in=mnts)) & Q(status=Request.STATE_OPEN)).distinct()
|
||||
|
||||
return render(request, "dncore/dashboard.html", {"asns": asns, "inetnums": inetnums, "domains": domains, 'rrequests': rrequests})
|
||||
return render(request, "dncore/dashboard.html", {"asns": asns, "inetnums": inetnums, "domains": domains, 'rrequests': rrequests})
|
||||
|
||||
|
||||
def index(request):
|
||||
if request.user.is_authenticated():
|
||||
return HttpResponseRedirect(reverse("dashboard"))
|
||||
if request.user.is_authenticated():
|
||||
return HttpResponseRedirect(reverse("dashboard"))
|
||||
|
||||
return render(request, "index.html", {})
|
||||
return render(request, "index.html", {})
|
||||
|
||||
|
||||
class RegisterUser(CreateView):
|
||||
template_name = "dncore/registration.html"
|
||||
form_class = CustomUserCreationForm
|
||||
success_url = reverse_lazy("user:login")
|
||||
template_name = "dncore/registration.html"
|
||||
form_class = CustomUserCreationForm
|
||||
success_url = reverse_lazy("user:login")
|
||||
|
||||
def form_valid(self, form):
|
||||
ret = super(RegisterUser, self).form_valid(form)
|
||||
messages.success(self.request, "You successfully registered as user %s and can now log in!" % form.instance.username)
|
||||
def form_valid(self, form):
|
||||
ret = super(RegisterUser, self).form_valid(form)
|
||||
messages.success(self.request, "You successfully registered as user %s and can now log in!" % form.instance.username)
|
||||
|
||||
return ret
|
||||
return ret
|
||||
|
|
|
@ -21,7 +21,7 @@ from django.contrib import messages
|
|||
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
TLD_NAMESERVERS = [
|
||||
'10.100.100.100',
|
||||
'10.100.100.100',
|
||||
]
|
||||
|
||||
DATETIME_FORMAT = "Y-m-d H:i:s"
|
||||
|
@ -42,47 +42,47 @@ ALLOWED_HOSTS = ["*"]
|
|||
# Application definition
|
||||
|
||||
INSTALLED_APPS = [
|
||||
'django.contrib.admin',
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.messages',
|
||||
'django.contrib.staticfiles',
|
||||
'crispy_forms',
|
||||
'formtools',
|
||||
'dncore',
|
||||
'whoisdb',
|
||||
'rrequests',
|
||||
'domains',
|
||||
'api',
|
||||
'django.contrib.admin',
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.messages',
|
||||
'django.contrib.staticfiles',
|
||||
'crispy_forms',
|
||||
'formtools',
|
||||
'dncore',
|
||||
'whoisdb',
|
||||
'rrequests',
|
||||
'domains',
|
||||
'api',
|
||||
]
|
||||
|
||||
MIDDLEWARE = [
|
||||
'django.middleware.security.SecurityMiddleware',
|
||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
'django.middleware.csrf.CsrfViewMiddleware',
|
||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||
'django.contrib.messages.middleware.MessageMiddleware',
|
||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||
'django.middleware.security.SecurityMiddleware',
|
||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
'django.middleware.csrf.CsrfViewMiddleware',
|
||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||
'django.contrib.messages.middleware.MessageMiddleware',
|
||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||
]
|
||||
|
||||
ROOT_URLCONF = 'dnmgmt.urls'
|
||||
|
||||
TEMPLATES = [
|
||||
{
|
||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||
'DIRS': [os.path.join(BASE_DIR, "templates/")],
|
||||
'APP_DIRS': True,
|
||||
'OPTIONS': {
|
||||
'context_processors': [
|
||||
'django.template.context_processors.debug',
|
||||
'django.template.context_processors.request',
|
||||
'django.contrib.auth.context_processors.auth',
|
||||
'django.contrib.messages.context_processors.messages',
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||
'DIRS': [os.path.join(BASE_DIR, "templates/")],
|
||||
'APP_DIRS': True,
|
||||
'OPTIONS': {
|
||||
'context_processors': [
|
||||
'django.template.context_processors.debug',
|
||||
'django.template.context_processors.request',
|
||||
'django.contrib.auth.context_processors.auth',
|
||||
'django.contrib.messages.context_processors.messages',
|
||||
],
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
WSGI_APPLICATION = 'dnmgmt.wsgi.application'
|
||||
|
@ -92,10 +92,10 @@ WSGI_APPLICATION = 'dnmgmt.wsgi.application'
|
|||
# https://docs.djangoproject.com/en/1.10/ref/settings/#databases
|
||||
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.sqlite3',
|
||||
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
|
||||
}
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.sqlite3',
|
||||
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -103,18 +103,18 @@ DATABASES = {
|
|||
# https://docs.djangoproject.com/en/1.10/ref/settings/#auth-password-validators
|
||||
|
||||
AUTH_PASSWORD_VALIDATORS = [
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
|
||||
},
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
|
||||
},
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
|
||||
},
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
|
||||
},
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
|
||||
},
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
|
||||
},
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
|
||||
},
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
|
@ -139,11 +139,11 @@ USE_TZ = True
|
|||
STATIC_URL = '/static/'
|
||||
STATIC_ROOT = os.path.join(BASE_DIR, "cstatic")
|
||||
STATICFILES_DIRS = [
|
||||
os.path.join(BASE_DIR, "static"),
|
||||
os.path.join(BASE_DIR, "static"),
|
||||
]
|
||||
CRISPY_TEMPLATE_PACK = 'bootstrap3'
|
||||
MESSAGE_TAGS = {
|
||||
messages.ERROR: 'danger',
|
||||
messages.ERROR: 'danger',
|
||||
}
|
||||
|
||||
AUTH_USER_MODEL = 'dncore.User'
|
||||
|
|
|
@ -30,15 +30,15 @@ import api.urls
|
|||
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^$', dncore.views.index, name='index'),
|
||||
url(r'^dashboard/$', dncore.views.dashboard, name='dashboard'),
|
||||
url(r'^$', dncore.views.index, name='index'),
|
||||
url(r'^dashboard/$', dncore.views.dashboard, name='dashboard'),
|
||||
|
||||
url(r'^admin/', admin.site.urls),
|
||||
url(r'^user/', include(dncore.urls, namespace='user')),
|
||||
url(r'^whoisdb/', include(whoisdb.urls, namespace='whoisdb')),
|
||||
url(r'^rrequests/', include(rrequests.urls, namespace='rrequests')),
|
||||
url(r'^domains/', include(domains.urls, namespace='domains')),
|
||||
url(r'^api/', include(api.urls, namespace='api')),
|
||||
url(r'^user/', include(dncore.urls, namespace='user')),
|
||||
url(r'^whoisdb/', include(whoisdb.urls, namespace='whoisdb')),
|
||||
url(r'^rrequests/', include(rrequests.urls, namespace='rrequests')),
|
||||
url(r'^domains/', include(domains.urls, namespace='domains')),
|
||||
url(r'^api/', include(api.urls, namespace='api')),
|
||||
|
||||
url(r'^help/$', TemplateView.as_view(template_name='help/help.html'), name='help'),
|
||||
url(r'^help/$', TemplateView.as_view(template_name='help/help.html'), name='help'),
|
||||
]
|
||||
|
|
357
domains/forms.py
357
domains/forms.py
|
@ -15,229 +15,260 @@ import re
|
|||
import ipaddress
|
||||
|
||||
|
||||
class DomainForm(MntFormMixin, WhoisObjectFormMixin, forms.ModelForm):
|
||||
class Meta:
|
||||
model = Domain
|
||||
fields = ['name', 'nameservers', 'mnt_by', 'admin_c']
|
||||
class DSRecordMixin(object):
|
||||
ds_re = re.compile(r"^(?P<id>\d+)\s+(?P<crypto>\d+)\s+(?P<hashtype>\d+)\s+(?P<hash>[0-9a-fA-F]+)$")
|
||||
HASH_SUPPORTED = (1, 2)
|
||||
CRYPTO_SUPPORTED = (3, 5, 6, 8, 10, 13, 15)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(DomainForm, self).__init__(*args, **kwargs)
|
||||
def clean_ds_records(self):
|
||||
ds_records = self.cleaned_data['ds_records'].strip()
|
||||
result = []
|
||||
|
||||
mnts = self._user.maintainer_set.all()
|
||||
self.fields['nameservers'].queryset = Nameserver.objects.filter(Q(mnt_by__in=mnts))
|
||||
if not ds_records:
|
||||
return ''
|
||||
|
||||
instance = getattr(self, "instance", None)
|
||||
self._create = not (instance and instance.pk)
|
||||
for n, rec in enumerate(ds_records.split("\n"), 1):
|
||||
rec = rec.strip()
|
||||
m = self.ds_re.match(rec)
|
||||
if not m:
|
||||
raise forms.ValidationError("Could not parse records {} - needs to be in format "
|
||||
"'<id> <crypto> <hashtype> <hash>'".format(n))
|
||||
|
||||
if not self._create:
|
||||
self.fields['name'].disabled = True
|
||||
self.fields['nameservers'].queryset |= self.instance.nameservers.all()
|
||||
if int(m.group('hashtype')) not in self.HASH_SUPPORTED:
|
||||
raise forms.ValidationError("Record {} has an invalid hashtype of {}, supported are {}"
|
||||
"".format(n, m.group('hashtype'), " ".join(map(str, self.HASH_SUPPORTED))))
|
||||
if int(m.group('crypto')) not in self.CRYPTO_SUPPORTED:
|
||||
raise forms.ValidationError("Record {} has unsupported crypto {}, supported are {}"
|
||||
"".format(n, m.group('crypto'), " ".join(map(str, self.CRYPTO_SUPPORTED))))
|
||||
|
||||
self.fields['nameservers'].queryset = self.fields['nameservers'].queryset.distinct()
|
||||
result.append("{id} {crypto} {hashtype} {hash}".format(**m.groupdict()))
|
||||
|
||||
def clean_name(self):
|
||||
name = self.cleaned_data['name'].lower()
|
||||
if self._create:
|
||||
if not name.endswith("."):
|
||||
name += "."
|
||||
return "\n".join(result)
|
||||
|
||||
if not name.endswith("dn."):
|
||||
raise forms.ValidationError("Only .dn domains can be registered at this point")
|
||||
|
||||
if name.count(".") > 2:
|
||||
raise forms.ValidationError("No subdomains can be registered")
|
||||
class DomainForm(MntFormMixin, WhoisObjectFormMixin, DSRecordMixin, forms.ModelForm):
|
||||
class Meta:
|
||||
model = Domain
|
||||
fields = ['name', 'nameservers', 'mnt_by', 'admin_c', 'ds_records']
|
||||
|
||||
if not re.match("^[a-z0-9.-]+$", name):
|
||||
raise forms.ValidationError("Only a-z, 0-9 and - are allowed inside the domain name")
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(DomainForm, self).__init__(*args, **kwargs)
|
||||
|
||||
try:
|
||||
Domain.objects.get(name=name)
|
||||
raise forms.ValidationError("Domain already exists")
|
||||
except Domain.DoesNotExist:
|
||||
pass
|
||||
mnts = self._user.maintainer_set.all()
|
||||
self.fields['nameservers'].queryset = Nameserver.objects.filter(Q(mnt_by__in=mnts))
|
||||
|
||||
return name
|
||||
instance = getattr(self, "instance", None)
|
||||
self._create = not (instance and instance.pk)
|
||||
|
||||
if not self._create:
|
||||
self.fields['name'].disabled = True
|
||||
self.fields['nameservers'].queryset |= self.instance.nameservers.all()
|
||||
|
||||
self.fields['nameservers'].queryset = self.fields['nameservers'].queryset.distinct()
|
||||
|
||||
def clean_name(self):
|
||||
name = self.cleaned_data['name'].lower()
|
||||
if self._create:
|
||||
if not name.endswith("."):
|
||||
name += "."
|
||||
|
||||
if not name.endswith("dn."):
|
||||
raise forms.ValidationError("Only .dn domains can be registered at this point")
|
||||
|
||||
if name.count(".") > 2:
|
||||
raise forms.ValidationError("No subdomains can be registered")
|
||||
|
||||
if not re.match("^[a-z0-9.-]+$", name):
|
||||
raise forms.ValidationError("Only a-z, 0-9 and - are allowed inside the domain name")
|
||||
|
||||
try:
|
||||
Domain.objects.get(name=name)
|
||||
raise forms.ValidationError("Domain already exists")
|
||||
except Domain.DoesNotExist:
|
||||
pass
|
||||
|
||||
return name
|
||||
|
||||
|
||||
class NameserverForm(MntFormMixin, WhoisObjectFormMixin, forms.ModelForm):
|
||||
class Meta:
|
||||
model = Nameserver
|
||||
fields = ['name', 'glueIPv4', 'glueIPv6', 'mnt_by', 'admin_c']
|
||||
class Meta:
|
||||
model = Nameserver
|
||||
fields = ['name', 'glueIPv4', 'glueIPv6', 'mnt_by', 'admin_c']
|
||||
|
||||
help_texts = {
|
||||
"glueIPv4": "Note: You can only set a glue record if the base domain of this nameserver belongs to you!"
|
||||
}
|
||||
help_texts = {
|
||||
"glueIPv4": "Note: You can only set a glue record if the base domain of this nameserver belongs to you!"
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(NameserverForm, self).__init__(*args, **kwargs)
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(NameserverForm, self).__init__(*args, **kwargs)
|
||||
|
||||
instance = getattr(self, "instance", None)
|
||||
self._create = not (instance and instance.pk)
|
||||
instance = getattr(self, "instance", None)
|
||||
self._create = not (instance and instance.pk)
|
||||
|
||||
def cleanNetwork(self, glue):
|
||||
ip = ipaddress.ip_address(glue)
|
||||
proto = InetNum.IPv4 if ip.version == 4 else InetNum.IPv6
|
||||
nets = InetNum.objects.filter(parent_range=None, protocol=proto)
|
||||
def cleanNetwork(self, glue):
|
||||
ip = ipaddress.ip_address(glue)
|
||||
proto = InetNum.IPv4 if ip.version == 4 else InetNum.IPv6
|
||||
nets = InetNum.objects.filter(parent_range=None, protocol=proto)
|
||||
|
||||
if len(nets) == 0:
|
||||
raise forms.ValidationError("No range has been registered for IPv%s in the whois interface" % ip.version)
|
||||
if len(nets) == 0:
|
||||
raise forms.ValidationError("No range has been registered for IPv%s in the whois interface" % ip.version)
|
||||
|
||||
for net in nets:
|
||||
if ip in net.getNetwork():
|
||||
break
|
||||
else:
|
||||
raise forms.ValidationError("Glue record address is not inside DarkNet (subnet %s)" % ", ".join(map(lambda _x: _x.prefix(), nets)))
|
||||
for net in nets:
|
||||
if ip in net.getNetwork():
|
||||
break
|
||||
else:
|
||||
raise forms.ValidationError("Glue record address is not inside DarkNet (subnet %s)" % ", ".join(map(lambda _x: _x.prefix(), nets)))
|
||||
|
||||
def clean_glueIPv4(self):
|
||||
glue = self.cleaned_data['glueIPv4']
|
||||
def clean_glueIPv4(self):
|
||||
glue = self.cleaned_data['glueIPv4']
|
||||
|
||||
if glue:
|
||||
self.cleanNetwork(glue)
|
||||
if glue:
|
||||
self.cleanNetwork(glue)
|
||||
|
||||
return glue
|
||||
return glue
|
||||
|
||||
def clean_glueIPv6(self):
|
||||
glue = self.cleaned_data['glueIPv6']
|
||||
def clean_glueIPv6(self):
|
||||
glue = self.cleaned_data['glueIPv6']
|
||||
|
||||
if glue:
|
||||
self.cleanNetwork(glue)
|
||||
if glue:
|
||||
self.cleanNetwork(glue)
|
||||
|
||||
return glue
|
||||
return glue
|
||||
|
||||
def clean_name(self):
|
||||
name = self.cleaned_data['name'].lower().strip()
|
||||
if not name.endswith("."):
|
||||
name += "."
|
||||
def clean_name(self):
|
||||
name = self.cleaned_data['name'].lower().strip()
|
||||
if not name.endswith("."):
|
||||
name += "."
|
||||
|
||||
# allow name to stay if it did not change
|
||||
if not self._create and self.instance.name == name:
|
||||
return name
|
||||
# allow name to stay if it did not change
|
||||
if not self._create and self.instance.name == name:
|
||||
return name
|
||||
|
||||
if name.count(".") <= 2:
|
||||
raise forms.ValidationError("Nameserver must be inside a domain (e.g. ns1.noot.dn.)")
|
||||
if name.count(".") <= 2:
|
||||
raise forms.ValidationError("Nameserver must be inside a domain (e.g. ns1.noot.dn.)")
|
||||
|
||||
mnts = self._user.maintainer_set.all()
|
||||
try:
|
||||
obj = Nameserver.objects.get(name=name, mnt_by__in=mnts)
|
||||
if self._create or not self._create and obj.pk != self.instance.pk:
|
||||
raise forms.ValidationError("You already have a nameserver with this name under your control")
|
||||
except Nameserver.DoesNotExist:
|
||||
pass
|
||||
except Nameserver.MultipleObjectsReturned:
|
||||
pass
|
||||
mnts = self._user.maintainer_set.all()
|
||||
try:
|
||||
obj = Nameserver.objects.get(name=name, mnt_by__in=mnts)
|
||||
if self._create or not self._create and obj.pk != self.instance.pk:
|
||||
raise forms.ValidationError("You already have a nameserver with this name under your control")
|
||||
except Nameserver.DoesNotExist:
|
||||
pass
|
||||
except Nameserver.MultipleObjectsReturned:
|
||||
pass
|
||||
|
||||
return name
|
||||
return name
|
||||
|
||||
def clean(self):
|
||||
cleaned_data = super(NameserverForm, self).clean()
|
||||
def clean(self):
|
||||
cleaned_data = super(NameserverForm, self).clean()
|
||||
|
||||
if not self.errors:
|
||||
name = cleaned_data.get("name")
|
||||
mntBy = cleaned_data.get("mnt_by")
|
||||
zone = ".".join(name.split(".")[-3:])
|
||||
ipv4 = cleaned_data.get("glueIPv4", None)
|
||||
ipv6 = cleaned_data.get("glueIPv6", None)
|
||||
if not self.errors:
|
||||
name = cleaned_data.get("name")
|
||||
mntBy = cleaned_data.get("mnt_by")
|
||||
zone = ".".join(name.split(".")[-3:])
|
||||
ipv4 = cleaned_data.get("glueIPv4", None)
|
||||
ipv6 = cleaned_data.get("glueIPv6", None)
|
||||
|
||||
if not ipv4:
|
||||
ipv4 = None
|
||||
if not ipv6:
|
||||
ipv6 = None
|
||||
if not ipv4:
|
||||
ipv4 = None
|
||||
if not ipv6:
|
||||
ipv6 = None
|
||||
|
||||
if self._create and (ipv4 or ipv6) or not self._create and not (self.instance.glueIPv4 == ipv4 and self.instance.glueIPv6 == ipv6):
|
||||
mnts = self._user.maintainer_set.all()
|
||||
domains = Domain.objects.filter(mnt_by__in=mnts)
|
||||
found = False
|
||||
for domain in domains:
|
||||
if domain.name == zone:
|
||||
found = True
|
||||
break
|
||||
if self._create and (ipv4 or ipv6) or not self._create and not (self.instance.glueIPv4 == ipv4 and self.instance.glueIPv6 == ipv6):
|
||||
mnts = self._user.maintainer_set.all()
|
||||
domains = Domain.objects.filter(mnt_by__in=mnts)
|
||||
found = False
|
||||
for domain in domains:
|
||||
if domain.name == zone:
|
||||
found = True
|
||||
break
|
||||
|
||||
if not found:
|
||||
raise forms.ValidationError("You have glue IPs set, but this domain is not under a domain you control.")
|
||||
if not found:
|
||||
raise forms.ValidationError("You have glue IPs set, but this domain is not under a domain you control.")
|
||||
|
||||
if ipv4 or ipv6:
|
||||
try:
|
||||
ns = Nameserver.objects.get(Q(name=name) & (Q(glueIPv4__isnull=False) | Q(glueIPv6__isnull=False)))
|
||||
if self._create or ns.pk != self.instance.pk:
|
||||
nsMnts = ", ".join(n.handle for n in ns.mnt_by.all())
|
||||
if ipv4 or ipv6:
|
||||
try:
|
||||
ns = Nameserver.objects.get(Q(name=name) & (Q(glueIPv4__isnull=False) | Q(glueIPv6__isnull=False)))
|
||||
if self._create or ns.pk != self.instance.pk:
|
||||
nsMnts = ", ".join(n.handle for n in ns.mnt_by.all())
|
||||
|
||||
raise forms.ValidationError("Only one nameserver for this domain can have glue records and one already exists (maintained by %s)" % nsMnts)
|
||||
except Nameserver.DoesNotExist:
|
||||
pass
|
||||
raise forms.ValidationError("Only one nameserver for this domain can have glue records and one already exists (maintained by %s)" % nsMnts)
|
||||
except Nameserver.DoesNotExist:
|
||||
pass
|
||||
|
||||
failedMnts = set()
|
||||
for ns in Nameserver.objects.filter(name=name, mnt_by__in=mntBy):
|
||||
if self._create or self.instance.pk != ns.pk:
|
||||
for mnt in ns.mnt_by.all():
|
||||
if mnt in mntBy:
|
||||
failedMnts.add(mnt.handle)
|
||||
failedMnts = set()
|
||||
for ns in Nameserver.objects.filter(name=name, mnt_by__in=mntBy):
|
||||
if self._create or self.instance.pk != ns.pk:
|
||||
for mnt in ns.mnt_by.all():
|
||||
if mnt in mntBy:
|
||||
failedMnts.add(mnt.handle)
|
||||
|
||||
if len(failedMnts) > 0:
|
||||
raise forms.ValidationError("The following maintainer objects already have this nameservers: %s" % ", ".join(failedMnts))
|
||||
if len(failedMnts) > 0:
|
||||
raise forms.ValidationError("The following maintainer objects already have this nameservers: %s" % ", ".join(failedMnts))
|
||||
|
||||
|
||||
return cleaned_data
|
||||
return cleaned_data
|
||||
|
||||
|
||||
class ReverseZoneForm(forms.ModelForm):
|
||||
prefix = forms.CharField(validators=[IP46CIDRValidator])
|
||||
class ReverseZoneForm(DSRecordMixin, forms.ModelForm):
|
||||
prefix = forms.CharField(validators=[IP46CIDRValidator])
|
||||
|
||||
class Meta:
|
||||
model = ReverseZone
|
||||
fields = ['parentNet', 'nameservers']
|
||||
class Meta:
|
||||
model = ReverseZone
|
||||
fields = ['parentNet', 'nameservers']
|
||||
|
||||
help_texts = {
|
||||
"prefix": "The prefix in CIDR form for which this object is responsible",
|
||||
}
|
||||
help_texts = {
|
||||
"prefix": "The prefix in CIDR form for which this object is responsible",
|
||||
}
|
||||
|
||||
def __init__(self, user, *args, **kwargs):
|
||||
self._user = user
|
||||
def __init__(self, user, *args, **kwargs):
|
||||
self._user = user
|
||||
|
||||
super(ReverseZoneForm, self).__init__(*args, **kwargs)
|
||||
super(ReverseZoneForm, self).__init__(*args, **kwargs)
|
||||
|
||||
instance = getattr(self, "instance", None)
|
||||
self._create = not (instance and instance.pk)
|
||||
instance = getattr(self, "instance", None)
|
||||
self._create = not (instance and instance.pk)
|
||||
|
||||
mnts = self._user.maintainer_set.all()
|
||||
self.fields['parentNet'].queryset = InetNum.objects.filter(Q(mnt_by__in=mnts) | Q(mnt_lower__in=mnts)).distinct()
|
||||
mnts = self._user.maintainer_set.all()
|
||||
self.fields['parentNet'].queryset = InetNum.objects.filter(Q(mnt_by__in=mnts) | Q(mnt_lower__in=mnts)).distinct()
|
||||
|
||||
self.fields['nameservers'].queryset = Nameserver.objects.filter(Q(mnt_by__in=mnts))
|
||||
self.fields['nameservers'].queryset = Nameserver.objects.filter(Q(mnt_by__in=mnts))
|
||||
|
||||
if not self._create:
|
||||
self.fields['prefix'].disabled = True
|
||||
self.fields['nameservers'].queryset |= self.instance.nameservers.all()
|
||||
if not self._create:
|
||||
self.fields['prefix'].disabled = True
|
||||
self.fields['nameservers'].queryset |= self.instance.nameservers.all()
|
||||
|
||||
self.fields['nameservers'].queryset = self.fields['nameservers'].queryset.distinct()
|
||||
self.fields['nameservers'].queryset = self.fields['nameservers'].queryset.distinct()
|
||||
|
||||
def clean_prefix(self):
|
||||
prefix = self.cleaned_data['prefix']
|
||||
def clean_prefix(self):
|
||||
prefix = self.cleaned_data['prefix']
|
||||
|
||||
net = ipaddress.ip_network(prefix)
|
||||
if net.version == 6 and net.prefixlen % 4 != 0:
|
||||
raise forms.ValidationError("IPv6 reverse zone prefix length has to be a multiple of 4")
|
||||
net = ipaddress.ip_network(prefix)
|
||||
if net.version == 6 and net.prefixlen % 4 != 0:
|
||||
raise forms.ValidationError("IPv6 reverse zone prefix length has to be a multiple of 4")
|
||||
|
||||
return prefix
|
||||
return prefix
|
||||
|
||||
def clean(self):
|
||||
cleaned_data = super(ReverseZoneForm, self).clean()
|
||||
def clean(self):
|
||||
cleaned_data = super(ReverseZoneForm, self).clean()
|
||||
|
||||
if not self.errors:
|
||||
if self._create:
|
||||
net = ipaddress.ip_network(cleaned_data['prefix'])
|
||||
parentNet = cleaned_data['parentNet'].getNetwork()
|
||||
if not self.errors:
|
||||
if self._create:
|
||||
net = ipaddress.ip_network(cleaned_data['prefix'])
|
||||
parentNet = cleaned_data['parentNet'].getNetwork()
|
||||
|
||||
if net.network_address not in parentNet:
|
||||
raise forms.ValidationError("Given prefix %s is not inside of parent netblock %s" % (net, parentNet))
|
||||
if net.network_address not in parentNet:
|
||||
raise forms.ValidationError("Given prefix %s is not inside of parent netblock %s" % (net, parentNet))
|
||||
|
||||
# For now just check all the zones...
|
||||
#zones = ReverseZone.objects.filter(parentNet=cleaned_data['parentNet'])
|
||||
zones = ReverseZone.objects.all()
|
||||
for zone in zones:
|
||||
if net.network_address in zone.parentNet.getNetwork():
|
||||
raise forms.ValidationError("Given prefix already has a reverse zone object associated to it: %s" % zone)
|
||||
# For now just check all the zones...
|
||||
#zones = ReverseZone.objects.filter(parentNet=cleaned_data['parentNet'])
|
||||
zones = ReverseZone.objects.all()
|
||||
for zone in zones:
|
||||
if net.network_address in zone.parentNet.getNetwork():
|
||||
raise forms.ValidationError("Given prefix already has a reverse zone object associated to it: %s" % zone)
|
||||
|
||||
self.instance.address = str(net.network_address)
|
||||
self.instance.netmask = net.prefixlen
|
||||
self.instance.address = str(net.network_address)
|
||||
self.instance.netmask = net.prefixlen
|
||||
|
||||
|
||||
return cleaned_data
|
||||
return cleaned_data
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.5 on 2017-04-03 05:33
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('domains', '0003_auto_20170322_1801'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='domain',
|
||||
name='mnt_by',
|
||||
field=models.ManyToManyField(help_text='You can select multiple maintainers here', to='whoisdb.Maintainer'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='nameserver',
|
||||
name='mnt_by',
|
||||
field=models.ManyToManyField(help_text='You can select multiple maintainers here', to='whoisdb.Maintainer'),
|
||||
),
|
||||
]
|
|
@ -0,0 +1,20 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11 on 2019-05-30 21:18
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('domains', '0004_auto_20170403_0533'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='domain',
|
||||
name='ds_records',
|
||||
field=models.TextField(blank=True),
|
||||
),
|
||||
]
|
|
@ -13,139 +13,146 @@ import ipaddress
|
|||
# allow owners of a subnet to create reverse dns record?
|
||||
|
||||
|
||||
class DSRecordModelMixin(models.Model):
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
ds_records = models.TextField(blank=True, verbose_name='DS Records',
|
||||
help_text='DS Records in the format of [id] [crypto-algo] [hash-algo] [hash]')
|
||||
|
||||
class Nameserver(MntdObject):
|
||||
handleSuffix = "NS"
|
||||
# dns name
|
||||
# ip address, if glue
|
||||
# ipv4/ipv6 address?
|
||||
handle = None
|
||||
name = models.CharField(max_length=256)
|
||||
glueIPv4 = models.GenericIPAddressField(protocol='IPv4', blank=True, null=True)
|
||||
glueIPv6 = models.GenericIPAddressField(protocol='IPv6', blank=True, null=True)
|
||||
handleSuffix = "NS"
|
||||
# dns name
|
||||
# ip address, if glue
|
||||
# ipv4/ipv6 address?
|
||||
handle = None
|
||||
name = models.CharField(max_length=256)
|
||||
glueIPv4 = models.GenericIPAddressField(protocol='IPv4', blank=True, null=True)
|
||||
glueIPv6 = models.GenericIPAddressField(protocol='IPv6', blank=True, null=True)
|
||||
|
||||
admin_c = models.ManyToManyField(Contact)
|
||||
admin_c = models.ManyToManyField(Contact)
|
||||
|
||||
def getPK(self):
|
||||
return self.pk
|
||||
def getPK(self):
|
||||
return self.pk
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("domains:nameserver-show", args=(self.pk,))
|
||||
def get_absolute_url(self):
|
||||
return reverse("domains:nameserver-show", args=(self.pk,))
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
def getAppName(self):
|
||||
return "domains"
|
||||
def getAppName(self):
|
||||
return "domains"
|
||||
|
||||
def getNoDeleteReasons(self):
|
||||
# nameservers can always be deleted
|
||||
return []
|
||||
def getNoDeleteReasons(self):
|
||||
# nameservers can always be deleted
|
||||
return []
|
||||
|
||||
|
||||
class Domain(MntdObject):
|
||||
handle = None
|
||||
handleSuffix = "DOM"
|
||||
name = models.CharField(max_length=67, unique=True, db_index=True)
|
||||
class Domain(DSRecordModelMixin, MntdObject):
|
||||
handle = None
|
||||
handleSuffix = "DOM"
|
||||
name = models.CharField(max_length=67, unique=True, db_index=True)
|
||||
|
||||
nameservers = models.ManyToManyField(Nameserver, blank=True)
|
||||
admin_c = models.ManyToManyField(Contact)
|
||||
nameservers = models.ManyToManyField(Nameserver, blank=True)
|
||||
admin_c = models.ManyToManyField(Contact)
|
||||
|
||||
def getPK(self):
|
||||
return self.name
|
||||
def getPK(self):
|
||||
return self.name
|
||||
|
||||
def getZone(self):
|
||||
return self.name
|
||||
def getZone(self):
|
||||
return self.name
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("domains:domain-show", args=(self.name,))
|
||||
def get_absolute_url(self):
|
||||
return reverse("domains:domain-show", args=(self.name,))
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
def getAppName(self):
|
||||
return "domains"
|
||||
def getAppName(self):
|
||||
return "domains"
|
||||
|
||||
def getNoDeleteReasons(self):
|
||||
reasons = []
|
||||
def getNoDeleteReasons(self):
|
||||
reasons = []
|
||||
|
||||
nameservers = Nameserver.objects.filter(name__endswith="." + self.name)
|
||||
for ns in nameservers:
|
||||
# FIXME: check if the nameserver has a glue record.... and also if it is maintained by us
|
||||
reasons.append("Nameserver %s depends on this domain" % ns.name)
|
||||
nameservers = Nameserver.objects.filter(name__endswith="." + self.name)
|
||||
for ns in nameservers:
|
||||
# FIXME: check if the nameserver has a glue record.... and also if it is maintained by us
|
||||
reasons.append("Nameserver %s depends on this domain" % ns.name)
|
||||
|
||||
return reasons
|
||||
return reasons
|
||||
|
||||
@classmethod
|
||||
def fixName(clazz, name):
|
||||
if not name.endswith("."):
|
||||
name += "."
|
||||
return name.lower()
|
||||
@classmethod
|
||||
def fixName(clazz, name):
|
||||
if not name.endswith("."):
|
||||
name += "."
|
||||
return name.lower()
|
||||
|
||||
|
||||
class ReverseZone(WhoisObject):
|
||||
handle = None
|
||||
class ReverseZone(DSRecordModelMixin, WhoisObject):
|
||||
handle = None
|
||||
|
||||
parentNet = models.ForeignKey(InetNum)
|
||||
address = models.GenericIPAddressField(db_index=True)
|
||||
netmask = models.PositiveIntegerField()
|
||||
parentNet = models.ForeignKey(InetNum)
|
||||
address = models.GenericIPAddressField(db_index=True)
|
||||
netmask = models.PositiveIntegerField()
|
||||
|
||||
nameservers = models.ManyToManyField(Nameserver)
|
||||
nameservers = models.ManyToManyField(Nameserver)
|
||||
|
||||
def getPK(self):
|
||||
return self.pk
|
||||
def getPK(self):
|
||||
return self.pk
|
||||
|
||||
def prefix(self):
|
||||
""" Helper function, mainly used in templates """
|
||||
return "%s/%s" % (self.address, self.netmask)
|
||||
def prefix(self):
|
||||
""" Helper function, mainly used in templates """
|
||||
return "%s/%s" % (self.address, self.netmask)
|
||||
|
||||
def getNetwork(self):
|
||||
return ipaddress.ip_network(self.prefix())
|
||||
def getNetwork(self):
|
||||
return ipaddress.ip_network(self.prefix())
|
||||
|
||||
def getZone(self):
|
||||
net = self.parentNet.getNetwork()
|
||||
if net.version == 4:
|
||||
# does not work with python3.4
|
||||
## for these we delegate the full domain
|
||||
#if 0 < net.prefixlen < 32 and net.prefixlen % 8 == 0:
|
||||
# zoneParts = net.reverse_pointer.split(".")
|
||||
def getZone(self):
|
||||
net = self.parentNet.getNetwork()
|
||||
if net.version == 4:
|
||||
# does not work with python3.4
|
||||
## for these we delegate the full domain
|
||||
#if 0 < net.prefixlen < 32 and net.prefixlen % 8 == 0:
|
||||
# zoneParts = net.reverse_pointer.split(".")
|
||||
|
||||
# return ".".join(zoneParts[1:])
|
||||
#else:
|
||||
# # return RFC2317 compliant zone
|
||||
# return net.reverse_pointer
|
||||
parts = list(reversed(str(net.network_address).split(".")))
|
||||
domain = ".".join(parts[4 - net.prefixlen // 8:]) + ".in-addr.arpa."
|
||||
if net.prefixlen % 8 == 0:
|
||||
# clean cut!
|
||||
return domain
|
||||
else:
|
||||
# RFC2317 compliant!
|
||||
rfc2317Domain = "%s/%s.%s" % (parts[4 - net.prefixlen // 8 - 1], net.prefixlen, domain)
|
||||
return rfc2317Domain
|
||||
else:
|
||||
## does not work with python3.4
|
||||
## ipv6
|
||||
## thefuck ipaddress lib... _the_ _fuck_
|
||||
#zoneParts = net.reverse_pointer.split(".")[-2 - net.prefixlen // 4:]
|
||||
#return ".".join(zoneParts)
|
||||
# return ".".join(zoneParts[1:])
|
||||
#else:
|
||||
# # return RFC2317 compliant zone
|
||||
# return net.reverse_pointer
|
||||
parts = list(reversed(str(net.network_address).split(".")))
|
||||
domain = ".".join(parts[4 - net.prefixlen // 8:]) + ".in-addr.arpa."
|
||||
if net.prefixlen % 8 == 0:
|
||||
# clean cut!
|
||||
return domain
|
||||
else:
|
||||
# RFC2317 compliant!
|
||||
rfc2317Domain = "%s/%s.%s" % (parts[4 - net.prefixlen // 8 - 1], net.prefixlen, domain)
|
||||
return rfc2317Domain
|
||||
else:
|
||||
## does not work with python3.4
|
||||
## ipv6
|
||||
## thefuck ipaddress lib... _the_ _fuck_
|
||||
#zoneParts = net.reverse_pointer.split(".")[-2 - net.prefixlen // 4:]
|
||||
#return ".".join(zoneParts)
|
||||
|
||||
parts = list(reversed(net.exploded.split("/")[0].replace(":", "")))[32 - net.prefixlen // 4:]
|
||||
return ".".join(parts) + ".ip6.arpa."
|
||||
parts = list(reversed(net.exploded.split("/")[0].replace(":", "")))[32 - net.prefixlen // 4:]
|
||||
return ".".join(parts) + ".ip6.arpa."
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("domains:reversezone-show", args=(self.pk,))
|
||||
def get_absolute_url(self):
|
||||
return reverse("domains:reversezone-show", args=(self.pk,))
|
||||
|
||||
def getAppName(self):
|
||||
return "domains"
|
||||
def getAppName(self):
|
||||
return "domains"
|
||||
|
||||
def __str__(self):
|
||||
return "%s @ %s" % (self.prefix(), self.parentNet)
|
||||
def __str__(self):
|
||||
return "%s @ %s" % (self.prefix(), self.parentNet)
|
||||
|
||||
def getNoDeleteReasons(self):
|
||||
return []
|
||||
def getNoDeleteReasons(self):
|
||||
return []
|
||||
|
||||
def canEdit(self, user):
|
||||
if self.parentNet:
|
||||
return self.parentNet.canEdit(user)
|
||||
else:
|
||||
return False
|
||||
def canEdit(self, user):
|
||||
if self.parentNet:
|
||||
return self.parentNet.canEdit(user)
|
||||
else:
|
||||
return False
|
||||
|
|
|
@ -7,23 +7,23 @@ from django.conf.urls import url
|
|||
from . import views as domains_views
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^$', domains_views.overview, name='overview'),
|
||||
url(r'^$', domains_views.overview, name='overview'),
|
||||
|
||||
url(r'domain/create/$', domains_views.DomainCreate.as_view(), name='domain-create'),
|
||||
url(r'domain/check/(?P<domain>[a-z0-9.-]+)/$', domains_views.DomainCheck.as_view(), name='domain-check'),
|
||||
url(r'domain/show/(?P<domain>[a-z0-9.-]+)/$', domains_views.DomainDetail.as_view(), name='domain-show'),
|
||||
url(r'domain/edit/(?P<domain>[a-z0-9.-]+)/$', domains_views.DomainEdit.as_view(), name='domain-edit'),
|
||||
url(r'domain/delete/(?P<domain>[a-z0-9.-]+)/$', domains_views.DomainDelete.as_view(), name='domain-delete'),
|
||||
url(r'domain/create/$', domains_views.DomainCreate.as_view(), name='domain-create'),
|
||||
url(r'domain/check/(?P<domain>[a-z0-9.-]+)/$', domains_views.DomainCheck.as_view(), name='domain-check'),
|
||||
url(r'domain/show/(?P<domain>[a-z0-9.-]+)/$', domains_views.DomainDetail.as_view(), name='domain-show'),
|
||||
url(r'domain/edit/(?P<domain>[a-z0-9.-]+)/$', domains_views.DomainEdit.as_view(), name='domain-edit'),
|
||||
url(r'domain/delete/(?P<domain>[a-z0-9.-]+)/$', domains_views.DomainDelete.as_view(), name='domain-delete'),
|
||||
|
||||
url(r'nameserver/create/$', domains_views.NameserverCreate.as_view(), name='nameserver-create'),
|
||||
url(r'nameserver/show/(?P<pk>[0-9]+)/$', domains_views.NameserverDetail.as_view(), name='nameserver-show'),
|
||||
url(r'nameserver/edit/(?P<pk>[0-9]+)/$', domains_views.NameserverEdit.as_view(), name='nameserver-edit'),
|
||||
url(r'nameserver/delete/(?P<pk>[0-9]+)/$', domains_views.NameserverDelete.as_view(), name='nameserver-delete'),
|
||||
url(r'nameserver/create/$', domains_views.NameserverCreate.as_view(), name='nameserver-create'),
|
||||
url(r'nameserver/show/(?P<pk>[0-9]+)/$', domains_views.NameserverDetail.as_view(), name='nameserver-show'),
|
||||
url(r'nameserver/edit/(?P<pk>[0-9]+)/$', domains_views.NameserverEdit.as_view(), name='nameserver-edit'),
|
||||
url(r'nameserver/delete/(?P<pk>[0-9]+)/$', domains_views.NameserverDelete.as_view(), name='nameserver-delete'),
|
||||
|
||||
url(r'reversezone/create/$', domains_views.ReverseZoneCreate.as_view(), name='reversezone-create'),
|
||||
url(r'reversezone/show/(?P<pk>[0-9]+)/$', domains_views.ReverseZoneDetail.as_view(), name='reversezone-show'),
|
||||
url(r'reversezone/check/(?P<pk>[0-9]+)/$', domains_views.ReverseZoneCheck.as_view(), name='reversezone-check'),
|
||||
url(r'reversezone/edit/(?P<pk>[0-9]+)/$', domains_views.ReverseZoneEdit.as_view(), name='reversezone-edit'),
|
||||
url(r'reversezone/delete/(?P<pk>[0-9]+)/$', domains_views.ReverseZoneDelete.as_view(), name='reversezone-delete'),
|
||||
url(r'reversezone/create/$', domains_views.ReverseZoneCreate.as_view(), name='reversezone-create'),
|
||||
url(r'reversezone/show/(?P<pk>[0-9]+)/$', domains_views.ReverseZoneDetail.as_view(), name='reversezone-show'),
|
||||
url(r'reversezone/check/(?P<pk>[0-9]+)/$', domains_views.ReverseZoneCheck.as_view(), name='reversezone-check'),
|
||||
url(r'reversezone/edit/(?P<pk>[0-9]+)/$', domains_views.ReverseZoneEdit.as_view(), name='reversezone-edit'),
|
||||
url(r'reversezone/delete/(?P<pk>[0-9]+)/$', domains_views.ReverseZoneDelete.as_view(), name='reversezone-delete'),
|
||||
|
||||
]
|
||||
|
|
186
domains/views.py
186
domains/views.py
|
@ -17,157 +17,157 @@ from .forms import DomainForm, NameserverForm, ReverseZoneForm
|
|||
|
||||
@login_required
|
||||
def overview(request):
|
||||
mnts = request.user.maintainer_set.all()
|
||||
mnts = request.user.maintainer_set.all()
|
||||
|
||||
# get all domains and nameservers
|
||||
domains = Domain.objects.filter(mnt_by__in=mnts).distinct()
|
||||
nameservers = Nameserver.objects.filter(mnt_by__in=mnts).distinct()
|
||||
reversezones = ReverseZone.objects.filter(Q(parentNet__mnt_by__in=mnts) | Q(parentNet__mnt_lower__in=mnts)).distinct()
|
||||
# get all domains and nameservers
|
||||
domains = Domain.objects.filter(mnt_by__in=mnts).distinct()
|
||||
nameservers = Nameserver.objects.filter(mnt_by__in=mnts).distinct()
|
||||
reversezones = ReverseZone.objects.filter(Q(parentNet__mnt_by__in=mnts) | Q(parentNet__mnt_lower__in=mnts)).distinct()
|
||||
|
||||
return render(request, "domains/overview.html", {"mnts": mnts, "domains": domains, "nameservers": nameservers, 'reversezones': reversezones})
|
||||
return render(request, "domains/overview.html", {"mnts": mnts, "domains": domains, "nameservers": nameservers, 'reversezones': reversezones})
|
||||
|
||||
|
||||
class DomainCreate(LoginRequiredMixin, CreateView):
|
||||
template_name = "domains/obj_create.html"
|
||||
form_class = DomainForm
|
||||
template_name = "domains/obj_create.html"
|
||||
form_class = DomainForm
|
||||
|
||||
def get_form_kwargs(self, *args, **kwargs):
|
||||
kwargs = super(DomainCreate, self).get_form_kwargs(*args, **kwargs)
|
||||
kwargs["user"] = self.request.user
|
||||
def get_form_kwargs(self, *args, **kwargs):
|
||||
kwargs = super(DomainCreate, self).get_form_kwargs(*args, **kwargs)
|
||||
kwargs["user"] = self.request.user
|
||||
|
||||
return kwargs
|
||||
return kwargs
|
||||
|
||||
|
||||
class DomainCheck(LoginRequiredMixin, DetailView):
|
||||
model = Domain
|
||||
slug_field = "name"
|
||||
slug_url_kwarg = "domain"
|
||||
context_object_name = "domain"
|
||||
template_name = "domains/dns_check.html"
|
||||
model = Domain
|
||||
slug_field = "name"
|
||||
slug_url_kwarg = "domain"
|
||||
context_object_name = "domain"
|
||||
template_name = "domains/dns_check.html"
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
ctx = super(DomainCheck, self).get_context_data(**kwargs)
|
||||
ctx["key"] = self.object.name
|
||||
ctx["apiUrl"] = reverse("api:domain-check")
|
||||
def get_context_data(self, **kwargs):
|
||||
ctx = super(DomainCheck, self).get_context_data(**kwargs)
|
||||
ctx["key"] = self.object.name
|
||||
ctx["apiUrl"] = reverse("api:domain-check")
|
||||
|
||||
return ctx
|
||||
return ctx
|
||||
|
||||
|
||||
class DomainDetail(LoginRequiredMixin, DetailView):
|
||||
model = Domain
|
||||
slug_field = "name"
|
||||
slug_url_kwarg = "domain"
|
||||
context_object_name = "domain"
|
||||
model = Domain
|
||||
slug_field = "name"
|
||||
slug_url_kwarg = "domain"
|
||||
context_object_name = "domain"
|
||||
|
||||
template_name = "whoisdb/handle_show.html"
|
||||
template_name = "whoisdb/handle_show.html"
|
||||
|
||||
|
||||
class DomainEdit(MntGenericMixin, LoginRequiredMixin, UpdateView):
|
||||
model = Domain
|
||||
form_class = DomainForm
|
||||
slug_field = "name"
|
||||
slug_url_kwarg = "domain"
|
||||
template_name = "domains/obj_edit.html"
|
||||
model = Domain
|
||||
form_class = DomainForm
|
||||
slug_field = "name"
|
||||
slug_url_kwarg = "domain"
|
||||
template_name = "domains/obj_edit.html"
|
||||
|
||||
def get_form_kwargs(self, *args, **kwargs):
|
||||
kwargs = super(DomainEdit, self).get_form_kwargs(*args, **kwargs)
|
||||
kwargs["user"] = self.request.user
|
||||
return kwargs
|
||||
def get_form_kwargs(self, *args, **kwargs):
|
||||
kwargs = super(DomainEdit, self).get_form_kwargs(*args, **kwargs)
|
||||
kwargs["user"] = self.request.user
|
||||
return kwargs
|
||||
|
||||
|
||||
class DomainDelete(MntGenericMixin, LoginRequiredMixin, DeleteCheckView):
|
||||
template_name = "domains/obj_delete.html"
|
||||
model = Domain
|
||||
slug_field = "name"
|
||||
slug_url_kwarg = "domain"
|
||||
success_url = reverse_lazy("domains:overview")
|
||||
template_name = "domains/obj_delete.html"
|
||||
model = Domain
|
||||
slug_field = "name"
|
||||
slug_url_kwarg = "domain"
|
||||
success_url = reverse_lazy("domains:overview")
|
||||
|
||||
|
||||
class NameserverCreate(LoginRequiredMixin, CreateView):
|
||||
template_name = "domains/obj_create.html"
|
||||
form_class = NameserverForm
|
||||
template_name = "domains/obj_create.html"
|
||||
form_class = NameserverForm
|
||||
|
||||
def get_form_kwargs(self, *args, **kwargs):
|
||||
kwargs = super(NameserverCreate, self).get_form_kwargs(*args, **kwargs)
|
||||
kwargs["user"] = self.request.user
|
||||
def get_form_kwargs(self, *args, **kwargs):
|
||||
kwargs = super(NameserverCreate, self).get_form_kwargs(*args, **kwargs)
|
||||
kwargs["user"] = self.request.user
|
||||
|
||||
return kwargs
|
||||
return kwargs
|
||||
|
||||
|
||||
class NameserverDetail(LoginRequiredMixin, DetailView):
|
||||
model = Nameserver
|
||||
template_name = "whoisdb/handle_show.html"
|
||||
model = Nameserver
|
||||
template_name = "whoisdb/handle_show.html"
|
||||
|
||||
|
||||
class NameserverEdit(MntGenericMixin, LoginRequiredMixin, UpdateView):
|
||||
model = Nameserver
|
||||
form_class = NameserverForm
|
||||
template_name = "domains/obj_edit.html"
|
||||
model = Nameserver
|
||||
form_class = NameserverForm
|
||||
template_name = "domains/obj_edit.html"
|
||||
|
||||
def get_form_kwargs(self, *args, **kwargs):
|
||||
kwargs = super(NameserverEdit, self).get_form_kwargs(*args, **kwargs)
|
||||
kwargs["user"] = self.request.user
|
||||
return kwargs
|
||||
def get_form_kwargs(self, *args, **kwargs):
|
||||
kwargs = super(NameserverEdit, self).get_form_kwargs(*args, **kwargs)
|
||||
kwargs["user"] = self.request.user
|
||||
return kwargs
|
||||
|
||||
|
||||
class NameserverDelete(MntGenericMixin, LoginRequiredMixin, DeleteCheckView):
|
||||
template_name = "domains/obj_delete.html"
|
||||
model = Nameserver
|
||||
success_url = reverse_lazy("domains:overview")
|
||||
template_name = "domains/obj_delete.html"
|
||||
model = Nameserver
|
||||
success_url = reverse_lazy("domains:overview")
|
||||
|
||||
|
||||
class ReverseZoneCreate(LoginRequiredMixin, CreateView):
|
||||
template_name = "domains/obj_create.html"
|
||||
form_class = ReverseZoneForm
|
||||
template_name = "domains/obj_create.html"
|
||||
form_class = ReverseZoneForm
|
||||
|
||||
def get_form_kwargs(self, *args, **kwargs):
|
||||
kwargs = super(ReverseZoneCreate, self).get_form_kwargs(*args, **kwargs)
|
||||
kwargs["user"] = self.request.user
|
||||
def get_form_kwargs(self, *args, **kwargs):
|
||||
kwargs = super(ReverseZoneCreate, self).get_form_kwargs(*args, **kwargs)
|
||||
kwargs["user"] = self.request.user
|
||||
|
||||
return kwargs
|
||||
return kwargs
|
||||
|
||||
|
||||
class ReverseZoneCheck(LoginRequiredMixin, DetailView):
|
||||
model = ReverseZone
|
||||
template_name = "domains/dns_check.html"
|
||||
model = ReverseZone
|
||||
template_name = "domains/dns_check.html"
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
ctx = super(ReverseZoneCheck, self).get_context_data(**kwargs)
|
||||
ctx["key"] = self.object.id
|
||||
ctx["apiUrl"] = reverse("api:reversezone-check")
|
||||
def get_context_data(self, **kwargs):
|
||||
ctx = super(ReverseZoneCheck, self).get_context_data(**kwargs)
|
||||
ctx["key"] = self.object.id
|
||||
ctx["apiUrl"] = reverse("api:reversezone-check")
|
||||
|
||||
return ctx
|
||||
return ctx
|
||||
|
||||
class ReverseZoneDetail(LoginRequiredMixin, DetailView):
|
||||
model = ReverseZone
|
||||
template_name = "whoisdb/handle_show.html"
|
||||
model = ReverseZone
|
||||
template_name = "whoisdb/handle_show.html"
|
||||
|
||||
|
||||
class ReverseZoneEdit(MntGenericMixin, LoginRequiredMixin, UpdateView):
|
||||
model = ReverseZone
|
||||
form_class = ReverseZoneForm
|
||||
template_name = "domains/obj_edit.html"
|
||||
model = ReverseZone
|
||||
form_class = ReverseZoneForm
|
||||
template_name = "domains/obj_edit.html"
|
||||
|
||||
def get_form_kwargs(self, *args, **kwargs):
|
||||
kwargs = super(ReverseZoneEdit, self).get_form_kwargs(*args, **kwargs)
|
||||
kwargs["user"] = self.request.user
|
||||
def get_form_kwargs(self, *args, **kwargs):
|
||||
kwargs = super(ReverseZoneEdit, self).get_form_kwargs(*args, **kwargs)
|
||||
kwargs["user"] = self.request.user
|
||||
|
||||
if "initial" not in kwargs:
|
||||
kwargs["initial"] = {}
|
||||
if "initial" not in kwargs:
|
||||
kwargs["initial"] = {}
|
||||
|
||||
kwargs["initial"]["prefix"] = self.object.prefix()
|
||||
return kwargs
|
||||
kwargs["initial"]["prefix"] = self.object.prefix()
|
||||
return kwargs
|
||||
|
||||
def get_queryset(self):
|
||||
mnts = self.request.user.maintainer_set.all()
|
||||
return ReverseZone.objects.filter(Q(parentNet__mnt_by__in=mnts) | Q(parentNet__mnt_lower__in=mnts)).distinct()
|
||||
def get_queryset(self):
|
||||
mnts = self.request.user.maintainer_set.all()
|
||||
return ReverseZone.objects.filter(Q(parentNet__mnt_by__in=mnts) | Q(parentNet__mnt_lower__in=mnts)).distinct()
|
||||
|
||||
|
||||
class ReverseZoneDelete(LoginRequiredMixin, DeleteCheckView):
|
||||
template_name = "domains/obj_delete.html"
|
||||
model = ReverseZone
|
||||
success_url = reverse_lazy("domains:overview")
|
||||
template_name = "domains/obj_delete.html"
|
||||
model = ReverseZone
|
||||
success_url = reverse_lazy("domains:overview")
|
||||
|
||||
def get_queryset(self):
|
||||
mnts = self.request.user.maintainer_set.all()
|
||||
return ReverseZone.objects.filter(Q(parentNet__mnt_by__in=mnts) | Q(parentNet__mnt_lower__in=mnts)).distinct()
|
||||
def get_queryset(self):
|
||||
mnts = self.request.user.maintainer_set.all()
|
||||
return ReverseZone.objects.filter(Q(parentNet__mnt_by__in=mnts) | Q(parentNet__mnt_lower__in=mnts)).distinct()
|
||||
|
|
|
@ -9,51 +9,51 @@ from .models import Request
|
|||
from whoisdb.models import Maintainer
|
||||
|
||||
class RequestForm(forms.Form):
|
||||
RESOURCES = map(lambda _x: (_x, _x), [
|
||||
"AS Number (16bit)", "IPv4 /27", "IPv4 > /27", "IPv6", "other"
|
||||
])
|
||||
RESOURCES = map(lambda _x: (_x, _x), [
|
||||
"AS Number (16bit)", "IPv4 /27", "IPv4 > /27", "IPv6", "other"
|
||||
])
|
||||
|
||||
applicant = forms.ModelChoiceField(Maintainer.objects.none(), label="Applicant (you)", help_text="Maintainer you want to request resources for")
|
||||
provider = forms.ModelChoiceField(Maintainer.objects.none(), label="Provider", help_text="LIR/RIR you want to request resources from")
|
||||
applicant = forms.ModelChoiceField(Maintainer.objects.none(), label="Applicant (you)", help_text="Maintainer you want to request resources for")
|
||||
provider = forms.ModelChoiceField(Maintainer.objects.none(), label="Provider", help_text="LIR/RIR you want to request resources from")
|
||||
|
||||
subject = forms.CharField(label="Subject")
|
||||
resources = forms.CheckboxSelectMultiple(choices=RESOURCES)
|
||||
message = forms.CharField(widget=forms.Textarea, help_text="Describe shortly what resources you need and what you need them for")
|
||||
subject = forms.CharField(label="Subject")
|
||||
resources = forms.CheckboxSelectMultiple(choices=RESOURCES)
|
||||
message = forms.CharField(widget=forms.Textarea, help_text="Describe shortly what resources you need and what you need them for")
|
||||
|
||||
def __init__(self, user, *args, **kwargs):
|
||||
super(RequestForm, self).__init__(*args, **kwargs)
|
||||
def __init__(self, user, *args, **kwargs):
|
||||
super(RequestForm, self).__init__(*args, **kwargs)
|
||||
|
||||
self._user = user
|
||||
self.fields['applicant'].queryset = self._user.maintainer_set.all()
|
||||
self.fields['provider'].queryset = Maintainer.objects.filter(Q(rir=True) | Q(lir=True))
|
||||
self._user = user
|
||||
self.fields['applicant'].queryset = self._user.maintainer_set.all()
|
||||
self.fields['provider'].queryset = Maintainer.objects.filter(Q(rir=True) | Q(lir=True))
|
||||
|
||||
def clean(self):
|
||||
cleaned_data = super(RequestForm, self).clean()
|
||||
def clean(self):
|
||||
cleaned_data = super(RequestForm, self).clean()
|
||||
|
||||
if not self.errors:
|
||||
mnts = self._user.maintainer_set.all()
|
||||
if cleaned_data['applicant'] in mnts and cleaned_data['provider'] in mnts:
|
||||
raise forms.ValidationError("You could request resources from yourself, but this would actually not make that much sense.")
|
||||
if not self.errors:
|
||||
mnts = self._user.maintainer_set.all()
|
||||
if cleaned_data['applicant'] in mnts and cleaned_data['provider'] in mnts:
|
||||
raise forms.ValidationError("You could request resources from yourself, but this would actually not make that much sense.")
|
||||
|
||||
class ResponseForm(forms.Form):
|
||||
new_status = forms.ChoiceField(choices=[("KEEP", "----", )] + list(Request.STATES), initial="KEEP", help_text="Only set this if you want to change the status of this request")
|
||||
message = forms.CharField(widget=forms.Textarea)
|
||||
new_status = forms.ChoiceField(choices=[("KEEP", "----", )] + list(Request.STATES), initial="KEEP", help_text="Only set this if you want to change the status of this request")
|
||||
message = forms.CharField(widget=forms.Textarea)
|
||||
|
||||
def __init__(self, request, user, *args, **kwargs):
|
||||
super(ResponseForm, self).__init__(*args, **kwargs)
|
||||
self._request = request
|
||||
self._user = user
|
||||
def __init__(self, request, user, *args, **kwargs):
|
||||
super(ResponseForm, self).__init__(*args, **kwargs)
|
||||
self._request = request
|
||||
self._user = user
|
||||
|
||||
def clean(self):
|
||||
cleaned_data = super(ResponseForm, self).clean()
|
||||
def clean(self):
|
||||
cleaned_data = super(ResponseForm, self).clean()
|
||||
|
||||
if not self.errors:
|
||||
if cleaned_data['new_status'] == self._request.status:
|
||||
raise forms.ValidationError("Status changed to same as ticket")
|
||||
if self._request.status in (Request.STATE_RESOLVED, Request.STATE_REJECTED) and \
|
||||
cleaned_data['new_status'] not in (Request.STATE_OPEN,):
|
||||
raise forms.ValidationError("Please put this ticket in an open state before adding messages")
|
||||
if not self.errors:
|
||||
if cleaned_data['new_status'] == self._request.status:
|
||||
raise forms.ValidationError("Status changed to same as ticket")
|
||||
if self._request.status in (Request.STATE_RESOLVED, Request.STATE_REJECTED) and \
|
||||
cleaned_data['new_status'] not in (Request.STATE_OPEN,):
|
||||
raise forms.ValidationError("Please put this ticket in an open state before adding messages")
|
||||
|
||||
|
||||
class ProviderResponseForm(ResponseForm):
|
||||
createdResources = forms.CharField(label="Created resources", help_text="If you have created resources for this request, please enter their handles here", required=False)
|
||||
createdResources = forms.CharField(label="Created resources", help_text="If you have created resources for this request, please enter their handles here", required=False)
|
||||
|
|
|
@ -8,49 +8,49 @@ from django.urls import reverse
|
|||
from whoisdb.models import Maintainer
|
||||
|
||||
class Request(models.Model):
|
||||
STATE_OPEN = "OPEN"
|
||||
STATE_RESOLVED = "RESOLVED"
|
||||
STATE_REJECTED = "REJECTED"
|
||||
STATES = (
|
||||
(STATE_OPEN, 'Open'),
|
||||
(STATE_RESOLVED, 'Resolved'),
|
||||
(STATE_REJECTED, 'Rejected'),
|
||||
)
|
||||
STATE_OPEN = "OPEN"
|
||||
STATE_RESOLVED = "RESOLVED"
|
||||
STATE_REJECTED = "REJECTED"
|
||||
STATES = (
|
||||
(STATE_OPEN, 'Open'),
|
||||
(STATE_RESOLVED, 'Resolved'),
|
||||
(STATE_REJECTED, 'Rejected'),
|
||||
)
|
||||
|
||||
# request goes to mnt?
|
||||
subject = models.CharField(max_length=200)
|
||||
# request goes to mnt?
|
||||
subject = models.CharField(max_length=200)
|
||||
|
||||
status = models.CharField(max_length=16, choices=STATES)
|
||||
status = models.CharField(max_length=16, choices=STATES)
|
||||
|
||||
applicant = models.ForeignKey(Maintainer)
|
||||
provider = models.ForeignKey(Maintainer, related_name='requestfrom_set')
|
||||
applicant = models.ForeignKey(Maintainer)
|
||||
provider = models.ForeignKey(Maintainer, related_name='requestfrom_set')
|
||||
|
||||
requestResources = models.TextField()
|
||||
grantedResources = models.TextField()
|
||||
requestResources = models.TextField()
|
||||
grantedResources = models.TextField()
|
||||
|
||||
created = models.DateTimeField(auto_now_add=True)
|
||||
lastAction = models.DateTimeField(auto_now_add=True)
|
||||
created = models.DateTimeField(auto_now_add=True)
|
||||
lastAction = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("rrequests:show", args=(self.pk,))
|
||||
def get_absolute_url(self):
|
||||
return reverse("rrequests:show", args=(self.pk,))
|
||||
|
||||
def __str__(self):
|
||||
return "(%s -> %s) [%s] %s" % (self.applicant, self.provider, self.status, self.subject)
|
||||
def __str__(self):
|
||||
return "(%s -> %s) [%s] %s" % (self.applicant, self.provider, self.status, self.subject)
|
||||
|
||||
def getLastActionBy(self):
|
||||
msgs = self.requestmessage_set.order_by("-created")
|
||||
def getLastActionBy(self):
|
||||
msgs = self.requestmessage_set.order_by("-created")
|
||||
|
||||
if msgs.count() > 0:
|
||||
return msgs[0].creator
|
||||
else:
|
||||
return None
|
||||
if msgs.count() > 0:
|
||||
return msgs[0].creator
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
class RequestMessage(models.Model):
|
||||
request = models.ForeignKey(Request)
|
||||
request = models.ForeignKey(Request)
|
||||
|
||||
statusChanged = models.CharField(max_length=16, choices=Request.STATES, default=None, null=True, blank=True)
|
||||
statusChanged = models.CharField(max_length=16, choices=Request.STATES, default=None, null=True, blank=True)
|
||||
|
||||
creator = models.ForeignKey(Maintainer)
|
||||
message = models.TextField()
|
||||
created = models.DateTimeField(auto_now_add=True)
|
||||
creator = models.ForeignKey(Maintainer)
|
||||
message = models.TextField()
|
||||
created = models.DateTimeField(auto_now_add=True)
|
||||
|
|
|
@ -7,8 +7,8 @@ from django.conf.urls import url
|
|||
from . import views as rrequests_views
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^$', rrequests_views.listRequests, name='dashboard'),
|
||||
url(r'^$', rrequests_views.listRequests, name='dashboard'),
|
||||
|
||||
url(r'create/$', rrequests_views.RrequestCreate.as_view(), name='create'),
|
||||
url(r'show/(?P<pk>\d+)/$', rrequests_views.rrequestDetail, name='show'),
|
||||
url(r'create/$', rrequests_views.RrequestCreate.as_view(), name='create'),
|
||||
url(r'show/(?P<pk>\d+)/$', rrequests_views.rrequestDetail, name='show'),
|
||||
]
|
||||
|
|
|
@ -17,88 +17,88 @@ from .forms import RequestForm, ResponseForm, ProviderResponseForm
|
|||
|
||||
@login_required
|
||||
def listRequests(request):
|
||||
mnts = request.user.maintainer_set.all()
|
||||
requestedFromMe = Request.objects.filter(applicant__in=mnts)
|
||||
requestedToMe = Request.objects.filter(provider__in=mnts)
|
||||
requests = (requestedFromMe | requestedToMe).order_by("-lastAction")
|
||||
mnts = request.user.maintainer_set.all()
|
||||
requestedFromMe = Request.objects.filter(applicant__in=mnts)
|
||||
requestedToMe = Request.objects.filter(provider__in=mnts)
|
||||
requests = (requestedFromMe | requestedToMe).order_by("-lastAction")
|
||||
|
||||
return render(request, "rrequests/list.html", {"mnts": mnts, "requests": requests, "requestedFromMe": requestedFromMe, "requestedToMe": requestedToMe})
|
||||
return render(request, "rrequests/list.html", {"mnts": mnts, "requests": requests, "requestedFromMe": requestedFromMe, "requestedToMe": requestedToMe})
|
||||
|
||||
|
||||
class RrequestCreate(LoginRequiredMixin, FormView):
|
||||
template_name = "rrequests/request_create.html"
|
||||
form_class = RequestForm
|
||||
template_name = "rrequests/request_create.html"
|
||||
form_class = RequestForm
|
||||
|
||||
def get_form_kwargs(self, *args, **kwargs):
|
||||
kwargs = super(RrequestCreate, self).get_form_kwargs(*args, **kwargs)
|
||||
kwargs['user'] = self.request.user
|
||||
def get_form_kwargs(self, *args, **kwargs):
|
||||
kwargs = super(RrequestCreate, self).get_form_kwargs(*args, **kwargs)
|
||||
kwargs['user'] = self.request.user
|
||||
|
||||
return kwargs
|
||||
return kwargs
|
||||
|
||||
def form_valid(self, form):
|
||||
formData = form.cleaned_data
|
||||
print(formData)
|
||||
request = Request(
|
||||
subject=formData['subject'],
|
||||
status=Request.STATE_OPEN,
|
||||
applicant=formData['applicant'],
|
||||
provider=formData['provider'],
|
||||
)
|
||||
request.save()
|
||||
def form_valid(self, form):
|
||||
formData = form.cleaned_data
|
||||
print(formData)
|
||||
request = Request(
|
||||
subject=formData['subject'],
|
||||
status=Request.STATE_OPEN,
|
||||
applicant=formData['applicant'],
|
||||
provider=formData['provider'],
|
||||
)
|
||||
request.save()
|
||||
|
||||
requestMsg = RequestMessage(
|
||||
request=request,
|
||||
requestMsg = RequestMessage(
|
||||
request=request,
|
||||
|
||||
creator=formData['applicant'],
|
||||
message=formData['message'],
|
||||
)
|
||||
requestMsg.save()
|
||||
creator=formData['applicant'],
|
||||
message=formData['message'],
|
||||
)
|
||||
requestMsg.save()
|
||||
|
||||
return HttpResponseRedirect(request.get_absolute_url())
|
||||
return HttpResponseRedirect(request.get_absolute_url())
|
||||
|
||||
@login_required
|
||||
def rrequestDetail(request, pk):
|
||||
mnts = request.user.maintainer_set.all()
|
||||
reqObj = get_object_or_404(Request.objects.filter(Q(provider__in=mnts) | Q(applicant__in=mnts)), pk=pk)
|
||||
mnts = request.user.maintainer_set.all()
|
||||
reqObj = get_object_or_404(Request.objects.filter(Q(provider__in=mnts) | Q(applicant__in=mnts)), pk=pk)
|
||||
|
||||
mnts = request.user.maintainer_set.all()
|
||||
formClass = None
|
||||
provider = None
|
||||
initialFormData = {}
|
||||
if reqObj.provider in mnts:
|
||||
provider = True
|
||||
formClass = ProviderResponseForm
|
||||
initialFormData["createdResources"] = reqObj.grantedResources
|
||||
else:
|
||||
provider = False
|
||||
formClass = ResponseForm
|
||||
mnts = request.user.maintainer_set.all()
|
||||
formClass = None
|
||||
provider = None
|
||||
initialFormData = {}
|
||||
if reqObj.provider in mnts:
|
||||
provider = True
|
||||
formClass = ProviderResponseForm
|
||||
initialFormData["createdResources"] = reqObj.grantedResources
|
||||
else:
|
||||
provider = False
|
||||
formClass = ResponseForm
|
||||
|
||||
if request.method == "POST":
|
||||
form = formClass(request=reqObj, user=request.user, data=request.POST)
|
||||
if form.is_valid():
|
||||
# create message object
|
||||
msg = RequestMessage(
|
||||
request=reqObj,
|
||||
creator=reqObj.provider if provider else reqObj.applicant,
|
||||
message=form.cleaned_data['message']
|
||||
)
|
||||
if form.cleaned_data['new_status'] != "KEEP":
|
||||
msg.statusChanged = form.cleaned_data['new_status']
|
||||
reqObj.status = msg.statusChanged
|
||||
if request.method == "POST":
|
||||
form = formClass(request=reqObj, user=request.user, data=request.POST)
|
||||
if form.is_valid():
|
||||
# create message object
|
||||
msg = RequestMessage(
|
||||
request=reqObj,
|
||||
creator=reqObj.provider if provider else reqObj.applicant,
|
||||
message=form.cleaned_data['message']
|
||||
)
|
||||
if form.cleaned_data['new_status'] != "KEEP":
|
||||
msg.statusChanged = form.cleaned_data['new_status']
|
||||
reqObj.status = msg.statusChanged
|
||||
|
||||
msg.save()
|
||||
msg.save()
|
||||
|
||||
if "createdResources" in form.cleaned_data and \
|
||||
form.cleaned_data['createdResources'].strip() != "":
|
||||
reqObj.grantedResources = form.cleaned_data["createdResources"].strip()
|
||||
if "createdResources" in form.cleaned_data and \
|
||||
form.cleaned_data['createdResources'].strip() != "":
|
||||
reqObj.grantedResources = form.cleaned_data["createdResources"].strip()
|
||||
|
||||
reqObj.lastAction = timezone.now()
|
||||
reqObj.save()
|
||||
reqObj.lastAction = timezone.now()
|
||||
reqObj.save()
|
||||
|
||||
|
||||
return HttpResponseRedirect(reverse("rrequests:show", args=(pk,)))
|
||||
else:
|
||||
form = formClass(request=reqObj, user=request.user, initial=initialFormData)
|
||||
return HttpResponseRedirect(reverse("rrequests:show", args=(pk,)))
|
||||
else:
|
||||
form = formClass(request=reqObj, user=request.user, initial=initialFormData)
|
||||
|
||||
return render(request, "rrequests/request_detail.html", {"request": reqObj, "form": form})
|
||||
return render(request, "rrequests/request_detail.html", {"request": reqObj, "form": form})
|
||||
|
||||
|
|
|
@ -6,33 +6,33 @@ from django import forms
|
|||
|
||||
|
||||
class MultiTextInput(forms.widgets.Input):
|
||||
input_type = "text"
|
||||
input_type = "text"
|
||||
|
||||
def render(self, name, value, attrs=None):
|
||||
if value is not None:
|
||||
selectedOptions = []
|
||||
for val in value:
|
||||
for k, v in self.choices:
|
||||
if val == k:
|
||||
selectedOptions.append(v)
|
||||
def render(self, name, value, attrs=None):
|
||||
if value is not None:
|
||||
selectedOptions = []
|
||||
for val in value:
|
||||
for k, v in self.choices:
|
||||
if val == k:
|
||||
selectedOptions.append(v)
|
||||
|
||||
value = " ".join(selectedOptions)
|
||||
value = " ".join(selectedOptions)
|
||||
|
||||
return super(MultiTextInput, self).render(name, value, attrs)
|
||||
return super(MultiTextInput, self).render(name, value, attrs)
|
||||
|
||||
def value_from_datadict(self, data, files, name):
|
||||
values = list(filter(bool, map(lambda _x: _x.strip(), data.get(name).split(" "))))
|
||||
def value_from_datadict(self, data, files, name):
|
||||
values = list(filter(bool, map(lambda _x: _x.strip(), data.get(name).split(" "))))
|
||||
|
||||
result = []
|
||||
for value in values:
|
||||
# FIXME: using value here throws a weird error message at some point
|
||||
# could be handled by overriding the messages in ChoiceField
|
||||
# or... well, don't know
|
||||
kId = value
|
||||
for k, v in self.choices:
|
||||
if v.lower() == value.lower():
|
||||
kId = str(k)
|
||||
break
|
||||
result.append(kId)
|
||||
result = []
|
||||
for value in values:
|
||||
# FIXME: using value here throws a weird error message at some point
|
||||
# could be handled by overriding the messages in ChoiceField
|
||||
# or... well, don't know
|
||||
kId = value
|
||||
for k, v in self.choices:
|
||||
if v.lower() == value.lower():
|
||||
kId = str(k)
|
||||
break
|
||||
result.append(kId)
|
||||
|
||||
return result
|
||||
return result
|
||||
|
|
492
whoisdb/forms.py
492
whoisdb/forms.py
|
@ -15,351 +15,351 @@ import ipaddress
|
|||
|
||||
|
||||
class WhoisObjectFormMixin(object):
|
||||
def __init__(self, user, *args, **kwargs):
|
||||
super(WhoisObjectFormMixin, self).__init__(*args, **kwargs)
|
||||
self._user = user
|
||||
def __init__(self, user, *args, **kwargs):
|
||||
super(WhoisObjectFormMixin, self).__init__(*args, **kwargs)
|
||||
self._user = user
|
||||
|
||||
instance = getattr(self, 'instance', None)
|
||||
if instance and instance.pk:
|
||||
self._create = False
|
||||
#self.fields['handle'].disabled = True
|
||||
else:
|
||||
self._create = True
|
||||
instance = getattr(self, 'instance', None)
|
||||
if instance and instance.pk:
|
||||
self._create = False
|
||||
#self.fields['handle'].disabled = True
|
||||
else:
|
||||
self._create = True
|
||||
|
||||
if 'handle' in self.fields:
|
||||
self.fields['handle'].help_text = "Handle for this object in uppercase with a suffix of -%s" % instance.handleSuffix
|
||||
if 'handle' in self.fields:
|
||||
self.fields['handle'].help_text = "Handle for this object in uppercase with a suffix of -%s" % instance.handleSuffix
|
||||
|
||||
# only show users contacts and already present contacts
|
||||
mnts = self._user.maintainer_set.all()
|
||||
if 'admin_c' in self.fields:
|
||||
self.fields['admin_c'].queryset = Contact.getMntQueryset(mnts, self.instance, "admin_c")
|
||||
# only show users contacts and already present contacts
|
||||
mnts = self._user.maintainer_set.all()
|
||||
if 'admin_c' in self.fields:
|
||||
self.fields['admin_c'].queryset = Contact.getMntQueryset(mnts, self.instance, "admin_c")
|
||||
|
||||
def clean_handle(self):
|
||||
HandleValidatorWithSuffix(self.instance.handleSuffix)(self.cleaned_data['handle'])
|
||||
return self.cleaned_data['handle']
|
||||
def clean_handle(self):
|
||||
HandleValidatorWithSuffix(self.instance.handleSuffix)(self.cleaned_data['handle'])
|
||||
return self.cleaned_data['handle']
|
||||
|
||||
def clean(self):
|
||||
cleaned_data = super(WhoisObjectFormMixin, self).clean()
|
||||
if cleaned_data.get("handle") == "AUTO" and not self.errors:
|
||||
name = cleaned_data.get("name")
|
||||
if name is None:
|
||||
name = self._user.username
|
||||
def clean(self):
|
||||
cleaned_data = super(WhoisObjectFormMixin, self).clean()
|
||||
if cleaned_data.get("handle") == "AUTO" and not self.errors:
|
||||
name = cleaned_data.get("name")
|
||||
if name is None:
|
||||
name = self._user.username
|
||||
|
||||
cleaned_data['handle'] = self._meta.model.genGenericHandle(name)
|
||||
cleaned_data['handle'] = self._meta.model.genGenericHandle(name)
|
||||
|
||||
# XXX: Find a better position to update last_changed
|
||||
self.instance.last_modified = timezone.now()
|
||||
# XXX: Find a better position to update last_changed
|
||||
self.instance.last_modified = timezone.now()
|
||||
|
||||
return cleaned_data
|
||||
return cleaned_data
|
||||
|
||||
|
||||
class MntFormMixin(object):
|
||||
protectedFields = []
|
||||
protectedFields = []
|
||||
|
||||
def __init__(self, lower=False, *args, **kwargs):
|
||||
super(MntFormMixin, self).__init__(*args, **kwargs)
|
||||
def __init__(self, lower=False, *args, **kwargs):
|
||||
super(MntFormMixin, self).__init__(*args, **kwargs)
|
||||
|
||||
self._editLower = lower
|
||||
self._editLower = lower
|
||||
|
||||
if self._editLower:
|
||||
for key in self.protectedFields:
|
||||
self.fields[key].disabled = True
|
||||
if self._editLower:
|
||||
for key in self.protectedFields:
|
||||
self.fields[key].disabled = True
|
||||
|
||||
instance = getattr(self, "instance", None)
|
||||
if not hasattr(self, "_create"):
|
||||
self._create = not (instance and instance.pk)
|
||||
instance = getattr(self, "instance", None)
|
||||
if not hasattr(self, "_create"):
|
||||
self._create = not (instance and instance.pk)
|
||||
|
||||
mntQs = orderQueryset(Maintainer.objects.all(), Q(auth=self._user), Q(pk__in=instance.mnt_by.all()) if not self._create else None)
|
||||
self.fields["mnt_by"].queryset = mntQs
|
||||
mntQs = orderQueryset(Maintainer.objects.all(), Q(auth=self._user), Q(pk__in=instance.mnt_by.all()) if not self._create else None)
|
||||
self.fields["mnt_by"].queryset = mntQs
|
||||
|
||||
if "mnt_lower" in self.fields:
|
||||
self.fields["mnt_lower"].queryset = mntQs
|
||||
if "mnt_lower" in self.fields:
|
||||
self.fields["mnt_lower"].queryset = mntQs
|
||||
|
||||
def clean(self):
|
||||
cleaned_data = super(MntFormMixin, self).clean()
|
||||
def clean(self):
|
||||
cleaned_data = super(MntFormMixin, self).clean()
|
||||
|
||||
if not self.errors:
|
||||
if self._create:
|
||||
# at least one own mnt on creation
|
||||
mnts = self._user.maintainer_set.all()
|
||||
if not self.errors:
|
||||
if self._create:
|
||||
# at least one own mnt on creation
|
||||
mnts = self._user.maintainer_set.all()
|
||||
|
||||
for mnt in cleaned_data['mnt_by']:
|
||||
if mnt in mnts:
|
||||
break
|
||||
else:
|
||||
raise forms.ValidationError("On object creation at least one maintainer needs to be under your control")
|
||||
for mnt in cleaned_data['mnt_by']:
|
||||
if mnt in mnts:
|
||||
break
|
||||
else:
|
||||
raise forms.ValidationError("On object creation at least one maintainer needs to be under your control")
|
||||
|
||||
if cleaned_data['mnt_by'].count() > 5 or "mnt_lower" in self.fields and cleaned_data['mnt_lower'].count() > 5:
|
||||
raise forms.ValidationError("Currently only 5 MNTs per object allowed. If you need more ask @ irc/rrequest and state your use case")
|
||||
if cleaned_data['mnt_by'].count() > 5 or "mnt_lower" in self.fields and cleaned_data['mnt_lower'].count() > 5:
|
||||
raise forms.ValidationError("Currently only 5 MNTs per object allowed. If you need more ask @ irc/rrequest and state your use case")
|
||||
|
||||
return cleaned_data
|
||||
return cleaned_data
|
||||
|
||||
|
||||
class MntForm(WhoisObjectFormMixin, forms.ModelForm):
|
||||
class Meta:
|
||||
model = Maintainer
|
||||
#fields = ['handle', 'description', 'admin_c', 'auth']
|
||||
fields = ['handle', 'description', 'admin_c']
|
||||
widgets = {'auth': MultiTextInput()}
|
||||
class Meta:
|
||||
model = Maintainer
|
||||
#fields = ['handle', 'description', 'admin_c', 'auth']
|
||||
fields = ['handle', 'description', 'admin_c']
|
||||
widgets = {'auth': MultiTextInput()}
|
||||
|
||||
help_texts = {
|
||||
'auth': 'Enter names of users which can edit this object (space separated; '
|
||||
'and yes, validation is somewhat broken (values disappear on error - just reload))'
|
||||
}
|
||||
help_texts = {
|
||||
'auth': 'Enter names of users which can edit this object (space separated; '
|
||||
'and yes, validation is somewhat broken (values disappear on error - just reload))'
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(MntForm, self).__init__(*args, **kwargs)
|
||||
print(args, kwargs)
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(MntForm, self).__init__(*args, **kwargs)
|
||||
print(args, kwargs)
|
||||
|
||||
#if self._create:
|
||||
# self.fields['auth'].text("noot")
|
||||
#if self._create:
|
||||
# self.fields['auth'].text("noot")
|
||||
|
||||
|
||||
class MntInitialForm(MntForm):
|
||||
class Meta:
|
||||
model = Maintainer
|
||||
fields = ['handle', 'description']
|
||||
class Meta:
|
||||
model = Maintainer
|
||||
fields = ['handle', 'description']
|
||||
|
||||
|
||||
class ContactForm(WhoisObjectFormMixin, forms.ModelForm):
|
||||
class Meta:
|
||||
model = Contact
|
||||
fields = ['handle', 'name', 'mnt_by']
|
||||
class Meta:
|
||||
model = Contact
|
||||
fields = ['handle', 'name', 'mnt_by']
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(ContactForm, self).__init__(*args, **kwargs)
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(ContactForm, self).__init__(*args, **kwargs)
|
||||
|
||||
if "mnt_by" in self.fields:
|
||||
self.fields['mnt_by'].queryset = Maintainer.objects.filter(auth=self._user).distinct()
|
||||
if "mnt_by" in self.fields:
|
||||
self.fields['mnt_by'].queryset = Maintainer.objects.filter(auth=self._user).distinct()
|
||||
|
||||
|
||||
class ContactInitialForm(ContactForm):
|
||||
class Meta:
|
||||
model = Contact
|
||||
fields = ['handle', 'name']
|
||||
class Meta:
|
||||
model = Contact
|
||||
fields = ['handle', 'name']
|
||||
|
||||
|
||||
class InetNumForm(MntFormMixin, WhoisObjectFormMixin, forms.ModelForm):
|
||||
prefix = forms.CharField()
|
||||
protectedFields = ['protocol', 'parent_range', 'mnt_by', 'prefix']
|
||||
prefix = forms.CharField()
|
||||
protectedFields = ['protocol', 'parent_range', 'mnt_by', 'prefix']
|
||||
|
||||
class Meta:
|
||||
model = InetNum
|
||||
fields = ['handle', 'protocol', 'parent_range', 'prefix', 'name', 'description', 'origin_as', 'mnt_by', 'mnt_lower', 'admin_c']
|
||||
class Meta:
|
||||
model = InetNum
|
||||
fields = ['handle', 'protocol', 'parent_range', 'prefix', 'name', 'description', 'origin_as', 'mnt_by', 'mnt_lower', 'admin_c']
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(InetNumForm, self).__init__(*args, **kwargs)
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(InetNumForm, self).__init__(*args, **kwargs)
|
||||
|
||||
if self._editLower:
|
||||
for key in self.protectedFields:
|
||||
self.fields[key].disabled = True
|
||||
if self._editLower:
|
||||
for key in self.protectedFields:
|
||||
self.fields[key].disabled = True
|
||||
|
||||
mnts = self._user.maintainer_set.all()
|
||||
#self.fields['parent_range'].queryset = InetNum.objects.filter(Q(mnt_by__in=mnts) | Q(mnt_lower__in=mnts))
|
||||
#if not self._create:
|
||||
# self.fields['parent_range'].queryset |= InetNum.objects.filter(pk=self.instance.pk)
|
||||
mnts = self._user.maintainer_set.all()
|
||||
#self.fields['parent_range'].queryset = InetNum.objects.filter(Q(mnt_by__in=mnts) | Q(mnt_lower__in=mnts))
|
||||
#if not self._create:
|
||||
# self.fields['parent_range'].queryset |= InetNum.objects.filter(pk=self.instance.pk)
|
||||
|
||||
#self.fields['parent_range'].queryset = self.fields['parent_range'].queryset.distinct()
|
||||
self.fields['parent_range'].queryset = InetNum.getMntQueryset(mnts, self.instance, "parent_range")
|
||||
self.fields['origin_as'].queryset = ASNumber.getMntQueryset(mnts, self.instance, "origin_as")
|
||||
#self.fields['parent_range'].queryset = self.fields['parent_range'].queryset.distinct()
|
||||
self.fields['parent_range'].queryset = InetNum.getMntQueryset(mnts, self.instance, "parent_range")
|
||||
self.fields['origin_as'].queryset = ASNumber.getMntQueryset(mnts, self.instance, "origin_as")
|
||||
|
||||
def clean_prefix(self):
|
||||
# make sure this is a subnet we're getting
|
||||
net = self.cleaned_data['prefix'].lower()
|
||||
IP46CIDRValidator(net)
|
||||
def clean_prefix(self):
|
||||
# make sure this is a subnet we're getting
|
||||
net = self.cleaned_data['prefix'].lower()
|
||||
IP46CIDRValidator(net)
|
||||
|
||||
try:
|
||||
net = ipaddress.ip_network(net)
|
||||
except ValueError as e:
|
||||
raise forms.ValidationError(str(e))
|
||||
try:
|
||||
net = ipaddress.ip_network(net)
|
||||
except ValueError as e:
|
||||
raise forms.ValidationError(str(e))
|
||||
|
||||
return net
|
||||
return net
|
||||
|
||||
def clean_parent_range(self):
|
||||
parent_range = self.cleaned_data.get('parent_range', None)
|
||||
def clean_parent_range(self):
|
||||
parent_range = self.cleaned_data.get('parent_range', None)
|
||||
|
||||
|
||||
# allow parent range to be unset for already present objects
|
||||
if not parent_range and (self._create or not self._create and self.instance.parent_range):
|
||||
raise forms.ValidationError("Parent range must be set")
|
||||
# allow parent range to be unset for already present objects
|
||||
if not parent_range and (self._create or not self._create and self.instance.parent_range):
|
||||
raise forms.ValidationError("Parent range must be set")
|
||||
|
||||
if not self._create and parent_range:
|
||||
# make sure we don't have circular dependencies
|
||||
obj = parent_range
|
||||
while obj.parent_range:
|
||||
if obj.pk == self.instance.pk:
|
||||
raise forms.ValidationError("No circular dependencies allowed")
|
||||
obj = obj.parent_range
|
||||
if not self._create and parent_range:
|
||||
# make sure we don't have circular dependencies
|
||||
obj = parent_range
|
||||
while obj.parent_range:
|
||||
if obj.pk == self.instance.pk:
|
||||
raise forms.ValidationError("No circular dependencies allowed")
|
||||
obj = obj.parent_range
|
||||
|
||||
if parent_range.origin_as.count() > 0:
|
||||
raise forms.ValidationError("Parent range has origin as set")
|
||||
if parent_range.origin_as.count() > 0:
|
||||
raise forms.ValidationError("Parent range has origin as set")
|
||||
|
||||
return parent_range
|
||||
return parent_range
|
||||
|
||||
def clean(self):
|
||||
cleaned_data = super(InetNumForm, self).clean()
|
||||
def clean(self):
|
||||
cleaned_data = super(InetNumForm, self).clean()
|
||||
|
||||
if not self._editLower:
|
||||
if not self.errors:
|
||||
if not self._create and self.cleaned_data['origin_as']:
|
||||
if self.instance.inetnum_set.count() > 0:
|
||||
ranges = ", ".join(map(str, self.instance.inetnum_set.all()))
|
||||
raise forms.ValidationError("You cannot set an origin as if there are already existing subranges (%s)" % (ranges))
|
||||
if not self._editLower:
|
||||
if not self.errors:
|
||||
if not self._create and self.cleaned_data['origin_as']:
|
||||
if self.instance.inetnum_set.count() > 0:
|
||||
ranges = ", ".join(map(str, self.instance.inetnum_set.all()))
|
||||
raise forms.ValidationError("You cannot set an origin as if there are already existing subranges (%s)" % (ranges))
|
||||
|
||||
prefix = cleaned_data['prefix']
|
||||
parent = cleaned_data['parent_range']
|
||||
if parent:
|
||||
parentNet = parent.getNetwork()
|
||||
prefix = cleaned_data['prefix']
|
||||
parent = cleaned_data['parent_range']
|
||||
if parent:
|
||||
parentNet = parent.getNetwork()
|
||||
|
||||
if cleaned_data['protocol'] != parent.protocol:
|
||||
raise forms.ValidationError("Protocol type for prefix must be same as parent network")
|
||||
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 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
|
||||
# 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)
|
||||
if otherNet.getNetwork().overlaps(prefix):
|
||||
raise forms.ValidationError("The given prefix overlaps with network %s" % otherNet.handle)
|
||||
|
||||
# check if subnets to this subnet are (still) in current network
|
||||
if not self._create:
|
||||
for subnet in self.instance.inetnum_set.all():
|
||||
if subnet.getNetwork().network_address not in self.instance.getNetwork():
|
||||
raise forms.ValidationError("Subnet %s with %s is not in block anymore" % (subnet, subnet.getNetwork()))
|
||||
# check if subnets to this subnet are (still) in current network
|
||||
if not self._create:
|
||||
for subnet in self.instance.inetnum_set.all():
|
||||
if subnet.getNetwork().network_address not in self.instance.getNetwork():
|
||||
raise forms.ValidationError("Subnet %s with %s is not in block anymore" % (subnet, subnet.getNetwork()))
|
||||
|
||||
self.instance.address = str(prefix.network_address)
|
||||
self.instance.netmask = prefix.prefixlen
|
||||
self.instance.address = str(prefix.network_address)
|
||||
self.instance.netmask = prefix.prefixlen
|
||||
|
||||
return cleaned_data
|
||||
return cleaned_data
|
||||
|
||||
|
||||
class ASBlockForm(MntFormMixin, WhoisObjectFormMixin, forms.ModelForm):
|
||||
protectedFields = ['parent_block', 'asBegin', 'asEnd', 'mnt_by']
|
||||
protectedFields = ['parent_block', 'asBegin', 'asEnd', 'mnt_by']
|
||||
|
||||
# FIXME: Filter blocks
|
||||
class Meta:
|
||||
model = ASBlock
|
||||
fields = ['handle', 'parent_block', 'asBegin', 'asEnd', 'name', 'description', 'mnt_by', 'mnt_lower', 'admin_c']
|
||||
# FIXME: Filter blocks
|
||||
class Meta:
|
||||
model = ASBlock
|
||||
fields = ['handle', 'parent_block', 'asBegin', 'asEnd', 'name', 'description', 'mnt_by', 'mnt_lower', 'admin_c']
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(ASBlockForm, self).__init__(*args, **kwargs)
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(ASBlockForm, self).__init__(*args, **kwargs)
|
||||
|
||||
if not self.instance or self.instance and self.instance and self.instance.parent_block:
|
||||
self.fields["parent_block"].required = True
|
||||
if self.instance and self.instance.pk:
|
||||
self.fields["parent_block"].disabled = True
|
||||
if not self.instance or self.instance and self.instance and self.instance.parent_block:
|
||||
self.fields["parent_block"].required = True
|
||||
if self.instance and self.instance.pk:
|
||||
self.fields["parent_block"].disabled = True
|
||||
|
||||
mnts = self._user.maintainer_set.all()
|
||||
self.fields['parent_block'].queryset = ASBlock.getMntQueryset(mnts, self.instance, "parent_block")
|
||||
mnts = self._user.maintainer_set.all()
|
||||
self.fields['parent_block'].queryset = ASBlock.getMntQueryset(mnts, self.instance, "parent_block")
|
||||
|
||||
def clean_parent_block(self):
|
||||
parent_block = self.cleaned_data.get('parent_block', None)
|
||||
def clean_parent_block(self):
|
||||
parent_block = self.cleaned_data.get('parent_block', None)
|
||||
|
||||
# allow parent range to be unset for already present objects
|
||||
if not parent_block and (self._create or not self._create and self.instance.parent_block):
|
||||
raise forms.ValidationError("Parent block must be set")
|
||||
# allow parent range to be unset for already present objects
|
||||
if not parent_block and (self._create or not self._create and self.instance.parent_block):
|
||||
raise forms.ValidationError("Parent block must be set")
|
||||
|
||||
if not self._create and parent_block:
|
||||
# make sure we don't have circular dependencies
|
||||
obj = parent_block
|
||||
while obj.parent_block:
|
||||
if obj.pk == self.instance.pk:
|
||||
raise forms.ValidationError("No circular dependencies allowed")
|
||||
obj = obj.parent_block
|
||||
if not self._create and parent_block:
|
||||
# make sure we don't have circular dependencies
|
||||
obj = parent_block
|
||||
while obj.parent_block:
|
||||
if obj.pk == self.instance.pk:
|
||||
raise forms.ValidationError("No circular dependencies allowed")
|
||||
obj = obj.parent_block
|
||||
|
||||
return parent_block
|
||||
return parent_block
|
||||
|
||||
def clean(self):
|
||||
cleaned_data = super(ASBlockForm, self).clean()
|
||||
def clean(self):
|
||||
cleaned_data = super(ASBlockForm, self).clean()
|
||||
|
||||
if not self.errors:
|
||||
asBegin = cleaned_data['asBegin']
|
||||
asEnd = cleaned_data['asEnd']
|
||||
parent = cleaned_data['parent_block']
|
||||
# check if somebody is already using this block
|
||||
if not self.errors:
|
||||
asBegin = cleaned_data['asBegin']
|
||||
asEnd = cleaned_data['asEnd']
|
||||
parent = cleaned_data['parent_block']
|
||||
# check if somebody is already using this block
|
||||
|
||||
# check if in range
|
||||
if asBegin > asEnd:
|
||||
raise forms.ValidationError("AS beginning must be smaller or equal to AS end")
|
||||
# check if in range
|
||||
if asBegin > asEnd:
|
||||
raise forms.ValidationError("AS beginning must be smaller or equal to AS end")
|
||||
|
||||
if parent:
|
||||
if parent.asnumber_set.count() > 0:
|
||||
raise forms.ValidationError("The parent AS block is already references by following AS number objects: %s" % (", ".join(map(lambda _x: _x.handle, parent.asnumber_set.all())),))
|
||||
if parent:
|
||||
if parent.asnumber_set.count() > 0:
|
||||
raise forms.ValidationError("The parent AS block is already references by following AS number objects: %s" % (", ".join(map(lambda _x: _x.handle, parent.asnumber_set.all())),))
|
||||
|
||||
# check if same range
|
||||
if not (asBegin >= parent.asBegin and asEnd <= parent.asEnd):
|
||||
raise forms.ValidationError("AS beginning and end must be inside the range of the parent AS block")
|
||||
# check if same range
|
||||
if not (asBegin >= parent.asBegin and asEnd <= parent.asEnd):
|
||||
raise forms.ValidationError("AS beginning and end must be inside the range of the parent AS block")
|
||||
|
||||
if parent.asBegin == asBegin and parent.asEnd == asEnd:
|
||||
raise forms.ValidationError("The range of this block cannot be the same range AS the parent AS block")
|
||||
if parent.asBegin == asBegin and parent.asEnd == asEnd:
|
||||
raise forms.ValidationError("The range of this block cannot be the same range AS the parent AS block")
|
||||
|
||||
# check for overlap with other asblocks
|
||||
for block in parent.asblock_set.all():
|
||||
if self.instance and self.instance.pk and block.pk == self.instance.pk:
|
||||
continue
|
||||
# check for overlap with other asblocks
|
||||
for block in parent.asblock_set.all():
|
||||
if self.instance and self.instance.pk and block.pk == self.instance.pk:
|
||||
continue
|
||||
|
||||
if block.asBegin <= asBegin <= block.asEnd or block.asBegin <= asEnd <= block.asEnd or \
|
||||
asBegin <= block.asBegin <= asEnd or asBegin <= block.asEnd <= asEnd:
|
||||
raise forms.ValidationError("Block overlaps with block %s" % block.handle)
|
||||
if block.asBegin <= asBegin <= block.asEnd or block.asBegin <= asEnd <= block.asEnd or \
|
||||
asBegin <= block.asBegin <= asEnd or asBegin <= block.asEnd <= asEnd:
|
||||
raise forms.ValidationError("Block overlaps with block %s" % block.handle)
|
||||
|
||||
if not self._create:
|
||||
# check if subblocks are still in range
|
||||
for subblock in self.instance.asblock_set.all():
|
||||
if not (asBegin <= subblock.asBegin <= asEnd and asBegin <= subblock.asEnd <= asEnd):
|
||||
raise forms.ValidationError("Subblock %s (%s - %s) is not contained in this block anymore" % (subblock, subblock.asBegin, subblock.asEnd))
|
||||
if not self._create:
|
||||
# check if subblocks are still in range
|
||||
for subblock in self.instance.asblock_set.all():
|
||||
if not (asBegin <= subblock.asBegin <= asEnd and asBegin <= subblock.asEnd <= asEnd):
|
||||
raise forms.ValidationError("Subblock %s (%s - %s) is not contained in this block anymore" % (subblock, subblock.asBegin, subblock.asEnd))
|
||||
|
||||
# check if asnumbers are still in range
|
||||
for asnumber in self.instance.asnumber_set.all():
|
||||
if not (asBegin <= asnumber.number <= asEnd):
|
||||
raise forms.ValidationError("AS %s (%s) is not contained in this block anymore" % (asnumber, asnumber.number))
|
||||
# check if asnumbers are still in range
|
||||
for asnumber in self.instance.asnumber_set.all():
|
||||
if not (asBegin <= asnumber.number <= asEnd):
|
||||
raise forms.ValidationError("AS %s (%s) is not contained in this block anymore" % (asnumber, asnumber.number))
|
||||
|
||||
|
||||
return cleaned_data
|
||||
return cleaned_data
|
||||
|
||||
|
||||
class ASNumberForm(MntFormMixin, WhoisObjectFormMixin, forms.ModelForm):
|
||||
protectedFields = ['asblock', 'number', 'mnt_by']
|
||||
protectedFields = ['asblock', 'number', 'mnt_by']
|
||||
|
||||
class Meta:
|
||||
model = ASNumber
|
||||
fields = ['handle', 'asblock', 'number', 'volatile', 'name', 'description', 'mnt_by', 'mnt_lower', 'admin_c']
|
||||
class Meta:
|
||||
model = ASNumber
|
||||
fields = ['handle', 'asblock', 'number', 'volatile', 'name', 'description', 'mnt_by', 'mnt_lower', 'admin_c']
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(ASNumberForm, self).__init__(*args, **kwargs)
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(ASNumberForm, self).__init__(*args, **kwargs)
|
||||
|
||||
if not (self.instance and self.instance.pk):
|
||||
self.fields["asblock"].required = True
|
||||
else:
|
||||
self.fields["asblock"].disabled = True
|
||||
if not (self.instance and self.instance.pk):
|
||||
self.fields["asblock"].required = True
|
||||
else:
|
||||
self.fields["asblock"].disabled = True
|
||||
|
||||
mnts = self._user.maintainer_set.all()
|
||||
self.fields['asblock'].queryset = ASBlock.getMntQueryset(mnts, self.instance, "asblock")
|
||||
mnts = self._user.maintainer_set.all()
|
||||
self.fields['asblock'].queryset = ASBlock.getMntQueryset(mnts, self.instance, "asblock")
|
||||
|
||||
def clean(self):
|
||||
cleaned_data = super(ASNumberForm, self).clean()
|
||||
def clean(self):
|
||||
cleaned_data = super(ASNumberForm, self).clean()
|
||||
|
||||
if not self.errors:
|
||||
number = cleaned_data['number']
|
||||
block = cleaned_data['asblock']
|
||||
if not self.errors:
|
||||
number = cleaned_data['number']
|
||||
block = cleaned_data['asblock']
|
||||
|
||||
# belongs to asblock?
|
||||
if number < block.asBegin or number > block.asEnd:
|
||||
raise forms.ValidationError("AS number is not inside AS block")
|
||||
# belongs to asblock?
|
||||
if number < block.asBegin or number > block.asEnd:
|
||||
raise forms.ValidationError("AS number is not inside AS block")
|
||||
|
||||
# does an entry already exist?
|
||||
try:
|
||||
otherAS = ASNumber.objects.get(number=number)
|
||||
if not (self.instance and self.instance.pk and self.instance.pk == otherAS.pk):
|
||||
raise forms.ValidationError("This AS number is already represented by %s" % otherAS.handle)
|
||||
except ASNumber.DoesNotExist:
|
||||
pass
|
||||
# does an entry already exist?
|
||||
try:
|
||||
otherAS = ASNumber.objects.get(number=number)
|
||||
if not (self.instance and self.instance.pk and self.instance.pk == otherAS.pk):
|
||||
raise forms.ValidationError("This AS number is already represented by %s" % otherAS.handle)
|
||||
except ASNumber.DoesNotExist:
|
||||
pass
|
||||
|
||||
# has already other asblock?
|
||||
if block.asblock_set.count() > 0:
|
||||
raise forms.ValidationError("The given AS block is already references by following sub AS blocks: %s" % (", ".join(map(lambda _x: _x.handle, block.asblock_set.all())),))
|
||||
# has already other asblock?
|
||||
if block.asblock_set.count() > 0:
|
||||
raise forms.ValidationError("The given AS block is already references by following sub AS blocks: %s" % (", ".join(map(lambda _x: _x.handle, block.asblock_set.all())),))
|
||||
|
|
|
@ -9,45 +9,45 @@ from django.db.models import Q
|
|||
|
||||
|
||||
class DeleteCheckView(DeleteView):
|
||||
""" Check if object actually can be deleted. Provide reasons to template
|
||||
if not.
|
||||
"""
|
||||
def delete(self, request, *args, **kwargs):
|
||||
self.object = self.get_object()
|
||||
success_url = self.get_success_url()
|
||||
""" Check if object actually can be deleted. Provide reasons to template
|
||||
if not.
|
||||
"""
|
||||
def delete(self, request, *args, **kwargs):
|
||||
self.object = self.get_object()
|
||||
success_url = self.get_success_url()
|
||||
|
||||
reasons = self.object.getNoDeleteReasons()
|
||||
if reasons:
|
||||
# do not delete, do what get does...
|
||||
return self.get(request, *args, **kwargs)
|
||||
else:
|
||||
self.object.delete()
|
||||
messages.info(request, "Object %s has been deleted" % str(self.object))
|
||||
return HttpResponseRedirect(success_url)
|
||||
reasons = self.object.getNoDeleteReasons()
|
||||
if reasons:
|
||||
# do not delete, do what get does...
|
||||
return self.get(request, *args, **kwargs)
|
||||
else:
|
||||
self.object.delete()
|
||||
messages.info(request, "Object %s has been deleted" % str(self.object))
|
||||
return HttpResponseRedirect(success_url)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
if 'reasons' not in kwargs:
|
||||
kwargs['reasons'] = self.object.getNoDeleteReasons()
|
||||
return super(DeleteCheckView, self).get_context_data(**kwargs)
|
||||
def get_context_data(self, **kwargs):
|
||||
if 'reasons' not in kwargs:
|
||||
kwargs['reasons'] = self.object.getNoDeleteReasons()
|
||||
return super(DeleteCheckView, self).get_context_data(**kwargs)
|
||||
|
||||
|
||||
class MntGenericMixin(object):
|
||||
def get_queryset(self):
|
||||
mnts = self.request.user.maintainer_set.all()
|
||||
def get_queryset(self):
|
||||
mnts = self.request.user.maintainer_set.all()
|
||||
|
||||
q = Q(mnt_by__in=mnts)
|
||||
if hasattr(self.model, "mnt_lower"):
|
||||
q |= Q(mnt_lower__in=mnts)
|
||||
q = Q(mnt_by__in=mnts)
|
||||
if hasattr(self.model, "mnt_lower"):
|
||||
q |= Q(mnt_lower__in=mnts)
|
||||
|
||||
return self.model.objects.filter(q).distinct()
|
||||
return self.model.objects.filter(q).distinct()
|
||||
|
||||
def get_form_kwargs(self, *args, **kwargs):
|
||||
kwargs = super(MntGenericMixin, self).get_form_kwargs(*args, **kwargs)
|
||||
def get_form_kwargs(self, *args, **kwargs):
|
||||
kwargs = super(MntGenericMixin, self).get_form_kwargs(*args, **kwargs)
|
||||
|
||||
if hasattr(self.model, "mnt_lower"):
|
||||
mnts = self.request.user.maintainer_set.all()
|
||||
if not any(mnt in self.object.mnt_by.all() for mnt in mnts):
|
||||
# we are in mnt_lower
|
||||
kwargs["lower"] = True
|
||||
if hasattr(self.model, "mnt_lower"):
|
||||
mnts = self.request.user.maintainer_set.all()
|
||||
if not any(mnt in self.object.mnt_by.all() for mnt in mnts):
|
||||
# we are in mnt_lower
|
||||
kwargs["lower"] = True
|
||||
|
||||
return kwargs
|
||||
return kwargs
|
||||
|
|
|
@ -11,161 +11,161 @@ import ipaddress
|
|||
import re
|
||||
|
||||
def _addFields(fields, obj, fieldNames):
|
||||
for fieldName in fieldNames:
|
||||
fields.append((fieldName.capitalize().replace("_", " "), getattr(obj, fieldName)))
|
||||
for fieldName in fieldNames:
|
||||
fields.append((fieldName.capitalize().replace("_", " "), getattr(obj, fieldName)))
|
||||
|
||||
|
||||
def getWhoisObjectFields(obj, owner):
|
||||
fields = []
|
||||
fields = []
|
||||
|
||||
if getattr(obj, "handle", None):
|
||||
_addFields(fields, obj, ["handle"])
|
||||
if getattr(obj, "handle", None):
|
||||
_addFields(fields, obj, ["handle"])
|
||||
|
||||
c = type(obj)
|
||||
if c == whoisdb.models.Maintainer:
|
||||
_addFields(fields, obj, ["description", "admin_c"])
|
||||
if owner:
|
||||
_addFields(fields, obj, ["auth"])
|
||||
elif c == whoisdb.models.Contact:
|
||||
_addFields(fields, obj, ["name", "mnt_by"])
|
||||
elif c == whoisdb.models.ASBlock:
|
||||
_addFields(fields, obj, ["name"])
|
||||
fields.append(("AS Range", "%s - %s" % (obj.asBegin, obj.asEnd)))
|
||||
_addFields(fields, obj, ["description", "parent_block", "mnt_by", "mnt_lower", "admin_c"])
|
||||
elif c == whoisdb.models.ASNumber:
|
||||
_addFields(fields, obj, ["name", "number", "description", "asblock", "volatile", "mnt_by", "mnt_lower", "admin_c"])
|
||||
elif c == whoisdb.models.InetNum:
|
||||
_addFields(fields, obj, ["name"])
|
||||
fields.append(("Address CIDR", obj.prefix()))
|
||||
_addFields(fields, obj, ["description", "parent_range", "origin_as", "mnt_by", "mnt_lower", "admin_c"])
|
||||
elif c == domains.models.Domain:
|
||||
_addFields(fields, obj, ["name", "nameservers", "mnt_by", "admin_c"])
|
||||
elif c == domains.models.Nameserver:
|
||||
_addFields(fields, obj, ["name", "glueIPv4", "glueIPv6", "mnt_by", "admin_c"])
|
||||
elif c == domains.models.ReverseZone:
|
||||
#_addFields(fields, obj, ["name"])
|
||||
fields.append(("Address CIDR", obj.prefix()))
|
||||
_addFields(fields, obj, ["parentNet", "nameservers"])
|
||||
c = type(obj)
|
||||
if c == whoisdb.models.Maintainer:
|
||||
_addFields(fields, obj, ["description", "admin_c"])
|
||||
if owner:
|
||||
_addFields(fields, obj, ["auth"])
|
||||
elif c == whoisdb.models.Contact:
|
||||
_addFields(fields, obj, ["name", "mnt_by"])
|
||||
elif c == whoisdb.models.ASBlock:
|
||||
_addFields(fields, obj, ["name"])
|
||||
fields.append(("AS Range", "%s - %s" % (obj.asBegin, obj.asEnd)))
|
||||
_addFields(fields, obj, ["description", "parent_block", "mnt_by", "mnt_lower", "admin_c"])
|
||||
elif c == whoisdb.models.ASNumber:
|
||||
_addFields(fields, obj, ["name", "number", "description", "asblock", "volatile", "mnt_by", "mnt_lower", "admin_c"])
|
||||
elif c == whoisdb.models.InetNum:
|
||||
_addFields(fields, obj, ["name"])
|
||||
fields.append(("Address CIDR", obj.prefix()))
|
||||
_addFields(fields, obj, ["description", "parent_range", "origin_as", "mnt_by", "mnt_lower", "admin_c"])
|
||||
elif c == domains.models.Domain:
|
||||
_addFields(fields, obj, ["name", "nameservers", "mnt_by", "admin_c", "ds_records"])
|
||||
elif c == domains.models.Nameserver:
|
||||
_addFields(fields, obj, ["name", "glueIPv4", "glueIPv6", "mnt_by", "admin_c"])
|
||||
elif c == domains.models.ReverseZone:
|
||||
#_addFields(fields, obj, ["name"])
|
||||
fields.append(("Address CIDR", obj.prefix()))
|
||||
_addFields(fields, obj, ["parentNet", "nameservers"])
|
||||
|
||||
_addFields(fields, obj, ["created", "last_modified"])
|
||||
_addFields(fields, obj, ["created", "last_modified"])
|
||||
|
||||
return fields
|
||||
return fields
|
||||
|
||||
|
||||
def guessWhoisObject(self, handle):
|
||||
# is it a normal handle?
|
||||
pass
|
||||
# is it a normal handle?
|
||||
pass
|
||||
|
||||
def findInDatabase(rawValue):
|
||||
# is this an ip address?
|
||||
rawValue = rawValue.strip().upper()
|
||||
value = None
|
||||
results = []
|
||||
# is this an ip address?
|
||||
rawValue = rawValue.strip().upper()
|
||||
value = None
|
||||
results = []
|
||||
|
||||
# try subnetwork
|
||||
try:
|
||||
value = ipaddress.ip_network(rawValue, strict=False)
|
||||
except ValueError:
|
||||
pass
|
||||
# try subnetwork
|
||||
try:
|
||||
value = ipaddress.ip_network(rawValue, strict=False)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
if value:
|
||||
# ssubnet
|
||||
obj = whoisdb.models.InetNum.objects.filter(address=str(value.network_address), netmask=value.prefixlen)
|
||||
results.extend(obj)
|
||||
if value:
|
||||
# ssubnet
|
||||
obj = whoisdb.models.InetNum.objects.filter(address=str(value.network_address), netmask=value.prefixlen)
|
||||
results.extend(obj)
|
||||
|
||||
# single ip
|
||||
value = None
|
||||
try:
|
||||
value = ipaddress.ip_address(rawValue)
|
||||
except ValueError:
|
||||
pass
|
||||
# single ip
|
||||
value = None
|
||||
try:
|
||||
value = ipaddress.ip_address(rawValue)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
if value:
|
||||
# NOTE: this is only for "small subnets", we could increase this...
|
||||
baseaddr = None
|
||||
if value.version == 4:
|
||||
basenet = ipaddress.ip_network("%s/24" % value, strict=False)
|
||||
baseaddr = ".".join(str(basenet).split(".")[0:3]) + "."
|
||||
else:
|
||||
basenet = ipaddress.ip_network("%s/56" % value.exploded, strict=False)
|
||||
baseaddr = ":".join(str(basenet).split(":")[0:4])[-2]
|
||||
if value:
|
||||
# NOTE: this is only for "small subnets", we could increase this...
|
||||
baseaddr = None
|
||||
if value.version == 4:
|
||||
basenet = ipaddress.ip_network("%s/24" % value, strict=False)
|
||||
baseaddr = ".".join(str(basenet).split(".")[0:3]) + "."
|
||||
else:
|
||||
basenet = ipaddress.ip_network("%s/56" % value.exploded, strict=False)
|
||||
baseaddr = ":".join(str(basenet).split(":")[0:4])[-2]
|
||||
|
||||
nets = whoisdb.models.InetNum.objects.filter(address__startswith=baseaddr).order_by("-netmask")
|
||||
for net in nets:
|
||||
if value in net.getNetwork():
|
||||
results.append(net)
|
||||
break
|
||||
nets = whoisdb.models.InetNum.objects.filter(address__startswith=baseaddr).order_by("-netmask")
|
||||
for net in nets:
|
||||
if value in net.getNetwork():
|
||||
results.append(net)
|
||||
break
|
||||
|
||||
# asnumber?
|
||||
m = re.match("^(?:AS)?(\d+)$", rawValue)
|
||||
if m:
|
||||
# asnumber!
|
||||
num = int(m.group(1))
|
||||
obj = whoisdb.models.ASNumber.objects.filter(number=num)
|
||||
results.extend(obj)
|
||||
# asnumber?
|
||||
m = re.match("^(?:AS)?(\d+)$", rawValue)
|
||||
if m:
|
||||
# asnumber!
|
||||
num = int(m.group(1))
|
||||
obj = whoisdb.models.ASNumber.objects.filter(number=num)
|
||||
results.extend(obj)
|
||||
|
||||
# find a matching block
|
||||
blocks = whoisdb.models.ASBlock.objects.filter(asBegin__lte=num, asEnd__gte=num).annotate(size=F('asEnd')-F('asBegin')).order_by('size')
|
||||
if blocks.count() > 0:
|
||||
results.append(blocks[0])
|
||||
# find a matching block
|
||||
blocks = whoisdb.models.ASBlock.objects.filter(asBegin__lte=num, asEnd__gte=num).annotate(size=F('asEnd')-F('asBegin')).order_by('size')
|
||||
if blocks.count() > 0:
|
||||
results.append(blocks[0])
|
||||
|
||||
# asblocks? smallest asblock containing the range
|
||||
# WHEN anotation foo... could also be done in asnumber match
|
||||
# also look for number - number queries?
|
||||
# asblocks? smallest asblock containing the range
|
||||
# WHEN anotation foo... could also be done in asnumber match
|
||||
# also look for number - number queries?
|
||||
|
||||
# domain?
|
||||
if rawValue.endswith("DN") or rawValue.endswith("DN."):
|
||||
value = rawValue.lower()
|
||||
if not value.endswith("."):
|
||||
value += "."
|
||||
# domain?
|
||||
if rawValue.endswith("DN") or rawValue.endswith("DN."):
|
||||
value = rawValue.lower()
|
||||
if not value.endswith("."):
|
||||
value += "."
|
||||
|
||||
obj = domains.models.Domain.objects.filter(name=value)
|
||||
results.extend(obj)
|
||||
obj = domains.models.Domain.objects.filter(name=value)
|
||||
results.extend(obj)
|
||||
|
||||
# contact by name?
|
||||
# contact by name?
|
||||
|
||||
# handlenames for Maintainer, Contact, InetNum, ASNumber, ASBlock
|
||||
handleObjs = [
|
||||
whoisdb.models.Contact,
|
||||
whoisdb.models.Maintainer,
|
||||
whoisdb.models.InetNum,
|
||||
whoisdb.models.ASBlock,
|
||||
whoisdb.models.ASNumber,
|
||||
]
|
||||
for handleObj in handleObjs:
|
||||
obj = handleObj.objects.filter(handle=rawValue)
|
||||
if not obj and len(rawValue) >= 3:
|
||||
obj = handleObj.objects.filter(handle__startswith=rawValue)
|
||||
results.extend(obj)
|
||||
# handlenames for Maintainer, Contact, InetNum, ASNumber, ASBlock
|
||||
handleObjs = [
|
||||
whoisdb.models.Contact,
|
||||
whoisdb.models.Maintainer,
|
||||
whoisdb.models.InetNum,
|
||||
whoisdb.models.ASBlock,
|
||||
whoisdb.models.ASNumber,
|
||||
]
|
||||
for handleObj in handleObjs:
|
||||
obj = handleObj.objects.filter(handle=rawValue)
|
||||
if not obj and len(rawValue) >= 3:
|
||||
obj = handleObj.objects.filter(handle__startswith=rawValue)
|
||||
results.extend(obj)
|
||||
|
||||
return results
|
||||
return results
|
||||
|
||||
def findHandleFromStr(rawValue):
|
||||
handleObjs = [
|
||||
whoisdb.models.Contact,
|
||||
whoisdb.models.Maintainer,
|
||||
whoisdb.models.InetNum,
|
||||
whoisdb.models.ASBlock,
|
||||
whoisdb.models.ASNumber,
|
||||
]
|
||||
handleObjs = [
|
||||
whoisdb.models.Contact,
|
||||
whoisdb.models.Maintainer,
|
||||
whoisdb.models.InetNum,
|
||||
whoisdb.models.ASBlock,
|
||||
whoisdb.models.ASNumber,
|
||||
]
|
||||
|
||||
for handleObj in handleObjs:
|
||||
try:
|
||||
return handleObj.objects.get(handle=rawValue)
|
||||
except handleObj.DoesNotExist:
|
||||
pass
|
||||
for handleObj in handleObjs:
|
||||
try:
|
||||
return handleObj.objects.get(handle=rawValue)
|
||||
except handleObj.DoesNotExist:
|
||||
pass
|
||||
|
||||
return None
|
||||
return None
|
||||
|
||||
|
||||
def orderQueryset(qs, userOwned, objOwned):
|
||||
# when for
|
||||
whens = [When(userOwned, then=2)]
|
||||
if objOwned:
|
||||
# add existing
|
||||
whens.append(When(objOwned, then=1))
|
||||
# when for
|
||||
whens = [When(userOwned, then=2)]
|
||||
if objOwned:
|
||||
# add existing
|
||||
whens.append(When(objOwned, then=1))
|
||||
|
||||
qs = qs.annotate(card=Max(Case(*whens, default=0, output_field=IntegerField()))).order_by("-card")
|
||||
qs = qs.annotate(card=Max(Case(*whens, default=0, output_field=IntegerField()))).order_by("-card")
|
||||
|
||||
return qs
|
||||
return qs
|
||||
|
||||
|
|
|
@ -13,269 +13,269 @@ import ipaddress
|
|||
|
||||
|
||||
class WhoisObject(models.Model):
|
||||
class Meta:
|
||||
abstract = True
|
||||
handleSuffix = ""
|
||||
class Meta:
|
||||
abstract = True
|
||||
handleSuffix = ""
|
||||
|
||||
handle = models.SlugField(max_length=32, unique=True, verbose_name='handle', validators=[HandleValidator()])
|
||||
created = models.DateTimeField(auto_now_add=True)
|
||||
last_modified = models.DateTimeField(auto_now_add=True)
|
||||
handle = models.SlugField(max_length=32, unique=True, verbose_name='handle', validators=[HandleValidator()])
|
||||
created = models.DateTimeField(auto_now_add=True)
|
||||
last_modified = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
#def __init__(self, *args, **kwargs):
|
||||
# super(WhoisObject, self).__init__(*args, **kwargs)
|
||||
#def __init__(self, *args, **kwargs):
|
||||
# super(WhoisObject, self).__init__(*args, **kwargs)
|
||||
|
||||
# if getattr(self, "handle"):
|
||||
# field = self._meta.get_field("handle")
|
||||
# if HandleValidatorWithSuffix not in map(type, field.validators):
|
||||
# print(self.handle, "NOOOOT")
|
||||
# field.validators.append(HandleValidatorWithSuffix(self.handleSuffix))
|
||||
# else:
|
||||
# print(self.handle, list(map(type, field.validators)))
|
||||
# if getattr(self, "handle"):
|
||||
# field = self._meta.get_field("handle")
|
||||
# if HandleValidatorWithSuffix not in map(type, field.validators):
|
||||
# print(self.handle, "NOOOOT")
|
||||
# field.validators.append(HandleValidatorWithSuffix(self.handleSuffix))
|
||||
# else:
|
||||
# print(self.handle, list(map(type, field.validators)))
|
||||
|
||||
def getPK(self):
|
||||
return self.handle
|
||||
def getPK(self):
|
||||
return self.handle
|
||||
|
||||
def __str__(self):
|
||||
return self.handle
|
||||
def __str__(self):
|
||||
return self.handle
|
||||
|
||||
def getAppName(self):
|
||||
return "whoisdb"
|
||||
def getAppName(self):
|
||||
return "whoisdb"
|
||||
|
||||
def getClassName(self):
|
||||
return self._meta.object_name
|
||||
def getClassName(self):
|
||||
return self._meta.object_name
|
||||
|
||||
def genHandle(self, main=None):
|
||||
if not main:
|
||||
main = self.name
|
||||
return self.genGenericHandle(main)
|
||||
def genHandle(self, main=None):
|
||||
if not main:
|
||||
main = self.name
|
||||
return self.genGenericHandle(main)
|
||||
|
||||
@classmethod
|
||||
def genGenericHandle(clazz, main):
|
||||
prefix = ""
|
||||
if " " in main:
|
||||
parts = main.split(" ")
|
||||
prefix = "".join(map(lambda _x: _x[0], parts))
|
||||
if len(prefix) < 3 and len(parts[-1]) > 1:
|
||||
prefix += parts[-1][1:4 - len(prefix)]
|
||||
else:
|
||||
prefix = main[0:3]
|
||||
prefix = prefix.upper()
|
||||
@classmethod
|
||||
def genGenericHandle(clazz, main):
|
||||
prefix = ""
|
||||
if " " in main:
|
||||
parts = main.split(" ")
|
||||
prefix = "".join(map(lambda _x: _x[0], parts))
|
||||
if len(prefix) < 3 and len(parts[-1]) > 1:
|
||||
prefix += parts[-1][1:4 - len(prefix)]
|
||||
else:
|
||||
prefix = main[0:3]
|
||||
prefix = prefix.upper()
|
||||
|
||||
i = 1
|
||||
handle = "%s%%d-%s" % (prefix, clazz.handleSuffix)
|
||||
while True:
|
||||
try:
|
||||
prefix
|
||||
clazz.objects.get(handle=handle % i)
|
||||
i += 1
|
||||
except clazz.DoesNotExist:
|
||||
break
|
||||
i = 1
|
||||
handle = "%s%%d-%s" % (prefix, clazz.handleSuffix)
|
||||
while True:
|
||||
try:
|
||||
prefix
|
||||
clazz.objects.get(handle=handle % i)
|
||||
i += 1
|
||||
except clazz.DoesNotExist:
|
||||
break
|
||||
|
||||
return handle % i
|
||||
return handle % i
|
||||
|
||||
def getNoDeleteReasons(self):
|
||||
raise NotImplementedError("Delete reason checking is not implemented for this model")
|
||||
def getNoDeleteReasons(self):
|
||||
raise NotImplementedError("Delete reason checking is not implemented for this model")
|
||||
|
||||
def canBeDeleted(self):
|
||||
return not bool(self.getNoDeleteReasons())
|
||||
def canBeDeleted(self):
|
||||
return not bool(self.getNoDeleteReasons())
|
||||
|
||||
def handleAuto(self, name=None):
|
||||
if self.handle == "AUTO":
|
||||
self.handle = self.genHandle(name)
|
||||
def handleAuto(self, name=None):
|
||||
if self.handle == "AUTO":
|
||||
self.handle = self.genHandle(name)
|
||||
|
||||
|
||||
class Maintainer(WhoisObject):
|
||||
handleSuffix = "MNT"
|
||||
handleSuffix = "MNT"
|
||||
|
||||
auth = models.ManyToManyField(User)
|
||||
handle = models.SlugField(max_length=32, unique=True, verbose_name='handle', validators=[HandleValidatorWithSuffix('MNT')], help_text="Must end with -MNT, eg FOO3-MNT")
|
||||
description = models.CharField(max_length=64, blank=True, help_text="Short description what this maintainer is for")
|
||||
auth = models.ManyToManyField(User)
|
||||
handle = models.SlugField(max_length=32, unique=True, verbose_name='handle', validators=[HandleValidatorWithSuffix('MNT')], help_text="Must end with -MNT, eg FOO3-MNT")
|
||||
description = models.CharField(max_length=64, blank=True, help_text="Short description what this maintainer is for")
|
||||
|
||||
admin_c = models.ManyToManyField("Contact", verbose_name="Administrative Contact")
|
||||
admin_c = models.ManyToManyField("Contact", verbose_name="Administrative Contact")
|
||||
|
||||
rir = models.BooleanField(default=False)
|
||||
lir = models.BooleanField(default=False)
|
||||
rir = models.BooleanField(default=False)
|
||||
lir = models.BooleanField(default=False)
|
||||
|
||||
# autoInclude = models.BooleanField(default=True)
|
||||
# autoInclude = models.BooleanField(default=True)
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("whoisdb:handle-detail", kwargs={"handle": self.handle})
|
||||
def get_absolute_url(self):
|
||||
return reverse("whoisdb:handle-detail", kwargs={"handle": self.handle})
|
||||
|
||||
def getNoDeleteReasons(self):
|
||||
reasons = []
|
||||
def getNoDeleteReasons(self):
|
||||
reasons = []
|
||||
|
||||
# FIXME: Tempfix for circular dependency problem
|
||||
import domains.models
|
||||
# FIXME: Tempfix for circular dependency problem
|
||||
import domains.models
|
||||
|
||||
mntables = [Contact, ASBlock, ASNumber, InetNum, domains.models.Domain, domains.models.Nameserver]
|
||||
for mntable in mntables:
|
||||
candidates = mntable.objects.filter(mnt_by=self).annotate(mntCount=models.Count('mnt_by')).filter(mntCount__lte=1)
|
||||
for candidate in candidates:
|
||||
reasons.append("Object %s would have no maintainers left." % candidate.handle)
|
||||
mntables = [Contact, ASBlock, ASNumber, InetNum, domains.models.Domain, domains.models.Nameserver]
|
||||
for mntable in mntables:
|
||||
candidates = mntable.objects.filter(mnt_by=self).annotate(mntCount=models.Count('mnt_by')).filter(mntCount__lte=1)
|
||||
for candidate in candidates:
|
||||
reasons.append("Object %s would have no maintainers left." % candidate.handle)
|
||||
|
||||
return reasons
|
||||
return reasons
|
||||
|
||||
def canEdit(self, user):
|
||||
return user in self.auth.all()
|
||||
def canEdit(self, user):
|
||||
return user in self.auth.all()
|
||||
|
||||
|
||||
class MntdObject(WhoisObject):
|
||||
class Meta:
|
||||
abstract = True
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
mnt_by = models.ManyToManyField(Maintainer, help_text="You can select multiple maintainers here")
|
||||
mnt_by = models.ManyToManyField(Maintainer, help_text="You can select multiple maintainers here")
|
||||
|
||||
def canEdit(self, user):
|
||||
if not hasattr(user, "maintainer_set"):
|
||||
return False
|
||||
def canEdit(self, user):
|
||||
if not hasattr(user, "maintainer_set"):
|
||||
return False
|
||||
|
||||
mnts = user.maintainer_set.all()
|
||||
objmnts = self.mnt_by.all()
|
||||
if hasattr(self, "mnt_lower"):
|
||||
objmnts |= self.mnt_lower.all()
|
||||
mnts = user.maintainer_set.all()
|
||||
objmnts = self.mnt_by.all()
|
||||
if hasattr(self, "mnt_lower"):
|
||||
objmnts |= self.mnt_lower.all()
|
||||
|
||||
for objmnt in objmnts:
|
||||
if objmnt in mnts:
|
||||
return True
|
||||
return False
|
||||
for objmnt in objmnts:
|
||||
if objmnt in mnts:
|
||||
return True
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
def getMntQueryset(clazz, mnts, instance, attr=None):
|
||||
mntQ = Q(mnt_by__in=mnts)
|
||||
if hasattr(clazz, "mnt_lower"):
|
||||
mntQ |= Q(mnt_lower__in=mnts)
|
||||
@classmethod
|
||||
def getMntQueryset(clazz, mnts, instance, attr=None):
|
||||
mntQ = Q(mnt_by__in=mnts)
|
||||
if hasattr(clazz, "mnt_lower"):
|
||||
mntQ |= Q(mnt_lower__in=mnts)
|
||||
|
||||
qs = clazz.objects.filter(mntQ)
|
||||
if attr and instance and instance.pk:
|
||||
if type(instance._meta.get_field(attr)) == models.ManyToManyField:
|
||||
qs |= getattr(instance, attr).all()
|
||||
elif getattr(instance, attr) is not None:
|
||||
qs |= clazz.objects.filter(pk=getattr(instance, attr).pk)
|
||||
qs = clazz.objects.filter(mntQ)
|
||||
if attr and instance and instance.pk:
|
||||
if type(instance._meta.get_field(attr)) == models.ManyToManyField:
|
||||
qs |= getattr(instance, attr).all()
|
||||
elif getattr(instance, attr) is not None:
|
||||
qs |= clazz.objects.filter(pk=getattr(instance, attr).pk)
|
||||
|
||||
return qs.distinct()
|
||||
return qs.distinct()
|
||||
|
||||
|
||||
class Contact(MntdObject):
|
||||
handleSuffix = "DN"
|
||||
TYPE_PERSON = 'PERSON'
|
||||
TYPE_ROLE = 'ROLE'
|
||||
TYPE = (('person', TYPE_PERSON), ('role', TYPE_ROLE))
|
||||
TYPE = (('person', TYPE_PERSON),)
|
||||
handleSuffix = "DN"
|
||||
TYPE_PERSON = 'PERSON'
|
||||
TYPE_ROLE = 'ROLE'
|
||||
TYPE = (('person', TYPE_PERSON), ('role', TYPE_ROLE))
|
||||
TYPE = (('person', TYPE_PERSON),)
|
||||
|
||||
name = models.CharField(max_length=128)
|
||||
type = models.CharField(max_length=10, choices=TYPE, default=TYPE_PERSON)
|
||||
name = models.CharField(max_length=128)
|
||||
type = models.CharField(max_length=10, choices=TYPE, default=TYPE_PERSON)
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("whoisdb:handle-detail", kwargs={"handle": self.handle})
|
||||
def get_absolute_url(self):
|
||||
return reverse("whoisdb:handle-detail", kwargs={"handle": self.handle})
|
||||
|
||||
def getNoDeleteReasons(self):
|
||||
reasons = []
|
||||
def getNoDeleteReasons(self):
|
||||
reasons = []
|
||||
|
||||
contactables = [Maintainer, ASBlock, ASNumber, InetNum]
|
||||
for contactable in contactables:
|
||||
candidates = contactable.objects.filter(admin_c=self).annotate(contactCount=models.Count('admin_c')).filter(contactCount__lte=1)
|
||||
for candidate in candidates:
|
||||
reasons.append("Object %s would have no contact left." % candidate.handle)
|
||||
contactables = [Maintainer, ASBlock, ASNumber, InetNum]
|
||||
for contactable in contactables:
|
||||
candidates = contactable.objects.filter(admin_c=self).annotate(contactCount=models.Count('admin_c')).filter(contactCount__lte=1)
|
||||
for candidate in candidates:
|
||||
reasons.append("Object %s would have no contact left." % candidate.handle)
|
||||
|
||||
return reasons
|
||||
return reasons
|
||||
|
||||
|
||||
class ASBlock(MntdObject):
|
||||
handleSuffix = "ASB"
|
||||
handleSuffix = "ASB"
|
||||
|
||||
parent_block = models.ForeignKey("ASBlock", models.CASCADE, null=True, blank=True, default=None)
|
||||
name = models.CharField(max_length=32)
|
||||
asBegin = models.PositiveIntegerField()
|
||||
asEnd = models.PositiveIntegerField()
|
||||
description = models.CharField(max_length=64, blank=True)
|
||||
admin_c = models.ManyToManyField("Contact")
|
||||
parent_block = models.ForeignKey("ASBlock", models.CASCADE, null=True, blank=True, default=None)
|
||||
name = models.CharField(max_length=32)
|
||||
asBegin = models.PositiveIntegerField()
|
||||
asEnd = models.PositiveIntegerField()
|
||||
description = models.CharField(max_length=64, blank=True)
|
||||
admin_c = models.ManyToManyField("Contact")
|
||||
|
||||
mnt_lower = models.ManyToManyField(Maintainer, related_name='lower_asblock_set', blank=True)
|
||||
mnt_lower = models.ManyToManyField(Maintainer, related_name='lower_asblock_set', blank=True)
|
||||
|
||||
def contains(self, block):
|
||||
return self.asBegin <= block.asBegin <= self.asEnd and self.asBegin <= block.asEnd <= self.asEnd
|
||||
def contains(self, block):
|
||||
return self.asBegin <= block.asBegin <= self.asEnd and self.asBegin <= block.asEnd <= self.asEnd
|
||||
|
||||
def getResource(self):
|
||||
return "%s - %s" % (self.asBegin, self.asEnd)
|
||||
def getResource(self):
|
||||
return "%s - %s" % (self.asBegin, self.asEnd)
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("whoisdb:handle-detail", kwargs={"handle": self.handle})
|
||||
def get_absolute_url(self):
|
||||
return reverse("whoisdb:handle-detail", kwargs={"handle": self.handle})
|
||||
|
||||
def getNoDeleteReasons(self):
|
||||
reasons = []
|
||||
def getNoDeleteReasons(self):
|
||||
reasons = []
|
||||
|
||||
if self.asblock_set.count() > 0:
|
||||
reasons.append("The AS block is referenced by the following other blocks: %s" % (", ".join(map(lambda _x: _x.handle, self.asblock_set.all()))))
|
||||
if self.asblock_set.count() > 0:
|
||||
reasons.append("The AS block is referenced by the following other blocks: %s" % (", ".join(map(lambda _x: _x.handle, self.asblock_set.all()))))
|
||||
|
||||
if self.asnumber_set.count() > 0:
|
||||
reasons.append("The AS block is referenced by the following as numbers: %s" % (", ".join(map(lambda _x: _x.handle, self.asnumber_set.all()))))
|
||||
if self.asnumber_set.count() > 0:
|
||||
reasons.append("The AS block is referenced by the following as numbers: %s" % (", ".join(map(lambda _x: _x.handle, self.asnumber_set.all()))))
|
||||
|
||||
return reasons
|
||||
return reasons
|
||||
|
||||
|
||||
class ASNumber(MntdObject):
|
||||
handleSuffix = "AS"
|
||||
handleSuffix = "AS"
|
||||
|
||||
number = models.PositiveIntegerField(unique=True, db_index=True)
|
||||
volatile = models.BooleanField(default=False, help_text="Check if this AS is not going to be online 24/7 (for example on a laptop)")
|
||||
asblock = models.ForeignKey(ASBlock, models.CASCADE)
|
||||
name = models.CharField(max_length=32)
|
||||
description = models.CharField(max_length=64, blank=True)
|
||||
admin_c = models.ManyToManyField("Contact")
|
||||
number = models.PositiveIntegerField(unique=True, db_index=True)
|
||||
volatile = models.BooleanField(default=False, help_text="Check if this AS is not going to be online 24/7 (for example on a laptop)")
|
||||
asblock = models.ForeignKey(ASBlock, models.CASCADE)
|
||||
name = models.CharField(max_length=32)
|
||||
description = models.CharField(max_length=64, blank=True)
|
||||
admin_c = models.ManyToManyField("Contact")
|
||||
|
||||
mnt_lower = models.ManyToManyField(Maintainer, related_name='lower_asnumber_set', blank=True)
|
||||
mnt_lower = models.ManyToManyField(Maintainer, related_name='lower_asnumber_set', blank=True)
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("whoisdb:handle-detail", kwargs={"handle": self.handle})
|
||||
def get_absolute_url(self):
|
||||
return reverse("whoisdb:handle-detail", kwargs={"handle": self.handle})
|
||||
|
||||
def getNoDeleteReasons(self):
|
||||
reasons = []
|
||||
def getNoDeleteReasons(self):
|
||||
reasons = []
|
||||
|
||||
return reasons
|
||||
return reasons
|
||||
|
||||
def getResource(self):
|
||||
return str(self.number)
|
||||
def getResource(self):
|
||||
return str(self.number)
|
||||
|
||||
|
||||
class InetNum(MntdObject):
|
||||
class Meta:
|
||||
unique_together = (
|
||||
("address", "netmask"),
|
||||
)
|
||||
class Meta:
|
||||
unique_together = (
|
||||
("address", "netmask"),
|
||||
)
|
||||
|
||||
handleSuffix = "NET"
|
||||
handleSuffix = "NET"
|
||||
|
||||
IPv4 = "ipv4"
|
||||
IPv6 = "ipv6"
|
||||
IPv4 = "ipv4"
|
||||
IPv6 = "ipv6"
|
||||
|
||||
PROTO = ((IPv4, 'IPv4'), (IPv6, 'IPv6'))
|
||||
protocol = models.CharField(max_length=4, choices=PROTO)
|
||||
address = models.GenericIPAddressField(db_index=True)
|
||||
netmask = models.PositiveIntegerField()
|
||||
parent_range = models.ForeignKey("InetNum", models.CASCADE, null=True, blank=True, default=None)
|
||||
name = models.CharField(max_length=64)
|
||||
description = models.CharField(max_length=64, blank=True)
|
||||
origin_as = models.ManyToManyField(ASNumber, blank=True)
|
||||
admin_c = models.ManyToManyField("Contact")
|
||||
PROTO = ((IPv4, 'IPv4'), (IPv6, 'IPv6'))
|
||||
protocol = models.CharField(max_length=4, choices=PROTO)
|
||||
address = models.GenericIPAddressField(db_index=True)
|
||||
netmask = models.PositiveIntegerField()
|
||||
parent_range = models.ForeignKey("InetNum", models.CASCADE, null=True, blank=True, default=None)
|
||||
name = models.CharField(max_length=64)
|
||||
description = models.CharField(max_length=64, blank=True)
|
||||
origin_as = models.ManyToManyField(ASNumber, blank=True)
|
||||
admin_c = models.ManyToManyField("Contact")
|
||||
|
||||
mnt_lower = models.ManyToManyField(Maintainer, related_name='lower_inetnum_set', blank=True)
|
||||
mnt_lower = models.ManyToManyField(Maintainer, related_name='lower_inetnum_set', blank=True)
|
||||
|
||||
def getResource(self):
|
||||
return self.prefix()
|
||||
def getResource(self):
|
||||
return self.prefix()
|
||||
|
||||
def prefix(self):
|
||||
""" Helper function, mainly used in templates """
|
||||
return "%s/%s" % (self.address, self.netmask)
|
||||
def prefix(self):
|
||||
""" Helper function, mainly used in templates """
|
||||
return "%s/%s" % (self.address, self.netmask)
|
||||
|
||||
def getNetwork(self):
|
||||
return ipaddress.ip_network(self.prefix())
|
||||
def getNetwork(self):
|
||||
return ipaddress.ip_network(self.prefix())
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("whoisdb:handle-detail", kwargs={"handle": self.handle})
|
||||
def get_absolute_url(self):
|
||||
return reverse("whoisdb:handle-detail", kwargs={"handle": self.handle})
|
||||
|
||||
def getNoDeleteReasons(self):
|
||||
reasons = []
|
||||
if self.inetnum_set.all().count() > 0:
|
||||
reasons.append("The following networks depend on this network: %s" % ", ".join(map(lambda _x: _x.handle, self.inetnum_set.all())))
|
||||
def getNoDeleteReasons(self):
|
||||
reasons = []
|
||||
if self.inetnum_set.all().count() > 0:
|
||||
reasons.append("The following networks depend on this network: %s" % ", ".join(map(lambda _x: _x.handle, self.inetnum_set.all())))
|
||||
|
||||
return reasons
|
||||
return reasons
|
||||
|
|
|
@ -9,44 +9,44 @@ register = template.Library()
|
|||
|
||||
@register.filter
|
||||
def linkObject(value):
|
||||
return mark_safe('<a href="%s">%s</a>' % (value.get_absolute_url(), str(value)))
|
||||
return mark_safe('<a href="%s">%s</a>' % (value.get_absolute_url(), str(value)))
|
||||
|
||||
@register.filter
|
||||
def tryLinkHandle(handle):
|
||||
try:
|
||||
if not handle:
|
||||
raise ValueError()
|
||||
HandleValidator()(str(handle))
|
||||
obj = findHandleFromStr(handle)
|
||||
if obj:
|
||||
return linkObject(obj)
|
||||
except:
|
||||
pass
|
||||
try:
|
||||
if not handle:
|
||||
raise ValueError()
|
||||
HandleValidator()(str(handle))
|
||||
obj = findHandleFromStr(handle)
|
||||
if obj:
|
||||
return linkObject(obj)
|
||||
except:
|
||||
pass
|
||||
|
||||
return handle
|
||||
return handle
|
||||
|
||||
|
||||
|
||||
@register.filter
|
||||
def linkObjects(value):
|
||||
links = []
|
||||
for obj in value:
|
||||
if hasattr(obj, "get_absolute_url"):
|
||||
links.append('<a href="%s">%s</a>' % (obj.get_absolute_url(), str(obj)))
|
||||
else:
|
||||
links.append(str(obj))
|
||||
links = []
|
||||
for obj in value:
|
||||
if hasattr(obj, "get_absolute_url"):
|
||||
links.append('<a href="%s">%s</a>' % (obj.get_absolute_url(), str(obj)))
|
||||
else:
|
||||
links.append(str(obj))
|
||||
|
||||
return mark_safe(", ".join(links))
|
||||
return mark_safe(", ".join(links))
|
||||
|
||||
@register.filter
|
||||
def getFields(value, user):
|
||||
owner = value.canEdit(user)
|
||||
owner = value.canEdit(user)
|
||||
|
||||
return getWhoisObjectFields(value, owner)
|
||||
return getWhoisObjectFields(value, owner)
|
||||
|
||||
|
||||
@register.filter
|
||||
def userCanEdit(value, user):
|
||||
if hasattr(value, "canEdit"):
|
||||
return value.canEdit(user)
|
||||
return False
|
||||
if hasattr(value, "canEdit"):
|
||||
return value.canEdit(user)
|
||||
return False
|
||||
|
|
|
@ -7,40 +7,40 @@ from django.conf.urls import url
|
|||
from . import views as whoisdb_views
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^$', whoisdb_views.dbDashboard, name='dashboard'),
|
||||
url(r'^$', whoisdb_views.dbDashboard, name='dashboard'),
|
||||
|
||||
url(r'^search/$', whoisdb_views.searchObject, name='search'),
|
||||
url(r'^search/$', whoisdb_views.searchObject, name='search'),
|
||||
|
||||
|
||||
url(r'^create/$', whoisdb_views.createObjectOverview, name='createObjectOverview'),
|
||||
url(r'^handle/(?P<handle>[A-Z0-9-]+)/$', whoisdb_views.showHandle, name='showhandle'),
|
||||
url(r'^handle/(?P<handle>[A-Z0-9-]+)/$', whoisdb_views.showHandle, name='handle-detail'),
|
||||
url(r'^create/$', whoisdb_views.createObjectOverview, name='createObjectOverview'),
|
||||
url(r'^handle/(?P<handle>[A-Z0-9-]+)/$', whoisdb_views.showHandle, name='showhandle'),
|
||||
url(r'^handle/(?P<handle>[A-Z0-9-]+)/$', whoisdb_views.showHandle, name='handle-detail'),
|
||||
|
||||
url(r'^mnt/create/$', whoisdb_views.MaintainerCreate.as_view(), name='maintainer-create'),
|
||||
url(r'^mnt/show/(?P<handle>[A-Z0-9-]+)/$', whoisdb_views.MaintainerDetail.as_view(), name='maintainer-detail'),
|
||||
url(r'^mnt/edit/(?P<handle>[A-Z0-9-]+)/$', whoisdb_views.MaintainerEdit.as_view(), name='maintainer-edit'),
|
||||
url(r'^mnt/delete/(?P<handle>[A-Z0-9-]+)/$', whoisdb_views.MaintainerDelete.as_view(), name='maintainer-delete'),
|
||||
url(r'^mnt/create/$', whoisdb_views.MaintainerCreate.as_view(), name='maintainer-create'),
|
||||
url(r'^mnt/show/(?P<handle>[A-Z0-9-]+)/$', whoisdb_views.MaintainerDetail.as_view(), name='maintainer-detail'),
|
||||
url(r'^mnt/edit/(?P<handle>[A-Z0-9-]+)/$', whoisdb_views.MaintainerEdit.as_view(), name='maintainer-edit'),
|
||||
url(r'^mnt/delete/(?P<handle>[A-Z0-9-]+)/$', whoisdb_views.MaintainerDelete.as_view(), name='maintainer-delete'),
|
||||
|
||||
url(r'^contact/create/$', whoisdb_views.ContactCreate.as_view(), name='contact-create'),
|
||||
url(r'^contact/show/(?P<handle>[A-Z0-9-]+)/$', whoisdb_views.ContactDetail.as_view(), name='contact-detail'),
|
||||
url(r'^contact/edit/(?P<handle>[A-Z0-9-]+)/$', whoisdb_views.ContactEdit.as_view(), name='contact-edit'),
|
||||
url(r'^contact/delete/(?P<handle>[A-Z0-9-]+)/$', whoisdb_views.ContactDelete.as_view(), name='contact-delete'),
|
||||
url(r'^contact/create/$', whoisdb_views.ContactCreate.as_view(), name='contact-create'),
|
||||
url(r'^contact/show/(?P<handle>[A-Z0-9-]+)/$', whoisdb_views.ContactDetail.as_view(), name='contact-detail'),
|
||||
url(r'^contact/edit/(?P<handle>[A-Z0-9-]+)/$', whoisdb_views.ContactEdit.as_view(), name='contact-edit'),
|
||||
url(r'^contact/delete/(?P<handle>[A-Z0-9-]+)/$', whoisdb_views.ContactDelete.as_view(), name='contact-delete'),
|
||||
|
||||
url(r'^inetnum/create/$', whoisdb_views.InetNumCreate.as_view(), name='inetnum-create'),
|
||||
url(r'^inetnum/show/(?P<handle>[A-Z0-9-]+)/$', whoisdb_views.InetNumDetail.as_view(), name='inetnum-detail'),
|
||||
url(r'^inetnum/edit/(?P<handle>[A-Z0-9-]+)/$', whoisdb_views.InetNumEdit.as_view(), name='inetnum-edit'),
|
||||
url(r'^inetnum/delete/(?P<handle>[A-Z0-9-]+)/$', whoisdb_views.InetNumDelete.as_view(), name='inetnum-delete'),
|
||||
url(r'^inetnum/create/$', whoisdb_views.InetNumCreate.as_view(), name='inetnum-create'),
|
||||
url(r'^inetnum/show/(?P<handle>[A-Z0-9-]+)/$', whoisdb_views.InetNumDetail.as_view(), name='inetnum-detail'),
|
||||
url(r'^inetnum/edit/(?P<handle>[A-Z0-9-]+)/$', whoisdb_views.InetNumEdit.as_view(), name='inetnum-edit'),
|
||||
url(r'^inetnum/delete/(?P<handle>[A-Z0-9-]+)/$', whoisdb_views.InetNumDelete.as_view(), name='inetnum-delete'),
|
||||
|
||||
url(r'^asblock/create/$', whoisdb_views.ASBlockCreate.as_view(), name='asblock-create'),
|
||||
url(r'^asblock/show/(?P<handle>[A-Z0-9-]+)/$', whoisdb_views.ASBlockDetail.as_view(), name='asblock-detail'),
|
||||
url(r'^asblock/edit/(?P<handle>[A-Z0-9-]+)/$', whoisdb_views.ASBlockEdit.as_view(), name='asblock-edit'),
|
||||
url(r'^asblock/delete/(?P<handle>[A-Z0-9-]+)/$', whoisdb_views.ASBlockDelete.as_view(), name='asblock-delete'),
|
||||
url(r'^asblock/create/$', whoisdb_views.ASBlockCreate.as_view(), name='asblock-create'),
|
||||
url(r'^asblock/show/(?P<handle>[A-Z0-9-]+)/$', whoisdb_views.ASBlockDetail.as_view(), name='asblock-detail'),
|
||||
url(r'^asblock/edit/(?P<handle>[A-Z0-9-]+)/$', whoisdb_views.ASBlockEdit.as_view(), name='asblock-edit'),
|
||||
url(r'^asblock/delete/(?P<handle>[A-Z0-9-]+)/$', whoisdb_views.ASBlockDelete.as_view(), name='asblock-delete'),
|
||||
|
||||
url(r'^asnumber/create/$', whoisdb_views.ASNumberCreate.as_view(), name='asnumber-create'),
|
||||
url(r'^asnumber/show/(?P<handle>[A-Z0-9-]+)/$', whoisdb_views.ASNumberDetail.as_view(), name='asnumber-detail'),
|
||||
url(r'^asnumber/edit/(?P<handle>[A-Z0-9-]+)/$', whoisdb_views.ASNumberEdit.as_view(), name='asnumber-edit'),
|
||||
url(r'^asnumber/delete/(?P<handle>[A-Z0-9-]+)/$', whoisdb_views.ASNumberDelete.as_view(), name='asnumber-delete'),
|
||||
url(r'^asnumber/create/$', whoisdb_views.ASNumberCreate.as_view(), name='asnumber-create'),
|
||||
url(r'^asnumber/show/(?P<handle>[A-Z0-9-]+)/$', whoisdb_views.ASNumberDetail.as_view(), name='asnumber-detail'),
|
||||
url(r'^asnumber/edit/(?P<handle>[A-Z0-9-]+)/$', whoisdb_views.ASNumberEdit.as_view(), name='asnumber-edit'),
|
||||
url(r'^asnumber/delete/(?P<handle>[A-Z0-9-]+)/$', whoisdb_views.ASNumberDelete.as_view(), name='asnumber-delete'),
|
||||
|
||||
|
||||
url(r'^assubnetset/create/$', whoisdb_views.ASAndSubnetWizard.as_view(), name='asandsubnet-wizard'),
|
||||
url(r'^assubnetset/create/$', whoisdb_views.ASAndSubnetWizard.as_view(), name='asandsubnet-wizard'),
|
||||
]
|
||||
|
|
|
@ -14,31 +14,31 @@ import ipaddress
|
|||
|
||||
@deconstructible
|
||||
class HandleValidator(validators.RegexValidator):
|
||||
regex = r'^(?:[A-Z]+[0-9]*(-[A-Z]+)|AUTO)$'
|
||||
message = _(
|
||||
'Enter a valid handle (all uppercase)'
|
||||
)
|
||||
flags = re.ASCII if six.PY3 else 0
|
||||
regex = r'^(?:[A-Z]+[0-9]*(-[A-Z]+)|AUTO)$'
|
||||
message = _(
|
||||
'Enter a valid handle (all uppercase)'
|
||||
)
|
||||
flags = re.ASCII if six.PY3 else 0
|
||||
|
||||
|
||||
@deconstructible
|
||||
class HandleValidatorWithSuffix(validators.RegexValidator):
|
||||
flags = re.ASCII if six.PY3 else 0
|
||||
flags = re.ASCII if six.PY3 else 0
|
||||
|
||||
def __init__(self, suffix):
|
||||
self.regex = r'^(?:[A-Z]+[0-9]*-%s|AUTO)$' % re.escape(suffix)
|
||||
self.message = _(
|
||||
'Enter a valid handle with suffix %s (all uppercase), e.g. FOO3-%s' % (suffix, suffix)
|
||||
)
|
||||
def __init__(self, suffix):
|
||||
self.regex = r'^(?:[A-Z]+[0-9]*-%s|AUTO)$' % re.escape(suffix)
|
||||
self.message = _(
|
||||
'Enter a valid handle with suffix %s (all uppercase), e.g. FOO3-%s' % (suffix, suffix)
|
||||
)
|
||||
|
||||
super(HandleValidatorWithSuffix, self).__init__()
|
||||
super(HandleValidatorWithSuffix, self).__init__()
|
||||
|
||||
|
||||
def IP46CIDRValidator(value):
|
||||
if not re.match(r"[0-9a-fA-F:.]+/[0-9]+", value):
|
||||
raise ValidationError("Address needs to be a subnet in the format of ip/prefix")
|
||||
if not re.match(r"[0-9a-fA-F:.]+/[0-9]+", value):
|
||||
raise ValidationError("Address needs to be a subnet in the format of ip/prefix")
|
||||
|
||||
try:
|
||||
ipaddress.ip_network(value)
|
||||
except ValueError as e:
|
||||
raise ValidationError(str(e))
|
||||
try:
|
||||
ipaddress.ip_network(value)
|
||||
except ValueError as e:
|
||||
raise ValidationError(str(e))
|
||||
|
|
458
whoisdb/views.py
458
whoisdb/views.py
|
@ -20,349 +20,349 @@ from .helpers import findInDatabase
|
|||
|
||||
@login_required
|
||||
def createObjectOverview(request):
|
||||
mnts = request.user.maintainer_set.filter().all()
|
||||
netblocks = InetNum.objects.filter(Q(mnt_by__in=mnts) | Q(mnt_lower__in=mnts)).distinct()
|
||||
asblocks = ASBlock.objects.filter(Q(mnt_by__in=mnts) | Q(mnt_lower__in=mnts)).distinct()
|
||||
mnts = request.user.maintainer_set.filter().all()
|
||||
netblocks = InetNum.objects.filter(Q(mnt_by__in=mnts) | Q(mnt_lower__in=mnts)).distinct()
|
||||
asblocks = ASBlock.objects.filter(Q(mnt_by__in=mnts) | Q(mnt_lower__in=mnts)).distinct()
|
||||
|
||||
return render(request, "whoisdb/create_overview.html", {"netblocks": netblocks, "asblocks": asblocks})
|
||||
return render(request, "whoisdb/create_overview.html", {"netblocks": netblocks, "asblocks": asblocks})
|
||||
|
||||
|
||||
@login_required
|
||||
def dbDashboard(request):
|
||||
mnts = request.user.maintainer_set.filter(rir=False, lir=False).all()
|
||||
if request.GET.get("delegated", None) or mnts.count() == 0:
|
||||
# if user wants to see rir/lir objects or only has rir/lir mnts, use all available mnts
|
||||
mnts = request.user.maintainer_set.all()
|
||||
showDelegations = True
|
||||
else:
|
||||
showDelegations = False
|
||||
mnts = request.user.maintainer_set.filter(rir=False, lir=False).all()
|
||||
if request.GET.get("delegated", None) or mnts.count() == 0:
|
||||
# if user wants to see rir/lir objects or only has rir/lir mnts, use all available mnts
|
||||
mnts = request.user.maintainer_set.all()
|
||||
showDelegations = True
|
||||
else:
|
||||
showDelegations = False
|
||||
|
||||
hasDelegations = request.user.maintainer_set.filter(Q(rir=True) | Q(lir=True)).count() > 0
|
||||
hasDelegations = request.user.maintainer_set.filter(Q(rir=True) | Q(lir=True)).count() > 0
|
||||
|
||||
contacts = Contact.objects.filter(mnt_by__in=mnts)
|
||||
netblocks = InetNum.objects.filter(Q(mnt_by__in=mnts) | Q(mnt_lower__in=mnts)).distinct()
|
||||
asblocks = ASBlock.objects.filter(Q(mnt_by__in=mnts) | Q(mnt_lower__in=mnts)).distinct()
|
||||
asnumbers = ASNumber.objects.filter(Q(mnt_by__in=mnts) | Q(mnt_lower__in=mnts)).distinct()
|
||||
mntForm = contactForm = None
|
||||
contacts = Contact.objects.filter(mnt_by__in=mnts)
|
||||
netblocks = InetNum.objects.filter(Q(mnt_by__in=mnts) | Q(mnt_lower__in=mnts)).distinct()
|
||||
asblocks = ASBlock.objects.filter(Q(mnt_by__in=mnts) | Q(mnt_lower__in=mnts)).distinct()
|
||||
asnumbers = ASNumber.objects.filter(Q(mnt_by__in=mnts) | Q(mnt_lower__in=mnts)).distinct()
|
||||
mntForm = contactForm = None
|
||||
|
||||
if mnts.count() == 0:
|
||||
mntForm = contactForm = None
|
||||
if request.method == "POST":
|
||||
mntForm = MntInitialForm(user=request.user, data=request.POST, prefix="mnt")
|
||||
contactForm = ContactInitialForm(user=request.user, data=request.POST, prefix="contact")
|
||||
if mntForm.is_valid() and contactForm.is_valid():
|
||||
mnt = mntForm.save(commit=False)
|
||||
mnt.handleAuto(request.user.username)
|
||||
mnt.save()
|
||||
if mnts.count() == 0:
|
||||
mntForm = contactForm = None
|
||||
if request.method == "POST":
|
||||
mntForm = MntInitialForm(user=request.user, data=request.POST, prefix="mnt")
|
||||
contactForm = ContactInitialForm(user=request.user, data=request.POST, prefix="contact")
|
||||
if mntForm.is_valid() and contactForm.is_valid():
|
||||
mnt = mntForm.save(commit=False)
|
||||
mnt.handleAuto(request.user.username)
|
||||
mnt.save()
|
||||
|
||||
contact = contactForm.save(commit=False)
|
||||
contact.handleAuto()
|
||||
contact.type = Contact.TYPE_PERSON
|
||||
contact.save()
|
||||
contact.mnt_by.add(mnt.id)
|
||||
contact.save()
|
||||
contact = contactForm.save(commit=False)
|
||||
contact.handleAuto()
|
||||
contact.type = Contact.TYPE_PERSON
|
||||
contact.save()
|
||||
contact.mnt_by.add(mnt.id)
|
||||
contact.save()
|
||||
|
||||
mnt.auth.add(request.user.id)
|
||||
mnt.admin_c.add(contact.id)
|
||||
mnt.save()
|
||||
mnt.auth.add(request.user.id)
|
||||
mnt.admin_c.add(contact.id)
|
||||
mnt.save()
|
||||
|
||||
return HttpResponseRedirect(reverse("whoisdb:dashboard"))
|
||||
else:
|
||||
mntForm = MntInitialForm(user=request.user, prefix="mnt", initial={'handle': 'AUTO', 'description': 'Primary maintainer of %s' % request.user.username})
|
||||
contactForm = ContactInitialForm(user=request.user, initial={'handle': 'AUTO', 'name': request.user.username.capitalize()}, prefix='contact')
|
||||
return HttpResponseRedirect(reverse("whoisdb:dashboard"))
|
||||
else:
|
||||
mntForm = MntInitialForm(user=request.user, prefix="mnt", initial={'handle': 'AUTO', 'description': 'Primary maintainer of %s' % request.user.username})
|
||||
contactForm = ContactInitialForm(user=request.user, initial={'handle': 'AUTO', 'name': request.user.username.capitalize()}, prefix='contact')
|
||||
|
||||
return render(request, "whoisdb/overview.html", {"mnts": mnts, "contacts": contacts, "mntForm": mntForm, "contactForm": contactForm, "netblocks": netblocks, "asblocks": asblocks, "asnumbers": asnumbers, 'hasDelegations': hasDelegations, "showDelegations": showDelegations})
|
||||
return render(request, "whoisdb/overview.html", {"mnts": mnts, "contacts": contacts, "mntForm": mntForm, "contactForm": contactForm, "netblocks": netblocks, "asblocks": asblocks, "asnumbers": asnumbers, 'hasDelegations': hasDelegations, "showDelegations": showDelegations})
|
||||
|
||||
|
||||
def showHandle(request, handle):
|
||||
# a) find handle
|
||||
models = [Contact, Maintainer, ASBlock, ASNumber, InetNum]
|
||||
obj = None
|
||||
# a) find handle
|
||||
models = [Contact, Maintainer, ASBlock, ASNumber, InetNum]
|
||||
obj = None
|
||||
|
||||
for model in models:
|
||||
if handle.endswith(model.handleSuffix):
|
||||
obj = get_object_or_404(model, handle=handle)
|
||||
break
|
||||
for model in models:
|
||||
if handle.endswith(model.handleSuffix):
|
||||
obj = get_object_or_404(model, handle=handle)
|
||||
break
|
||||
|
||||
if not obj:
|
||||
raise Http404("Handle object not found")
|
||||
if not obj:
|
||||
raise Http404("Handle object not found")
|
||||
|
||||
return render(request, "whoisdb/handle_show.html", {"object": obj})
|
||||
return render(request, "whoisdb/handle_show.html", {"object": obj})
|
||||
|
||||
|
||||
def searchObject(request):
|
||||
results = None
|
||||
term = request.GET.get("q", None)
|
||||
if term:
|
||||
results = findInDatabase(term)
|
||||
return render(request, "whoisdb/search.html", {"results": results, "term": term})
|
||||
results = None
|
||||
term = request.GET.get("q", None)
|
||||
if term:
|
||||
results = findInDatabase(term)
|
||||
return render(request, "whoisdb/search.html", {"results": results, "term": term})
|
||||
|
||||
|
||||
class MaintainerCreate(LoginRequiredMixin, CreateView):
|
||||
template_name = "whoisdb/obj_create.html"
|
||||
form_class = MntForm
|
||||
template_name = "whoisdb/obj_create.html"
|
||||
form_class = MntForm
|
||||
|
||||
def get_form_kwargs(self, *args, **kwargs):
|
||||
kwargs = super(MaintainerCreate, self).get_form_kwargs(*args, **kwargs)
|
||||
kwargs["user"] = self.request.user
|
||||
kwargs["initial"] = {
|
||||
"handle": "AUTO",
|
||||
#"auth": self.request.user.username,
|
||||
}
|
||||
def get_form_kwargs(self, *args, **kwargs):
|
||||
kwargs = super(MaintainerCreate, self).get_form_kwargs(*args, **kwargs)
|
||||
kwargs["user"] = self.request.user
|
||||
kwargs["initial"] = {
|
||||
"handle": "AUTO",
|
||||
#"auth": self.request.user.username,
|
||||
}
|
||||
|
||||
return kwargs
|
||||
return kwargs
|
||||
|
||||
def form_valid(self, form):
|
||||
self.object = form.save(commit=False)
|
||||
self.object.handleAuto(self.request.user.username)
|
||||
self.object.save()
|
||||
self.object.auth.add(self.request.user)
|
||||
self.object.save()
|
||||
def form_valid(self, form):
|
||||
self.object = form.save(commit=False)
|
||||
self.object.handleAuto(self.request.user.username)
|
||||
self.object.save()
|
||||
self.object.auth.add(self.request.user)
|
||||
self.object.save()
|
||||
|
||||
return super(MaintainerCreate, self).form_valid(form)
|
||||
return super(MaintainerCreate, self).form_valid(form)
|
||||
|
||||
|
||||
class MaintainerEdit(LoginRequiredMixin, UpdateView):
|
||||
template_name = "whoisdb/obj_edit.html"
|
||||
model = Maintainer
|
||||
form_class = MntForm
|
||||
slug_field = "handle"
|
||||
slug_url_kwarg = "handle"
|
||||
template_name = "whoisdb/obj_edit.html"
|
||||
model = Maintainer
|
||||
form_class = MntForm
|
||||
slug_field = "handle"
|
||||
slug_url_kwarg = "handle"
|
||||
|
||||
def get_form_kwargs(self, *args, **kwargs):
|
||||
kwargs = super(MaintainerEdit, self).get_form_kwargs(*args, **kwargs)
|
||||
kwargs["user"] = self.request.user
|
||||
return kwargs
|
||||
def get_form_kwargs(self, *args, **kwargs):
|
||||
kwargs = super(MaintainerEdit, self).get_form_kwargs(*args, **kwargs)
|
||||
kwargs["user"] = self.request.user
|
||||
return kwargs
|
||||
|
||||
def get_queryset(self):
|
||||
return self.model.objects.filter(auth=self.request.user)
|
||||
def get_queryset(self):
|
||||
return self.model.objects.filter(auth=self.request.user)
|
||||
|
||||
|
||||
class MaintainerDelete(LoginRequiredMixin, DeleteCheckView):
|
||||
template_name = "whoisdb/obj_delete.html"
|
||||
model = Maintainer
|
||||
slug_field = "handle"
|
||||
slug_url_kwarg = "handle"
|
||||
success_url = reverse_lazy("whoisdb:dashboard")
|
||||
template_name = "whoisdb/obj_delete.html"
|
||||
model = Maintainer
|
||||
slug_field = "handle"
|
||||
slug_url_kwarg = "handle"
|
||||
success_url = reverse_lazy("whoisdb:dashboard")
|
||||
|
||||
def get_queryset(self):
|
||||
return self.model.objects.filter(auth=self.request.user)
|
||||
def get_queryset(self):
|
||||
return self.model.objects.filter(auth=self.request.user)
|
||||
|
||||
|
||||
class MaintainerDetail(LoginRequiredMixin, DetailView):
|
||||
template_name = "whoisdb/handle_show.html"
|
||||
model = Maintainer
|
||||
slug_field = "handle"
|
||||
slug_url_kwarg = "handle"
|
||||
#context_object_name = "mnt"
|
||||
template_name = "whoisdb/handle_show.html"
|
||||
model = Maintainer
|
||||
slug_field = "handle"
|
||||
slug_url_kwarg = "handle"
|
||||
#context_object_name = "mnt"
|
||||
|
||||
|
||||
class ContactDetail(DetailView):
|
||||
model = Contact
|
||||
slug_field = "handle"
|
||||
slug_url_kwarg = "handle"
|
||||
context_object_name = "contact"
|
||||
model = Contact
|
||||
slug_field = "handle"
|
||||
slug_url_kwarg = "handle"
|
||||
context_object_name = "contact"
|
||||
|
||||
|
||||
class ContactEdit(MntGenericMixin, LoginRequiredMixin, UpdateView):
|
||||
template_name = "whoisdb/obj_edit.html"
|
||||
model = Contact
|
||||
form_class = ContactForm
|
||||
slug_field = "handle"
|
||||
slug_url_kwarg = "handle"
|
||||
template_name = "whoisdb/obj_edit.html"
|
||||
model = Contact
|
||||
form_class = ContactForm
|
||||
slug_field = "handle"
|
||||
slug_url_kwarg = "handle"
|
||||
|
||||
def get_form_kwargs(self, *args, **kwargs):
|
||||
kwargs = super(ContactEdit, self).get_form_kwargs(*args, **kwargs)
|
||||
kwargs["user"] = self.request.user
|
||||
return kwargs
|
||||
def get_form_kwargs(self, *args, **kwargs):
|
||||
kwargs = super(ContactEdit, self).get_form_kwargs(*args, **kwargs)
|
||||
kwargs["user"] = self.request.user
|
||||
return kwargs
|
||||
|
||||
|
||||
class ContactCreate(LoginRequiredMixin, CreateView):
|
||||
template_name = "whoisdb/obj_create.html"
|
||||
form_class = ContactForm
|
||||
template_name = "whoisdb/obj_create.html"
|
||||
form_class = ContactForm
|
||||
|
||||
def get_form_kwargs(self, *args, **kwargs):
|
||||
kwargs = super(ContactCreate, self).get_form_kwargs(*args, **kwargs)
|
||||
kwargs["user"] = self.request.user
|
||||
kwargs["initial"] = {
|
||||
"handle": "AUTO",
|
||||
"type": Contact.TYPE_PERSON
|
||||
}
|
||||
return kwargs
|
||||
def get_form_kwargs(self, *args, **kwargs):
|
||||
kwargs = super(ContactCreate, self).get_form_kwargs(*args, **kwargs)
|
||||
kwargs["user"] = self.request.user
|
||||
kwargs["initial"] = {
|
||||
"handle": "AUTO",
|
||||
"type": Contact.TYPE_PERSON
|
||||
}
|
||||
return kwargs
|
||||
|
||||
|
||||
class ContactDelete(MntGenericMixin, LoginRequiredMixin, DeleteCheckView):
|
||||
template_name = "whoisdb/obj_delete.html"
|
||||
model = Contact
|
||||
slug_field = "handle"
|
||||
slug_url_kwarg = "handle"
|
||||
success_url = reverse_lazy("whoisdb:dashboard")
|
||||
template_name = "whoisdb/obj_delete.html"
|
||||
model = Contact
|
||||
slug_field = "handle"
|
||||
slug_url_kwarg = "handle"
|
||||
success_url = reverse_lazy("whoisdb:dashboard")
|
||||
|
||||
|
||||
# InetNum
|
||||
class InetNumCreate(LoginRequiredMixin, CreateView):
|
||||
template_name = "whoisdb/obj_create.html"
|
||||
form_class = InetNumForm
|
||||
template_name = "whoisdb/obj_create.html"
|
||||
form_class = InetNumForm
|
||||
|
||||
def get_form_kwargs(self, *args, **kwargs):
|
||||
print("NOOOOOOOOOOOOOOOOOOOOOOOOOOOOT", args, kwargs)
|
||||
kwargs = super(InetNumCreate, self).get_form_kwargs(*args, **kwargs)
|
||||
kwargs["user"] = self.request.user
|
||||
kwargs["initial"] = {
|
||||
"handle": "AUTO",
|
||||
}
|
||||
def get_form_kwargs(self, *args, **kwargs):
|
||||
print("NOOOOOOOOOOOOOOOOOOOOOOOOOOOOT", args, kwargs)
|
||||
kwargs = super(InetNumCreate, self).get_form_kwargs(*args, **kwargs)
|
||||
kwargs["user"] = self.request.user
|
||||
kwargs["initial"] = {
|
||||
"handle": "AUTO",
|
||||
}
|
||||
|
||||
return kwargs
|
||||
return kwargs
|
||||
|
||||
|
||||
class InetNumDetail(DetailView):
|
||||
model = InetNum
|
||||
slug_field = "handle"
|
||||
slug_url_kwarg = "handle"
|
||||
context_object_name = "inetnum"
|
||||
model = InetNum
|
||||
slug_field = "handle"
|
||||
slug_url_kwarg = "handle"
|
||||
context_object_name = "inetnum"
|
||||
|
||||
|
||||
class InetNumEdit(MntGenericMixin, LoginRequiredMixin, UpdateView):
|
||||
template_name = "whoisdb/obj_edit.html"
|
||||
model = InetNum
|
||||
form_class = InetNumForm
|
||||
slug_field = "handle"
|
||||
slug_url_kwarg = "handle"
|
||||
template_name = "whoisdb/obj_edit.html"
|
||||
model = InetNum
|
||||
form_class = InetNumForm
|
||||
slug_field = "handle"
|
||||
slug_url_kwarg = "handle"
|
||||
|
||||
def get_form_kwargs(self, *args, **kwargs):
|
||||
kwargs = super(InetNumEdit, self).get_form_kwargs(*args, **kwargs)
|
||||
kwargs["user"] = self.request.user
|
||||
kwargs["initial"] = {'prefix': str(self.object.getNetwork())}
|
||||
def get_form_kwargs(self, *args, **kwargs):
|
||||
kwargs = super(InetNumEdit, self).get_form_kwargs(*args, **kwargs)
|
||||
kwargs["user"] = self.request.user
|
||||
kwargs["initial"] = {'prefix': str(self.object.getNetwork())}
|
||||
|
||||
return kwargs
|
||||
return kwargs
|
||||
|
||||
|
||||
class InetNumDelete(MntGenericMixin, LoginRequiredMixin, DeleteCheckView):
|
||||
template_name = "whoisdb/obj_delete.html"
|
||||
model = InetNum
|
||||
slug_field = "handle"
|
||||
slug_url_kwarg = "handle"
|
||||
success_url = reverse_lazy("whoisdb:dashboard")
|
||||
template_name = "whoisdb/obj_delete.html"
|
||||
model = InetNum
|
||||
slug_field = "handle"
|
||||
slug_url_kwarg = "handle"
|
||||
success_url = reverse_lazy("whoisdb:dashboard")
|
||||
|
||||
|
||||
# asblock
|
||||
class ASBlockCreate(LoginRequiredMixin, CreateView):
|
||||
template_name = "whoisdb/obj_create.html"
|
||||
form_class = ASBlockForm
|
||||
template_name = "whoisdb/obj_create.html"
|
||||
form_class = ASBlockForm
|
||||
|
||||
def get_form_kwargs(self, *args, **kwargs):
|
||||
kwargs = super(ASBlockCreate, self).get_form_kwargs(*args, **kwargs)
|
||||
kwargs["user"] = self.request.user
|
||||
kwargs["initial"] = {
|
||||
"handle": "AUTO",
|
||||
}
|
||||
def get_form_kwargs(self, *args, **kwargs):
|
||||
kwargs = super(ASBlockCreate, self).get_form_kwargs(*args, **kwargs)
|
||||
kwargs["user"] = self.request.user
|
||||
kwargs["initial"] = {
|
||||
"handle": "AUTO",
|
||||
}
|
||||
|
||||
return kwargs
|
||||
return kwargs
|
||||
|
||||
|
||||
class ASBlockDetail(DetailView):
|
||||
model = ASBlock
|
||||
slug_field = "handle"
|
||||
slug_url_kwarg = "handle"
|
||||
context_object_name = "asblock"
|
||||
model = ASBlock
|
||||
slug_field = "handle"
|
||||
slug_url_kwarg = "handle"
|
||||
context_object_name = "asblock"
|
||||
|
||||
|
||||
class ASBlockEdit(MntGenericMixin, LoginRequiredMixin, UpdateView):
|
||||
template_name = "whoisdb/obj_edit.html"
|
||||
model = ASBlock
|
||||
form_class = ASBlockForm
|
||||
slug_field = "handle"
|
||||
slug_url_kwarg = "handle"
|
||||
template_name = "whoisdb/obj_edit.html"
|
||||
model = ASBlock
|
||||
form_class = ASBlockForm
|
||||
slug_field = "handle"
|
||||
slug_url_kwarg = "handle"
|
||||
|
||||
def get_form_kwargs(self, *args, **kwargs):
|
||||
kwargs = super(ASBlockEdit, self).get_form_kwargs(*args, **kwargs)
|
||||
kwargs["user"] = self.request.user
|
||||
#kwargs["initial"] = {'prefix': str(self.object.getNetwork())}
|
||||
def get_form_kwargs(self, *args, **kwargs):
|
||||
kwargs = super(ASBlockEdit, self).get_form_kwargs(*args, **kwargs)
|
||||
kwargs["user"] = self.request.user
|
||||
#kwargs["initial"] = {'prefix': str(self.object.getNetwork())}
|
||||
|
||||
return kwargs
|
||||
return kwargs
|
||||
|
||||
|
||||
class ASBlockDelete(MntGenericMixin, LoginRequiredMixin, DeleteCheckView):
|
||||
template_name = "whoisdb/obj_delete.html"
|
||||
model = ASBlock
|
||||
slug_field = "handle"
|
||||
slug_url_kwarg = "handle"
|
||||
success_url = reverse_lazy("whoisdb:dashboard")
|
||||
template_name = "whoisdb/obj_delete.html"
|
||||
model = ASBlock
|
||||
slug_field = "handle"
|
||||
slug_url_kwarg = "handle"
|
||||
success_url = reverse_lazy("whoisdb:dashboard")
|
||||
|
||||
|
||||
# asnumber
|
||||
class ASNumberCreate(LoginRequiredMixin, CreateView):
|
||||
template_name = "whoisdb/obj_create.html"
|
||||
form_class = ASNumberForm
|
||||
template_name = "whoisdb/obj_create.html"
|
||||
form_class = ASNumberForm
|
||||
|
||||
def get_form_kwargs(self, *args, **kwargs):
|
||||
kwargs = super(ASNumberCreate, self).get_form_kwargs(*args, **kwargs)
|
||||
kwargs["user"] = self.request.user
|
||||
kwargs["initial"] = {
|
||||
"handle": "AUTO",
|
||||
}
|
||||
def get_form_kwargs(self, *args, **kwargs):
|
||||
kwargs = super(ASNumberCreate, self).get_form_kwargs(*args, **kwargs)
|
||||
kwargs["user"] = self.request.user
|
||||
kwargs["initial"] = {
|
||||
"handle": "AUTO",
|
||||
}
|
||||
|
||||
return kwargs
|
||||
return kwargs
|
||||
|
||||
|
||||
class ASNumberDetail(DetailView):
|
||||
model = ASNumber
|
||||
slug_field = "handle"
|
||||
slug_url_kwarg = "handle"
|
||||
context_object_name = "asnumber"
|
||||
model = ASNumber
|
||||
slug_field = "handle"
|
||||
slug_url_kwarg = "handle"
|
||||
context_object_name = "asnumber"
|
||||
|
||||
|
||||
class ASNumberEdit(MntGenericMixin, LoginRequiredMixin, UpdateView):
|
||||
template_name = "whoisdb/obj_edit.html"
|
||||
model = ASNumber
|
||||
form_class = ASNumberForm
|
||||
slug_field = "handle"
|
||||
slug_url_kwarg = "handle"
|
||||
template_name = "whoisdb/obj_edit.html"
|
||||
model = ASNumber
|
||||
form_class = ASNumberForm
|
||||
slug_field = "handle"
|
||||
slug_url_kwarg = "handle"
|
||||
|
||||
def get_form_kwargs(self, *args, **kwargs):
|
||||
kwargs = super(ASNumberEdit, self).get_form_kwargs(*args, **kwargs)
|
||||
kwargs["user"] = self.request.user
|
||||
def get_form_kwargs(self, *args, **kwargs):
|
||||
kwargs = super(ASNumberEdit, self).get_form_kwargs(*args, **kwargs)
|
||||
kwargs["user"] = self.request.user
|
||||
|
||||
return kwargs
|
||||
return kwargs
|
||||
|
||||
|
||||
class ASNumberDelete(MntGenericMixin, LoginRequiredMixin, DeleteCheckView):
|
||||
template_name = "whoisdb/obj_delete.html"
|
||||
model = ASNumber
|
||||
slug_field = "handle"
|
||||
slug_url_kwarg = "handle"
|
||||
success_url = reverse_lazy("whoisdb:dashboard")
|
||||
template_name = "whoisdb/obj_delete.html"
|
||||
model = ASNumber
|
||||
slug_field = "handle"
|
||||
slug_url_kwarg = "handle"
|
||||
success_url = reverse_lazy("whoisdb:dashboard")
|
||||
|
||||
|
||||
class ASAndSubnetWizard(LoginRequiredMixin, SessionWizardView):
|
||||
form_list = [ASNumberForm, InetNumForm]
|
||||
template_name = "whoisdb/wizard.html"
|
||||
form_list = [ASNumberForm, InetNumForm]
|
||||
template_name = "whoisdb/wizard.html"
|
||||
|
||||
def get_form_initial(self, step):
|
||||
return {"handle": "AUTO"}
|
||||
def get_form_initial(self, step):
|
||||
return {"handle": "AUTO"}
|
||||
|
||||
def done(self, form_list, **kwargs):
|
||||
fl = list(form_list)
|
||||
asNum = fl[0].save()
|
||||
net = fl[1].save()
|
||||
def done(self, form_list, **kwargs):
|
||||
fl = list(form_list)
|
||||
asNum = fl[0].save()
|
||||
net = fl[1].save()
|
||||
|
||||
messages.info(self.request, "The following objects have been created: AS %s %s, Subnet %s %s" % (asNum.handle, asNum.number, net.handle, net.getNetwork()))
|
||||
messages.info(self.request, "The following objects have been created: AS %s %s, Subnet %s %s" % (asNum.handle, asNum.number, net.handle, net.getNetwork()))
|
||||
|
||||
return HttpResponseRedirect(reverse("whoisdb:dashboard"))
|
||||
return HttpResponseRedirect(reverse("whoisdb:dashboard"))
|
||||
|
||||
def get_form_kwargs(self, *args, **kwargs):
|
||||
kwargs = super(ASAndSubnetWizard, self).get_form_kwargs(*args, **kwargs)
|
||||
kwargs["user"] = self.request.user
|
||||
def get_form_kwargs(self, *args, **kwargs):
|
||||
kwargs = super(ASAndSubnetWizard, self).get_form_kwargs(*args, **kwargs)
|
||||
kwargs["user"] = self.request.user
|
||||
|
||||
return kwargs
|
||||
return kwargs
|
||||
|
||||
def get_context_data(self, *args, **kwargs):
|
||||
d = super(ASAndSubnetWizard, self).get_context_data(*args, **kwargs)
|
||||
def get_context_data(self, *args, **kwargs):
|
||||
d = super(ASAndSubnetWizard, self).get_context_data(*args, **kwargs)
|
||||
|
||||
step = d["wizard"]["steps"].step1
|
||||
if step == 1:
|
||||
d["message"] = "Create an AS object"
|
||||
elif step == 2:
|
||||
d["message"] = "Create a Subnet"
|
||||
step = d["wizard"]["steps"].step1
|
||||
if step == 1:
|
||||
d["message"] = "Create an AS object"
|
||||
elif step == 2:
|
||||
d["message"] = "Create a Subnet"
|
||||
|
||||
return d
|
||||
return d
|
||||
|
|
Loading…
Reference in New Issue