mirror of
				https://github.com/usmannasir/cyberpanel.git
				synced 2025-10-31 10:26:01 +01:00 
			
		
		
		
	- Remove zone_id and id fields from DNS record update payload as they are not expected by Cloudflare API - Fix KeyError 'zone_id' when accessing DNS record properties that don't exist - Cloudflare API expects only the data fields in PUT request body, not the identifiers Fixes #1478
		
			
				
	
	
		
			1428 lines
		
	
	
		
			54 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			1428 lines
		
	
	
		
			54 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| #!/usr/local/CyberCP/bin/python
 | |
| import argparse
 | |
| import errno
 | |
| import os.path
 | |
| import sys
 | |
| import django
 | |
| 
 | |
| sys.path.append('/usr/local/CyberCP')
 | |
| os.environ.setdefault("DJANGO_SETTINGS_MODULE", "CyberCP.settings")
 | |
| django.setup()
 | |
| from django.http import HttpResponse
 | |
| import json
 | |
| try:
 | |
|     from plogical.dnsUtilities import DNS
 | |
|     from loginSystem.models import Administrator
 | |
|     from .models import Domains,Records
 | |
|     from plogical.mailUtilities import mailUtilities
 | |
| except:
 | |
|     pass
 | |
| import os
 | |
| from re import match,I,M
 | |
| from plogical.acl import ACLManager
 | |
| import CloudFlare
 | |
| import re
 | |
| import plogical.CyberCPLogFileWriter as logging
 | |
| from plogical.processUtilities import ProcessUtilities
 | |
| from plogical.httpProc import httpProc
 | |
| 
 | |
| class DNSManager:
 | |
|     defaultNameServersPath = '/home/cyberpanel/defaultNameservers'
 | |
| 
 | |
|     def __init__(self, extraArgs=None):
 | |
|         self.extraArgs = extraArgs
 | |
| 
 | |
|     def loadCFKeys(self):
 | |
|         cfFile = '%s%s' % (DNS.CFPath, self.admin.userName)
 | |
|         data = open(cfFile, 'r').readlines()
 | |
|         self.email = data[0].rstrip('\n')
 | |
|         self.key = data[1].rstrip('\n')
 | |
| 
 | |
|     def loadDNSHome(self, request = None, userID = None):
 | |
|         admin = Administrator.objects.get(pk=userID)
 | |
|         template = 'dns/index.html'
 | |
|         proc = httpProc(request, template, {"type": admin.type}, 'createDNSZone')
 | |
|         return proc.render()
 | |
| 
 | |
|     def createNameserver(self, request = None, userID = None):
 | |
|         mailUtilities.checkHome()
 | |
| 
 | |
|         if os.path.exists('/home/cyberpanel/powerdns'):
 | |
|             finalData = {"status": 1}
 | |
|         else:
 | |
|             finalData = {"status": 0}
 | |
| 
 | |
|         template = 'dns/createNameServer.html'
 | |
|         proc = httpProc(request, template, finalData, 'createNameServer')
 | |
|         return proc.render()
 | |
| 
 | |
|     def NSCreation(self, userID = None, data = None):
 | |
|         try:
 | |
|             admin = Administrator.objects.get(pk=userID)
 | |
|             currentACL = ACLManager.loadedACL(userID)
 | |
| 
 | |
|             if ACLManager.currentContextPermission(currentACL, 'createNameServer') == 0:
 | |
|                 return ACLManager.loadErrorJson('NSCreation', 0)
 | |
| 
 | |
| 
 | |
|             domainForNS = data['domainForNS']
 | |
|             ns1 = data['ns1']
 | |
|             ns2 = data['ns2']
 | |
|             firstNSIP = data['firstNSIP']
 | |
|             secondNSIP = data['secondNSIP']
 | |
| 
 | |
|             DNS.dnsTemplate(domainForNS, admin)
 | |
| 
 | |
|             newZone = Domains.objects.get(name=domainForNS)
 | |
| 
 | |
|             ## NS1
 | |
| 
 | |
| 
 | |
|             record = Records(domainOwner=newZone,
 | |
|                              domain_id=newZone.id,
 | |
|                              name=ns1,
 | |
|                              type="A",
 | |
|                              content=firstNSIP,
 | |
|                              ttl=3600,
 | |
|                              prio=0,
 | |
|                              disabled=0,
 | |
|                              auth=1)
 | |
|             record.save()
 | |
| 
 | |
|             ## NS2
 | |
| 
 | |
|             record = Records(domainOwner=newZone,
 | |
|                              domain_id=newZone.id,
 | |
|                              name=ns2,
 | |
|                              type="A",
 | |
|                              content=secondNSIP,
 | |
|                              ttl=3600,
 | |
|                              prio=0,
 | |
|                              disabled=0,
 | |
|                              auth=1)
 | |
|             record.save()
 | |
| 
 | |
|             final_dic = {'NSCreation': 1, 'error_message': "None"}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             final_dic = {'NSCreation': 0, 'error_message': str(msg)}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|     def createDNSZone(self, request = None, userID = None):
 | |
| 
 | |
|         if os.path.exists('/home/cyberpanel/powerdns'):
 | |
|             finalData = {'status': 1}
 | |
|         else:
 | |
|             finalData = {'status': 0}
 | |
| 
 | |
|         template = 'dns/createDNSZone.html'
 | |
|         proc = httpProc(request, template, finalData, 'createDNSZone')
 | |
|         return proc.render()
 | |
| 
 | |
|     def zoneCreation(self, userID = None, data = None):
 | |
|         try:
 | |
|             admin = Administrator.objects.get(pk=userID)
 | |
| 
 | |
|             currentACL = ACLManager.loadedACL(userID)
 | |
|             if ACLManager.currentContextPermission(currentACL, 'createDNSZone') == 0:
 | |
|                 return ACLManager.loadErrorJson('zoneCreation', 0)
 | |
| 
 | |
|             zoneDomain = data['zoneDomain']
 | |
| 
 | |
|             newZone = Domains(admin=admin, name=zoneDomain, type="MASTER")
 | |
|             newZone.save()
 | |
| 
 | |
|             content = "ns1." + zoneDomain + " hostmaster." + zoneDomain + " 1 10800 3600 1209600 3600"
 | |
| 
 | |
|             soaRecord = Records(domainOwner=newZone,
 | |
|                                 domain_id=newZone.id,
 | |
|                                 name=zoneDomain,
 | |
|                                 type="SOA",
 | |
|                                 content=content,
 | |
|                                 ttl=3600,
 | |
|                                 prio=0,
 | |
|                                 disabled=0,
 | |
|                                 auth=1)
 | |
|             soaRecord.save()
 | |
| 
 | |
|             final_dic = {'zoneCreation': 1}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             final_dic = {'zoneCreation': 0, 'error_message': str(msg)}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|     def addDeleteDNSRecords(self, request = None, userID = None):
 | |
|         currentACL = ACLManager.loadedACL(userID)
 | |
| 
 | |
|         if not os.path.exists('/home/cyberpanel/powerdns'):
 | |
|             finalData = {"status": 0}
 | |
|         else:
 | |
|             finalData = {"status": 1}
 | |
| 
 | |
|         # Get DNS zones directly from the Domains table instead of just websites
 | |
|         finalData['domainsList'] = ACLManager.findAllDNSZones(currentACL, userID)
 | |
| 
 | |
| 
 | |
|         template = 'dns/addDeleteDNSRecords.html'
 | |
|         proc = httpProc(request, template, finalData, 'addDeleteRecords')
 | |
|         return proc.render()
 | |
| 
 | |
|     def getCurrentRecordsForDomain(self, userID = None, data = None):
 | |
|         try:
 | |
| 
 | |
|             currentACL = ACLManager.loadedACL(userID)
 | |
| 
 | |
|             if ACLManager.currentContextPermission(currentACL, 'addDeleteRecords') == 0:
 | |
|                 return ACLManager.loadErrorJson('fetchStatus', 0)
 | |
| 
 | |
| 
 | |
|             zoneDomain = data['selectedZone']
 | |
|             currentSelection = data['currentSelection']
 | |
| 
 | |
|             admin = Administrator.objects.get(pk=userID)
 | |
|             if ACLManager.checkOwnershipZone(zoneDomain, admin, currentACL) == 1:
 | |
|                 pass
 | |
|             else:
 | |
|                 return ACLManager.loadErrorJson()
 | |
| 
 | |
|             domain = Domains.objects.get(name=zoneDomain)
 | |
|             records = Records.objects.filter(domain_id=domain.id)
 | |
| 
 | |
|             fetchType = ""
 | |
| 
 | |
|             if currentSelection == 'aRecord':
 | |
|                 fetchType = 'A'
 | |
|             elif currentSelection == 'aaaaRecord':
 | |
|                 fetchType = 'AAAA'
 | |
|             elif currentSelection == 'cNameRecord':
 | |
|                 fetchType = 'CNAME'
 | |
|             elif currentSelection == 'mxRecord':
 | |
|                 fetchType = 'MX'
 | |
|             elif currentSelection == 'txtRecord':
 | |
|                 fetchType = 'TXT'
 | |
|             elif currentSelection == 'spfRecord':
 | |
|                 fetchType = 'SPF'
 | |
|             elif currentSelection == 'nsRecord':
 | |
|                 fetchType = 'NS'
 | |
|             elif currentSelection == 'soaRecord':
 | |
|                 fetchType = 'SOA'
 | |
|             elif currentSelection == 'srvRecord':
 | |
|                 fetchType = 'SRV'
 | |
|             elif currentSelection == 'caaRecord':
 | |
|                 fetchType = 'CAA'
 | |
| 
 | |
|             json_data = "["
 | |
|             checker = 0
 | |
| 
 | |
|             for items in records:
 | |
|                 if items.type == fetchType:
 | |
|                     dic = {'id': items.id,
 | |
|                            'type': items.type,
 | |
|                            'name': items.name,
 | |
|                            'content': items.content,
 | |
|                            'priority': items.prio,
 | |
|                            'ttl': items.ttl
 | |
|                            }
 | |
| 
 | |
|                     if checker == 0:
 | |
|                         json_data = json_data + json.dumps(dic)
 | |
|                         checker = 1
 | |
|                     else:
 | |
|                         json_data = json_data + ',' + json.dumps(dic)
 | |
|                 else:
 | |
|                     continue
 | |
| 
 | |
|             json_data = json_data + ']'
 | |
|             final_json = json.dumps({'status': 1, 'fetchStatus': 1, 'error_message': "None", "data": json_data})
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             final_dic = {'status': 0, 'fetchStatus': 0, 'error_message': str(msg)}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|     def addDNSRecord(self, userID = None, data = None):
 | |
|         try:
 | |
| 
 | |
|             currentACL = ACLManager.loadedACL(userID)
 | |
| 
 | |
|             if ACLManager.currentContextPermission(currentACL, 'addDeleteRecords') == 0:
 | |
|                 return ACLManager.loadErrorJson('add_status', 0)
 | |
| 
 | |
|             zoneDomain = data['selectedZone']
 | |
|             recordType = data['recordType']
 | |
|             recordName = data['recordName']
 | |
| 
 | |
|             ttl = int(data['ttl'])
 | |
|             if ttl < 0:
 | |
|                 raise ValueError("TTL: The item must be greater than 0")
 | |
|             elif ttl > 86400:
 | |
|                 raise ValueError("TTL: The item must be lesser than 86401")
 | |
| 
 | |
|             admin = Administrator.objects.get(pk=userID)
 | |
|             if ACLManager.checkOwnershipZone(zoneDomain, admin, currentACL) == 1:
 | |
|                 pass
 | |
|             else:
 | |
|                 return ACLManager.loadErrorJson()
 | |
| 
 | |
|             zone = Domains.objects.get(name=zoneDomain)
 | |
|             value = ""
 | |
| 
 | |
|             if recordType == "A":
 | |
| 
 | |
|                 recordContentA = data['recordContentA']  ## IP or pointing value
 | |
| 
 | |
|                 if recordName == "@":
 | |
|                     value = zoneDomain
 | |
|                 ## re.match
 | |
|                 elif match(r'([\da-z\.-]+\.[a-z\.]{2,12}|[\d\.]+)([\/:?=&#]{1}[\da-z\.-]+)*[\/\?]?', recordName,
 | |
|                            M | I):
 | |
|                     value = recordName
 | |
|                 else:
 | |
|                     value = recordName + "." + zoneDomain
 | |
| 
 | |
|                 DNS.createDNSRecord(zone, value, recordType, recordContentA, 0, ttl)
 | |
| 
 | |
|             elif recordType == "MX":
 | |
| 
 | |
|                 if recordName == "@":
 | |
|                     value = zoneDomain
 | |
|                 ## re.match
 | |
|                 elif match(r'([\da-z\.-]+\.[a-z\.]{2,12}|[\d\.]+)([\/:?=&#]{1}[\da-z\.-]+)*[\/\?]?', recordName,
 | |
|                            M | I):
 | |
|                     value = recordName
 | |
|                 else:
 | |
|                     value = recordName + "." + zoneDomain
 | |
| 
 | |
|                 recordContentMX = data['recordContentMX']
 | |
|                 priority = data['priority']
 | |
| 
 | |
|                 DNS.createDNSRecord(zone, value, recordType, recordContentMX, priority, ttl)
 | |
| 
 | |
|             elif recordType == "AAAA":
 | |
| 
 | |
|                 if recordName == "@":
 | |
|                     value = zoneDomain
 | |
|                 ## re.match
 | |
|                 elif match(r'([\da-z\.-]+\.[a-z\.]{2,12}|[\d\.]+)([\/:?=&#]{1}[\da-z\.-]+)*[\/\?]?', recordName,
 | |
|                            M | I):
 | |
|                     value = recordName
 | |
|                 else:
 | |
|                     value = recordName + "." + zoneDomain
 | |
| 
 | |
|                 recordContentAAAA = data['recordContentAAAA']  ## IP or pointing value
 | |
| 
 | |
|                 DNS.createDNSRecord(zone, value, recordType, recordContentAAAA, 0, ttl)
 | |
| 
 | |
|             elif recordType == "CNAME":
 | |
| 
 | |
|                 if recordName == "@":
 | |
|                     value = zoneDomain
 | |
|                 ## re.match
 | |
|                 elif match(r'([\da-z\.-]+\.[a-z\.]{2,12}|[\d\.]+)([\/:?=&#]{1}[\da-z\.-]+)*[\/\?]?', recordName,
 | |
|                            M | I):
 | |
|                     value = recordName
 | |
|                 else:
 | |
|                     value = recordName + "." + zoneDomain
 | |
| 
 | |
|                 recordContentCNAME = data['recordContentCNAME']  ## IP or pointing value
 | |
| 
 | |
|                 DNS.createDNSRecord(zone, value, recordType, recordContentCNAME, 0, ttl)
 | |
| 
 | |
|             elif recordType == "SPF":
 | |
| 
 | |
|                 if recordName == "@":
 | |
|                     value = zoneDomain
 | |
|                 ## re.match
 | |
|                 elif match(r'([\da-z\.-]+\.[a-z\.]{2,12}|[\d\.]+)([\/:?=&#]{1}[\da-z\.-]+)*[\/\?]?', recordName,
 | |
|                            M | I):
 | |
|                     value = recordName
 | |
|                 else:
 | |
|                     value = recordName + "." + zoneDomain
 | |
| 
 | |
|                 recordContentSPF = data['recordContentSPF']  ## IP or pointing value
 | |
| 
 | |
|                 DNS.createDNSRecord(zone, value, recordType, recordContentSPF, 0, ttl)
 | |
| 
 | |
|             elif recordType == "TXT":
 | |
| 
 | |
|                 if recordName == "@":
 | |
|                     value = zoneDomain
 | |
|                 ## re.match
 | |
|                 elif match(r'([\da-z\.-]+\.[a-z\.]{2,12}|[\d\.]+)([\/:?=&#]{1}[\da-z\.-]+)*[\/\?]?', recordName,
 | |
|                            M | I):
 | |
|                     value = recordName
 | |
|                 else:
 | |
|                     value = recordName + "." + zoneDomain
 | |
| 
 | |
|                 recordContentTXT = data['recordContentTXT']  ## IP or pointing value
 | |
| 
 | |
|                 DNS.createDNSRecord(zone, value, recordType, recordContentTXT, 0, ttl)
 | |
| 
 | |
|             elif recordType == "SOA":
 | |
| 
 | |
|                 recordContentSOA = data['recordContentSOA']
 | |
| 
 | |
|                 DNS.createDNSRecord(zone, recordName, recordType, recordContentSOA, 0, ttl)
 | |
| 
 | |
|             elif recordType == "NS":
 | |
| 
 | |
|                 recordContentNS = data['recordContentNS']
 | |
| 
 | |
|                 if recordContentNS == "@":
 | |
|                     recordContentNS = "ns1." + zoneDomain
 | |
|                 ## re.match
 | |
|                 elif match(r'([\da-z\.-]+\.[a-z\.]{2,12}|[\d\.]+)([\/:?=&#]{1}[\da-z\.-]+)*[\/\?]?',
 | |
|                            recordContentNS, M | I):
 | |
|                     recordContentNS = recordContentNS
 | |
|                 else:
 | |
|                     recordContentNS = recordContentNS + "." + zoneDomain
 | |
| 
 | |
|                 DNS.createDNSRecord(zone, recordName, recordType, recordContentNS, 0, ttl)
 | |
| 
 | |
|             elif recordType == "SRV":
 | |
| 
 | |
|                 if recordName == "@":
 | |
|                     value = zoneDomain
 | |
|                 ## re.match
 | |
|                 elif match(r'([\da-z\.-]+\.[a-z\.]{2,12}|[\d\.]+)([\/:?=&#]{1}[\da-z\.-]+)*[\/\?]?', recordName,
 | |
|                            M | I):
 | |
|                     value = recordName
 | |
|                 else:
 | |
|                     value = recordName + "." + zoneDomain
 | |
| 
 | |
|                 recordContentSRV = data['recordContentSRV']
 | |
|                 priority = data['priority']
 | |
| 
 | |
|                 DNS.createDNSRecord(zone, value, recordType, recordContentSRV, priority, ttl)
 | |
| 
 | |
|             elif recordType == "CAA":
 | |
|                 if recordName == "@":
 | |
|                     value = zoneDomain
 | |
|                 ## re.match
 | |
|                 elif match(r'([\da-z\.-]+\.[a-z\.]{2,12}|[\d\.]+)([\/:?=&#]{1}[\da-z\.-]+)*[\/\?]?', recordName,
 | |
|                            M | I):
 | |
|                     value = recordName
 | |
|                 else:
 | |
|                     value = recordName + "." + zoneDomain
 | |
|                 recordContentCAA = data['recordContentCAA']  ## IP or pointing value
 | |
|                 DNS.createDNSRecord(zone, value, recordType, recordContentCAA, 0, ttl)
 | |
| 
 | |
|             final_dic = {'status': 1, 'add_status': 1, 'error_message': "None"}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             final_dic = {'status': 0, 'add_status': 0, 'error_message': str(msg)}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|     def updateRecord(self, userID = None, data = None):
 | |
|         try:
 | |
| 
 | |
|             currentACL = ACLManager.loadedACL(userID)
 | |
| 
 | |
|             if ACLManager.currentContextPermission(currentACL, 'addDeleteRecords') == 0:
 | |
|                 return ACLManager.loadErrorJson('add_status', 0)
 | |
| 
 | |
|             zoneDomain = data['selectedZone']
 | |
| 
 | |
|             admin = Administrator.objects.get(pk=userID)
 | |
|             if ACLManager.checkOwnershipZone(zoneDomain, admin, currentACL) == 1:
 | |
|                 pass
 | |
|             else:
 | |
|                 return ACLManager.loadErrorJson()
 | |
| 
 | |
|             record = Records.objects.get(pk=data['id'])
 | |
| 
 | |
|             if ACLManager.VerifyRecordOwner(currentACL, record, zoneDomain) == 1:
 | |
|                 pass
 | |
|             else:
 | |
|                 return ACLManager.loadErrorJson()
 | |
| 
 | |
|             if data['nameNow'] != None:
 | |
|                 record.name = data['nameNow']
 | |
| 
 | |
|             if data['ttlNow'] != None:
 | |
|                 record.ttl = int(data['ttlNow'])
 | |
|                 if record.ttl < 0:
 | |
|                     raise ValueError("TTL: The item must be greater than 0")
 | |
|                 elif record.ttl > 86400:
 | |
|                     raise ValueError("TTL: The item must be lesser than 86401")
 | |
| 
 | |
|             if data['priorityNow'] != None:
 | |
|                 record.prio = int(data['priorityNow'])
 | |
| 
 | |
|             if data['contentNow'] != None:
 | |
|                 record.content = data['contentNow']
 | |
| 
 | |
|             record.save()
 | |
| 
 | |
|             final_dic = {'status': 1, 'error_message': "None"}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             final_dic = {'status': 0, 'error_message': str(msg)}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|     def deleteDNSRecord(self, userID = None, data = None):
 | |
|         try:
 | |
|             currentACL = ACLManager.loadedACL(userID)
 | |
| 
 | |
|             if ACLManager.currentContextPermission(currentACL, 'addDeleteRecords') == 0:
 | |
|                 return ACLManager.loadErrorJson('delete_status', 0)
 | |
| 
 | |
|             id = data['id']
 | |
| 
 | |
|             delRecord = Records.objects.get(id=id)
 | |
| 
 | |
|             admin = Administrator.objects.get(pk=userID)
 | |
| 
 | |
|             if ACLManager.checkOwnershipZone(delRecord.domainOwner.name, admin, currentACL) == 1:
 | |
|                 pass
 | |
|             else:
 | |
|                 return ACLManager.loadError()
 | |
| 
 | |
| 
 | |
|             delRecord.delete()
 | |
| 
 | |
|             final_dic = {'status': 1, 'delete_status': 1, 'error_message': "None"}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             final_dic = {'status': 0, 'delete_status': 0, 'error_message': str(msg)}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|     def deleteDNSZone(self, request = None, userID = None):
 | |
|         currentACL = ACLManager.loadedACL(userID)
 | |
|         if not os.path.exists('/home/cyberpanel/powerdns'):
 | |
|             finalData = {"status": 0}
 | |
|         else:
 | |
|             finalData = {"status": 1}
 | |
| 
 | |
|         # Get DNS zones directly from the Domains table instead of just websites
 | |
|         finalData['domainsList'] = ACLManager.findAllDNSZones(currentACL, userID)
 | |
|         template = 'dns/deleteDNSZone.html'
 | |
|         proc = httpProc(request, template, finalData, 'deleteZone')
 | |
|         return proc.render()
 | |
| 
 | |
|     def submitZoneDeletion(self, userID = None, data = None):
 | |
|         try:
 | |
|             zoneDomain = data['zoneDomain']
 | |
| 
 | |
|             currentACL = ACLManager.loadedACL(userID)
 | |
|             admin = Administrator.objects.get(pk=userID)
 | |
|             if ACLManager.currentContextPermission(currentACL, 'deleteZone') == 0:
 | |
|                 return ACLManager.loadErrorJson('delete_status', 0)
 | |
| 
 | |
| 
 | |
|             if ACLManager.checkOwnershipZone(zoneDomain, admin, currentACL) == 1:
 | |
|                 pass
 | |
|             else:
 | |
|                 return ACLManager.loadError()
 | |
| 
 | |
|             delZone = Domains.objects.get(name=zoneDomain)
 | |
|             admin = Administrator.objects.get(pk=userID)
 | |
|             if currentACL['admin'] == 1:
 | |
|                 if delZone.admin != admin:
 | |
|                     return ACLManager.loadErrorJson()
 | |
| 
 | |
|             delZone.delete()
 | |
| 
 | |
|             final_dic = {'delete_status': 1, 'error_message': "None"}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             final_dic = {'delete_status': 0, 'error_message': str(msg)}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|     def configureDefaultNameServers(self, request=None, userID=None):
 | |
|         currentACL = ACLManager.loadedACL(userID)
 | |
| 
 | |
|         if not os.path.exists('/home/cyberpanel/powerdns'):
 | |
|             data = {"status": 0}
 | |
|         else:
 | |
|             data = {"status": 1}
 | |
| 
 | |
|         data['domainsList'] = ACLManager.findAllDomains(currentACL, userID)
 | |
|         if os.path.exists(DNSManager.defaultNameServersPath):
 | |
|             nsData = open(DNSManager.defaultNameServersPath, 'r').readlines()
 | |
|             try:
 | |
|                 data['firstNS'] = nsData[0].rstrip('\n')
 | |
|             except:
 | |
|                 pass
 | |
|             try:
 | |
|                 data['secondNS'] = nsData[1].rstrip('\n')
 | |
|             except:
 | |
|                 pass
 | |
|             try:
 | |
|                 data['thirdNS'] = nsData[2].rstrip('\n')
 | |
|             except:
 | |
|                 pass
 | |
|             try:
 | |
|                 data['forthNS'] = nsData[3].rstrip('\n')
 | |
|             except:
 | |
|                 pass
 | |
| 
 | |
|         template = 'dns/configureDefaultNameServers.html'
 | |
|         proc = httpProc(request, template, data, 'admin')
 | |
|         return proc.render()
 | |
| 
 | |
|     def saveNSConfigurations(self, userID = None, data = None):
 | |
|         try:
 | |
|             currentACL = ACLManager.loadedACL(userID)
 | |
| 
 | |
|             if currentACL['admin'] == 1:
 | |
|                 pass
 | |
|             else:
 | |
|                 return ACLManager.loadErrorJson()
 | |
| 
 | |
|             nsContent = ''
 | |
| 
 | |
|             try:
 | |
|                 nsContent = '%s\n%s\n%s\n%s\n' % (data['firstNS'].rstrip('\n'), data['secondNS'].rstrip('\n'), data['thirdNS'].rstrip('\n'), data['forthNS'].rstrip('\n'))
 | |
|             except:
 | |
|                 try:
 | |
|                     nsContent = '%s\n%s\n%s\n' % (data['firstNS'].rstrip('\n'), data['secondNS'].rstrip('\n'), data['thirdNS'].rstrip('\n'))
 | |
|                 except:
 | |
|                     try:
 | |
|                         nsContent = '%s\n%s\n' % (data['firstNS'].rstrip('\n'), data['secondNS'].rstrip('\n'))
 | |
|                     except:
 | |
|                         try:
 | |
|                             nsContent = '%s\n' % (data['firstNS'].rstrip('\n'))
 | |
|                         except:
 | |
|                             pass
 | |
| 
 | |
|             writeToFile = open(DNSManager.defaultNameServersPath, 'w')
 | |
|             writeToFile.write(nsContent.rstrip('\n'))
 | |
|             writeToFile.close()
 | |
| 
 | |
|             ###
 | |
| 
 | |
|             import tldextract
 | |
| 
 | |
|             no_cache_extract = tldextract.TLDExtract(cache_dir=None)
 | |
| 
 | |
|             nsData = open(DNSManager.defaultNameServersPath, 'r').readlines()
 | |
| 
 | |
|             for ns in nsData:
 | |
|                 extractDomain = no_cache_extract(ns.rstrip('\n'))
 | |
|                 topLevelDomain = extractDomain.domain + '.' + extractDomain.suffix
 | |
| 
 | |
|                 zone = Domains.objects.get(name=topLevelDomain)
 | |
| 
 | |
|                 DNS.createDNSRecord(zone, ns, 'A', ACLManager.fetchIP(), 0, 1400)
 | |
| 
 | |
|             final_dic = {'status': 1, 'error_message': "None"}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             final_dic = {'status': 0, 'error_message': str(msg)}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|     def addDeleteDNSRecordsCloudFlare(self, request = None, userID = None):
 | |
|         currentACL = ACLManager.loadedACL(userID)
 | |
|         if not os.path.exists('/home/cyberpanel/powerdns'):
 | |
|             status = 0
 | |
|         else:
 | |
|             status = 1
 | |
|         admin = Administrator.objects.get(pk=userID)
 | |
| 
 | |
|         CloudFlare = 0
 | |
| 
 | |
|         cfPath = '%s%s' % (DNS.CFPath, admin.userName)
 | |
| 
 | |
|         if os.path.exists(cfPath):
 | |
|             CloudFlare = 1
 | |
|             domainsList = ACLManager.findAllDomains(currentACL, userID)
 | |
|             self.admin = admin
 | |
|             self.loadCFKeys()
 | |
|             data = {"domainsList": domainsList, "status": status, 'CloudFlare': CloudFlare, 'cfEmail': self.email,
 | |
|                     'cfToken': self.key}
 | |
|         else:
 | |
|             data = {"status": status, 'CloudFlare': CloudFlare}
 | |
| 
 | |
|         template = 'dns/addDeleteDNSRecordsCloudFlare.html'
 | |
|         proc = httpProc(request, template, data, 'addDeleteRecords')
 | |
|         return proc.render()
 | |
| 
 | |
|     def saveCFConfigs(self, userID = None, data = None):
 | |
|         try:
 | |
|             cfEmail = data['cfEmail']
 | |
|             cfToken = data['cfToken']
 | |
|             cfSync = data['cfSync']
 | |
| 
 | |
|             currentACL = ACLManager.loadedACL(userID)
 | |
| 
 | |
|             if ACLManager.currentContextPermission(currentACL, 'addDeleteRecords') == 0:
 | |
|                 return ACLManager.loadErrorJson('status', 0)
 | |
| 
 | |
|             admin = Administrator.objects.get(pk=userID)
 | |
|             cfPath = '%s%s' % (DNS.CFPath, admin.userName)
 | |
| 
 | |
|             writeToFile = open(cfPath, 'w')
 | |
|             writeToFile.write('%s\n%s\n%s' % (cfEmail, cfToken, cfSync))
 | |
|             writeToFile.close()
 | |
| 
 | |
|             os.chmod(cfPath, 0o600)
 | |
| 
 | |
|             final_dic = {'status': 1, 'error_message': "None"}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             final_dic = {'status': 0, 'error_message': str(msg)}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|     def getCurrentRecordsForDomainCloudFlare(self, userID = None, data = None):
 | |
|         try:
 | |
| 
 | |
|             currentACL = ACLManager.loadedACL(userID)
 | |
| 
 | |
|             if ACLManager.currentContextPermission(currentACL, 'addDeleteRecords') == 0:
 | |
|                 return ACLManager.loadErrorJson('fetchStatus', 0)
 | |
| 
 | |
| 
 | |
|             zoneDomain = data['selectedZone']
 | |
|             currentSelection = data['currentSelection']
 | |
| 
 | |
|             admin = Administrator.objects.get(pk=userID)
 | |
|             self.admin = admin
 | |
| 
 | |
|             if ACLManager.checkOwnershipZone(zoneDomain, admin, currentACL) == 1:
 | |
|                 pass
 | |
|             else:
 | |
|                 return ACLManager.loadErrorJson()
 | |
| 
 | |
|             self.loadCFKeys()
 | |
| 
 | |
|             params = {'name': zoneDomain, 'per_page':50}
 | |
|             cf = CloudFlare.CloudFlare(email=self.email,token=self.key)
 | |
| 
 | |
|             try:
 | |
|                 zones = cf.zones.get(params=params)
 | |
|             except BaseException as e:
 | |
|                 final_json = json.dumps({'status': 0, 'fetchStatus': 0, 'error_message': str(e), "data": '[]'})
 | |
|                 return HttpResponse(final_json)
 | |
| 
 | |
|             # there should only be one zone
 | |
| 
 | |
|             if len(zones) == 0:
 | |
|                 final_json = json.dumps({'status': 1, 'fetchStatus': 1, 'error_message': '', "data": '[]'})
 | |
|                 return HttpResponse(final_json)
 | |
| 
 | |
|             for zone in sorted(zones, key=lambda v: v['name']):
 | |
|                 zone_name = zone['name']
 | |
|                 zone_id = zone['id']
 | |
| 
 | |
|                 fetchType = ""
 | |
| 
 | |
|                 if currentSelection == 'aRecord':
 | |
|                     fetchType = 'A'
 | |
|                 elif currentSelection == 'aaaaRecord':
 | |
|                     fetchType = 'AAAA'
 | |
|                 elif currentSelection == 'cNameRecord':
 | |
|                     fetchType = 'CNAME'
 | |
|                 elif currentSelection == 'mxRecord':
 | |
|                     fetchType = 'MX'
 | |
|                 elif currentSelection == 'txtRecord':
 | |
|                     fetchType = 'TXT'
 | |
|                 elif currentSelection == 'spfRecord':
 | |
|                     fetchType = 'SPF'
 | |
|                 elif currentSelection == 'nsRecord':
 | |
|                     fetchType = 'NS'
 | |
|                 elif currentSelection == 'soaRecord':
 | |
|                     fetchType = 'SOA'
 | |
|                 elif currentSelection == 'srvRecord':
 | |
|                     fetchType = 'SRV'
 | |
|                 elif currentSelection == 'caaRecord':
 | |
|                     fetchType = 'CAA'
 | |
| 
 | |
|                 try:
 | |
|                     dns_records = cf.zones.dns_records.get(zone_id, params={'per_page':50, 'type':fetchType})
 | |
|                 except BaseException as e:
 | |
|                     final_json = json.dumps({'status': 0, 'fetchStatus': 0, 'error_message': str(e), "data": '[]'})
 | |
|                     return HttpResponse(final_json)
 | |
| 
 | |
|                 prog = re.compile('\.*' + zone_name + '$')
 | |
|                 dns_records = sorted(dns_records, key=lambda v: prog.sub('', v['name']) + '_' + v['type'])
 | |
| 
 | |
|                 json_data = "["
 | |
|                 checker = 0
 | |
| 
 | |
|                 for dns_record in dns_records:
 | |
|                     if dns_record['ttl'] == 1:
 | |
|                         ttl = 'AUTO'
 | |
|                     else:
 | |
|                         ttl = dns_record['ttl']
 | |
| 
 | |
|                     dic = {'id': dns_record['id'],
 | |
|                            'type': dns_record['type'],
 | |
|                            'name': dns_record['name'],
 | |
|                            'content': dns_record['content'],
 | |
|                            'priority': '1400',
 | |
|                            'ttl': ttl,
 | |
|                            'proxy': dns_record['proxied'],
 | |
|                            'proxiable': dns_record['proxiable']
 | |
|                            }
 | |
| 
 | |
|                     if checker == 0:
 | |
|                         json_data = json_data + json.dumps(dic)
 | |
|                         checker = 1
 | |
|                     else:
 | |
|                         json_data = json_data + ',' + json.dumps(dic)
 | |
| 
 | |
| 
 | |
|                 json_data = json_data + ']'
 | |
|                 final_json = json.dumps({'status': 1, 'fetchStatus': 1, 'error_message': "None", "data": json_data})
 | |
|                 return HttpResponse(final_json)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             final_dic = {'status': 0, 'fetchStatus': 0, 'error_message': str(msg)}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|     def deleteDNSRecordCloudFlare(self, userID = None, data = None):
 | |
|         try:
 | |
|             currentACL = ACLManager.loadedACL(userID)
 | |
| 
 | |
|             if ACLManager.currentContextPermission(currentACL, 'addDeleteRecords') == 0:
 | |
|                 return ACLManager.loadErrorJson('fetchStatus', 0)
 | |
| 
 | |
|             zoneDomain = data['selectedZone']
 | |
|             id = data['id']
 | |
| 
 | |
|             admin = Administrator.objects.get(pk=userID)
 | |
|             self.admin = admin
 | |
| 
 | |
|             if ACLManager.checkOwnershipZone(zoneDomain, admin, currentACL) == 1:
 | |
|                 pass
 | |
|             else:
 | |
|                 return ACLManager.loadErrorJson()
 | |
| 
 | |
|             self.loadCFKeys()
 | |
| 
 | |
|             params = {'name': zoneDomain, 'per_page': 50}
 | |
|             cf = CloudFlare.CloudFlare(email=self.email, token=self.key)
 | |
| 
 | |
|             try:
 | |
|                 zones = cf.zones.get(params=params)
 | |
|             except BaseException as e:
 | |
|                 final_json = json.dumps({'status': 0, 'delete_status': 0, 'error_message': str(e), "data": '[]'})
 | |
|                 return HttpResponse(final_json)
 | |
| 
 | |
|             for zone in sorted(zones, key=lambda v: v['name']):
 | |
|                 zone_id = zone['id']
 | |
| 
 | |
|                 cf.zones.dns_records.delete(zone_id, id)
 | |
| 
 | |
|                 final_dic = {'status': 1, 'delete_status': 1, 'error_message': "None"}
 | |
|                 final_json = json.dumps(final_dic)
 | |
|                 return HttpResponse(final_json)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             final_dic = {'status': 0, 'delete_status': 0, 'error_message': str(msg)}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
| 
 | |
|     def addDNSRecordCloudFlare(self, userID = None, data = None):
 | |
|         try:
 | |
| 
 | |
|             currentACL = ACLManager.loadedACL(userID)
 | |
| 
 | |
|             if ACLManager.currentContextPermission(currentACL, 'addDeleteRecords') == 0:
 | |
|                 return ACLManager.loadErrorJson('add_status', 0)
 | |
| 
 | |
|             zoneDomain = data['selectedZone']
 | |
|             recordType = data['recordType']
 | |
|             recordName = data['recordName']
 | |
|             ttl = int(data['ttl'])
 | |
|             if ttl < 0:
 | |
|                 raise ValueError("TTL: The item must be greater than 0")
 | |
|             elif ttl > 86400:
 | |
|                 raise ValueError("TTL: The item must be lesser than 86401")
 | |
| 
 | |
|             admin = Administrator.objects.get(pk=userID)
 | |
|             self.admin = admin
 | |
|             if ACLManager.checkOwnershipZone(zoneDomain, admin, currentACL) == 1:
 | |
|                 pass
 | |
|             else:
 | |
|                 return ACLManager.loadErrorJson()
 | |
| 
 | |
|             ## Get zone
 | |
| 
 | |
|             self.loadCFKeys()
 | |
| 
 | |
|             params = {'name': zoneDomain, 'per_page': 50}
 | |
|             cf = CloudFlare.CloudFlare(email=self.email, token=self.key)
 | |
| 
 | |
|             try:
 | |
|                 zones = cf.zones.get(params=params)
 | |
|             except BaseException as e:
 | |
|                 final_json = json.dumps({'status': 0, 'delete_status': 0, 'error_message': str(e), "data": '[]'})
 | |
|                 return HttpResponse(final_json)
 | |
| 
 | |
|             for zone in sorted(zones, key=lambda v: v['name']):
 | |
|                 zone = zone['id']
 | |
| 
 | |
|                 value = ""
 | |
| 
 | |
|                 if recordType == "A":
 | |
| 
 | |
|                     recordContentA = data['recordContentA']  ## IP or pointing value
 | |
| 
 | |
|                     if recordName == "@":
 | |
|                         value = zoneDomain
 | |
|                     ## re.match
 | |
|                     elif match(r'([\da-z\.-]+\.[a-z\.]{2,12}|[\d\.]+)([\/:?=&#]{1}[\da-z\.-]+)*[\/\?]?', recordName,
 | |
|                                M | I):
 | |
|                         value = recordName
 | |
|                     else:
 | |
|                         value = recordName + "." + zoneDomain
 | |
| 
 | |
|                     DNS.createDNSRecordCloudFlare(cf, zone, value, recordType, recordContentA, 0, ttl)
 | |
| 
 | |
|                 elif recordType == "MX":
 | |
| 
 | |
|                     if recordName == "@":
 | |
|                         value = zoneDomain
 | |
|                     ## re.match
 | |
|                     elif match(r'([\da-z\.-]+\.[a-z\.]{2,12}|[\d\.]+)([\/:?=&#]{1}[\da-z\.-]+)*[\/\?]?', recordName,
 | |
|                                M | I):
 | |
|                         value = recordName
 | |
|                     else:
 | |
|                         value = recordName + "." + zoneDomain
 | |
| 
 | |
|                     recordContentMX = data['recordContentMX']
 | |
|                     priority = data['priority']
 | |
| 
 | |
|                     DNS.createDNSRecordCloudFlare(cf, zone, value, recordType, recordContentMX, priority, ttl)
 | |
| 
 | |
|                 elif recordType == "AAAA":
 | |
| 
 | |
|                     if recordName == "@":
 | |
|                         value = zoneDomain
 | |
|                     ## re.match
 | |
|                     elif match(r'([\da-z\.-]+\.[a-z\.]{2,12}|[\d\.]+)([\/:?=&#]{1}[\da-z\.-]+)*[\/\?]?', recordName,
 | |
|                                M | I):
 | |
|                         value = recordName
 | |
|                     else:
 | |
|                         value = recordName + "." + zoneDomain
 | |
| 
 | |
|                     recordContentAAAA = data['recordContentAAAA']  ## IP or pointing value
 | |
| 
 | |
|                     DNS.createDNSRecordCloudFlare(cf, zone, value, recordType, recordContentAAAA, 0, ttl)
 | |
| 
 | |
|                 elif recordType == "CNAME":
 | |
| 
 | |
|                     if recordName == "@":
 | |
|                         value = zoneDomain
 | |
|                     ## re.match
 | |
|                     elif match(r'([\da-z\.-]+\.[a-z\.]{2,12}|[\d\.]+)([\/:?=&#]{1}[\da-z\.-]+)*[\/\?]?', recordName,
 | |
|                                M | I):
 | |
|                         value = recordName
 | |
|                     else:
 | |
|                         value = recordName + "." + zoneDomain
 | |
| 
 | |
|                     recordContentCNAME = data['recordContentCNAME']  ## IP or pointing value
 | |
| 
 | |
|                     DNS.createDNSRecordCloudFlare(cf, zone, value, recordType, recordContentCNAME, 0, ttl)
 | |
| 
 | |
|                 elif recordType == "SPF":
 | |
| 
 | |
|                     if recordName == "@":
 | |
|                         value = zoneDomain
 | |
|                     ## re.match
 | |
|                     elif match(r'([\da-z\.-]+\.[a-z\.]{2,12}|[\d\.]+)([\/:?=&#]{1}[\da-z\.-]+)*[\/\?]?', recordName,
 | |
|                                M | I):
 | |
|                         value = recordName
 | |
|                     else:
 | |
|                         value = recordName + "." + zoneDomain
 | |
| 
 | |
|                     recordContentSPF = data['recordContentSPF']  ## IP or pointing value
 | |
| 
 | |
|                     DNS.createDNSRecordCloudFlare(cf, zone, value, recordType, recordContentSPF, 0, ttl)
 | |
| 
 | |
|                 elif recordType == "TXT":
 | |
| 
 | |
|                     if recordName == "@":
 | |
|                         value = zoneDomain
 | |
|                     ## re.match
 | |
|                     elif match(r'([\da-z\.-]+\.[a-z\.]{2,12}|[\d\.]+)([\/:?=&#]{1}[\da-z\.-]+)*[\/\?]?', recordName,
 | |
|                                M | I):
 | |
|                         value = recordName
 | |
|                     else:
 | |
|                         value = recordName + "." + zoneDomain
 | |
| 
 | |
|                     recordContentTXT = data['recordContentTXT']  ## IP or pointing value
 | |
| 
 | |
|                     DNS.createDNSRecordCloudFlare(cf, zone, value, recordType, recordContentTXT, 0, ttl)
 | |
| 
 | |
|                 elif recordType == "SOA":
 | |
| 
 | |
|                     recordContentSOA = data['recordContentSOA']
 | |
| 
 | |
|                     DNS.createDNSRecordCloudFlare(cf, zone, recordName, recordType, recordContentSOA, 0, ttl)
 | |
| 
 | |
|                 elif recordType == "NS":
 | |
| 
 | |
|                     recordContentNS = data['recordContentNS']
 | |
| 
 | |
|                     if recordContentNS == "@":
 | |
|                         recordContentNS = "ns1." + zoneDomain
 | |
|                     ## re.match
 | |
|                     elif match(r'([\da-z\.-]+\.[a-z\.]{2,12}|[\d\.]+)([\/:?=&#]{1}[\da-z\.-]+)*[\/\?]?',
 | |
|                                recordContentNS, M | I):
 | |
|                         recordContentNS = recordContentNS
 | |
|                     else:
 | |
|                         recordContentNS = recordContentNS + "." + zoneDomain
 | |
| 
 | |
|                     DNS.createDNSRecordCloudFlare(cf, zone, recordName, recordType, recordContentNS, 0, ttl)
 | |
| 
 | |
|                 elif recordType == "SRV":
 | |
| 
 | |
|                     if recordName == "@":
 | |
|                         value = zoneDomain
 | |
|                     ## re.match
 | |
|                     elif match(r'([\da-z\.-]+\.[a-z\.]{2,12}|[\d\.]+)([\/:?=&#]{1}[\da-z\.-]+)*[\/\?]?', recordName,
 | |
|                                M | I):
 | |
|                         value = recordName
 | |
|                     else:
 | |
|                         value = recordName + "." + zoneDomain
 | |
| 
 | |
|                     recordContentSRV = data['recordContentSRV']
 | |
|                     priority = data['priority']
 | |
| 
 | |
|                     DNS.createDNSRecordCloudFlare(cf, zone, value, recordType, recordContentSRV, priority, ttl)
 | |
| 
 | |
|                 elif recordType == "CAA":
 | |
|                     if recordName == "@":
 | |
|                         value = zoneDomain
 | |
|                     ## re.match
 | |
|                     elif match(r'([\da-z\.-]+\.[a-z\.]{2,12}|[\d\.]+)([\/:?=&#]{1}[\da-z\.-]+)*[\/\?]?', recordName,
 | |
|                                M | I):
 | |
|                         value = recordName
 | |
|                     else:
 | |
|                         value = recordName + "." + zoneDomain
 | |
|                     recordContentCAA = data['recordContentCAA']  ## IP or pointing value
 | |
|                     DNS.createDNSRecordCloudFlare(cf, zone, value, recordType, recordContentCAA, 0, ttl)
 | |
| 
 | |
|                 final_dic = {'status': 1, 'add_status': 1, 'error_message': "None"}
 | |
|                 final_json = json.dumps(final_dic)
 | |
|                 return HttpResponse(final_json)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             final_dic = {'status': 0, 'add_status': 0, 'error_message': str(msg)}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|     def syncCF(self, userID = None, data = None):
 | |
|         try:
 | |
| 
 | |
|             currentACL = ACLManager.loadedACL(userID)
 | |
| 
 | |
|             if ACLManager.currentContextPermission(currentACL, 'addDeleteRecords') == 0:
 | |
|                 return ACLManager.loadErrorJson('add_status', 0)
 | |
| 
 | |
|             zoneDomain = data['selectedZone']
 | |
| 
 | |
|             admin = Administrator.objects.get(pk=userID)
 | |
|             self.admin = admin
 | |
| 
 | |
|             if ACLManager.checkOwnershipZone(zoneDomain, admin, currentACL) == 1:
 | |
|                 pass
 | |
|             else:
 | |
|                 return ACLManager.loadErrorJson()
 | |
| 
 | |
|             ## Get zone
 | |
| 
 | |
|             dns = DNS()
 | |
| 
 | |
|             status, error = dns.cfTemplate(zoneDomain, admin)
 | |
| 
 | |
|             if status == 1:
 | |
|                 final_dic = {'status': 1, 'error_message': 'None'}
 | |
|                 final_json = json.dumps(final_dic)
 | |
|                 return HttpResponse(final_json)
 | |
|             else:
 | |
|                 final_dic = {'status': 0, 'error_message': error}
 | |
|                 final_json = json.dumps(final_dic)
 | |
|                 return HttpResponse(final_json)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             final_dic = {'status': 0, 'error_message': str(msg)}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
| 
 | |
|     def enableProxy(self, userID = None, data = None):
 | |
|         try:
 | |
|             currentACL = ACLManager.loadedACL(userID)
 | |
| 
 | |
|             if ACLManager.currentContextPermission(currentACL, 'addDeleteRecords') == 0:
 | |
|                 return ACLManager.loadErrorJson('fetchStatus', 0)
 | |
| 
 | |
|             zoneDomain = data['selectedZone']
 | |
|             name = data['name']
 | |
|             value = data['value']
 | |
| 
 | |
|             admin = Administrator.objects.get(pk=userID)
 | |
|             self.admin = admin
 | |
| 
 | |
|             if ACLManager.checkOwnershipZone(zoneDomain, admin, currentACL) == 1:
 | |
|                 pass
 | |
|             else:
 | |
|                 return ACLManager.loadErrorJson()
 | |
| 
 | |
|             self.loadCFKeys()
 | |
| 
 | |
|             params = {'name': zoneDomain, 'per_page': 50}
 | |
|             cf = CloudFlare.CloudFlare(email=self.email, token=self.key)
 | |
| 
 | |
|             ## Get zone
 | |
| 
 | |
|             zones = cf.zones.get(params=params)
 | |
| 
 | |
|             zone = zones[0]
 | |
| 
 | |
|             ##
 | |
| 
 | |
|             zone_id = zone['id']
 | |
| 
 | |
|             params = {'name': name}
 | |
|             dns_records = cf.zones.dns_records.get(zone_id, params=params)
 | |
| 
 | |
|             ##
 | |
| 
 | |
| 
 | |
|             if value == True:
 | |
|                 new_r_proxied_flag = False
 | |
|             else:
 | |
|                 new_r_proxied_flag = True
 | |
| 
 | |
|             for dns_record in dns_records:
 | |
|                 r_name = dns_record['name']
 | |
|                 r_type = dns_record['type']
 | |
|                 r_content = dns_record['content']
 | |
|                 r_ttl = dns_record['ttl']
 | |
|                 r_proxied = dns_record['proxied']
 | |
| 
 | |
|                 if r_proxied == new_r_proxied_flag:
 | |
|                     # Nothing to do
 | |
|                     continue
 | |
| 
 | |
|                 dns_record_id = dns_record['id']
 | |
| 
 | |
|                 new_dns_record = {
 | |
|                     'type': r_type,
 | |
|                     'name': r_name,
 | |
|                     'content': r_content,
 | |
|                     'ttl': r_ttl,
 | |
|                     'proxied': new_r_proxied_flag
 | |
|                 }
 | |
| 
 | |
|                 cf.zones.dns_records.put(zone_id, dns_record_id, data=new_dns_record)
 | |
| 
 | |
|                 final_dic = {'status': 1, 'delete_status': 1, 'error_message': "None"}
 | |
|                 final_json = json.dumps(final_dic)
 | |
|                 return HttpResponse(final_json)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             final_dic = {'status': 0, 'delete_status': 0, 'error_message': str(msg)}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|     def installPowerDNS(self):
 | |
|         try:
 | |
| 
 | |
|             if ProcessUtilities.decideDistro() == ProcessUtilities.ubuntu or ProcessUtilities.decideDistro() == ProcessUtilities.cent8:
 | |
| 
 | |
|                 command = 'systemctl stop systemd-resolved'
 | |
|                 ProcessUtilities.executioner(command, 'root', True)
 | |
|                 command = 'systemctl disable systemd-resolved.service'
 | |
|                 ProcessUtilities.executioner(command, 'root', True)
 | |
| 
 | |
|             if ProcessUtilities.decideDistro() == ProcessUtilities.ubuntu or ProcessUtilities.ubuntu20:
 | |
| 
 | |
|                 command = 'DEBIAN_FRONTEND=noninteractive apt-get -y purge pdns-server pdns-backend-mysql -y'
 | |
|                 ProcessUtilities.executioner(command, 'root', True)
 | |
|             else:
 | |
|                 command = 'yum -y erase pdns pdns-backend-mysql'
 | |
|                 ProcessUtilities.executioner(command, 'root', True)
 | |
| 
 | |
| 
 | |
|             #### new install
 | |
| 
 | |
|             if ProcessUtilities.decideDistro() == ProcessUtilities.ubuntu or ProcessUtilities.decideDistro() == ProcessUtilities.cent8:
 | |
|                 try:
 | |
|                     os.rename('/etc/resolv.conf', 'etc/resolved.conf')
 | |
|                 except OSError as e:
 | |
|                     if e.errno != errno.EEXIST and e.errno != errno.ENOENT:
 | |
|                         logging.CyberCPLogFileWriter.statusWriter(self.extraArgs['tempStatusPath'], "[ERROR] Unable to rename /etc/resolv.conf to install PowerDNS: " +
 | |
|                                                  str(e) + "[404]")
 | |
|                         return 0
 | |
|                     try:
 | |
|                         os.remove('/etc/resolv.conf')
 | |
|                     except OSError as e1:
 | |
|                         logging.CyberCPLogFileWriter.statusWriter(self.extraArgs['tempStatusPath'],
 | |
|                                                                   "[ERROR] Unable to remove existing /etc/resolv.conf to install PowerDNS: " +
 | |
|                             str(e1) + "[404]")
 | |
|                         return 0
 | |
| 
 | |
| 
 | |
|             if ProcessUtilities.decideDistro() == ProcessUtilities.ubuntu or ProcessUtilities.decideDistro() == ProcessUtilities.ubuntu20:
 | |
|                 # Update package list first
 | |
|                 command = "DEBIAN_FRONTEND=noninteractive apt-get update"
 | |
|                 ProcessUtilities.executioner(command, 'root', True)
 | |
|                 
 | |
|                 command = "DEBIAN_FRONTEND=noninteractive apt-get -y install pdns-server pdns-backend-mysql"
 | |
|                 result = ProcessUtilities.executioner(command, 'root', True)
 | |
|                 
 | |
|                 # Ensure service is stopped after installation for configuration
 | |
|                 command = 'systemctl stop pdns || true'
 | |
|                 ProcessUtilities.executioner(command, 'root', True)
 | |
|                 
 | |
|                 return 1
 | |
|             else:
 | |
|                 command = 'yum -y install pdns pdns-backend-mysql'
 | |
| 
 | |
|             ProcessUtilities.executioner(command, 'root', True)
 | |
| 
 | |
|             return 1
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             logging.CyberCPLogFileWriter.writeToFile('[ERROR] ' + str(msg) + " [installPowerDNS]")
 | |
|             logging.CyberCPLogFileWriter.statusWriter(self.extraArgs['tempStatusPath'],
 | |
|                                                       '[ERROR] ' + str(msg) + " [installPowerDNS][404]")
 | |
|             return 0
 | |
| 
 | |
|     def installPowerDNSConfigurations(self, mysqlPassword):
 | |
|         try:
 | |
| 
 | |
|             ### let see if this is needed the chdir
 | |
|             cwd = os.getcwd()
 | |
|             os.chdir('/usr/local/CyberCP/install')
 | |
|             if ProcessUtilities.decideDistro() == ProcessUtilities.centos or ProcessUtilities.decideDistro() == ProcessUtilities.cent8:
 | |
|                 dnsPath = "/etc/pdns/pdns.conf"
 | |
|             else:
 | |
|                 dnsPath = "/etc/powerdns/pdns.conf"
 | |
|                 # Ensure directory exists for Ubuntu
 | |
|                 dnsDir = os.path.dirname(dnsPath)
 | |
|                 if not os.path.exists(dnsDir):
 | |
|                     try:
 | |
|                         os.makedirs(dnsDir, mode=0o755)
 | |
|                     except OSError as e:
 | |
|                         if e.errno != errno.EEXIST:
 | |
|                             raise
 | |
| 
 | |
|             import shutil
 | |
|             # Backup existing config if it exists
 | |
|             if os.path.exists(dnsPath):
 | |
|                 try:
 | |
|                     shutil.move(dnsPath, dnsPath + '.bak')
 | |
|                 except:
 | |
|                     os.remove(dnsPath)
 | |
|             
 | |
|             shutil.copy("dns-one/pdns.conf", dnsPath)
 | |
|             
 | |
|             # Verify the file was copied and has MySQL backend configuration
 | |
|             try:
 | |
|                 with open(dnsPath, "r") as f:
 | |
|                     content = f.read()
 | |
|                     if not content or "launch=gmysql" not in content:
 | |
|                         writeToFile.writeToFile("PowerDNS config incomplete, attempting to fix...")
 | |
|                         logging.InstallLog.writeToFile("PowerDNS config incomplete, fixing...")
 | |
|                         
 | |
|                         # Directly write the essential MySQL configuration
 | |
|                         mysql_config = """# PowerDNS MySQL Backend Configuration
 | |
| launch=gmysql
 | |
| gmysql-host=localhost
 | |
| gmysql-port=3306
 | |
| gmysql-user=cyberpanel
 | |
| gmysql-password=""" + mysqlPassword + """
 | |
| gmysql-dbname=cyberpanel
 | |
| 
 | |
| # Basic PowerDNS settings
 | |
| daemon=no
 | |
| guardian=no
 | |
| setgid=pdns
 | |
| setuid=pdns
 | |
| """
 | |
|                         # Write complete config
 | |
|                         with open(dnsPath, "w") as f:
 | |
|                             f.write(mysql_config)
 | |
|                         
 | |
|                         writeToFile.writeToFile("MySQL backend configuration written directly")
 | |
|             except Exception as e:
 | |
|                 writeToFile.writeToFile("Warning: Could not verify config content: " + str(e))
 | |
|                 # Continue anyway as the file copy might have worked
 | |
| 
 | |
|             data = open(dnsPath, "r").readlines()
 | |
| 
 | |
|             writeDataToFile = open(dnsPath, "w")
 | |
| 
 | |
|             dataWritten = "gmysql-password=" + mysqlPassword + "\n"
 | |
| 
 | |
|             for items in data:
 | |
|                 if items.find("gmysql-password") > -1:
 | |
|                     writeDataToFile.writelines(dataWritten)
 | |
|                 else:
 | |
|                     writeDataToFile.writelines(items)
 | |
| 
 | |
|             # if self.distro == ubuntu:
 | |
|             #    os.fchmod(writeDataToFile.fileno(), stat.S_IRUSR | stat.S_IWUSR)
 | |
| 
 | |
|             writeDataToFile.close()
 | |
| 
 | |
|             if self.remotemysql == 'ON':
 | |
|                 command = "sed -i 's|gmysql-host=localhost|gmysql-host=%s|g' %s" % (self.mysqlhost, dnsPath)
 | |
|                 ProcessUtilities.executioner(command, 'root', True)
 | |
| 
 | |
|                 command = "sed -i 's|gmysql-port=3306|gmysql-port=%s|g' %s" % (self.mysqlport, dnsPath)
 | |
|                 ProcessUtilities.executioner(command, 'root', True)
 | |
| 
 | |
|             # Set proper permissions for PowerDNS config
 | |
|             if ProcessUtilities.decideDistro() == ProcessUtilities.ubuntu or ProcessUtilities.decideDistro() == ProcessUtilities.ubuntu20:
 | |
|                 # Ensure pdns user/group exists
 | |
|                 command = 'id -u pdns &>/dev/null || useradd -r -s /usr/sbin/nologin pdns'
 | |
|                 ProcessUtilities.executioner(command, 'root', True)
 | |
|                 
 | |
|                 command = 'chown root:pdns %s' % dnsPath
 | |
|                 ProcessUtilities.executioner(command, 'root', True)
 | |
|                 
 | |
|                 command = 'chmod 640 %s' % dnsPath
 | |
|                 ProcessUtilities.executioner(command, 'root', True)
 | |
| 
 | |
|             return 1
 | |
|         except IOError as msg:
 | |
|             logging.CyberCPLogFileWriter.writeToFile('[ERROR] ' + str(msg) + " [installPowerDNSConfigurations]")
 | |
|             logging.CyberCPLogFileWriter.statusWriter(self.extraArgs['tempStatusPath'],
 | |
|                                                       '[ERROR] ' + str(msg) + " [installPowerDNSConfigurations][404]")
 | |
|             return 0
 | |
| 
 | |
|     def startPowerDNS(self):
 | |
| 
 | |
|         ############## Start PowerDNS ######################
 | |
| 
 | |
|         command = 'systemctl enable pdns'
 | |
|         ProcessUtilities.executioner(command)
 | |
| 
 | |
|         # Give PowerDNS time to read configuration
 | |
|         import time
 | |
|         time.sleep(2)
 | |
| 
 | |
|         command = 'systemctl start pdns'
 | |
|         result = ProcessUtilities.executioner(command)
 | |
|         
 | |
|         # Check if service started successfully
 | |
|         command = 'systemctl is-active pdns'
 | |
|         output = ProcessUtilities.outputExecutioner(command)
 | |
|         
 | |
|         if output.strip() != 'active':
 | |
|             logging.CyberCPLogFileWriter.writeToFile('[ERROR] PowerDNS failed to start. Service status: ' + output)
 | |
|             logging.CyberCPLogFileWriter.statusWriter(self.extraArgs['tempStatusPath'],
 | |
|                                                       '[ERROR] PowerDNS service failed to start properly [404]')
 | |
|             return 0
 | |
| 
 | |
|         return 1
 | |
| 
 | |
|     def ResetDNSConfigurations(self):
 | |
|         try:
 | |
| 
 | |
|             ### Check if remote or local mysql
 | |
| 
 | |
|             passFile = "/etc/cyberpanel/mysqlPassword"
 | |
| 
 | |
|             try:
 | |
|                 jsonData = json.loads(ProcessUtilities.outputExecutioner('cat %s' % (passFile)))
 | |
| 
 | |
|                 self.mysqluser = jsonData['mysqluser']
 | |
|                 self.mysqlpassword = jsonData['mysqlpassword']
 | |
|                 self.mysqlport = jsonData['mysqlport']
 | |
|                 self.mysqlhost = jsonData['mysqlhost']
 | |
|                 self.remotemysql = 'ON'
 | |
| 
 | |
|                 if self.mysqlhost.find('rds.amazon') > -1:
 | |
|                     self.RDS = 1
 | |
| 
 | |
|                 ## Also set localhost to this server
 | |
| 
 | |
|                 ipFile = "/etc/cyberpanel/machineIP"
 | |
|                 f = open(ipFile)
 | |
|                 ipData = f.read()
 | |
|                 ipAddressLocal = ipData.split('\n', 1)[0]
 | |
| 
 | |
|                 self.LOCALHOST = ipAddressLocal
 | |
|             except BaseException as msg:
 | |
|                 self.remotemysql = 'OFF'
 | |
| 
 | |
|                 if os.path.exists(ProcessUtilities.debugPath):
 | |
|                     logging.CyberCPLogFileWriter.writeToFile('%s. [setupConnection:75]' % (str(msg)))
 | |
| 
 | |
|             logging.CyberCPLogFileWriter.statusWriter(self.extraArgs['tempStatusPath'], 'Removing and re-installing DNS..,5')
 | |
| 
 | |
|             if self.installPowerDNS() == 0:
 | |
|                 logging.CyberCPLogFileWriter.statusWriter(self.extraArgs['tempStatusPath'],
 | |
|                                                           'installPowerDNS failed. [404].')
 | |
|                 return 0
 | |
| 
 | |
|             logging.CyberCPLogFileWriter.statusWriter(self.extraArgs['tempStatusPath'], 'Resetting configurations..,40')
 | |
| 
 | |
|             import sys
 | |
|             sys.path.append('/usr/local/CyberCP')
 | |
|             os.environ.setdefault("DJANGO_SETTINGS_MODULE", "CyberCP.settings")
 | |
|             from CyberCP import settings
 | |
| 
 | |
|             logging.CyberCPLogFileWriter.statusWriter(self.extraArgs['tempStatusPath'], 'Configurations reset..,70')
 | |
| 
 | |
|             if self.installPowerDNSConfigurations(settings.DATABASES['default']['PASSWORD']) == 0:
 | |
|                 logging.CyberCPLogFileWriter.statusWriter(self.extraArgs['tempStatusPath'], 'installPowerDNSConfigurations failed. [404].')
 | |
|                 return 0
 | |
| 
 | |
|             if self.startPowerDNS() == 0:
 | |
|                 logging.CyberCPLogFileWriter.statusWriter(self.extraArgs['tempStatusPath'],
 | |
|                                                           'startPowerDNS failed. [404].')
 | |
|                 return 0
 | |
| 
 | |
|             logging.CyberCPLogFileWriter.statusWriter(self.extraArgs['tempStatusPath'], 'Fixing permissions..,90')
 | |
| 
 | |
|             ACLManager.fixPermissions()
 | |
|             logging.CyberCPLogFileWriter.statusWriter(self.extraArgs['tempStatusPath'], 'Completed [200].')
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             final_dic = {'status': 0, 'error_message': str(msg)}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
| def main():
 | |
| 
 | |
|     parser = argparse.ArgumentParser(description='CyberPanel')
 | |
|     parser.add_argument('function', help='Specify a function to call!')
 | |
|     parser.add_argument('--tempStatusPath', help='Path of temporary status file.')
 | |
| 
 | |
|     args = parser.parse_args()
 | |
| 
 | |
|     if args.function == "ResetDNSConfigurations":
 | |
|         extraArgs = {'tempStatusPath': args.tempStatusPath}
 | |
|         ftp = DNSManager(extraArgs)
 | |
|         ftp.ResetDNSConfigurations()
 | |
| 
 | |
| if __name__ == "__main__":
 | |
|     main() |