mirror of
https://github.com/usmannasir/cyberpanel.git
synced 2025-12-15 21:09:42 +01:00
- Change from 'from plogical import ProcessUtilities' to correct import - Use 'from plogical.processUtilities import ProcessUtilities' - Resolves ImportError during Django initialization
452 lines
18 KiB
Python
452 lines
18 KiB
Python
#!/usr/local/CyberCP/bin/python
|
|
import os.path
|
|
import sys
|
|
import django
|
|
from plogical.httpProc import httpProc
|
|
sys.path.append('/usr/local/CyberCP')
|
|
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "CyberCP.settings")
|
|
django.setup()
|
|
from django.shortcuts import redirect
|
|
from django.http import HttpResponse
|
|
from loginSystem.views import loadLoginPage
|
|
from loginSystem.models import Administrator
|
|
import json
|
|
from .models import Package
|
|
from plogical.acl import ACLManager
|
|
from plogical.processUtilities import ProcessUtilities
|
|
|
|
class PackagesManager:
|
|
def __init__(self, request = None):
|
|
self.request = request
|
|
|
|
@staticmethod
|
|
def checkAddonAccess():
|
|
"""
|
|
Check if server has addon access for resource limits feature
|
|
Returns True if addons are available, False otherwise
|
|
"""
|
|
url = "https://platform.cyberpersons.com/CyberpanelAdOns/Adonpermission"
|
|
addon_data = {
|
|
"name": "all",
|
|
"IP": ACLManager.GetServerIP()
|
|
}
|
|
import requests
|
|
try:
|
|
response = requests.post(url, data=json.dumps(addon_data), timeout=5)
|
|
Status = response.json().get('status', 0)
|
|
except Exception:
|
|
Status = 0
|
|
return (Status == 1) or (ProcessUtilities.decideServer() == ProcessUtilities.ent)
|
|
|
|
def packagesHome(self):
|
|
proc = httpProc(self.request, 'packages/index.html',
|
|
None, 'createPackage')
|
|
return proc.render()
|
|
|
|
def createPacakge(self):
|
|
userID = self.request.session['userID']
|
|
admin = Administrator.objects.get(pk=userID)
|
|
has_addons = self.checkAddonAccess()
|
|
proc = httpProc(self.request, 'packages/createPackage.html',
|
|
{"adminNamePackage": admin.userName, "has_addons": has_addons}, 'createPackage')
|
|
return proc.render()
|
|
|
|
def deletePacakge(self):
|
|
userID = self.request.session['userID']
|
|
currentACL = ACLManager.loadedACL(userID)
|
|
packageList = ACLManager.loadPackages(userID, currentACL)
|
|
proc = httpProc(self.request, 'packages/deletePackage.html',
|
|
{"packageList": packageList}, 'deletePackage')
|
|
return proc.render()
|
|
|
|
def submitPackage(self):
|
|
try:
|
|
|
|
userID = self.request.session['userID']
|
|
currentACL = ACLManager.loadedACL(userID)
|
|
|
|
if ACLManager.currentContextPermission(currentACL, 'createPackage') == 0:
|
|
return ACLManager.loadErrorJson('saveStatus', 0)
|
|
|
|
data = json.loads(self.request.body)
|
|
packageName = data['packageName'].replace(' ', '')
|
|
packageSpace = int(data['diskSpace'])
|
|
packageBandwidth = int(data['bandwidth'])
|
|
packageDatabases = int(data['dataBases'])
|
|
ftpAccounts = int(data['ftpAccounts'])
|
|
emails = int(data['emails'])
|
|
allowedDomains = int(data['allowedDomains'])
|
|
|
|
try:
|
|
api = data['api']
|
|
except:
|
|
api = '0'
|
|
|
|
try:
|
|
allowFullDomain = int(data['allowFullDomain'])
|
|
except:
|
|
allowFullDomain = 1
|
|
|
|
try:
|
|
enforceDiskLimits = int(data['enforceDiskLimits'])
|
|
except:
|
|
enforceDiskLimits = 0
|
|
|
|
# Resource Limits - with backward compatibility
|
|
try:
|
|
memoryLimitMB = int(data['memoryLimitMB'])
|
|
except:
|
|
memoryLimitMB = 1024
|
|
|
|
try:
|
|
cpuCores = int(data['cpuCores'])
|
|
except:
|
|
cpuCores = 1
|
|
|
|
try:
|
|
ioLimitMBPS = int(data['ioLimitMBPS'])
|
|
except:
|
|
ioLimitMBPS = 10
|
|
|
|
try:
|
|
inodeLimit = int(data['inodeLimit'])
|
|
except:
|
|
inodeLimit = 400000
|
|
|
|
try:
|
|
maxConnections = int(data['maxConnections'])
|
|
except:
|
|
maxConnections = 10
|
|
|
|
try:
|
|
procSoftLimit = int(data['procSoftLimit'])
|
|
except:
|
|
procSoftLimit = 400
|
|
|
|
try:
|
|
procHardLimit = int(data['procHardLimit'])
|
|
except:
|
|
procHardLimit = 500
|
|
|
|
if packageSpace < 0 or packageBandwidth < 0 or packageDatabases < 0 or ftpAccounts < 0 or emails < 0 or allowedDomains < 0:
|
|
data_ret = {'saveStatus': 0, 'error_message': "All values should be positive or 0."}
|
|
json_data = json.dumps(data_ret)
|
|
return HttpResponse(json_data)
|
|
|
|
# Check addon access for resource limits feature
|
|
has_addons = self.checkAddonAccess()
|
|
if not has_addons and enforceDiskLimits == 1:
|
|
data_ret = {'saveStatus': 0, 'error_message': "Resource limits feature requires CyberPanel addons. Please visit https://cyberpanel.net/cyberpanel-addons to purchase."}
|
|
json_data = json.dumps(data_ret)
|
|
return HttpResponse(json_data)
|
|
|
|
# Reset resource limits to defaults if addons not available
|
|
if not has_addons:
|
|
enforceDiskLimits = 0
|
|
memoryLimitMB = 1024
|
|
cpuCores = 1
|
|
ioLimitMBPS = 10
|
|
inodeLimit = 400000
|
|
maxConnections = 10
|
|
procSoftLimit = 400
|
|
procHardLimit = 500
|
|
|
|
# Validate resource limits
|
|
if memoryLimitMB < 256 or cpuCores < 1 or ioLimitMBPS < 1 or inodeLimit < 10000 or maxConnections < 1 or procSoftLimit < 1 or procHardLimit < 1:
|
|
data_ret = {'saveStatus': 0, 'error_message': "Resource limits must be positive and within valid ranges."}
|
|
json_data = json.dumps(data_ret)
|
|
return HttpResponse(json_data)
|
|
|
|
admin = Administrator.objects.get(pk=userID)
|
|
|
|
if api == '0':
|
|
packageName = admin.userName + "_" + packageName
|
|
|
|
package = Package(admin=admin, packageName=packageName, diskSpace=packageSpace,
|
|
bandwidth=packageBandwidth, ftpAccounts=ftpAccounts, dataBases=packageDatabases,
|
|
emailAccounts=emails, allowedDomains=allowedDomains, allowFullDomain=allowFullDomain,
|
|
enforceDiskLimits=enforceDiskLimits, memoryLimitMB=memoryLimitMB, cpuCores=cpuCores,
|
|
ioLimitMBPS=ioLimitMBPS, inodeLimit=inodeLimit, maxConnections=maxConnections,
|
|
procSoftLimit=procSoftLimit, procHardLimit=procHardLimit)
|
|
|
|
package.save()
|
|
|
|
data_ret = {'status': 1, 'saveStatus': 1, 'error_message': "None"}
|
|
json_data = json.dumps(data_ret)
|
|
return HttpResponse(json_data)
|
|
|
|
except BaseException as msg:
|
|
data_ret = {'status': 0, 'saveStatus': 0, 'error_message': str(msg)}
|
|
json_data = json.dumps(data_ret)
|
|
return HttpResponse(json_data)
|
|
|
|
def submitDelete(self):
|
|
try:
|
|
userID = self.request.session['userID']
|
|
currentACL = ACLManager.loadedACL(userID)
|
|
|
|
if ACLManager.currentContextPermission(currentACL, 'deletePackage') == 0:
|
|
return ACLManager.loadErrorJson('deleteStatus', 0)
|
|
|
|
data = json.loads(self.request.body)
|
|
packageName = data['packageName']
|
|
|
|
delPackage = Package.objects.get(packageName=packageName)
|
|
|
|
## Check package ownership
|
|
admin = Administrator.objects.get(pk=userID)
|
|
if ACLManager.CheckPackageOwnership(delPackage, admin, currentACL) == 0:
|
|
return ACLManager.loadErrorJson('deleteStatus', 0)
|
|
|
|
delPackage.delete()
|
|
|
|
data_ret = {'status': 1, 'deleteStatus': 1, 'error_message': "None"}
|
|
json_data = json.dumps(data_ret)
|
|
return HttpResponse(json_data)
|
|
|
|
|
|
except BaseException as msg:
|
|
data_ret = {'status': 0, 'deleteStatus': 0, 'error_message': str(msg)}
|
|
json_data = json.dumps(data_ret)
|
|
return HttpResponse(json_data)
|
|
|
|
def modifyPackage(self):
|
|
userID = self.request.session['userID']
|
|
currentACL = ACLManager.loadedACL(userID)
|
|
packageList = ACLManager.loadPackages(userID, currentACL)
|
|
has_addons = self.checkAddonAccess()
|
|
proc = httpProc(self.request, 'packages/modifyPackage.html',
|
|
{"packList": packageList, "has_addons": has_addons}, 'modifyPackage')
|
|
return proc.render()
|
|
|
|
def submitModify(self):
|
|
try:
|
|
userID = self.request.session['userID']
|
|
data = json.loads(self.request.body)
|
|
packageName = data['packageName']
|
|
|
|
currentACL = ACLManager.loadedACL(userID)
|
|
|
|
if ACLManager.currentContextPermission(currentACL, 'modifyPackage') == 0:
|
|
return ACLManager.loadErrorJson('modifyStatus', 0)
|
|
|
|
modifyPack = Package.objects.get(packageName=packageName)
|
|
|
|
## Check package ownership
|
|
admin = Administrator.objects.get(pk=userID)
|
|
if ACLManager.CheckPackageOwnership(modifyPack, admin, currentACL) == 0:
|
|
return ACLManager.loadErrorJson('deleteStatus', 0)
|
|
|
|
diskSpace = modifyPack.diskSpace
|
|
bandwidth = modifyPack.bandwidth
|
|
ftpAccounts = modifyPack.ftpAccounts
|
|
dataBases = modifyPack.dataBases
|
|
emails = modifyPack.emailAccounts
|
|
|
|
|
|
data_ret = {'emails': emails, 'modifyStatus': 1, 'error_message': "None",
|
|
"diskSpace": diskSpace, "bandwidth": bandwidth, "ftpAccounts": ftpAccounts,
|
|
"dataBases": dataBases, "allowedDomains": modifyPack.allowedDomains,
|
|
'allowFullDomain': modifyPack.allowFullDomain, 'enforceDiskLimits': modifyPack.enforceDiskLimits,
|
|
'memoryLimitMB': modifyPack.memoryLimitMB, 'cpuCores': modifyPack.cpuCores,
|
|
'ioLimitMBPS': modifyPack.ioLimitMBPS, 'inodeLimit': modifyPack.inodeLimit,
|
|
'maxConnections': modifyPack.maxConnections, 'procSoftLimit': modifyPack.procSoftLimit,
|
|
'procHardLimit': modifyPack.procHardLimit}
|
|
json_data = json.dumps(data_ret)
|
|
return HttpResponse(json_data)
|
|
|
|
except BaseException as msg:
|
|
data_ret = {'modifyStatus': 0, 'error_message': str(msg)}
|
|
json_data = json.dumps(data_ret)
|
|
return HttpResponse(json_data)
|
|
|
|
def saveChanges(self):
|
|
try:
|
|
|
|
userID = self.request.session['userID']
|
|
currentACL = ACLManager.loadedACL(userID)
|
|
|
|
admin = Administrator.objects.get(pk=userID)
|
|
|
|
if ACLManager.currentContextPermission(currentACL, 'modifyPackage') == 0:
|
|
return ACLManager.loadErrorJson('saveStatus', 0)
|
|
|
|
data = json.loads(self.request.body)
|
|
packageName = data['packageName']
|
|
|
|
if data['diskSpace'] < 0 or data['bandwidth'] < 0 or data['ftpAccounts'] < 0 or data[
|
|
'dataBases'] < 0 or \
|
|
data['emails'] < 0 or data['allowedDomains'] < 0:
|
|
data_ret = {'saveStatus': 0, 'error_message': "All values should be positive or 0."}
|
|
json_data = json.dumps(data_ret)
|
|
return HttpResponse(json_data)
|
|
|
|
modifyPack = Package.objects.get(packageName=packageName)
|
|
|
|
if modifyPack.admin == admin:
|
|
|
|
modifyPack.diskSpace = data['diskSpace']
|
|
modifyPack.bandwidth = data['bandwidth']
|
|
modifyPack.ftpAccounts = data['ftpAccounts']
|
|
modifyPack.dataBases = data['dataBases']
|
|
modifyPack.emailAccounts = data['emails']
|
|
modifyPack.allowedDomains = data['allowedDomains']
|
|
|
|
try:
|
|
modifyPack.allowFullDomain = int(data['allowFullDomain'])
|
|
except:
|
|
modifyPack.allowFullDomain = 1
|
|
|
|
try:
|
|
modifyPack.enforceDiskLimits = int(data['enforceDiskLimits'])
|
|
except:
|
|
modifyPack.enforceDiskLimits = 0
|
|
|
|
# Check addon access for resource limits feature
|
|
has_addons = self.checkAddonAccess()
|
|
if not has_addons and modifyPack.enforceDiskLimits == 1:
|
|
data_ret = {'saveStatus': 0, 'error_message': "Resource limits feature requires CyberPanel addons. Please visit https://cyberpanel.net/cyberpanel-addons to purchase."}
|
|
json_data = json.dumps(data_ret)
|
|
return HttpResponse(json_data)
|
|
|
|
# Reset resource limits to defaults if addons not available
|
|
if not has_addons:
|
|
modifyPack.enforceDiskLimits = 0
|
|
modifyPack.memoryLimitMB = 1024
|
|
modifyPack.cpuCores = 1
|
|
modifyPack.ioLimitMBPS = 10
|
|
modifyPack.inodeLimit = 400000
|
|
modifyPack.maxConnections = 10
|
|
modifyPack.procSoftLimit = 400
|
|
modifyPack.procHardLimit = 500
|
|
|
|
# Update resource limits (only if addons available)
|
|
if has_addons:
|
|
try:
|
|
modifyPack.memoryLimitMB = int(data['memoryLimitMB'])
|
|
except:
|
|
pass # Keep existing value
|
|
|
|
try:
|
|
modifyPack.cpuCores = int(data['cpuCores'])
|
|
except:
|
|
pass # Keep existing value
|
|
|
|
try:
|
|
modifyPack.ioLimitMBPS = int(data['ioLimitMBPS'])
|
|
except:
|
|
pass # Keep existing value
|
|
|
|
try:
|
|
modifyPack.inodeLimit = int(data['inodeLimit'])
|
|
except:
|
|
pass # Keep existing value
|
|
|
|
try:
|
|
modifyPack.maxConnections = int(data['maxConnections'])
|
|
except:
|
|
pass # Keep existing value
|
|
|
|
try:
|
|
modifyPack.procSoftLimit = int(data['procSoftLimit'])
|
|
except:
|
|
pass # Keep existing value
|
|
|
|
try:
|
|
modifyPack.procHardLimit = int(data['procHardLimit'])
|
|
except:
|
|
pass # Keep existing value
|
|
|
|
modifyPack.save()
|
|
|
|
## Fix https://github.com/usmannasir/cyberpanel/issues/998
|
|
|
|
# from plogical.IncScheduler import IncScheduler
|
|
# isPU = IncScheduler('CalculateAndUpdateDiskUsage', {})
|
|
# isPU.start()
|
|
|
|
from plogical.processUtilities import ProcessUtilities
|
|
command = '/usr/local/CyberCP/bin/python /usr/local/CyberCP/plogical/IncScheduler.py UpdateDiskUsageForce'
|
|
ProcessUtilities.outputExecutioner(command)
|
|
|
|
data_ret = {'status': 1, 'saveStatus': 1, 'error_message': "None"}
|
|
json_data = json.dumps(data_ret)
|
|
return HttpResponse(json_data)
|
|
else:
|
|
data_ret = {'status': 0, 'saveStatus': 0, 'error_message': "You don't own this package."}
|
|
json_data = json.dumps(data_ret)
|
|
return HttpResponse(json_data)
|
|
|
|
except BaseException as msg:
|
|
data_ret = {'status': 0, 'saveStatus': 0, 'error_message': str(msg)}
|
|
json_data = json.dumps(data_ret)
|
|
return HttpResponse(json_data)
|
|
|
|
|
|
def listPackages(self):
|
|
userID = self.request.session['userID']
|
|
currentACL = ACLManager.loadedACL(userID)
|
|
packageList = ACLManager.loadPackages(userID, currentACL)
|
|
proc = httpProc(self.request, 'packages/listPackages.html',
|
|
{"packList": packageList}, 'listPackages')
|
|
return proc.render()
|
|
|
|
def listPackagesAPI(self,data=None):
|
|
"""
|
|
List of packages for API
|
|
:param data:
|
|
:return HttpResponse:
|
|
"""
|
|
try:
|
|
adminUser = data['adminUser']
|
|
admin = Administrator.objects.get(userName=adminUser)
|
|
currentACL = ACLManager.loadedACL(admin.id)
|
|
packageList = ACLManager.loadPackages(admin.id, currentACL)
|
|
return HttpResponse(json.dumps(packageList))
|
|
except BaseException as msg:
|
|
data_ret = {'status': 0, 'error_message': str(msg)}
|
|
json_data = json.dumps(data_ret)
|
|
return HttpResponse(json_data)
|
|
|
|
def fetchPackagesTable(self):
|
|
try:
|
|
userID = self.request.session['userID']
|
|
|
|
currentACL = ACLManager.loadedACL(userID)
|
|
|
|
if ACLManager.currentContextPermission(currentACL, 'listPackages') == 0:
|
|
return ACLManager.loadErrorJson()
|
|
|
|
|
|
packages = ACLManager.loadPackageObjects(userID, currentACL)
|
|
|
|
json_data = "["
|
|
checker = 0
|
|
|
|
for items in packages:
|
|
|
|
dic = {'package': items.packageName,
|
|
'diskSpace': items.diskSpace,
|
|
'bandwidth': items.bandwidth,
|
|
'emailAccounts': items.emailAccounts,
|
|
'dataBases': items.dataBases,
|
|
'ftpAccounts': items.ftpAccounts,
|
|
'allowedDomains': items.allowedDomains,
|
|
'allowFullDomain': items.allowFullDomain,
|
|
'enforceDiskLimits': items.enforceDiskLimits
|
|
}
|
|
|
|
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 KeyError:
|
|
return redirect(loadLoginPage)
|