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