Apache URL

This commit is contained in:
Zarak Khan
2024-02-10 12:54:13 +05:00
parent acfd8df385
commit 8b4c0ffc3b
21 changed files with 1921 additions and 296 deletions

View File

@@ -31,6 +31,7 @@ from googleapiclient.discovery import build
from websiteFunctions.models import NormalBackupDests, NormalBackupJobs, NormalBackupSites
from plogical.IncScheduler import IncScheduler
class BackupManager:
localBackupPath = '/home/cyberpanel/localBackupPath'
@@ -56,6 +57,16 @@ class BackupManager:
proc = httpProc(request, 'backup/backup.html', {'websiteList': websitesName}, 'createBackup')
return proc.render()
def backupSiteV2(self, request=None, userID=None, data=None):
currentACL = ACLManager.loadedACL(userID)
websitesName = ACLManager.findAllSites(currentACL, userID)
command = 'chmod 755 /home/backup'
ProcessUtilities.executioner(command)
proc = httpProc(request, 'backup/backupV2.html', {'websiteList': websitesName}, 'createBackup')
return proc.render()
def RestoreV2backupSite(self, request=None, userID=None, data=None):
if ACLManager.CheckForPremFeature('all'):
BackupStat = 1
@@ -63,7 +74,8 @@ class BackupManager:
BackupStat = 0
currentACL = ACLManager.loadedACL(userID)
websitesName = ACLManager.findAllSites(currentACL, userID)
proc = httpProc(request, 'IncBackups/RestoreV2Backup.html', {'websiteList': websitesName, 'BackupStat': BackupStat}, 'createBackup')
proc = httpProc(request, 'IncBackups/RestoreV2Backup.html',
{'websiteList': websitesName, 'BackupStat': BackupStat}, 'createBackup')
return proc.render()
def CreateV2backupSite(self, request=None, userID=None, data=None):
@@ -81,7 +93,8 @@ class BackupManager:
currentACL = ACLManager.loadedACL(userID)
websitesName = ACLManager.findAllSites(currentACL, userID)
proc = httpProc(request, 'IncBackups/ScheduleV2Backup.html', {'websiteList': websitesName, "BackupStat": BackupStat}, 'createBackup')
proc = httpProc(request, 'IncBackups/ScheduleV2Backup.html',
{'websiteList': websitesName, "BackupStat": BackupStat}, 'createBackup')
return proc.render()
def gDrive(self, request=None, userID=None, data=None):
@@ -340,7 +353,6 @@ class BackupManager:
json_data = json.dumps(data_ret)
return HttpResponse(json_data)
def changeFileRetention(self, request=None, userID=None, data=None):
try:
@@ -362,15 +374,13 @@ class BackupManager:
else:
return ACLManager.loadErrorJson('status', 0)
conf = gD.auth
# logging.CyberCPLogFileWriter.writeToFile("...... conf...%s " % conf)
config = json.loads(conf)
# logging.CyberCPLogFileWriter.writeToFile("...... config...%s " % config)
config['FileRetentiontime'] = Retentiontime
gD.auth=json.dumps(config)
gD.auth = json.dumps(config)
gD.save()
data_ret = {'status': 1}
@@ -435,6 +445,25 @@ class BackupManager:
proc = httpProc(request, 'backup/restore.html', {'backups': all_files}, 'restoreBackup')
return proc.render()
def restoreSiteV2(self, request=None, userID=None, data=None):
path = os.path.join("/home", "backup")
if not os.path.exists(path):
proc = httpProc(request, 'backup/restoreV2.html', None, 'restoreBackup')
return proc.render()
else:
all_files = []
ext = ".tar.gz"
command = 'sudo chown -R cyberpanel:cyberpanel ' + path
ACLManager.executeCall(command)
files = os.listdir(path)
for filename in files:
if filename.endswith(ext):
all_files.append(filename)
proc = httpProc(request, 'backup/restoreV2.html', {'backups': all_files}, 'restoreBackup')
return proc.render()
def getCurrentBackups(self, userID=None, data=None):
try:
currentACL = ACLManager.loadedACL(userID)
@@ -1495,7 +1524,6 @@ class BackupManager:
recordsToShow = int(data['recordsToShow'])
page = int(str(data['page']).strip('\n'))
if ACLManager.currentContextPermission(currentACL, 'scheduleBackups') == 0:
return ACLManager.loadErrorJson('scheduleStatus', 0)
@@ -1726,7 +1754,6 @@ class BackupManager:
json_data = json.dumps(data_ret)
return HttpResponse(json_data)
def deleteAccountNormal(self, request=None, userID=None, data=None):
try:
@@ -1838,7 +1865,7 @@ class BackupManager:
json_data = json.dumps(data_ret)
return HttpResponse(json_data)
#currentStatus:"cat: /home/cyberpanel/9219: No such file or directory"
# currentStatus:"cat: /home/cyberpanel/9219: No such file or directory"
statusData = ProcessUtilities.outputExecutioner("cat " + statusFile).splitlines()
@@ -1871,4 +1898,4 @@ class BackupManager:
except BaseException as msg:
data_ret = {'abort': 0, 'installStatus': 0, 'installationProgress': "0", 'error_message': str(msg)}
json_data = json.dumps(data_ret)
return HttpResponse(json_data)
return HttpResponse(json_data)

View File

@@ -0,0 +1,415 @@
newapp.controller('backupWebsiteControlV2', function ($scope, $http, $timeout) {
$(document).ready(function () {
$(".destinationHide").hide();
$('#create-backup-select').select2();
});
$('#create-backup-select').on('select2:select', function (e) {
var data = e.params.data;
$scope.websiteToBeBacked = data.text;
$(".destinationHide").show();
getBackupStatus();
populateCurrentRecords();
$scope.destination = false;
$scope.runningBackup = true;
});
$scope.destination = true;
$scope.backupButton = true;
$scope.backupLoading = true;
$scope.runningBackup = true;
$scope.cancelButton = true;
populateCurrentRecords();
$scope.cancelBackup = function () {
var backupCancellationDomain = $scope.websiteToBeBacked;
url = "/backup/cancelBackupCreation";
var data = {
backupCancellationDomain: backupCancellationDomain, fileName: $scope.fileName,
};
var config = {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
};
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
};
$scope.fetchDetails = function () {
getBackupStatus();
populateCurrentRecords();
$scope.destination = false;
$scope.runningBackup = true;
};
function getBackupStatus() {
$scope.backupLoadingBottom = false;
var websiteToBeBacked = $scope.websiteToBeBacked;
url = "/backup/backupStatus";
var data = {
websiteToBeBacked: websiteToBeBacked,
};
var config = {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
};
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
function ListInitialDatas(response) {
if (response.data.backupStatus === 1) {
if (response.data.abort === 1) {
$timeout.cancel();
$scope.backupLoadingBottom = true;
$scope.destination = false;
$scope.runningBackup = false;
$scope.cancelButton = true;
$scope.backupButton = false;
$scope.backupLoading = true;
$scope.fileName = response.data.fileName;
$scope.status = response.data.status;
populateCurrentRecords();
return;
} else {
$scope.destination = true;
$scope.backupButton = true;
$scope.runningBackup = false;
$scope.cancelButton = false;
$scope.fileName = response.data.fileName;
$scope.status = response.data.status;
$timeout(getBackupStatus, 2000);
}
} else {
$timeout.cancel();
$scope.backupLoadingBottom = true;
$scope.backupLoading = true;
$scope.cancelButton = true;
$scope.backupButton = false;
}
}
function cantLoadInitialDatas(response) {
}
};
$scope.destinationSelection = function () {
$scope.backupButton = false;
};
function populateCurrentRecords() {
var websiteToBeBacked = $scope.websiteToBeBacked;
url = "/backup/getCurrentBackups";
var data = {
websiteToBeBacked: websiteToBeBacked,
};
var config = {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
};
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
function ListInitialDatas(response) {
if (response.data.fetchStatus == 1) {
$scope.records = JSON.parse(response.data.data);
}
}
function cantLoadInitialDatas(response) {
}
};
$scope.createBackup = function () {
var createBackupButton = document.getElementById("createBackup");
createBackupButton.disabled = true;
var websiteToBeBacked = $scope.websiteToBeBacked;
$scope.backupLoading = false;
url = "/backup/submitBackupCreation";
var data = {
websiteToBeBacked: websiteToBeBacked,
};
var config = {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
};
// console.log("-------------------")
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
function ListInitialDatas(response) {
if (response.data.metaStatus === 1) {
getBackupStatus();
createBackupButton.disabled = false;
}
}
function cantLoadInitialDatas(response) {
createBackupButton.disabled = false;
}
};
$scope.deleteBackup = function (id) {
url = "/backup/deleteBackup";
var data = {
backupID: id,
};
var config = {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
};
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
function ListInitialDatas(response) {
if (response.data.deleteStatus == 1) {
populateCurrentRecords();
} else {
}
}
function cantLoadInitialDatas(response) {
}
};
});
$("#websiteDeleteFailure").hide();
$("#websiteDeleteSuccess").hide();
newapp.controller('restoreWebsiteControlV2', function ($scope, $http, $timeout) {
$scope.restoreLoading = true;
$scope.runningRestore = true;
$scope.restoreButton = true;
$scope.restoreFinished = false;
$scope.couldNotConnect = true;
$scope.backupError = true;
$scope.siteExists = true;
// check to start time of status function
var check = 1;
$scope.fetchDetails = function () {
$scope.restoreLoading = false;
getRestoreStatus();
};
function getRestoreStatus() {
var backupFile = $scope.backupFile;
url = "/backup/restoreStatus";
var data = {
backupFile: backupFile,
};
var config = {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
};
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
function ListInitialDatas(response) {
if (response.data.restoreStatus === 1) {
if (response.data.abort === 1) {
$scope.running = response.data.running;
$scope.fileName = $scope.backupFile;
$scope.restoreLoading = true;
$scope.status = response.data.status;
$scope.runningRestore = false;
$scope.restoreButton = false;
$scope.restoreFinished = true;
$timeout.cancel();
return;
} else {
$scope.running = response.data.running;
$scope.fileName = $scope.backupFile;
$scope.restoreLoading = false;
$scope.status = response.data.status;
$scope.runningRestore = false;
$scope.restoreButton = true;
$timeout(getRestoreStatus, 2000);
}
}
}
function cantLoadInitialDatas(response) {
$scope.couldNotConnect = false;
}
};
$scope.restoreBackup = function () {
var restoreBackupButton = document.getElementById("restoreBackup");
restoreBackupButton.disabled = true;
var backupFile = $scope.backupFile;
$scope.running = "Lets start.."
url = "/backup/submitRestore";
var data = {
backupFile: backupFile,
};
var config = {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
};
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
function ListInitialDatas(response) {
$scope.restoreLoading = true;
if (response.data.restoreStatus == 1) {
$scope.runningRestore = false;
$scope.running = "Running";
$scope.fileName = $scope.backupFile;
$scope.status = "Just Started..";
getRestoreStatus();
restoreBackupButton.disabled = false;
} else {
$scope.backupError = false;
$scope.errorMessage = response.data.error_message;
restoreBackupButton.disabled = false;
}
}
function cantLoadInitialDatas(response) {
$scope.couldNotConnect = false;
restoreBackupButton.disabled = false;
}
};
function createWebsite() {
var backupFile = $scope.backupFile;
url = "/websites/CreateWebsiteFromBackup";
var data = {
backupFile: backupFile,
};
var config = {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
};
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
function ListInitialDatas(response) {
if (response.data.createWebSiteStatus == 1) {
getRestoreStatus();
} else if (response.data.existsStatus == 1) {
$scope.backupError = false;
$scope.errorMessage = response.data.error_message;
$scope.restoreButton = true;
$scope.runningRestore = true;
} else {
$scope.websiteDomain = domainName;
$scope.backupError = false;
$scope.errorMessage = response.data.error_message;
}
}
function cantLoadInitialDatas(response) {
$scope.couldNotConnect = false;
}
};
});

View File

@@ -1,155 +1,131 @@
{% extends "baseTemplate/index.html" %}
{% load i18n %}
{% block title %}{% trans "Backup Website" %}{% endblock %}
{% block content %}
{% load static %}
{% load static %}
{% get_current_language as LANGUAGE_CODE %}
<!-- Current language: {{ LANGUAGE_CODE }} -->
{% get_current_language as LANGUAGE_CODE %}
<!-- Current language: {{ LANGUAGE_CODE }} -->
<div class="container">
<div id="page-title">
<h2>{% trans "Backup Website" %} - <a target="_blank" href="http://go.cyberpanel.net/backup" style="height: 23px;line-height: 21px;" class="btn btn-border btn-alt border-red btn-link font-red" title=""><span>{% trans "Backup Docs" %}</span></a></h2>
<p>{% trans "This page can be used to Backup your websites" %}</p>
</div>
<div class="container">
<div id="page-title">
<h2>{% trans "Backup Website" %} - <a target="_blank" href="http://go.cyberpanel.net/backup"
style="height: 23px;line-height: 21px;"
class="btn btn-border btn-alt border-red btn-link font-red"
title=""><span>{% trans "Backup Docs" %}</span></a></h2>
<p>{% trans "This page can be used to Backup your websites" %}</p>
</div>
<div ng-controller="backupWebsiteControl" class="panel">
<div class="panel-body">
<h3 class="title-hero">
{% trans "Backup Website" %} <img ng-hide="backupLoading" src="{% static 'images/loading.gif' %}">
</h3>
<div class="example-box-wrapper">
<form action="/" class="form-horizontal bordered-row">
<div class="form-group">
<label class="col-sm-3 control-label">{% trans "Select Website" %} </label>
<div class="col-sm-6">
<select id="create-backup-select" ng-model="websiteToBeBacked" class="form-control">
{% for items in websiteList %}
<option>{{ items }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="form-group destinationHide">
<label class="col-sm-3 control-label">{% trans "Destination" %}</label>
<div class="col-sm-6">
<select ng-change="destinationSelection()" ng-model="backupDestinations" class="form-control">
<option>{% trans "Home" %}</option>
</select>
</div>
</div>
<!---- if Backup is running ----->
<div ng-hide="runningBackup" class="form-group">
<div class="col-sm-12">
<table class="table">
<thead>
<tr>
<th></th>
<th>{% trans "File Name" %}</th>
<th>{% trans "Status" %} <img ng-hide="backupLoadingBottom" src="{% static 'images/loading.gif' %}"></th>
</tr>
</thead>
<tbody>
<tr>
<td>{% trans "Running" %}</td>
<td>{$ fileName $}</td>
<td style="color: red"><strong>{$ status $}</strong></td>
</tr>
</tbody>
</table>
</div>
</div>
<!---- if Backup is running------>
<div class="form-group destinationHide">
<label class="col-sm-3 control-label"></label>
<div class="col-sm-4">
<button type="button" ng-click="createBackup()" id="createBackup" class="btn btn-primary btn-lg btn-block">{% trans "Create Backup" %}</button>
</div>
</div>
<div ng-hide="cancelButton" class="form-group">
<label class="col-sm-3 control-label"></label>
<div class="col-sm-4">
<button type="button" ng-click="cancelBackup()" class="btn btn-primary btn-lg btn-block">{% trans "Cancel Backup" %}</button>
</div>
</div>
<!------ List of records --------------->
<div class="form-group">
<div class="col-sm-12">
<table class="table">
<thead>
<tr>
<th>{% trans "ID" %}</th>
<th>{% trans "File" %}</th>
<th>{% trans "Date" %}</th>
<th>{% trans "Size" %}</th>
<th>{% trans "Status" %}</th>
<th>{% trans "Delete" %}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="record in records track by $index">
<td ng-bind="record.id"></td>
<td ng-bind="record.file"></td>
<td ng-bind="record.date"></td>
<td ng-bind="record.size"></td>
<td ng-bind="record.status"></td>
<a href=""><td ng-click="deleteBackup(record.id)"><img src="{% static 'images/delete.png' %}"></td></a>
</tr>
</tbody>
</table>
</div>
</div>
<!------ List of records --------------->
<div class="form-group">
<label class="col-sm-3 control-label"></label>
<div class="col-sm-4">
<div id="websiteDeleteFailure" class="alert alert-danger">
<p>{% trans "Cannot delete website, Error message: " %}{$ errorMessage $}</p>
<div ng-controller="backupWebsiteControl" class="panel">
<div class="panel-body">
<h3 class="title-hero">
{% trans "Backup Website" %} <img ng-hide="backupLoading" src="{% static 'images/loading.gif' %}">
</h3>
<div class="example-box-wrapper">
<form action="/" class="form-horizontal bordered-row">
<div class="form-group">
<label class="col-sm-3 control-label">{% trans "Select Website" %} </label>
<div class="col-sm-6">
<select id="create-backup-select" ng-model="websiteToBeBacked" class="form-control">
{% for items in websiteList %}
<option>{{ items }}</option>
{% endfor %}
</select>
</div>
<div id="websiteDeleteSuccess" class="alert alert-success">
<p>Website <strong>{$ deletedWebsite $}</strong> {% trans "Successfully Deleted" %}</p>
</div>
<div class="form-group destinationHide">
<label class="col-sm-3 control-label">{% trans "Destination" %}</label>
<div class="col-sm-6">
<select ng-change="destinationSelection()" ng-model="backupDestinations"
class="form-control">
<option>{% trans "Home" %}</option>
</select>
</div>
</div>
</div>
<!---- if Backup is running ----->
<div ng-hide="runningBackup" class="form-group">
<div class="col-sm-12">
<table class="table">
<thead>
<tr>
<th></th>
<th>{% trans "File Name" %}</th>
<th>{% trans "Status" %} <img ng-hide="backupLoadingBottom"
src="{% static 'images/loading.gif' %}"></th>
</tr>
</thead>
<tbody>
<tr>
<td>{% trans "Running" %}</td>
<td>{$ fileName $}</td>
<td style="color: red"><strong>{$ status $}</strong></td>
</tr>
</tbody>
</table>
</div>
</div>
<!---- if Backup is running------>
<div class="form-group destinationHide">
<label class="col-sm-3 control-label"></label>
<div class="col-sm-4">
<button type="button" ng-click="createBackup()" id="createBackup"
class="btn btn-primary btn-lg btn-block">{% trans "Create Backup" %}</button>
</div>
</div>
<div ng-hide="cancelButton" class="form-group">
<label class="col-sm-3 control-label"></label>
<div class="col-sm-4">
<button type="button" ng-click="cancelBackup()"
class="btn btn-primary btn-lg btn-block">{% trans "Cancel Backup" %}</button>
</div>
</div>
<!------ List of records --------------->
<div class="form-group">
<div class="col-sm-12">
<table class="table">
<thead>
<tr>
<th>{% trans "ID" %}</th>
<th>{% trans "File" %}</th>
<th>{% trans "Date" %}</th>
<th>{% trans "Size" %}</th>
<th>{% trans "Status" %}</th>
<th>{% trans "Delete" %}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="record in records track by $index">
<td ng-bind="record.id"></td>
<td ng-bind="record.file"></td>
<td ng-bind="record.date"></td>
<td ng-bind="record.size"></td>
<td ng-bind="record.status"></td>
<a href="">
<td ng-click="deleteBackup(record.id)"><img
src="{% static 'images/delete.png' %}"></td>
</a>
</tr>
</tbody>
</table>
</div>
</div>
<!------ List of records --------------->
<div class="form-group">
<label class="col-sm-3 control-label"></label>
<div class="col-sm-4">
<div id="websiteDeleteFailure" class="alert alert-danger">
<p>{% trans "Cannot delete website, Error message: " %}{$ errorMessage $}</p>
</div>
<div id="websiteDeleteSuccess" class="alert alert-success">
<p>Website <strong>{$ deletedWebsite $}</strong> {% trans "Successfully Deleted" %}
</p>
</div>
</div>
</div>
</form>
</div>
</form>
</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="backupWebsiteControlV2" class="p-8">
<div class="flex lg:flex-row justify-between items-center sm:flex-col">
<div class="flex items-center">
<p class="text-4xl font-bold">Backup Website -</p>
<a target="_blank" href="http://go.cyberpanel.net/backup"
class="bg-blue-200 px-2 py-1 font-bold mt-2 ml-3"
title=""><span>{% trans "Backup Docs" %}</span></a>
</div>
</div>
<p class="text-xs text-gray-600 py-2 font-semibold">This page can be used to Backup your websites</p>
<div class="py-4">
<p class="text-xl font-bold">Backup Website</p>
<img ng-hide="backupLoading" src="{% static 'images/loading.gif' %}">
</div>
<hr>
<div class="flex mt-4 py-2 px-6">
<div>
<p class="font-semibold w-60">Select Website</p>
</div>
<div>
<select id="create-backup-select" ng-model="websiteToBeBacked"
class="w-80 bg-gray-100 rounded px-2 py-1">
{% for items in websiteList %}
<option>{{ items }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="flex mt-4 py-2 px-6 destinationHide">
<div>
<p class="font-semibold w-60">Destination</p>
</div>
<div>
<select ng-change="destinationSelection()" ng-model="backupDestinations"
class="w-80 bg-gray-100 rounded px-2 py-1">
<option>{% trans "Home" %}</option>
</select>
</div>
</div>
<hr>
<div ng-hide="runningBackup" 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">
File Name
</th>
<th scope="col" class="px-6 py-3">
Status <img ng-hide="backupLoadingBottom" src="{% static 'images/loading.gif' %}">
</th>
</tr>
</thead>
<tbody class="border shadow-lg py-3 px-6 rounded-b-lg">
<tr>
<td class="px-6 py-4">
Running
</td>
<td class="px-6 py-4">
{$ fileName $}
</td>
<td class="px-6 py-4 text-red-500 font-bold">
{$ status $}
</td>
</tr>
</tbody>
</table>
</div>
<div class="flex justify-center mt-6 destinationHide">
<button ng-click="createBackup()" id="createBackup"
class="bg-orange-500 text-white font-bold px-4 py-2 text-xl">
Create Backup
</button>
</div>
<div ng-hide="cancelButton" class="flex justify-center mt-6">
<button ng-click="cancelBackup()" id="createBackup"
class="bg-orange-500 text-white font-bold px-4 py-2 text-xl">
Cancel Backup
</button>
</div>
<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">
ID
</th>
<th scope="col" class="px-6 py-3">
File
</th>
<th scope="col" class="px-6 py-3">
Date
</th>
<th scope="col" class="px-6 py-3">
Size
</th>
<th scope="col" class="px-6 py-3">
Status
</th>
<th scope="col" class="px-6 py-3">
Delete
</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.id" class="px-6 py-4">
</td>
<td ng-bind="record.file" class="px-6 py-4">
</td>
<td ng-bind="record.date" class="px-6 py-4">
</td>
<td ng-bind="record.size" class="px-6 py-4">
</td>
<td ng-bind="record.status" class="px-6 py-4">
</td>
<td ng-click="deleteBackup(record.id)" class="px-6 py-4">
<img class="cursor-pointer" src="{% static 'images/delete.png' %}">
</td>
</tr>
</tbody>
</table>
</div>
<div class="py-4">
<div class="col-sm-4">
<div id="websiteDeleteFailure"
class="flex justify-center bg-red-500 rounded-lg text-white px-2 py-1 font-semibold">
<p>{% trans "Cannot delete website, Error message: " %}{$ errorMessage $}</p>
</div>
<div id="websiteDeleteSuccess"
class="flex justify-center bg-green-500 px-2 rounded-lg py-1 font-semibold">
<p>Website <strong>{$ deletedWebsite $}</strong> {% trans "Successfully Deleted" %}</p>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -3,114 +3,111 @@
{% block title %}{% trans "Restore Website - CyberPanel" %}{% endblock %}
{% block content %}
{% load static %}
{% get_current_language as LANGUAGE_CODE %}
<!-- Current language: {{ LANGUAGE_CODE }} -->
<div class="container">
<div id="page-title">
<h2>{% trans "Restore Website" %} - <a target="_blank" href="http://go.cyberpanel.net/backup" style="height: 23px;line-height: 21px;" class="btn btn-border btn-alt border-red btn-link font-red" title=""><span>{% trans "Backup Docs" %}</span></a></h2>
<p>{% trans "This page can be used to restore your websites, Backup should be generated from CyberPanel Backup generation tool, it will detect all Backups under <strong>/home/backup</strong>." %}</p>
</div>
<div ng-controller="restoreWebsiteControl" class="panel">
<div class="panel-body">
<h3 class="title-hero">
{% trans "Restore Website" %} <img ng-hide="restoreLoading" src="{% static 'images/loading.gif' %}">
</h3>
<div class="example-box-wrapper">
<form action="/" class="form-horizontal bordered-row">
<div class="form-group">
<label class="col-sm-3 control-label">{% trans "Select Backup" %}</label>
<div class="col-sm-6">
<select ng-change="fetchDetails()" ng-model="backupFile" class="form-control">
{% for items in backups %}
<option>{{ items }}</option>
{% endfor %}
</select>
</div>
</div>
<div ng-hide="restoreButton" class="form-group">
<label class="col-sm-3 control-label"></label>
<div class="col-sm-4">
<button type="button" ng-click="restoreBackup()" id="restoreBackup" class="btn btn-primary btn-lg btn-block">{% trans "Restore" %}</button>
</div>
</div>
<!---- if restore is running ----->
<div ng-hide="runningRestore" class="form-group">
<div class="col-sm-12">
<table class="table">
<thead>
<tr>
<th>{% trans "Condition" %}</th>
<th>{% trans "File Name" %}</th>
<th>{% trans "Status" %} <img ng-hide="restoreFinished" src="{% static 'images/loading.gif' %}"></th>
</tr>
</thead>
<tbody>
<tr>
<td>{$ running $}</td>
<td>{$ fileName $}</td>
<td style="color: red"><strong>{$ status $}</strong></td>
</tr>
</tbody>
</table>
</div>
</div>
<!---- if restore is running------>
<div class="form-group">
<label class="col-sm-3 control-label"></label>
<div class="col-sm-4">
<div ng-hide="backupError" class="alert alert-danger">
<p>{% trans "Error message:" %} {$ errorMessage $}</p>
</div>
<div ng-hide="siteExists" class="alert alert-danger">
<p>{% trans "Site related to this Backup already exists." %}</p>
</div>
<div ng-hide="couldNotConnect" class="alert alert-danger">
<p>{% trans "Could not connect to server. Please refresh this page." %}</p>
</div>
</div>
</div>
</form>
{% load static %}
{% get_current_language as LANGUAGE_CODE %}
<!-- Current language: {{ LANGUAGE_CODE }} -->
<div class="container">
<div id="page-title">
<h2>{% trans "Restore Website" %} - <a target="_blank" href="http://go.cyberpanel.net/backup"
style="height: 23px;line-height: 21px;"
class="btn btn-border btn-alt border-red btn-link font-red" title=""><span>{% trans "Backup Docs" %}</span></a>
</h2>
<p>{% trans "This page can be used to restore your websites, Backup should be generated from CyberPanel Backup generation tool, it will detect all Backups under <strong>/home/backup</strong>." %}</p>
</div>
<div ng-controller="restoreWebsiteControl" class="panel">
<div class="panel-body">
<h3 class="title-hero">
{% trans "Restore Website" %} <img ng-hide="restoreLoading" src="{% static 'images/loading.gif' %}">
</h3>
<div class="example-box-wrapper">
<form action="/" class="form-horizontal bordered-row">
<div class="form-group">
<label class="col-sm-3 control-label">{% trans "Select Backup" %}</label>
<div class="col-sm-6">
<select ng-change="fetchDetails()" ng-model="backupFile" class="form-control">
{% for items in backups %}
<option>{{ items }}</option>
{% endfor %}
</select>
</div>
</div>
<div ng-hide="restoreButton" class="form-group">
<label class="col-sm-3 control-label"></label>
<div class="col-sm-4">
<button type="button" ng-click="restoreBackup()" id="restoreBackup"
class="btn btn-primary btn-lg btn-block">{% trans "Restore" %}</button>
</div>
</div>
<!---- if restore is running ----->
<div ng-hide="runningRestore" class="form-group">
<div class="col-sm-12">
<table class="table">
<thead>
<tr>
<th>{% trans "Condition" %}</th>
<th>{% trans "File Name" %}</th>
<th>{% trans "Status" %} <img ng-hide="restoreFinished"
src="{% static 'images/loading.gif' %}"></th>
</tr>
</thead>
<tbody>
<tr>
<td>{$ running $}</td>
<td>{$ fileName $}</td>
<td style="color: red"><strong>{$ status $}</strong></td>
</tr>
</tbody>
</table>
</div>
</div>
<!---- if restore is running------>
<div class="form-group">
<label class="col-sm-3 control-label"></label>
<div class="col-sm-4">
<div ng-hide="backupError" class="alert alert-danger">
<p>{% trans "Error message:" %} {$ errorMessage $}</p>
</div>
<div ng-hide="siteExists" class="alert alert-danger">
<p>{% trans "Site related to this Backup already exists." %}</p>
</div>
<div ng-hide="couldNotConnect" class="alert alert-danger">
<p>{% trans "Could not connect to server. Please refresh this page." %}</p>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,91 @@
{% extends "baseTemplate/newBase.html" %}
{% load i18n %}
{% block titleNew %}{% trans "Home - CyberPanel" %}{% endblock %}
{% block newContent %}
{% load static %}
<div ng-controller="restoreWebsiteControlV2" class="p-8">
<div class="flex lg:flex-row justify-between items-center sm:flex-col">
<div class="flex items-center">
<p class="text-4xl font-bold">Restore Website -</p>
<a target="_blank" href="http://go.cyberpanel.net/backup"
class="bg-blue-200 px-2 py-1 font-bold mt-2 ml-3"
title=""><span>{% trans "Backup Docs" %}</span></a>
</div>
</div>
<p class="text-xs text-gray-600 py-2 font-semibold">This page can be used to restore your websites, Backup
should be generated from CyberPanel Backup generation tool, it will detect all Backups under <strong>/home/backup</strong>.
</p>
<div class="py-4">
<p class="text-xl font-bold">Restore Website</p>
<img ng-hide="restoreLoading" src="{% static 'images/loading.gif' %}">
</div>
<hr>
<div class="flex mt-4 py-2 px-6">
<div>
<p class="font-semibold w-60">Select Backup</p>
</div>
<div>
<select ng-change="fetchDetails()" ng-model="backupFile" class="w-80 bg-gray-100 rounded px-2 py-1">
{% for items in backups %}
<option>{{ items }}</option>
{% endfor %}
</select>
</div>
</div>
<div ng-hide="restoreButton" class="flex justify-center mt-6 mb-2">
<button ng-click="restoreBackup()" id="restoreBackup"
class="bg-orange-500 text-white font-bold px-4 py-2 text-xl">
Restore
</button>
</div>
<hr>
<div ng-hide="runningRestore" 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">
Condition
</th>
<th scope="col" class="px-6 py-3">
File Name
</th>
<th scope="col" class="px-6 py-3">
Status <img ng-hide="restoreFinished" src="{% static 'images/loading.gif' %}">
</th>
</tr>
</thead>
<tbody class="border shadow-lg py-3 px-6 rounded-b-lg">
<tr>
<td class="px-6 py-4">
{$ running $}
</td>
<td class="px-6 py-4">
{$ fileName $}
</td>
<td class="px-6 py-4 text-red-500 font-bold">
{$ status $}
</td>
</tr>
</tbody>
</table>
</div>
<div class="py-4">
<div class="col-sm-4">
<div ng-hide="backupError"
class="flex justify-center bg-red-500 rounded-lg text-white px-2 py-1 font-semibold">
<p>{% trans "Error message:" %} {$ errorMessage $}</p>
</div>
<div ng-hide="siteExists"
class="flex justify-center bg-red-500 rounded-lg text-white px-2 py-1 font-semibold">
<p>{% trans "Site related to this Backup already exists." %}</p>
</div>
<div ng-hide="couldNotConnect"
class="flex justify-center bg-red-500 rounded-lg text-white px-2 py-1 font-semibold">
<p>{% trans "Could not connect to server. Please refresh this page." %}</p>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -5,7 +5,9 @@ urlpatterns = [
url(r'^$', views.loadBackupHome, name='loadBackupHome'),
url(r'^getCurrentBackups', views.getCurrentBackups, name='getCurrentBackups'),
url(r'^backupSite', views.backupSite, name='backupSite'),
url(r'^V2/backupSiteV2', views.backupSiteV2, name='backupSiteV2'),
url(r'^restoreSite', views.restoreSite, name='restoreSite'),
url(r'^V2/restoreSiteV2', views.restoreSiteV2, name='restoreSiteV2'),
url(r'^gDrive$', views.gDrive, name='gDrive'),
url(r'^gDriveSetup$', views.gDriveSetup, name='gDriveSetup'),
url(r'^fetchgDriveSites$', views.fetchgDriveSites, name='fetchgDriveSites'),
@@ -16,7 +18,6 @@ urlpatterns = [
url(r'^deleteSitegDrive$', views.deleteSitegDrive, name='deleteSitegDrive'),
url(r'^fetchDriveLogs$', views.fetchDriveLogs, name='fetchDriveLogs'),
url(r'^submitBackupCreation', views.submitBackupCreation, name='submitBackupCreation'),
url(r'^cancelBackupCreation', views.cancelBackupCreation, name='cancelBackupCreation'),
url(r'^backupStatus', views.backupStatus, name='backupStatus'),
@@ -42,10 +43,8 @@ urlpatterns = [
url(r'^submitBackupSchedule', views.submitBackupSchedule, name='submitBackupSchedule'),
url(r'^scheduleDelete', views.scheduleDelete, name='scheduleDelete'),
url(r'^remoteBackups', views.remoteBackups, name='remoteBackups'),
url(r'^submitRemoteBackups', views.submitRemoteBackups, name='submitRemoteBackups'),
url(r'^getRemoteTransferStatus', views.getRemoteTransferStatus, name='getRemoteTransferStatus'),
@@ -67,4 +66,4 @@ urlpatterns = [
url(r'^deleteAccountNormal$', views.deleteAccountNormal, name='deleteAccountNormal'),
url(r'^fetchNormalLogs$', views.fetchNormalLogs, name='fetchNormalLogs'),
]
]

View File

@@ -14,6 +14,7 @@ from plogical.CyberCPLogFileWriter import CyberCPLogFileWriter as logging
from django.shortcuts import HttpResponse
from django.views.decorators.csrf import csrf_exempt
def loadBackupHome(request):
try:
userID = request.session['userID']
@@ -22,6 +23,7 @@ def loadBackupHome(request):
except KeyError:
return redirect(loadLoginPage)
def backupSite(request):
try:
userID = request.session['userID']
@@ -30,6 +32,16 @@ def backupSite(request):
except KeyError:
return redirect(loadLoginPage)
def backupSiteV2(request):
try:
userID = request.session['userID']
bm = BackupManager()
return bm.backupSiteV2(request, userID)
except KeyError:
return redirect(loadLoginPage)
def gDrive(request):
try:
userID = request.session['userID']
@@ -38,6 +50,7 @@ def gDrive(request):
except KeyError:
return redirect(loadLoginPage)
def gDriveSetup(request):
try:
userID = request.session['userID']
@@ -46,6 +59,7 @@ def gDriveSetup(request):
except KeyError:
return redirect(loadLoginPage)
def fetchgDriveSites(request):
try:
userID = request.session['userID']
@@ -54,6 +68,7 @@ def fetchgDriveSites(request):
except KeyError:
return redirect(loadLoginPage)
def addSitegDrive(request):
try:
userID = request.session['userID']
@@ -62,6 +77,7 @@ def addSitegDrive(request):
except KeyError:
return redirect(loadLoginPage)
def deleteAccountgDrive(request):
try:
userID = request.session['userID']
@@ -70,6 +86,7 @@ def deleteAccountgDrive(request):
except KeyError:
return redirect(loadLoginPage)
def changeAccountFrequencygDrive(request):
try:
userID = request.session['userID']
@@ -78,6 +95,7 @@ def changeAccountFrequencygDrive(request):
except KeyError:
return redirect(loadLoginPage)
def changeFileRetention(request):
try:
userID = request.session['userID']
@@ -86,6 +104,7 @@ def changeFileRetention(request):
except KeyError:
return redirect(loadLoginPage)
def deleteSitegDrive(request):
try:
userID = request.session['userID']
@@ -94,6 +113,7 @@ def deleteSitegDrive(request):
except KeyError:
return redirect(loadLoginPage)
def fetchDriveLogs(request):
try:
userID = request.session['userID']
@@ -102,6 +122,7 @@ def fetchDriveLogs(request):
except KeyError:
return redirect(loadLoginPage)
def restoreSite(request):
try:
userID = request.session['userID']
@@ -111,6 +132,15 @@ def restoreSite(request):
return redirect(loadLoginPage)
def restoreSiteV2(request):
try:
userID = request.session['userID']
bm = BackupManager()
return bm.restoreSiteV2(request, userID)
except KeyError:
return redirect(loadLoginPage)
def getCurrentBackups(request):
try:
userID = request.session['userID']
@@ -119,6 +149,7 @@ def getCurrentBackups(request):
except KeyError:
return redirect(loadLoginPage)
def submitBackupCreation(request):
try:
userID = request.session['userID']
@@ -128,7 +159,7 @@ def submitBackupCreation(request):
return result
wm = BackupManager()
coreResult = wm.submitBackupCreation(userID, json.loads(request.body))
coreResult = wm.submitBackupCreation(userID, json.loads(request.body))
return coreResult
@@ -226,6 +257,7 @@ def submitDestinationCreation(request):
except KeyError:
return redirect(loadLoginPage)
def getCurrentBackupDestinations(request):
try:
userID = request.session['userID']
@@ -234,6 +266,7 @@ def getCurrentBackupDestinations(request):
except KeyError:
return redirect(loadLoginPage)
def getConnectionStatus(request):
try:
userID = request.session['userID']
@@ -242,6 +275,7 @@ def getConnectionStatus(request):
except KeyError:
return redirect(loadLoginPage)
def deleteDestination(request):
try:
userID = request.session['userID']
@@ -260,6 +294,7 @@ def deleteDestination(request):
except KeyError:
return redirect(loadLoginPage)
def scheduleBackup(request):
try:
userID = request.session['userID']
@@ -268,6 +303,7 @@ def scheduleBackup(request):
except KeyError:
return redirect(loadLoginPage)
def getCurrentBackupSchedules(request):
try:
userID = request.session['userID']
@@ -276,6 +312,7 @@ def getCurrentBackupSchedules(request):
except KeyError:
return redirect(loadLoginPage)
def submitBackupSchedule(request):
try:
userID = request.session['userID']
@@ -294,6 +331,7 @@ def submitBackupSchedule(request):
except KeyError:
return redirect(loadLoginPage)
def scheduleDelete(request):
try:
userID = request.session['userID']
@@ -312,6 +350,7 @@ def scheduleDelete(request):
except KeyError:
return redirect(loadLoginPage)
def remoteBackups(request):
try:
userID = request.session['userID']
@@ -320,6 +359,7 @@ def remoteBackups(request):
except KeyError:
return redirect(loadLoginPage)
def submitRemoteBackups(request):
try:
userID = request.session['userID']
@@ -338,6 +378,7 @@ def submitRemoteBackups(request):
except KeyError:
return redirect(loadLoginPage)
def starRemoteTransfer(request):
try:
userID = request.session['userID']
@@ -356,6 +397,7 @@ def starRemoteTransfer(request):
except KeyError:
return redirect(loadLoginPage)
def getRemoteTransferStatus(request):
try:
userID = request.session['userID']
@@ -364,6 +406,7 @@ def getRemoteTransferStatus(request):
except KeyError:
return redirect(loadLoginPage)
def remoteBackupRestore(request):
try:
userID = request.session['userID']
@@ -382,6 +425,7 @@ def remoteBackupRestore(request):
except KeyError:
return redirect(loadLoginPage)
def localRestoreStatus(request):
try:
userID = request.session['userID']
@@ -390,6 +434,7 @@ def localRestoreStatus(request):
except KeyError:
return redirect(loadLoginPage)
def cancelRemoteBackup(request):
try:
userID = request.session['userID']
@@ -398,6 +443,7 @@ def cancelRemoteBackup(request):
except KeyError:
return redirect(loadLoginPage)
def backupLogs(request):
try:
userID = request.session['userID']
@@ -406,6 +452,7 @@ def backupLogs(request):
except KeyError:
return redirect(loadLoginPage)
def fetchLogs(request):
try:
userID = request.session['userID']
@@ -416,6 +463,7 @@ def fetchLogs(request):
except KeyError:
return redirect(loadLoginPage)
@csrf_exempt
def localInitiate(request):
try:
@@ -428,6 +476,7 @@ def localInitiate(request):
except BaseException as msg:
logging.writeToFile(str(msg))
def fetchgNormalSites(request):
try:
userID = request.session['userID']
@@ -436,6 +485,7 @@ def fetchgNormalSites(request):
except KeyError:
return redirect(loadLoginPage)
def fetchNormalJobs(request):
try:
userID = request.session['userID']
@@ -444,6 +494,7 @@ def fetchNormalJobs(request):
except KeyError:
return redirect(loadLoginPage)
def addSiteNormal(request):
try:
userID = request.session['userID']
@@ -452,6 +503,7 @@ def addSiteNormal(request):
except KeyError:
return redirect(loadLoginPage)
def deleteSiteNormal(request):
try:
userID = request.session['userID']
@@ -460,6 +512,7 @@ def deleteSiteNormal(request):
except KeyError:
return redirect(loadLoginPage)
def changeAccountFrequencyNormal(request):
try:
userID = request.session['userID']
@@ -468,6 +521,7 @@ def changeAccountFrequencyNormal(request):
except KeyError:
return redirect(loadLoginPage)
def deleteAccountNormal(request):
try:
userID = request.session['userID']
@@ -476,10 +530,11 @@ def deleteAccountNormal(request):
except KeyError:
return redirect(loadLoginPage)
def fetchNormalLogs(request):
try:
userID = request.session['userID']
wm = BackupManager()
return wm.fetchNormalLogs(request, userID)
except KeyError:
return redirect(loadLoginPage)
return redirect(loadLoginPage)

View File

@@ -733,17 +733,17 @@
</div>
<ul id="dropdown-example-8" class="hidden py-2 space-y-2">
<li>
<a href="#"
<a href="{% url 'createFTPAccountV2' %}"
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 FTP Account</a>
</li>
<li>
<a href="#"
<a href="{% url 'listFTPAccountsV2' %}"
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 FTP Account</a>
</li>
<li>
<a href="#"
<a href="{% url 'deleteFTPAccountV2' %}"
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 FTP Account</a>
</li>
@@ -817,12 +817,12 @@
</div>
<ul id="dropdown-example-10" class="hidden py-2 space-y-2">
<li>
<a href="#"
<a href="{% url 'backupSiteV2' %}"
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 Backup</a>
</li>
<li>
<a href="#"
<a href="{% url 'restoreSiteV2' %}"
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">
Restore Backup</a>
</li>
@@ -1689,6 +1689,8 @@
<script src="{% static 'mailServer/mailServerV2.js' %}"></script>
<script src="{% static 'emailPremium/emailPremiumV2.js' %}"></script>
<script src="{% static 'filemanager/js/fileManagerV2.js' %}"></script>
<script src="{% static 'ftp/ftpV2.js' %}"></script>
<script src="{% static 'backup/backupV2.js' %}"></script>
</body>
</html>

View File

@@ -1291,6 +1291,19 @@ function changeBackgroundColor(button) {
btn.classList.add('bg-white');
});
}
function showTab1(tabId1, tabColour) {
// Hide all tabs
var tabs1 = document.getElementsByClassName('tab-content1');
for (var i = 0; i < tabs1.length; i++) {
tabs1[i].style.display = 'none';
}
// Show the selected tab
var selectedTab1 = document.getElementById(tabId1);
if (selectedTab1) {
selectedTab1.style.display = 'block';
}
}
dnsTabButton.addEventListener("click", function () {

View File

@@ -74,21 +74,21 @@
<ul class="flex py-2">
<li id="dns_tab_button"
class="hover:bg-orange-200 border-2 border-black rounded-l-3xl px-2 py-2 w-60 cursor-pointer active"
onclick="showTab('dns_tab')">
onclick="showTab1('dns_tab')">
<a class="flex justify-center">
<p class="text-2xl font-bold">Manage DNS</p>
</a>
</li>
<li id="api_tab_button"
class="hover:bg-orange-200 border-2 border-black rounded-r-3xl px-2 py-2 w-60 cursor-pointer"
onclick="showTab('api_tab')">
onclick="showTab1('api_tab')">
<a class="flex justify-center">
<p class="text-2xl font-bold">API Settings</p>
</a>
</li>
</ul>
<hr>
<div id="dns_tab" class="tab-content">
<div id="dns_tab" class="tab-content1">
<div>
<div>
<div class="flex mt-4 py-2 px-6 items-center">
@@ -531,7 +531,7 @@
<p>{% trans "Could not connect to server. Please refresh this page." %}</p>
</div>
</div>
<div id="api_tab" class="tab-content">
<div id="api_tab" class="tab-content1" style="display: none;">
<div class="flex mt-4 py-2 px-6">
<div>
<p class="font-semibold w-60">CloudFlare Email</p>

View File

@@ -150,9 +150,10 @@ newapp.controller('fileManagerCtrlV2', function ($scope, $http, FileUploader, $w
//
var iNodePlus = document.createElement('i');
iNodePlus.setAttribute('class', 'fa fa-plus');
iNodePlus.setAttribute('aria-hidden', 'true');
iNodePlus.style.color = "#007bff";
iNodePlus.textContent = "+";
iNodePlus.setAttribute('class', 'font-bold text-3xl');
// iNodePlus.setAttribute('aria-hidden', 'true');
// iNodePlus.style.color = "#007bff";
var iNodeFolder = document.createElement('i');
iNodeFolder.setAttribute('class', 'fa fa-folder');
@@ -225,9 +226,10 @@ newapp.controller('fileManagerCtrlV2', function ($scope, $http, FileUploader, $w
var spaceNode = document.createTextNode(" ");
var iNodeMinus = document.createElement('i');
iNodeMinus.setAttribute('class', 'fa fa-minus');
iNodeMinus.setAttribute('aria-hidden', 'true');
iNodeMinus.style.color = "#007bff";
iNodeMinus.textContent = "-";
iNodeMinus.setAttribute('class', 'font-bold text-3xl');
// iNodeMinus.setAttribute('aria-hidden', 'true');
// iNodeMinus.style.color = "#007bff";
// prepare node
@@ -263,9 +265,10 @@ newapp.controller('fileManagerCtrlV2', function ($scope, $http, FileUploader, $w
var spaceNode = document.createTextNode(" ");
var iNodePlus = document.createElement('i');
iNodePlus.setAttribute('class', 'fa fa-plus');
iNodePlus.setAttribute('aria-hidden', 'true');
iNodePlus.style.color = "#007bff";
iNodePlus.textContent = "+";
iNodePlus.setAttribute('class', 'font-bold text-3xl');
// iNodePlus.setAttribute('aria-hidden', 'true');
// iNodePlus.style.color = "#007bff";
// prepare node

View File

@@ -57,12 +57,10 @@
</div>
<div>
<ul class="list-group list-group-flush">
<li class="flex text-orange-500">
<a href="#" onclick="return false;" ng-click="fetchChilds($event,currentRPath,'primary')">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5"
stroke="currentColor" class="w-6 h-6">
<path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15"/>
</svg>
<li class="flex text-orange-500 items-center">
<a class="mb-2 mr-1" href="#" onclick="return false;"
ng-click="fetchChilds($event,completeStartingPath,'primary')">
<i class="font-bold text-3xl">+</i>
</a>
<a onclick="return false;"
ng-click="fetchForTableSecondary($event,'fromTree',completeStartingPath)" href="#">

View File

@@ -11,12 +11,14 @@ django.setup()
import json
from django.shortcuts import redirect
from django.http import HttpResponse
try:
from .models import Users
from loginSystem.models import Administrator
except:
pass
import plogical.CyberCPLogFileWriter as logging
try:
from loginSystem.views import loadLoginPage
from websiteFunctions.models import Websites
@@ -29,8 +31,9 @@ import os
from plogical.processUtilities import ProcessUtilities
import argparse
class FTPManager:
def __init__(self, request, extraArgs = None):
def __init__(self, request, extraArgs=None):
self.request = request
self.extraArgs = extraArgs
@@ -56,6 +59,23 @@ class FTPManager:
{'websiteList': websitesName, 'OwnerFTP': admin.userName, "status": 1}, 'createFTPAccount')
return proc.render()
def createFTPAccountV2(self):
userID = self.request.session['userID']
currentACL = ACLManager.loadedACL(userID)
admin = Administrator.objects.get(pk=userID)
if not os.path.exists('/home/cyberpanel/pureftpd'):
proc = httpProc(self.request, 'ftp/createFTPAccountV2.html',
{"status": 0}, 'createFTPAccount')
return proc.render()
websitesName = ACLManager.findAllSites(currentACL, userID)
proc = httpProc(self.request, 'ftp/createFTPAccountV2.html',
{'websiteList': websitesName, 'OwnerFTP': admin.userName, "status": 1}, 'createFTPAccount')
return proc.render()
def submitFTPCreation(self):
try:
userID = self.request.session['userID']
@@ -93,7 +113,6 @@ class FTPManager:
except:
path = 'None'
result = FTPUtilities.submitFTPCreation(domainName, userName, password, path, admin.userName, api)
if result[0] == 1:
@@ -125,6 +144,21 @@ class FTPManager:
{'websiteList': websitesName, "status": 1}, 'deleteFTPAccount')
return proc.render()
def deleteFTPAccountV2(self):
userID = self.request.session['userID']
currentACL = ACLManager.loadedACL(userID)
if not os.path.exists('/home/cyberpanel/pureftpd'):
proc = httpProc(self.request, 'ftp/deleteFTPAccountV2.html',
{"status": 0}, 'deleteFTPAccount')
return proc.render()
websitesName = ACLManager.findAllSites(currentACL, userID)
proc = httpProc(self.request, 'ftp/deleteFTPAccountV2.html',
{'websiteList': websitesName, "status": 1}, 'deleteFTPAccount')
return proc.render()
def fetchFTPAccounts(self):
try:
userID = self.request.session['userID']
@@ -210,6 +244,20 @@ class FTPManager:
{'websiteList': websitesName, "status": 1}, 'listFTPAccounts')
return proc.render()
def listFTPAccountsV2(self):
userID = self.request.session['userID']
currentACL = ACLManager.loadedACL(userID)
if not os.path.exists('/home/cyberpanel/pureftpd'):
proc = httpProc(self.request, 'ftp/listFTPAccountsV2.html',
{"status": 0}, 'listFTPAccounts')
return proc.render()
websitesName = ACLManager.findAllSites(currentACL, userID)
proc = httpProc(self.request, 'ftp/listFTPAccountsV2.html',
{'websiteList': websitesName, "status": 1}, 'listFTPAccounts')
return proc.render()
def getAllFTPAccounts(self):
try:
userID = self.request.session['userID']
@@ -365,7 +413,8 @@ class FTPManager:
except:
pass
if (ProcessUtilities.decideDistro() == ProcessUtilities.centos or ProcessUtilities.decideDistro() == ProcessUtilities.cent8) or (
if (
ProcessUtilities.decideDistro() == ProcessUtilities.centos or ProcessUtilities.decideDistro() == ProcessUtilities.cent8) or (
ProcessUtilities.decideDistro() == ProcessUtilities.ubuntu20 and ProcessUtilities.decideDistro() == ProcessUtilities.ubuntu):
command = 'openssl req -newkey rsa:1024 -new -nodes -x509 -days 3650 -subj "/C=US/ST=Denial/L=Springfield/O=Dis/CN=www.example.com" -keyout /etc/ssl/private/pure-ftpd.pem -out /etc/ssl/private/pure-ftpd.pem'
else:
@@ -384,7 +433,6 @@ class FTPManager:
else:
shutil.copytree("/usr/local/CyberCP/install/pure-ftpd-one", ftpdPath)
if ProcessUtilities.decideDistro() == ProcessUtilities.ubuntu:
try:
os.mkdir('/etc/pure-ftpd/conf')
@@ -488,7 +536,8 @@ class FTPManager:
if os.path.exists(ProcessUtilities.debugPath):
logging.CyberCPLogFileWriter.writeToFile('%s. [setupConnection:75]' % (str(msg)))
logging.CyberCPLogFileWriter.statusWriter(self.extraArgs['tempStatusPath'], 'Removing and re-installing FTP..,5')
logging.CyberCPLogFileWriter.statusWriter(self.extraArgs['tempStatusPath'],
'Removing and re-installing FTP..,5')
if self.installPureFTPD() == 0:
logging.CyberCPLogFileWriter.statusWriter(self.extraArgs['tempStatusPath'],
@@ -505,7 +554,8 @@ class FTPManager:
logging.CyberCPLogFileWriter.statusWriter(self.extraArgs['tempStatusPath'], 'Configurations reset..,70')
if self.installPureFTPDConfigurations(settings.DATABASES['default']['PASSWORD']) == 0:
logging.CyberCPLogFileWriter.statusWriter(self.extraArgs['tempStatusPath'], 'installPureFTPDConfigurations failed. [404].')
logging.CyberCPLogFileWriter.statusWriter(self.extraArgs['tempStatusPath'],
'installPureFTPDConfigurations failed. [404].')
return 0
if self.startPureFTPD() == 0:
@@ -524,8 +574,8 @@ class FTPManager:
final_json = json.dumps(final_dic)
return HttpResponse(final_json)
def main():
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.')
@@ -537,5 +587,6 @@ def main():
ftp = FTPManager(None, extraArgs)
ftp.ResetFTPConfigurations()
if __name__ == "__main__":
main()
main()

443
ftp/static/ftp/ftpV2.js Normal file
View File

@@ -0,0 +1,443 @@
newapp.controller('createFTPAccountV2', function ($scope, $http) {
$(document).ready(function () {
$( ".ftpDetails" ).hide();
$( ".ftpPasswordView" ).hide();
$('.create-ftp-acct-select').select2();
});
$('.create-ftp-acct-select').on('select2:select', function (e) {
var data = e.params.data;
$scope.ftpDomain = data.text;
$( ".ftpDetails" ).show();
});
$scope.ftpLoading = true;
$scope.createFTPAccount = function () {
$scope.ftpLoading = false;
$scope.ftpDetails = false;
$scope.canNotCreate = true;
$scope.successfullyCreated = true;
$scope.couldNotConnect = true;
var ftpDomain = $scope.ftpDomain;
var ftpUserName = $scope.ftpUserName;
var ftpPassword = $scope.ftpPassword;
var path = $scope.ftpPath;
if (typeof path === 'undefined') {
path = "";
}
var url = "/ftp/submitFTPCreation";
var data = {
ftpDomain: ftpDomain,
ftpUserName: ftpUserName,
passwordByPass: ftpPassword,
path: path,
};
var config = {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
};
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
function ListInitialDatas(response) {
if (response.data.creatFTPStatus === 1) {
$scope.ftpLoading = true;
new PNotify({
title: 'Success!',
text: 'FTP account successfully created.',
type: 'success'
});
} else {
$scope.ftpLoading = true;
new PNotify({
title: 'Operation Failed!',
text: response.data.error_message,
type: 'error'
});
}
}
function cantLoadInitialDatas(response) {
$scope.ftpLoading = true;
new PNotify({
title: 'Operation Failed!',
text: 'Could not connect to server, please refresh this page',
type: 'error'
});
}
};
$scope.hideFewDetails = function () {
$scope.successfullyCreated = true;
};
///
$scope.generatePassword = function () {
$( ".ftpPasswordView" ).show();
$scope.ftpPassword = randomPassword(16);
};
$scope.usePassword = function () {
$(".ftpPasswordView" ).hide();
};
});
newapp.controller('deleteFTPAccountV2', function ($scope, $http) {
$scope.ftpAccountsOfDomain = true;
$scope.deleteFTPButton = true;
$scope.deleteFailure = true;
$scope.deleteSuccess = true;
$scope.couldNotConnect = true;
$scope.deleteFTPButtonInit = true;
$scope.getFTPAccounts = function () {
$scope.ftpAccountsOfDomain = true;
$scope.deleteFTPButton = true;
$scope.deleteFailure = true;
$scope.deleteSuccess = true;
$scope.couldNotConnect = true;
$scope.deleteFTPButtonInit = true;
var url = "/ftp/fetchFTPAccounts";
var data = {
ftpDomain: $scope.selectedDomain,
};
var config = {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
};
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
function ListInitialDatas(response) {
if (response.data.fetchStatus == 1) {
$scope.ftpAccountsFeteched = JSON.parse(response.data.data);
$scope.ftpAccountsOfDomain = false;
$scope.deleteFTPButton = true;
$scope.deleteFailure = true;
$scope.deleteSuccess = true;
$scope.couldNotConnect = true;
$scope.deleteFTPButtonInit = false;
} else {
$scope.ftpAccountsOfDomain = true;
$scope.deleteFTPButton = true;
$scope.deleteFailure = true;
$scope.deleteSuccess = true;
$scope.couldNotConnect = false;
$scope.deleteFTPButtonInit = true;
}
}
function cantLoadInitialDatas(response) {
$scope.ftpAccountsOfDomain = true;
$scope.deleteFTPButton = true;
$scope.deleteFailure = true;
$scope.deleteSuccess = true;
$scope.couldNotConnect = false;
$scope.deleteFTPButtonInit = true;
}
};
$scope.deleteFTPAccount = function () {
$scope.ftpAccountsOfDomain = false;
$scope.deleteFTPButton = false;
$scope.deleteFailure = true;
$scope.deleteSuccess = true;
$scope.couldNotConnect = true;
$scope.deleteFTPButtonInit = false;
};
$scope.deleteFTPFinal = function () {
var url = "/ftp/submitFTPDelete";
var data = {
ftpUsername: $scope.selectedFTPAccount,
};
var config = {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
};
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
function ListInitialDatas(response) {
if (response.data.deleteStatus == 1) {
$scope.ftpAccountsOfDomain = true;
$scope.deleteFTPButton = true;
$scope.deleteFailure = true;
$scope.deleteSuccess = false;
$scope.couldNotConnect = true;
$scope.deleteFTPButtonInit = true;
$scope.ftpUserNameDeleted = $scope.selectedFTPAccount;
} else {
$scope.ftpAccountsOfDomain = true;
$scope.deleteFTPButton = true;
$scope.deleteFailure = false;
$scope.deleteSuccess = true;
$scope.couldNotConnect = true;
$scope.deleteFTPButtonInit = false;
$scope.errorMessage = response.data.error_message;
}
}
function cantLoadInitialDatas(response) {
$scope.ftpAccountsOfDomain = true;
$scope.deleteFTPButton = true;
$scope.deleteFailure = false;
$scope.deleteSuccess = true;
$scope.couldNotConnect = false;
$scope.deleteFTPButtonInit = true;
}
};
});
newapp.controller('listFTPAccountsV2', function ($scope, $http) {
$scope.recordsFetched = true;
$scope.passwordChanged = true;
$scope.canNotChangePassword = true;
$scope.couldNotConnect = true;
$scope.ftpLoading = true;
$scope.ftpAccounts = true;
$scope.changePasswordBox = true;
$scope.notificationsBox = true;
var globalFTPUsername = "";
$scope.fetchFTPAccounts = function () {
populateCurrentRecords();
};
$scope.changePassword = function (ftpUsername) {
$scope.recordsFetched = true;
$scope.passwordChanged = true;
$scope.canNotChangePassword = true;
$scope.couldNotConnect = true;
$scope.ftpLoading = true;
$scope.changePasswordBox = false;
$scope.notificationsBox = true;
$scope.ftpUsername = ftpUsername;
globalFTPUsername = ftpUsername;
};
$scope.changePasswordBtn = function () {
$scope.ftpLoading = false;
url = "/ftp/changePassword";
var data = {
ftpUserName: globalFTPUsername,
passwordByPass: $scope.ftpPassword,
};
var config = {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
};
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
function ListInitialDatas(response) {
if (response.data.changePasswordStatus == 1) {
$scope.notificationsBox = false;
$scope.passwordChanged = false;
$scope.ftpLoading = true;
$scope.domainFeteched = $scope.selectedDomain;
} else {
$scope.notificationsBox = false;
$scope.canNotChangePassword = false;
$scope.ftpLoading = true;
$scope.canNotChangePassword = false;
$scope.errorMessage = response.data.error_message;
}
}
function cantLoadInitialDatas(response) {
$scope.notificationsBox = false;
$scope.couldNotConnect = false;
$scope.ftpLoading = true;
}
};
function populateCurrentRecords() {
$scope.recordsFetched = true;
$scope.passwordChanged = true;
$scope.canNotChangePassword = true;
$scope.couldNotConnect = true;
$scope.ftpLoading = false;
$scope.ftpAccounts = true;
$scope.changePasswordBox = true;
var selectedDomain = $scope.selectedDomain;
url = "/ftp/getAllFTPAccounts";
var data = {
selectedDomain: selectedDomain,
};
var config = {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
};
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
function ListInitialDatas(response) {
if (response.data.fetchStatus == 1) {
$scope.records = JSON.parse(response.data.data);
$scope.notificationsBox = false;
$scope.recordsFetched = false;
$scope.passwordChanged = true;
$scope.canNotChangePassword = true;
$scope.couldNotConnect = true;
$scope.ftpLoading = true;
$scope.ftpAccounts = false;
$scope.changePasswordBox = true;
$scope.domainFeteched = $scope.selectedDomain;
} else {
$scope.notificationsBox = false;
$scope.recordsFetched = true;
$scope.passwordChanged = true;
$scope.canNotChangePassword = true;
$scope.couldNotConnect = true;
$scope.ftpLoading = true;
$scope.ftpAccounts = true;
$scope.changePasswordBox = true;
$scope.errorMessage = response.data.error_message;
}
}
function cantLoadInitialDatas(response) {
$scope.notificationsBox = false;
$scope.recordsFetched = true;
$scope.passwordChanged = true;
$scope.canNotChangePassword = true;
$scope.couldNotConnect = false;
$scope.ftpLoading = true;
$scope.ftpAccounts = true;
$scope.changePasswordBox = true;
}
}
////
$scope.generatedPasswordView = true;
$scope.generatePassword = function () {
$scope.generatedPasswordView = false;
$scope.ftpPassword = randomPassword(16);
};
$scope.usePassword = function () {
$scope.generatedPasswordView = true;
};
});

View File

@@ -0,0 +1,114 @@
{% extends "baseTemplate/newBase.html" %}
{% load i18n %}
{% block titleNew %}{% trans "Home - CyberPanel" %}{% endblock %}
{% block newContent %}
{% load static %}
<div ng-controller="createFTPAccountV2" class="p-8">
<div>
<p class="text-4xl font-bold">Create FTP Account</p>
<p class="text-xs text-gray-600 py-2 font-semibold">Select the website from list, and its home directory
will be set as the path to ftp account.</p>
</div>
<div>
<div class="py-4">
<p class="text-xl font-bold">Create FTP Account</p>
<img ng-hide="ftpLoading" src="{% static 'images/loading.gif' %}">
</div>
<hr>
{% if not status %}
<div class="col-md-12 text-center" style="margin-bottom: 2%;">
<h3>{% trans "PureFTPD is disabled." %}
<a href="{% url 'managePureFtpd' %}">
<button class="btn btn-alt btn-hover btn-blue-alt">
<span>{% trans "Enable Now" %}</span>
<i class="glyph-icon icon-arrow-right"></i>
</button>
</a></h3>
</div>
{% else %}
<div>
<div class="flex mt-4 py-2 px-6">
<div>
<p class="font-semibold w-60">Select Website</p>
</div>
<div>
<select ng-model="ftpDomain"
class="w-80 bg-gray-100 rounded px-2 py-1 create-ftp-acct-select">
{% for items in websiteList %}
<option>{{ items }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="flex py-2 px-6 ftpDetails">
<div>
<p class="font-semibold w-60">User Name</p>
</div>
<div>
<input ng-change="hideFewDetails()" type="text" class="w-80 bg-gray-100 rounded px-2 py-1"
ng-model="ftpUserName" required>
</div>
<div class="text-orange-500 font-semibold ml-3">
<p>{{ OwnerFTP }}_{$ ftpUserName $}</p>
</div>
</div>
<div class="flex py-2 px-6 ftpDetails">
<div>
<p class="font-semibold w-60">FTP Password</p>
</div>
<div>
<input type="password" class="w-80 bg-gray-100 rounded px-2 py-1" ng-model="ftpPassword"
required>
</div>
<div class="w-80 ml-4">
<button ng-click="generatePassword()"
class="bg-orange-500 text-white font-semibold px-2 py-1">
Generate
</button>
</div>
</div>
<div>
<div class="flex py-2 px-6 ftpPasswordView">
<div>
<p class="font-semibold w-60">Generated Password</p>
</div>
<div>
<input type="text" name="email" class="w-80 bg-gray-100 rounded px-2 py-1"
ng-model="ftpPassword"
required>
</div>
<div class="w-80 ml-4">
<button ng-click="usePassword()"
class="bg-orange-500 text-white font-semibold px-2 py-1">
Use
</button>
</div>
</div>
</div>
<div>
<div ng-hide="ftpDetails" class="flex py-2 px-6 ftpDetails">
<div>
<p class="font-semibold w-60">Path (Relative)</p>
</div>
<div>
<input placeholder="{% trans 'Leave empty to select default home directory.' %}"
type="text" class="w-80 bg-gray-100 rounded px-2 py-1" ng-model="ftpPath"
required>
</div>
</div>
</div>
<div class="flex justify-center mt-6 dbDetails">
<button ng-click="createFTPAccount()"
class="bg-orange-500 text-white font-bold px-4 py-2 text-xl">
Create FTP
</button>
</div>
</div>
</div>
{% endif %}
</div>
{% endblock %}

View File

@@ -0,0 +1,89 @@
{% extends "baseTemplate/newBase.html" %}
{% load i18n %}
{% block titleNew %}{% trans "Home - CyberPanel" %}{% endblock %}
{% block newContent %}
{% load static %}
<div ng-controller="deleteFTPAccountV2" class="p-8">
<div>
<p class="text-4xl font-bold">Delete FTP Account</p>
<p class="text-xs text-gray-600 py-2 font-semibold">Select domain and delete its related FTP accounts.</p>
</div>
<div>
<div class="py-4">
<p class="text-xl font-bold">Delete FTP Account</p>
</div>
<hr>
{% if not status %}
<div class="col-md-12 text-center" style="margin-bottom: 2%;">
<h3>{% trans "PureFTPD is disabled." %}
<a href="{% url 'managePureFtpd' %}">
<button class="btn btn-alt btn-hover btn-blue-alt">
<span>{% trans "Enable Now" %}</span>
<i class="glyph-icon icon-arrow-right"></i>
</button>
</a></h3>
</div>
{% else %}
<div>
<div class="flex mt-4 py-2 px-6">
<div>
<p class="font-semibold w-60">Select Domain</p>
</div>
<div>
<select ng-change="getFTPAccounts()" ng-model="selectedDomain"
class="w-80 bg-gray-100 rounded px-2 py-1">
{% for items in websiteList %}
<option>{{ items }}</option>
{% endfor %}
</select>
</div>
</div>
<div ng-hide="ftpAccountsOfDomain" class="flex mt-4 py-2 px-6">
<div>
<p class="font-semibold w-60">Select FTP Account</p>
</div>
<div>
<select ng-model="selectedFTPAccount" class="w-80 bg-gray-100 rounded px-2 py-1">
<option ng-repeat="ftpAcct in ftpAccountsFeteched track by $index">{$ ftpAcct.userName
$}
</option>
</select>
</div>
</div>
<div ng-hide="deleteFTPButtonInit" class="flex justify-center mt-6">
<button ng-click="deleteFTPAccount()"
class="bg-orange-500 text-white font-bold px-4 py-2 text-xl">
Delete FTP Account
</button>
</div>
<div ng-hide="deleteFTPButton" class="flex justify-center mt-6">
<button type="button" ng-click="deleteFTPFinal()"
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 ng-hide="deleteFailure"
class="flex justify-center bg-red-500 rounded-lg text-white px-2 py-1 font-semibold">
<p>{% trans "Cannot delete account. Error message:" %} {$ errorMessage $}</p>
</div>
<div ng-hide="deleteSuccess"
class="flex justify-center bg-green-500 px-2 rounded-lg py-1 font-semibold">
<p>{% trans "FTP Account with username:" %} <strong>{$ ftpUserNameDeleted
$}</strong>{% trans " is successfully deleted." %}</p>
</div>
<div ng-hide="couldNotConnect"
class="flex justify-center bg-red-500 rounded-lg text-white px-2 py-1 font-semibold">
<p>{% trans "Could not connect to the server. Please refresh this page." %}</p>
</div>
</div>
</div>
</div>
{% endif %}
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,161 @@
{% extends "baseTemplate/newBase.html" %}
{% load i18n %}
{% block titleNew %}{% trans "Home - CyberPanel" %}{% endblock %}
{% block newContent %}
{% load static %}
<div ng-controller="listFTPAccountsV2" class="p-8">
<div class="flex lg:flex-row justify-between items-center sm:flex-col">
<div>
<p class="text-4xl font-bold">List FTP Accounts</p>
<p class="text-xs text-gray-600 py-2 font-semibold">List FTP Accounts or change their passwords.</p>
</div>
</div>
<div class="py-4">
<p class="text-xl font-bold">List FTP Accounts</p>
<img ng-hide="ftpLoading" src="{% static 'images/loading.gif' %}">
</div>
{% if not status %}
<div class="col-md-12 text-center" style="margin-bottom: 2%;">
<h3>{% trans "PureFTPD is disabled." %}
<a href="{% url 'managePureFtpd' %}">
<button class="btn btn-alt btn-hover btn-blue-alt">
<span>{% trans "Enable Now" %}</span>
<i class="glyph-icon icon-arrow-right"></i>
</button>
</a></h3>
</div>
{% else %}
<hr>
<div class="flex mt-4 py-2 px-6">
<div>
<p class="font-semibold w-60">Select Domain</p>
</div>
<div>
<select ng-change="fetchFTPAccounts()" ng-model="selectedDomain"
class="w-80 bg-gray-100 rounded px-2 py-1">
{% for items in websiteList %}
<option>{{ items }}</option>
{% endfor %}
</select>
</div>
</div>
<hr>
<div ng-hide="notificationsBox" class="py-4">
<div class="col-sm-6">
<div ng-hide="recordsFetched"
class="flex justify-center bg-green-500 px-2 rounded-lg py-1 font-semibold">
<p>{% trans "Records successfully fetched for" %} <strong>{$ domainFeteched
$}</strong></p>
</div>
<div ng-hide="passwordChanged"
class="flex justify-center bg-green-500 px-2 rounded-lg py-1 font-semibold">
<p>{% trans "Password changed for" %} <strong>{$ ftpUsername $}</strong></p>
</div>
<div ng-hide="canNotChangePassword"
class="flex justify-center bg-red-500 rounded-lg text-white px-2 py-1 font-semibold">
<p>{% trans "Cannot change password for <strong>{$ ftpUsername $}</strong>. Error message:" %}
{$ errorMessage $}</p>
</div>
<div ng-hide="couldNotConnect"
class="flex justify-center bg-red-500 rounded-lg text-white px-2 py-1 font-semibold">
<p>{% trans "Could Not Connect to server. Please refresh this page" %}</p>
</div>
</div>
</div>
<hr>
<div ng-hide="changePasswordBox" class="mb-3">
<div class="flex py-2 px-6 dbDetails">
<div>
<p class="font-semibold w-60">{$ ftpUsername $}</p>
</div>
<div>
<input name="dom" type="password" class="w-80 bg-gray-100 rounded px-2 py-1"
ng-model="ftpPassword"
required>
</div>
<div class="w-80 ml-4">
<button ng-click="generatePassword()" class="bg-orange-500 text-white font-semibold px-2 py-1">
Generate
</button>
</div>
</div>
<div>
<div ng-hide="generatedPasswordView" class="flex py-2 px-6">
<div>
<p class="font-semibold w-60">Generated Password</p>
</div>
<div>
<input name="dom" type="text" class="w-80 bg-gray-100 rounded px-2 py-1"
ng-model="ftpPassword" required>
</div>
<div class="w-80 ml-4">
<button ng-click="usePassword()"
class="bg-orange-500 text-white font-semibold px-2 py-1">
Use
</button>
</div>
</div>
</div>
<div class="flex justify-center mt-6">
<button ng-click="changePasswordBtn()"
class="bg-orange-500 text-white font-bold px-4 py-2 text-xl">
Change Password
</button>
</div>
</div>
<hr>
<div ng-hide="ftpAccounts" 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">
ID
</th>
<th scope="col" class="px-6 py-3">
User Name
</th>
<th scope="col" class="px-6 py-3">
Directory
</th>
<th scope="col" class="px-6 py-3">
Size
</th>
<th scope="col" class="px-6 py-3">
Password
</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.id" class="px-6 py-4">
</td>
<td ng-bind="record.user" class="px-6 py-4">
</td>
<td class="px-6 py-4">
<div class="flex">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor" class="w-6 h-6">
<path stroke-linecap="round" stroke-linejoin="round"
d="M2.25 12.75V12A2.25 2.25 0 0 1 4.5 9.75h15A2.25 2.25 0 0 1 21.75 12v.75m-8.69-6.44-2.12-2.12a1.5 1.5 0 0 0-1.061-.44H4.5A2.25 2.25 0 0 0 2.25 6v12a2.25 2.25 0 0 0 2.25 2.25h15A2.25 2.25 0 0 0 21.75 18V9a2.25 2.25 0 0 0-2.25-2.25h-5.379a1.5 1.5 0 0 1-1.06-.44Z"/>
</svg>
<span class="ml-2">{$ record.dir $}</span>
</div>
</td>
<td ng-bind="record.quotasize" class="px-6 py-4">
</td>
<td class="px-6 py-4">
<button type="button" ng-click="changePassword(record.user)"
class="bg-orange-500 text-white font-semibold px-2 py-1">{% trans "Change" %}</button>
</td>
</tr>
</tbody>
</table>
</div>
{% endif %}
</div>
{% endblock %}

View File

@@ -4,17 +4,19 @@ from . import views
urlpatterns = [
url(r'^$', views.loadFTPHome, name='loadFTPHome'),
url(r'^createFTPAccount', views.createFTPAccount, name='createFTPAccount'),
url(r'^V2/createFTPAccountV2', views.createFTPAccountV2, name='createFTPAccountV2'),
url(r'^submitFTPCreation', views.submitFTPCreation, name='ftpHome'),
url(r'^deleteFTPAccount', views.deleteFTPAccount, name='deleteFTPAccount'),
url(r'^V2/deleteFTPAccountV2', views.deleteFTPAccountV2, name='deleteFTPAccountV2'),
url(r'^fetchFTPAccounts', views.fetchFTPAccounts, name='fetchFTPAccounts'),
url(r'^submitFTPDelete', views.submitFTPDelete, name='submitFTPDelete'),
url(r'^listFTPAccounts', views.listFTPAccounts, name='listFTPAccounts'),
url(r'^V2/listFTPAccountsV2', views.listFTPAccountsV2, name='listFTPAccountsV2'),
url(r'^getAllFTPAccounts', views.getAllFTPAccounts, name='getAllFTPAccounts'),
url(r'^changePassword', views.changePassword, name='changePassword'),
]

View File

@@ -4,6 +4,8 @@ from django.shortcuts import redirect
from .ftpManager import FTPManager
from loginSystem.views import loadLoginPage
from .pluginManager import pluginManager
# Create your views here.
def loadFTPHome(request):
@@ -13,6 +15,7 @@ def loadFTPHome(request):
except KeyError:
return redirect(loadLoginPage)
def createFTPAccount(request):
try:
@@ -21,7 +24,7 @@ def createFTPAccount(request):
return result
fm = FTPManager(request)
coreResult = fm.createFTPAccount()
coreResult = fm.createFTPAccount()
result = pluginManager.postCreateFTPAccount(request, coreResult)
if result != 200:
@@ -32,6 +35,27 @@ def createFTPAccount(request):
except KeyError:
return redirect(loadLoginPage)
def createFTPAccountV2(request):
try:
result = pluginManager.preCreateFTPAccount(request)
if result != 200:
return result
fm = FTPManager(request)
coreResult = fm.createFTPAccountV2()
result = pluginManager.postCreateFTPAccount(request, coreResult)
if result != 200:
return result
return coreResult
except KeyError:
return redirect(loadLoginPage)
def submitFTPCreation(request):
try:
@@ -51,6 +75,7 @@ def submitFTPCreation(request):
except KeyError:
return redirect(loadLoginPage)
def deleteFTPAccount(request):
try:
fm = FTPManager(request)
@@ -58,6 +83,15 @@ def deleteFTPAccount(request):
except KeyError:
return redirect(loadLoginPage)
def deleteFTPAccountV2(request):
try:
fm = FTPManager(request)
return fm.deleteFTPAccountV2()
except KeyError:
return redirect(loadLoginPage)
def fetchFTPAccounts(request):
try:
fm = FTPManager(request)
@@ -65,6 +99,7 @@ def fetchFTPAccounts(request):
except KeyError:
return redirect(loadLoginPage)
def submitFTPDelete(request):
try:
@@ -84,6 +119,7 @@ def submitFTPDelete(request):
except KeyError:
return redirect(loadLoginPage)
def listFTPAccounts(request):
try:
fm = FTPManager(request)
@@ -91,6 +127,15 @@ def listFTPAccounts(request):
except KeyError:
return redirect(loadLoginPage)
def listFTPAccountsV2(request):
try:
fm = FTPManager(request)
return fm.listFTPAccountsV2()
except KeyError:
return redirect(loadLoginPage)
def getAllFTPAccounts(request):
try:
fm = FTPManager(request)
@@ -98,6 +143,7 @@ def getAllFTPAccounts(request):
except KeyError:
return redirect(loadLoginPage)
def changePassword(request):
try:
@@ -115,4 +161,4 @@ def changePassword(request):
return coreResult
except KeyError:
return redirect(loadLoginPage)
return redirect(loadLoginPage)

View File

@@ -203,7 +203,6 @@ urlpatterns = [
### Apache Manager
url(r'^ApacheManager/(?P<domain>(.*))$', views.ApacheManager, name='ApacheManager'),
url(r'^getSwitchStatus$', views.getSwitchStatus, name='getSwitchStatus'),
url(r'^switchServer$', views.switchServer, name='switchServer'),
url(r'^statusFunc$', views.statusFunc, name='statusFunc'),