Packages App

This commit is contained in:
Zarak Khan
2024-01-11 22:17:33 +05:00
parent 8892654843
commit 58d11cce81
9 changed files with 1233 additions and 18 deletions

View File

@@ -476,22 +476,22 @@
</div>
<ul id="dropdown-example-4" class="hidden py-2 space-y-2">
<li>
<a href="#"
<a href="{% url 'createPackageV2' %}"
class="flex items-center w-full text-base font-normal text-white transition duration-75 rounded-lg group hover:bg-cyan-400 dark:text-white dark:hover:bg-gray-700 pl-11">
Create Package</a>
</li>
<li>
<a href="#"
<a href="{% url 'listPackagesV2' %}"
class="flex items-center w-full text-base font-normal text-white transition duration-75 rounded-lg group hover:bg-cyan-400 dark:text-white dark:hover:bg-gray-700 pl-11">
List Packages</a>
</li>
<li>
<a href="#"
<a href="{% url 'deletePackageV2' %}"
class="flex items-center w-full text-base font-normal text-white transition duration-75 rounded-lg group hover:bg-cyan-400 dark:text-white dark:hover:bg-gray-700 pl-11">
Delete Package</a>
</li>
<li>
<a href="#"
<a href="{% url 'modifyPackageV2' %}"
class="flex items-center w-full text-base font-normal text-white transition duration-75 rounded-lg group hover:bg-cyan-400 dark:text-white dark:hover:bg-gray-700 pl-11">
Modify Package</a>
</li>
@@ -1669,6 +1669,7 @@
<script src="{% static 'baseTemplate/newBase.js' %}"></script>
<script src="{% static 'websiteFunctions/websiteFunctionsV2.js' %}"></script>
<script src="{% static 'userManagment/userManagementV2.js' %}"></script>
<script src="{% static 'packages/packagesV2.js' %}"></script>
</body>
</html>

View File

@@ -3,6 +3,7 @@ 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()
@@ -14,9 +15,10 @@ import json
from .models import Package
from plogical.acl import ACLManager
class PackagesManager:
def __init__(self, request = None):
self.request = request
def __init__(self, request=None):
self.request = request
def packagesHome(self):
proc = httpProc(self.request, 'packages/index.html',
@@ -30,6 +32,13 @@ class PackagesManager:
{"adminNamePackage": admin.userName}, 'createPackage')
return proc.render()
def createPacakgeV2(self):
userID = self.request.session['userID']
admin = Administrator.objects.get(pk=userID)
proc = httpProc(self.request, 'packages/createPackageV2.html',
{"adminNamePackage": admin.userName}, 'createPackage')
return proc.render()
def deletePacakge(self):
userID = self.request.session['userID']
currentACL = ACLManager.loadedACL(userID)
@@ -38,6 +47,14 @@ class PackagesManager:
{"packageList": packageList}, 'deletePackage')
return proc.render()
def deletePacakgeV2(self):
userID = self.request.session['userID']
currentACL = ACLManager.loadedACL(userID)
packageList = ACLManager.loadPackages(userID, currentACL)
proc = httpProc(self.request, 'packages/deletePackageV2.html',
{"packageList": packageList}, 'deletePackage')
return proc.render()
def submitPackage(self):
try:
@@ -71,7 +88,6 @@ class PackagesManager:
except:
enforceDiskLimits = 0
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)
@@ -84,7 +100,8 @@ class PackagesManager:
package = Package(admin=admin, packageName=packageName, diskSpace=packageSpace,
bandwidth=packageBandwidth, ftpAccounts=ftpAccounts, dataBases=packageDatabases,
emailAccounts=emails, allowedDomains=allowedDomains, allowFullDomain=allowFullDomain, enforceDiskLimits=enforceDiskLimits)
emailAccounts=emails, allowedDomains=allowedDomains, allowFullDomain=allowFullDomain,
enforceDiskLimits=enforceDiskLimits)
package.save()
@@ -135,6 +152,14 @@ class PackagesManager:
{"packList": packageList}, 'modifyPackage')
return proc.render()
def modifyPackageV2(self):
userID = self.request.session['userID']
currentACL = ACLManager.loadedACL(userID)
packageList = ACLManager.loadPackages(userID, currentACL)
proc = httpProc(self.request, 'packages/modifyPackageV2.html',
{"packList": packageList}, 'modifyPackage')
return proc.render()
def submitModify(self):
try:
userID = self.request.session['userID']
@@ -159,10 +184,11 @@ class PackagesManager:
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}
"dataBases": dataBases, "allowedDomains": modifyPack.allowedDomains,
'allowFullDomain': modifyPack.allowFullDomain,
'enforceDiskLimits': modifyPack.enforceDiskLimits}
json_data = json.dumps(data_ret)
return HttpResponse(json_data)
@@ -187,7 +213,7 @@ class PackagesManager:
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['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)
@@ -238,7 +264,6 @@ class PackagesManager:
json_data = json.dumps(data_ret)
return HttpResponse(json_data)
def listPackages(self):
userID = self.request.session['userID']
currentACL = ACLManager.loadedACL(userID)
@@ -247,7 +272,15 @@ class PackagesManager:
{"packList": packageList}, 'listPackages')
return proc.render()
def listPackagesAPI(self,data=None):
def listPackagesV2(self):
userID = self.request.session['userID']
currentACL = ACLManager.loadedACL(userID)
packageList = ACLManager.loadPackages(userID, currentACL)
proc = httpProc(self.request, 'packages/listPackagesV2.html',
{"packList": packageList}, 'listPackages')
return proc.render()
def listPackagesAPI(self, data=None):
"""
List of packages for API
:param data:
@@ -273,7 +306,6 @@ class PackagesManager:
if ACLManager.currentContextPermission(currentACL, 'listPackages') == 0:
return ACLManager.loadErrorJson()
packages = ACLManager.loadPackageObjects(userID, currentACL)
json_data = "["

View File

@@ -0,0 +1,471 @@
$("#packageCreationFailed").hide();
$("#packageCreated").hide();
newapp.controller('createPackageV2', function ($scope, $http) {
//$scope.pname = /([A-Z]){3,10}/gi;
$scope.insertPackInDB = function () {
var packageName = $scope.packageName;
var diskSpace = $scope.diskSpace;
var bandwidth = $scope.bandwidth;
var ftpAccounts = $scope.ftpAccounts;
var dataBases = $scope.dataBases;
var emails = $scope.emails;
if ($scope.allowFullDomain === undefined) {
$scope.allowFullDomain = 0;
}
url = "/packages/submitPackage";
var data = {
packageName: packageName,
diskSpace: diskSpace,
bandwidth: bandwidth,
ftpAccounts: ftpAccounts,
dataBases: dataBases,
emails: emails,
allowedDomains: $scope.allowedDomains,
enforceDiskLimits: $scope.enforceDiskLimits
};
var config = {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
};
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
function ListInitialDatas(response) {
console.log(response.data)
if (response.data.saveStatus == 0) {
$scope.errorMessage = response.data.error_message;
$("#packageCreationFailed").fadeIn();
$("#packageCreated").hide();
} else {
$("#packageCreationFailed").hide();
$("#packageCreated").fadeIn();
$scope.createdPackage = $scope.packageName;
}
}
function cantLoadInitialDatas(response) {
console.log("not good");
}
};
});
$("#deleteFailure").hide();
$("#deleteSuccess").hide();
$("#deletePackageButton").hide();
newapp.controller('deletePackageV2', function ($scope, $http) {
$scope.deletePackage = function () {
$("#deletePackageButton").fadeIn();
};
$scope.deletePackageFinal = function () {
var packageName = $scope.packageToBeDeleted;
url = "/packages/submitDelete";
var data = {
packageName: packageName,
};
var config = {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
};
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
function ListInitialDatas(response) {
console.log(response.data)
if (response.data.deleteStatus == 0) {
$scope.errorMessage = response.data.error_message;
$("#deleteFailure").fadeIn();
$("#deleteSuccess").hide();
$("#deletePackageButton").hide();
} else {
$("#deleteFailure").hide();
$("#deleteSuccess").fadeIn();
$("#deletePackageButton").hide();
$scope.deletedPackage = packageName;
}
}
function cantLoadInitialDatas(response) {
console.log("not good");
}
};
});
newapp.controller('listPackageTablesV2', function ($scope, $http) {
$scope.cyberpanelLoading = true;
$scope.populateCurrentRecords = function () {
$scope.cyberpanelLoading = false;
url = "/packages/fetchPackagesTable";
var data = {};
var config = {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
};
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
function ListInitialDatas(response) {
$scope.cyberpanelLoading = true;
if (response.data.status === 1) {
$scope.records = JSON.parse(response.data.data);
new PNotify({
title: 'Success!',
text: 'Packages successfully fetched!',
type: 'success'
});
} else {
new PNotify({
title: 'Error!',
text: response.data.error_message,
type: 'error'
});
}
}
function cantLoadInitialDatas(response) {
$scope.cyberpanelLoading = true;
new PNotify({
title: 'Error!',
text: 'Could not connect to server, please refresh this page.',
type: 'error'
});
}
};
$scope.populateCurrentRecords();
$scope.deletePackageFinal = function (packageToBeDeleted) {
$scope.cyberpanelLoading = false;
url = "/packages/submitDelete";
var data = {
packageName: packageToBeDeleted,
};
var config = {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
};
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
function ListInitialDatas(response) {
$scope.cyberpanelLoading = true;
if (response.data.status === 1) {
$scope.populateCurrentRecords();
new PNotify({
title: 'Success!',
text: 'Package successfully deleted!',
type: 'success'
});
} else {
new PNotify({
title: 'Error!',
text: response.data.error_message,
type: 'error'
});
}
}
function cantLoadInitialDatas(response) {
$scope.cyberpanelLoading = true;
new PNotify({
title: 'Error!',
text: 'Could not connect to server, please refresh this page.',
type: 'error'
});
}
};
$scope.editInitial = function (package, diskSpace, bandwidth,
emailAccounts, dataBases, ftpAccounts, allowedDomains, allowFullDomain, enforceDiskLimits) {
$scope.name = package;
$scope.diskSpace = diskSpace;
$scope.bandwidth = bandwidth;
$scope.emails = emailAccounts;
$scope.dataBases = dataBases;
$scope.ftpAccounts = ftpAccounts;
$scope.allowedDomains = allowedDomains;
$scope.allowFullDomain = allowFullDomain;
$scope.allowFullDomain = allowFullDomain === 1;
$scope.enforceDiskLimits = enforceDiskLimits === 1;
};
$scope.saveChanges = function () {
var packageName = $scope.name;
var diskSpace = $scope.diskSpace;
var bandwidth = $scope.bandwidth;
var ftpAccounts = $scope.ftpAccounts;
var dataBases = $scope.dataBases;
var emails = $scope.emails;
url = "/packages/saveChanges";
var data = {
packageName: packageName,
diskSpace: diskSpace,
bandwidth: bandwidth,
ftpAccounts: ftpAccounts,
dataBases: dataBases,
emails: emails,
allowedDomains: $scope.allowedDomains,
allowFullDomain: $scope.allowFullDomain,
enforceDiskLimits: $scope.enforceDiskLimits,
};
var config = {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
};
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
function ListInitialDatas(response) {
$scope.cyberpanelLoading = true;
if (response.data.saveStatus === 1) {
$scope.populateCurrentRecords();
new PNotify({
title: 'Success!',
text: 'Package successfully updated!',
type: 'success'
});
} else {
new PNotify({
title: 'Error!',
text: response.data.error_message,
type: 'error'
});
}
}
function cantLoadInitialDatas(response) {
$scope.cyberpanelLoading = true;
new PNotify({
title: 'Error!',
text: 'Could not connect to server, please refresh this page.',
type: 'error'
});
}
};
});
$("#packageDetailsToBeModified").hide();
$("#modifyFailure").hide();
$("#modifySuccess").hide();
$("#modifyButton").hide();
$("#packageLoading").hide();
$("#successfullyModified").hide();
newapp.controller('modifyPackagesV2', function ($scope, $http) {
$scope.fetchDetails = function () {
$("#packageLoading").show();
$("#successfullyModified").hide();
var packageName = $scope.packageToBeModified;
url = "/packages/submitModify";
var data = {
packageName: packageName,
};
var config = {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
};
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
function ListInitialDatas(response) {
if (response.data.modifyStatus === 0) {
$scope.errorMessage = response.data.error_message;
$("#modifyFailure").fadeIn();
$("#modifySuccess").hide();
$("#modifyButton").hide();
$("#packageLoading").hide();
} else {
$("#modifyButton").show();
$scope.diskSpace = response.data.diskSpace;
$scope.bandwidth = response.data.bandwidth;
$scope.ftpAccounts = response.data.ftpAccounts;
$scope.dataBases = response.data.dataBases;
$scope.emails = response.data.emails;
$scope.allowedDomains = response.data.allowedDomains;
$scope.allowFullDomain = response.data.allowFullDomain === 1;
$scope.enforceDiskLimits = response.data.enforceDiskLimits === 1;
$scope.modifyButton = "Save Details";
$("#packageDetailsToBeModified").fadeIn();
$("#modifyFailure").hide();
$("#modifySuccess").fadeIn();
$("#packageLoading").hide();
}
}
function cantLoadInitialDatas(response) {
console.log("not good");
}
};
$scope.modifyPackageFunc = function () {
var packageName = $scope.packageToBeModified;
var diskSpace = $scope.diskSpace;
var bandwidth = $scope.bandwidth;
var ftpAccounts = $scope.ftpAccounts;
var dataBases = $scope.dataBases;
var emails = $scope.emails;
$("#modifyFailure").hide();
$("#modifySuccess").hide();
$("#packageLoading").show();
$("#packageDetailsToBeModified").hide();
url = "/packages/saveChanges";
var data = {
packageName: packageName,
diskSpace: diskSpace,
bandwidth: bandwidth,
ftpAccounts: ftpAccounts,
dataBases: dataBases,
emails: emails,
allowedDomains: $scope.allowedDomains,
allowFullDomain: $scope.allowFullDomain,
enforceDiskLimits: $scope.enforceDiskLimits,
};
var config = {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
};
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
function ListInitialDatas(response) {
if (response.data.saveStatus === 0) {
$scope.errorMessage = response.data.error_message;
$("#modifyFailure").fadeIn();
$("#modifySuccess").hide();
$("#modifyButton").hide();
$("#packageLoading").hide();
} else {
$("#modifyButton").hide();
$("#successfullyModified").fadeIn();
$("#modifyFailure").hide();
$("#packageLoading").hide();
$scope.packageModified = packageName;
}
}
function cantLoadInitialDatas(response) {
console.log("not good");
}
};
});

View File

@@ -0,0 +1,138 @@
{% extends "baseTemplate/newBase.html" %}
{% load i18n %}
{% block titleNew %}{% trans "Home - CyberPanel" %}{% endblock %}
{% block newContent %}
{% load static %}
<div ng-controller="createPackageV2" class="p-8">
<div>
<p class="text-4xl font-bold">Create Package</p>
<p class="text-xs text-gray-600 py-2 font-semibold">Packages define resources for your websites, you need to
add package before creating a website.</p>
</div>
<div>
<div class="py-4">
<p class="text-xl font-bold">Package Details</p>
</div>
<hr>
<div id="createPackages">
<div class="flex mt-4 py-2 px-6">
<div>
<p class="font-semibold w-60">Package Name</p>
</div>
<div>
<input name="pname" type="text" class="w-80 bg-gray-100 rounded px-2 py-1"
ng-model="packageName" required>
</div>
<div class="text-orange-500 font-semibold ml-3">
<p>{{ adminNamePackage }}_{$ packageName $}</p>
</div>
</div>
<div class="flex py-2 px-6">
<div>
<p class="font-semibold w-60">Domains</p>
</div>
<div>
<input name="dspace" type="number" class="w-80 bg-gray-100 rounded px-2 py-1"
ng-model="allowedDomains"
required>
</div>
<div class="text-orange-500 font-semibold ml-3">
<p>{% trans "(0 = Unlimited)" %}</p>
</div>
</div>
<div class="flex py-2 px-6">
<div>
<p class="font-semibold w-60">Disk Space</p>
</div>
<div>
<input name="dspace" type="number" class="w-80 bg-gray-100 rounded px-2 py-1"
ng-model="diskSpace" required>
</div>
<div class="text-orange-500 font-semibold ml-3"><p>{% trans "MB (0 = Unlimited)" %}</p></div>
</div>
<div class="flex py-2 px-6">
<div>
<p class="font-semibold w-60">Bandwidth</p>
</div>
<div>
<input name="bwidth" type="number" class="w-80 bg-gray-100 rounded px-2 py-1"
ng-model="bandwidth" required>
</div>
<div class="text-orange-500 font-semibold ml-3"><p>{% trans "MB (0 = Unlimited)" %}</p></div>
</div>
<div class="flex py-2 px-6">
<div>
<p class="font-semibold w-60">FTP Account</p>
</div>
<div>
<input name="eaccts" type="number" class="w-80 bg-gray-100 rounded px-2 py-1"
ng-model="ftpAccounts" required>
</div>
</div>
<div class="flex py-2 px-6">
<div>
<p class="font-semibold w-60">Databases</p>
</div>
<div>
<input name="dbases" type="number" class="w-80 bg-gray-100 rounded px-2 py-1"
ng-model="dataBases" required>
</div>
</div>
<div class="flex py-2 px-6">
<div>
<p class="font-semibold w-60">Emails</p>
</div>
<div>
<input name="emails" type="number" class="w-80 bg-gray-100 rounded px-2 py-1" ng-model="emails"
required>
</div>
</div>
<div ng-hide="installationDetailsForm">
<div class="flex py-2 px-6">
<div>
<p class="font-semibold w-60">Additional Features</p>
</div>
<div>
<div class="checkbox">
<label>
<input ng-model="allowFullDomain" type="checkbox" value="">
Allow Creation of Fully Qualified Domain as Child-Domains
</label>
</div>
<div class="checkbox">
<label>
<input ng-model="enforceDiskLimits" type="checkbox" value="">
Enforce Disk Limits
</label>
</div>
</div>
</div>
</div>
<div class="flex justify-center mt-6">
<button ng-click="insertPackInDB()" class="bg-orange-500 text-white font-bold px-4 py-2 text-xl">
Create Package
</button>
</div>
<div class="mt-4">
<label class="col-sm-3 control-label"></label>
<div>
<div id="packageCreated"
class="flex justify-center bg-green-500 px-2 rounded-lg py-1 font-semibold">
<p>{% trans "Package" %} <strong>{$ createdPackage
$}</strong> {% trans "Successfully Created" %}</p>
</div>
<div id="packageCreationFailed"
class="flex justify-center bg-red-500 rounded-lg text-white px-2 py-1 font-semibold">
<p>{% trans "Cannot create package. Error message:" %} {$ errorMessage $}</p>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,60 @@
{% extends "baseTemplate/newBase.html" %}
{% load i18n %}
{% block titleNew %}{% trans "Home - CyberPanel" %}{% endblock %}
{% block newContent %}
{% load static %}
<div ng-controller="deletePackageV2" class="p-8">
<div>
<p class="text-4xl font-bold">Delete Package</p>
<p class="text-xs text-gray-600 py-2 font-semibold">Websites owned by this user will automatically transfer
to the root.</p>
</div>
<div>
<div class="py-4">
<p class="text-xl font-bold">Delete Package</p>
</div>
<hr>
<div>
<div class="flex mt-4 py-2 px-6">
<div>
<p class="font-semibold w-60">Select Package</p>
</div>
<div>
<select ng-model="packageToBeDeleted" class="w-80 bg-gray-100 rounded px-2 py-1">
{% for items in packageList %}
<option>{{ items }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="flex justify-center mt-6">
<button ng-click="deletePackage()"
class="bg-orange-500 text-white font-bold px-4 py-2 text-xl">
Delete Package
</button>
</div>
<div id="deletePackageButton" class="flex justify-center mt-6">
<button type="button" ng-click="deletePackageFinal()"
class="bg-gray-500 text-white font-bold px-4 py-2 text-xl">{% trans "Are you sure?" %}</button>
</div>
<div class="mt-4">
<label class="col-sm-3 control-label"></label>
<div>
<div id="deleteSuccess"
class="flex justify-center bg-green-500 px-2 rounded-lg py-1 font-semibold">
<p>{% trans "Package" %} <strong>{$ deletedPackage
$}</strong>{% trans " Successfully Deleted." %}</p>
</div>
<div id="deleteFailure"
class="flex justify-center bg-red-500 rounded-lg text-white px-2 py-1 font-semibold">
<p>{% trans "Cannot delete package. Error message:" %} {$ errorMessage $}</p>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,324 @@
{% extends "baseTemplate/newBase.html" %}
{% load i18n %}
{% block titleNew %}{% trans "Home - CyberPanel" %}{% endblock %}
{% block newContent %}
{% load static %}
<div ng-controller="listPackageTablesV2" class="p-8">
<div class="flex lg:flex-row justify-between items-center sm:flex-col">
<div>
<p class="text-4xl font-bold">List Packages</p>
<p class="text-xs text-gray-600 py-2 font-semibold">List packages and delete or edit them.</p>
</div>
</div>
<div class="py-4">
<p class="text-xl font-bold">List Packages</p>
<img ng-hide="cyberpanelLoading"
src="{% static 'images/loading.gif' %}">
</div>
<hr>
<div class="relative py-5 overflow-x-auto">
<table class="w-full text-sm text-left rtl:text-right">
<thead>
<tr>
<th scope="col" class="px-6 py-3">
Package
</th>
<th scope="col" class="px-6 py-3">
Diskspace
</th>
<th scope="col" class="px-6 py-3">
Bandwidth
</th>
<th scope="col" class="px-6 py-3">
Email Accounts
</th>
<th scope="col" class="px-6 py-3">
Databases
</th>
<th scope="col" class="px-6 py-3">
FTPs
</th>
<th scope="col" class="px-6 py-3">
Child Domains
</th>
<th scope="col" class="px-6 py-3">
Allow FQDN as Childs
</th>
<th scope="col" class="px-6 py-3">
Actions
</th>
</tr>
</thead>
<tbody ng-repeat="record in records track by $index"
class="border shadow-lg py-3 px-6 rounded-b-lg">
<tr>
<td ng-bind="record.package" class="px-6 py-4">
</td>
<td ng-bind="record.diskSpace" class="px-6 py-4">
</td>
<td ng-bind="record.bandwidth" class="px-6 py-4">
</td>
<td ng-bind="record.emailAccounts" class="px-6 py-4">
</td>
<td ng-bind="record.dataBases" class="px-6 py-4">
</td>
<td ng-bind="record.ftpAccounts" class="px-6 py-4">
</td>
<td ng-bind="record.allowedDomains" class="px-6 py-4">
</td>
<td class="px-6 py-4 text-green-500 font-semibold">
<span ng-hide="record.allowFullDomain==0">Enabled</span><span
ng-hide="record.allowFullDomain">Disabled</span>
</td>
<td class="flex gap-1 px-6 py-4">
<div>
<button ng-click="editInitial(record.package, record.diskSpace, record.bandwidth,
record.emailAccounts, record.dataBases, record.ftpAccounts, record.allowedDomains, record.allowFullDomain, record.enforceDiskLimits)"
data-modal-target="EditListUser"
data-modal-toggle="EditListUser"
class="bg-orange-500 px-2 py-1 text-white"
type="button">
Edit
</button>
<div id="EditListUser" tabindex="-1"
class="hidden overflow-y-auto overflow-x-hidden fixed top-0 right-0 left-0 z-50 justify-center items-center w-full md:inset-0 h-[calc(100%-1rem)] max-h-full">
<div>
<div class="relative bg-white rounded-lg shadow dark:bg-gray-700">
<h2 class="px-4 py-4 font-bold text-xl">Edit Users</h2>
<button type="button" data-modal-toggle="EditListUser"
class="absolute top-3 end-2.5 text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm w-8 h-8 ms-auto inline-flex justify-center items-center dark:hover:bg-gray-600 dark:hover:text-white"
data-modal-hide="EditListUser">
<svg class="w-3 h-3" aria-hidden="true"
xmlns="http://www.w3.org/2000/svg" fill="none"
viewBox="0 0 14 14">
<path stroke="currentColor" stroke-linecap="round"
stroke-linejoin="round" stroke-width="2"
d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6"/>
</svg>
<span class="sr-only">Close modal</span>
</button>
<div class="p-4">
<div ng-hide="installationDetailsForm" class="flex mt-4 py-2 px-6">
<div>
<p class="font-semibold w-60">Name</p>
</div>
<div>
<input name="name" type="text"
class="w-80 bg-gray-100 rounded px-2 py-1"
ng-model="name" readonly>
</div>
</div>
<div class="flex py-2 px-6">
<div>
<p class="font-semibold w-60">New Owner</p>
</div>
<div>
<select ng-change="saveResellerChanges()"
ng-model="$parent.newOwner"
class="w-80 bg-gray-100 rounded px-2 py-1">
{% for items in resellerPrivUsers %}
<option>{{ items }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="flex py-2 px-6">
<div>
<p class="font-semibold w-60">Select ACL</p>
</div>
<div>
<select ng-change="changeACLFunc()"
ng-model="$parent.selectedACL"
class="w-80 bg-gray-100 rounded px-2 py-1">
{% for items in aclNames %}
<option>{{ items }}</option>
{% endfor %}
</select>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div>
<button ng-click="deletePackageFinal(record.package)" data-modal-target="DeleteListUser"
data-modal-toggle="DeleteListUser"
class="bg-orange-500 px-2 py-1 text-white"
type="button">
Delete
</button>
<div id="DeleteListUser" tabindex="-1"
class="hidden overflow-y-auto overflow-x-hidden fixed top-0 right-0 left-0 z-50 justify-center items-center w-full md:inset-0 h-[calc(100%-1rem)] max-h-full">
<div class="relative p-4 w-full max-w-md max-h-full">
<div class="relative bg-white rounded-lg shadow dark:bg-gray-700">
<button type="button" data-modal-toggle="DeleteListUser"
class="absolute top-3 end-2.5 text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm w-8 h-8 ms-auto inline-flex justify-center items-center dark:hover:bg-gray-600 dark:hover:text-white"
data-modal-hide="DeleteListUser">
<svg class="w-3 h-3" aria-hidden="true"
xmlns="http://www.w3.org/2000/svg" fill="none"
viewBox="0 0 14 14">
<path stroke="currentColor" stroke-linecap="round"
stroke-linejoin="round" stroke-width="2"
d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6"/>
</svg>
<span class="sr-only">Close modal</span>
</button>
<div class="p-4 md:p-5 text-center">
<svg class="mx-auto mb-4 text-gray-400 w-12 h-12 dark:text-gray-200"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg" fill="none"
viewBox="0 0 20 20">
<path stroke="currentColor" stroke-linecap="round"
stroke-linejoin="round" stroke-width="2"
d="M10 11V6m0 8h.01M19 10a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"/>
</svg>
<h3 class="mb-5 text-lg font-normal text-gray-500 dark:text-gray-400">
Are you sure you want to
delete this user {$ UserToDelete $} ?</h3>
<button ng-click="deleteUserFinal()" data-modal-hide="DeleteListUser"
type="button"
data-modal-toggle="DeleteListUser"
class="text-white bg-red-600 hover:bg-red-800 focus:ring-4 focus:outline-none focus:ring-red-300 dark:focus:ring-red-800 font-medium rounded-lg text-sm inline-flex items-center px-5 py-2.5 text-center me-2">
Yes, I'm sure
</button>
<button data-modal-hide="DeleteListUser" type="button"
data-modal-toggle="DeleteListUser"
class="text-gray-500 bg-white hover:bg-gray-100 focus:ring-4 focus:outline-none focus:ring-gray-200 rounded-lg border border-gray-200 text-sm font-medium px-5 py-2.5 hover:text-gray-900 focus:z-10 dark:bg-gray-700 dark:text-gray-300 dark:border-gray-500 dark:hover:text-white dark:hover:bg-gray-600 dark:focus:ring-gray-600">
No, cancel
</button>
</div>
</div>
</div>
</div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
{# <div>#}
{# <button ng-click="deleteUserInitial(record.name)" data-modal-target="DeleteListUser"#}
{# data-modal-toggle="DeleteListUser"#}
{# class="bg-orange-500 px-2 py-1 text-white"#}
{# type="button">#}
{# Delete#}
{# </button>#}
{##}
{# <div id="DeleteListUser" tabindex="-1"#}
{# class="hidden overflow-y-auto overflow-x-hidden fixed top-0 right-0 left-0 z-50 justify-center items-center w-full md:inset-0 h-[calc(100%-1rem)] max-h-full">#}
{# <div class="relative p-4 w-full max-w-md max-h-full">#}
{# <div class="relative bg-white rounded-lg shadow dark:bg-gray-700">#}
{# <button type="button" data-modal-toggle="DeleteListUser"#}
{# class="absolute top-3 end-2.5 text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm w-8 h-8 ms-auto inline-flex justify-center items-center dark:hover:bg-gray-600 dark:hover:text-white"#}
{# data-modal-hide="DeleteListUser">#}
{# <svg class="w-3 h-3" aria-hidden="true"#}
{# xmlns="http://www.w3.org/2000/svg" fill="none"#}
{# viewBox="0 0 14 14">#}
{# <path stroke="currentColor" stroke-linecap="round"#}
{# stroke-linejoin="round" stroke-width="2"#}
{# d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6"/>#}
{# </svg>#}
{# <span class="sr-only">Close modal</span>#}
{# </button>#}
{# <div class="p-4 md:p-5 text-center">#}
{# <svg class="mx-auto mb-4 text-gray-400 w-12 h-12 dark:text-gray-200"#}
{# aria-hidden="true"#}
{# xmlns="http://www.w3.org/2000/svg" fill="none"#}
{# viewBox="0 0 20 20">#}
{# <path stroke="currentColor" stroke-linecap="round"#}
{# stroke-linejoin="round" stroke-width="2"#}
{# d="M10 11V6m0 8h.01M19 10a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"/>#}
{# </svg>#}
{# <h3 class="mb-5 text-lg font-normal text-gray-500 dark:text-gray-400">#}
{# Are you sure you want to#}
{# delete this user {$ UserToDelete $} ?</h3>#}
{# <button ng-click="deleteUserFinal()" data-modal-hide="DeleteListUser" type="button"#}
{# data-modal-toggle="DeleteListUser"#}
{# class="text-white bg-red-600 hover:bg-red-800 focus:ring-4 focus:outline-none focus:ring-red-300 dark:focus:ring-red-800 font-medium rounded-lg text-sm inline-flex items-center px-5 py-2.5 text-center me-2">#}
{# Yes, I'm sure#}
{# </button>#}
{# <button data-modal-hide="DeleteListUser" type="button"#}
{# data-modal-toggle="DeleteListUser"#}
{# class="text-gray-500 bg-white hover:bg-gray-100 focus:ring-4 focus:outline-none focus:ring-gray-200 rounded-lg border border-gray-200 text-sm font-medium px-5 py-2.5 hover:text-gray-900 focus:z-10 dark:bg-gray-700 dark:text-gray-300 dark:border-gray-500 dark:hover:text-white dark:hover:bg-gray-600 dark:focus:ring-gray-600">#}
{# No, cancel#}
{# </button>#}
{# </div>#}
{# </div>#}
{# </div>#}
{# </div>#}
{# </div>#}
{# <div>#}
{# <button ng-click="editInitial(record.name)" data-modal-target="EditListUser"#}
{# data-modal-toggle="EditListUser"#}
{# class="bg-orange-500 px-2 py-1 text-white"#}
{# type="button">#}
{# Edit#}
{# </button>#}
{##}
{# <div id="EditListUser" tabindex="-1"#}
{# class="hidden overflow-y-auto overflow-x-hidden fixed top-0 right-0 left-0 z-50 justify-center items-center w-full md:inset-0 h-[calc(100%-1rem)] max-h-full">#}
{# <div>#}
{# <div class="relative bg-white rounded-lg shadow dark:bg-gray-700">#}
{# <h2 class="px-4 py-4 font-bold text-xl">Edit Users</h2>#}
{# <button type="button" data-modal-toggle="EditListUser"#}
{# class="absolute top-3 end-2.5 text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm w-8 h-8 ms-auto inline-flex justify-center items-center dark:hover:bg-gray-600 dark:hover:text-white"#}
{# data-modal-hide="EditListUser">#}
{# <svg class="w-3 h-3" aria-hidden="true"#}
{# xmlns="http://www.w3.org/2000/svg" fill="none"#}
{# viewBox="0 0 14 14">#}
{# <path stroke="currentColor" stroke-linecap="round"#}
{# stroke-linejoin="round" stroke-width="2"#}
{# d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6"/>#}
{# </svg>#}
{# <span class="sr-only">Close modal</span>#}
{# </button>#}
{# <div class="p-4">#}
{# <div ng-hide="installationDetailsForm" class="flex mt-4 py-2 px-6">#}
{# <div>#}
{# <p class="font-semibold w-60">Name</p>#}
{# </div>#}
{# <div>#}
{# <input name="name" type="text" class="w-80 bg-gray-100 rounded px-2 py-1"#}
{# ng-model="name" readonly>#}
{# </div>#}
{# </div>#}
{# <div class="flex py-2 px-6">#}
{# <div>#}
{# <p class="font-semibold w-60">New Owner</p>#}
{# </div>#}
{# <div>#}
{# <select ng-change="saveResellerChanges()"#}
{# ng-model="$parent.newOwner"#}
{# class="w-80 bg-gray-100 rounded px-2 py-1">#}
{# {% for items in resellerPrivUsers %}#}
{# <option>{{ items }}</option>#}
{# {% endfor %}#}
{# </select>#}
{# </div>#}
{# </div>#}
{# <div class="flex py-2 px-6">#}
{# <div>#}
{# <p class="font-semibold w-60">Select ACL</p>#}
{# </div>#}
{# <div>#}
{# <select ng-change="changeACLFunc()"#}
{# ng-model="$parent.selectedACL"#}
{# class="w-80 bg-gray-100 rounded px-2 py-1">#}
{# {% for items in aclNames %}#}
{# <option>{{ items }}</option>#}
{# {% endfor %}#}
{# </select>#}
{# </div>#}
{# </div>#}
{# </div>#}
{# </div>#}
{# </div>#}
{# </div>#}
{# </div>#}
{% endblock %}

View File

@@ -0,0 +1,144 @@
{% extends "baseTemplate/newBase.html" %}
{% load i18n %}
{% block titleNew %}{% trans "Home - CyberPanel" %}{% endblock %}
{% block newContent %}
{% load static %}
<div ng-controller="modifyPackagesV2" class="p-8">
<div>
<p class="text-4xl font-bold">Modify Package</p>
<p class="text-xs text-gray-600 py-2 font-semibold">Packages define resources for your website, you need to
add package before creating a website.</p>
</div>
<div>
<div class="py-4">
<p class="text-xl font-bold">Modify Package</p>
<img id="packageLoading" src="{% static 'images/loading.gif' %}">
</div>
<hr>
<div id="modifyPackageForm">
<div class="flex mt-4 py-2 px-6">
<div>
<p class="font-semibold w-60">Select Package</p>
</div>
<div>
<select ng-change="fetchDetails()" ng-model="packageToBeModified"
class="w-80 bg-gray-100 rounded px-2 py-1">
{% for items in packList %}
<option>{{ items }}</option>
{% endfor %}
</select>
</div>
</div>
<div id="packageDetailsToBeModified">
<div class="flex mt-4 py-2 px-6">
<div>
<p class="font-semibold w-60">Domains</p>
</div>
<div>
<input type="number" class="w-80 bg-gray-100 rounded px-2 py-1" ng-model="allowedDomains"
required>
</div>
<div class="text-orange-500 font-semibold ml-3"><p>{% trans "(0 = Unlimited)" %}</p></div>
</div>
<div class="flex py-2 px-6">
<div>
<p class="font-semibold w-60">Disk Space</p>
</div>
<div>
<input type="number" class="w-80 bg-gray-100 rounded px-2 py-1" ng-model="diskSpace"
required>
</div>
<div class="text-orange-500 font-semibold ml-3"><p>{% trans "MB (0 = Unlimited)" %}</p></div>
</div>
<div class="flex py-2 px-6">
<div>
<p class="font-semibold w-60">Bandwidth</p>
</div>
<div>
<input type="number" class="w-80 bg-gray-100 rounded px-2 py-1" ng-model="bandwidth"
required>
</div>
<div class="text-orange-500 font-semibold ml-3"><p>{% trans "MB (0 = Unlimited)" %}</p></div>
</div>
<div class="flex py-2 px-6">
<div>
<p class="font-semibold w-60">FTP Account</p>
</div>
<div>
<input type="number" class="w-80 bg-gray-100 rounded px-2 py-1" ng-model="ftpAccounts"
required>
</div>
</div>
<div class="flex py-2 px-6">
<div>
<p class="font-semibold w-60">Databases</p>
</div>
<div>
<input type="number" class="w-80 bg-gray-100 rounded px-2 py-1" ng-model="dataBases"
required>
</div>
</div>
<div class="flex py-2 px-6">
<div>
<p class="font-semibold w-60">Emails</p>
</div>
<div>
<input type="number" class="w-80 bg-gray-100 rounded px-2 py-1" ng-model="emails" required>
</div>
</div>
<div>
<div ng-hide="installationDetailsForm" class="flex py-2 px-6">
<div>
<p class="font-semibold w-60">Additional Features</p>
</div>
<div>
<div class="checkbox">
<label>
<input ng-model="allowFullDomain" type="checkbox" value="">
Allow Creation of Fully Qualified Domain as Child-Domains
</label>
</div>
<div class="checkbox">
<label>
<input ng-model="enforceDiskLimits" type="checkbox" value="">
Enforce Disk Limits
</label>
</div>
</div>
</div>
</div>
<div class="flex justify-center mt-6">
<button ng-click="modifyPackageFunc()"
class="bg-orange-500 text-white font-bold px-4 py-2 text-xl">
Modify Package
</button>
</div>
</div>
<div class="mt-4">
<label class="col-sm-3 control-label"></label>
<div>
<div id="successfullyModified"
class="flex justify-center bg-green-500 px-2 rounded-lg py-1 font-semibold">
<p>{% trans "Package" %} <strong>{$ packageModified
$}</strong> {% trans "Successfully Modified" %}</p>
</div>
<div id="modifyFailure"
class="flex justify-center bg-red-500 rounded-lg text-white px-2 py-1 font-semibold">
<p>{% trans "Cannot fetch package details. Error message:" %} {$ errorMessage $}</p>
</div>
<div id="modifySuccess"
class="flex justify-center bg-green-500 px-2 rounded-lg py-1 font-semibold">
<p>{% trans "Package Details Successfully Fetched" %}</p>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -4,9 +4,13 @@ from . import views
urlpatterns = [
url(r'^$', views.packagesHome, name='packagesHome'),
url(r'^createPackage$', views.createPacakge, name='createPackage'),
url(r'^V2/createPackageV2$', views.createPacakgeV2, name='createPackageV2'),
url(r'^deletePacakge$', views.deletePacakge, name='deletePackage'),
url(r'^V2/deletePacakgeV2$', views.deletePacakgeV2, name='deletePackageV2'),
url(r'^modifyPackage$', views.modifyPackage, name='modifyPackage'),
url(r'^V2/modifyPackageV2$', views.modifyPackageV2, name='modifyPackageV2'),
url(r'^listPackages$', views.listPackages, name='listPackages'),
url(r'^V2/listPackagesV2$', views.listPackagesV2, name='listPackagesV2'),
url(r'^fetchPackagesTable$', views.fetchPackagesTable, name='fetchPackagesTable'),
# Pacakge Modification URLs
@@ -16,5 +20,4 @@ urlpatterns = [
url(r'^submitModify', views.submitModify, name='submitModify'),
url(r'^saveChanges', views.saveChanges, name='saveChanges'),
]
]

View File

@@ -6,6 +6,7 @@ from loginSystem.views import loadLoginPage
from .packagesManager import PackagesManager
from .pluginManager import pluginManager
# Create your views here.
@@ -16,6 +17,7 @@ def packagesHome(request):
except KeyError:
return redirect(loadLoginPage)
def createPacakge(request):
try:
@@ -34,6 +36,26 @@ def createPacakge(request):
except KeyError:
return redirect(loadLoginPage)
def createPacakgeV2(request):
try:
result = pluginManager.preCreatePacakge(request)
if result != 200:
return result
pm = PackagesManager(request)
coreResult = pm.createPacakgeV2()
result = pluginManager.postCreatePacakge(request, coreResult)
if result != 200:
return result
return coreResult
except KeyError:
return redirect(loadLoginPage)
def deletePacakge(request):
try:
pm = PackagesManager(request)
@@ -41,6 +63,13 @@ def deletePacakge(request):
except KeyError:
return redirect(loadLoginPage)
def deletePacakgeV2(request):
try:
pm = PackagesManager(request)
return pm.deletePacakgeV2()
except KeyError:
return redirect(loadLoginPage)
def submitPackage(request):
try:
@@ -59,6 +88,7 @@ def submitPackage(request):
except KeyError:
return redirect(loadLoginPage)
def submitDelete(request):
try:
@@ -77,6 +107,7 @@ def submitDelete(request):
except KeyError:
return redirect(loadLoginPage)
def modifyPackage(request):
try:
pm = PackagesManager(request)
@@ -84,6 +115,12 @@ def modifyPackage(request):
except KeyError:
return redirect(loadLoginPage)
def modifyPackageV2(request):
try:
pm = PackagesManager(request)
return pm.modifyPackageV2()
except KeyError:
return redirect(loadLoginPage)
def submitModify(request):
try:
pm = PackagesManager(request)
@@ -91,6 +128,7 @@ def submitModify(request):
except KeyError:
return redirect(loadLoginPage)
def saveChanges(request):
try:
@@ -117,8 +155,12 @@ def listPackages(request):
except KeyError:
return redirect(loadLoginPage)
def listPackagesV2(request):
try:
pm = PackagesManager(request)
return pm.listPackagesV2()
except KeyError:
return redirect(loadLoginPage)
def fetchPackagesTable(request):
try: