diff --git a/IncBackups/__init__.py b/IncBackups/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/IncBackups/admin.py b/IncBackups/admin.py
new file mode 100644
index 000000000..13be29d96
--- /dev/null
+++ b/IncBackups/admin.py
@@ -0,0 +1,6 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.contrib import admin
+
+# Register your models here.
diff --git a/IncBackups/apps.py b/IncBackups/apps.py
new file mode 100644
index 000000000..5511373f4
--- /dev/null
+++ b/IncBackups/apps.py
@@ -0,0 +1,8 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.apps import AppConfig
+
+
+class IncbackupsConfig(AppConfig):
+ name = 'IncBackups'
diff --git a/IncBackups/migrations/__init__.py b/IncBackups/migrations/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/IncBackups/models.py b/IncBackups/models.py
new file mode 100644
index 000000000..1dfab7604
--- /dev/null
+++ b/IncBackups/models.py
@@ -0,0 +1,6 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import models
+
+# Create your models here.
diff --git a/IncBackups/static/IncBackups/IncBackups.js b/IncBackups/static/IncBackups/IncBackups.js
new file mode 100644
index 000000000..a144ea0dd
--- /dev/null
+++ b/IncBackups/static/IncBackups/IncBackups.js
@@ -0,0 +1,417 @@
+//*** Backup site ****//
+
+app.controller('createIncrementalBackups', function ($scope, $http, $timeout) {
+
+ $scope.destination = true;
+ $scope.backupButton = true;
+ $scope.cyberpanelLoading = 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.cyberpanelLoadingBottom = 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.cyberpanelLoadingBottom = true;
+ $scope.destination = false;
+ $scope.runningBackup = false;
+ $scope.cancelButton = true;
+ $scope.backupButton = false;
+ $scope.cyberpanelLoading = 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.cyberpanelLoadingBottom = true;
+ $scope.cyberpanelLoading = 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 websiteToBeBacked = $scope.websiteToBeBacked;
+ $scope.cyberpanelLoading = false;
+
+
+ url = "/backup/submitBackupCreation";
+
+ 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.metaStatus === 1) {
+ getBackupStatus();
+ }
+
+ }
+
+ function cantLoadInitialDatas(response) {
+ }
+
+ };
+
+
+ $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) {
+
+
+ }
+
+
+ };
+
+
+});
+
+///** Backup site ends **///
+
+
+app.controller('incrementalDestinations', function ($scope, $http) {
+ $scope.cyberpanelLoading = true;
+ $scope.sftpHide = true;
+ $scope.awsHide = true;
+
+ $scope.fetchDetails = function () {
+
+ if ($scope.destinationType === 'SFTP') {
+ $scope.sftpHide = false;
+ $scope.populateCurrentRecords();
+ } else {
+ $scope.sftpHide = true;
+ $scope.awsHide = false;
+ $scope.populateCurrentRecords();
+ }
+ };
+
+ $scope.populateCurrentRecords = function () {
+
+ $scope.cyberpanelLoading = false;
+
+
+ url = "/IncrementalBackups/populateCurrentRecords";
+
+ var type = 'SFTP';
+ if ($scope.destinationType === 'SFTP'){
+ type = 'SFTP';
+ }else{
+ type = 'AWS';
+ }
+
+ var data = {
+ type: type
+ };
+
+ 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);
+ } else {
+ new PNotify({
+ title: 'Operation Failed!',
+ text: response.data.error_message,
+ type: 'error'
+ });
+ }
+
+ }
+
+ function cantLoadInitialDatas(response) {
+ $scope.cyberpanelLoading = true;
+ new PNotify({
+ title: 'Operation Failed!',
+ text: 'Could not connect to server, please refresh this page',
+ type: 'error'
+ });
+ }
+
+ };
+
+ $scope.addDestination = function (type) {
+ $scope.cyberpanelLoading = false;
+
+
+ url = "/IncrementalBackups/addDestination";
+
+ if(type === 'SFTP'){
+ var data = {
+ type: type,
+ IPAddress: $scope.IPAddress,
+ password: $scope.password,
+ backupSSHPort: $scope.backupSSHPort
+ };
+ }else {
+ var data = {
+ type: type,
+ AWS_ACCESS_KEY_ID: $scope.AWS_ACCESS_KEY_ID,
+ AWS_SECRET_ACCESS_KEY: $scope.AWS_SECRET_ACCESS_KEY,
+ };
+ }
+
+ var config = {
+ headers: {
+ 'X-CSRFToken': getCookie('csrftoken')
+ }
+ };
+
+
+ $http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
+
+
+ function ListInitialDatas(response) {
+ $scope.cyberpanelLoading = true;
+ $scope.populateCurrentRecords();
+ if (response.data.status === 1) {
+ new PNotify({
+ title: 'Success!',
+ text: 'Destination successfully added.',
+ type: 'success'
+ });
+ } else {
+ new PNotify({
+ title: 'Operation Failed!',
+ text: response.data.error_message,
+ type: 'error'
+ });
+ }
+
+ }
+
+ function cantLoadInitialDatas(response) {
+ $scope.cyberpanelLoading = true;
+ new PNotify({
+ title: 'Operation Failed!',
+ text: 'Could not connect to server, please refresh this page',
+ type: 'error'
+ });
+ }
+
+ };
+
+ $scope.removeDestination = function (type, ipAddress) {
+ $scope.cyberpanelLoading = false;
+
+
+ url = "/IncrementalBackups/removeDestination";
+
+ var data = {
+ type: type,
+ IPAddress: ipAddress,
+ };
+
+ var config = {
+ headers: {
+ 'X-CSRFToken': getCookie('csrftoken')
+ }
+ };
+
+
+ $http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
+
+
+ function ListInitialDatas(response) {
+ $scope.cyberpanelLoading = true;
+ $scope.populateCurrentRecords();
+ if (response.data.status === 1) {
+ new PNotify({
+ title: 'Success!',
+ text: 'Destination successfully removed.',
+ type: 'success'
+ });
+ } else {
+ new PNotify({
+ title: 'Operation Failed!',
+ text: response.data.error_message,
+ type: 'error'
+ });
+ }
+
+ }
+
+ function cantLoadInitialDatas(response) {
+ $scope.cyberpanelLoading = true;
+ new PNotify({
+ title: 'Operation Failed!',
+ text: 'Could not connect to server, please refresh this page',
+ type: 'error'
+ });
+ }
+
+ };
+
+
+});
\ No newline at end of file
diff --git a/IncBackups/templates/IncBackups/createBackup.html b/IncBackups/templates/IncBackups/createBackup.html
new file mode 100755
index 000000000..23a65a281
--- /dev/null
+++ b/IncBackups/templates/IncBackups/createBackup.html
@@ -0,0 +1,186 @@
+
+{% extends "baseTemplate/index.html" %}
+{% load i18n %}
+{% block title %}{% trans "Create Incremental Backup" %}{% endblock %}
+{% block content %}
+
+{% load static %}
+
+{% get_current_language as LANGUAGE_CODE %}
+
+
+
+
+
+
{% trans "This page can be used to create incremental backups for your websites." %}
+
+
+
+
+
+ {% trans "Back up Website" %}
+
+
+
+
+
+
+
+
+
+{% endblock %}
\ No newline at end of file
diff --git a/IncBackups/templates/IncBackups/incrementalDestinations.html b/IncBackups/templates/IncBackups/incrementalDestinations.html
new file mode 100755
index 000000000..602cad196
--- /dev/null
+++ b/IncBackups/templates/IncBackups/incrementalDestinations.html
@@ -0,0 +1,186 @@
+{% extends "baseTemplate/index.html" %}
+{% load i18n %}
+{% block title %}{% trans "Set up Back up Destinations" %}{% endblock %}
+{% block content %}
+
+ {% load static %}
+
+
+ {% get_current_language as LANGUAGE_CODE %}
+
+
+
+
+
{% trans "Set up Incremental Back up Destinations" %} - {% trans "Remote Backups" %}
+
+
{% trans "On this page you can set up your Back up destinations. (SFTP and AWS)" %}
+
+
+
+
+
+ {% trans "Set up Back up Destinations." %}
+
+
+
+
+
+
+
+
+
+{% endblock %}
\ No newline at end of file
diff --git a/IncBackups/tests.py b/IncBackups/tests.py
new file mode 100644
index 000000000..5982e6bcd
--- /dev/null
+++ b/IncBackups/tests.py
@@ -0,0 +1,6 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.test import TestCase
+
+# Create your tests here.
diff --git a/IncBackups/urls.py b/IncBackups/urls.py
new file mode 100644
index 000000000..e1fab2ab1
--- /dev/null
+++ b/IncBackups/urls.py
@@ -0,0 +1,11 @@
+from django.conf.urls import url
+import views
+
+urlpatterns = [
+ url(r'^createBackup$', views.createBackup, name='createBackupInc'),
+ url(r'^backupDestinations$', views.backupDestinations, name='backupDestinationsInc'),
+ url(r'^addDestination$', views.addDestination, name='addDestinationInc'),
+ url(r'^populateCurrentRecords$', views.populateCurrentRecords, name='populateCurrentRecordsInc'),
+ url(r'^removeDestination$', views.removeDestination, name='removeDestinationInc'),
+
+]
\ No newline at end of file
diff --git a/IncBackups/views.py b/IncBackups/views.py
new file mode 100644
index 000000000..37a429bc4
--- /dev/null
+++ b/IncBackups/views.py
@@ -0,0 +1,245 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.shortcuts import render
+from plogical.acl import ACLManager
+from django.shortcuts import HttpResponse
+from plogical.processUtilities import ProcessUtilities
+from plogical.virtualHostUtilities import virtualHostUtilities
+import json
+import os
+# Create your views here.
+
+
+def defRenderer(request, templateName, args):
+ return render(request, templateName, args)
+
+def createBackup(request):
+ try:
+ userID = request.session['userID']
+ currentACL = ACLManager.loadedACL(userID)
+
+ if ACLManager.currentContextPermission(currentACL, 'createBackup') == 0:
+ return ACLManager.loadError()
+
+ websitesName = ACLManager.findAllSites(currentACL, userID)
+ return defRenderer(request, 'IncBackups/createBackup.html', {'websiteList': websitesName})
+ except BaseException, msg:
+ return HttpResponse(str(msg))
+
+def backupDestinations(request):
+ try:
+ userID = request.session['userID']
+ currentACL = ACLManager.loadedACL(userID)
+
+ if ACLManager.currentContextPermission(currentACL, 'addDeleteDestinations') == 0:
+ return ACLManager.loadError()
+
+ return defRenderer(request, 'IncBackups/incrementalDestinations.html', {})
+ except BaseException, msg:
+ return HttpResponse(str(msg))
+
+def addDestination(request):
+ try:
+ userID = request.session['userID']
+ currentACL = ACLManager.loadedACL(userID)
+
+ if ACLManager.currentContextPermission(currentACL, 'addDeleteDestinations') == 0:
+ return ACLManager.loadErrorJson('destStatus', 0)
+
+ data = json.loads(request.body)
+
+
+
+ if data['type'] == 'SFTP':
+
+ ipAddress = data['IPAddress']
+ password = data['password']
+
+ ipFile = '/home/cyberpanel/sftp/%s' % (ipAddress)
+
+ try:
+ port = data['backupSSHPort']
+ except:
+ port = "22"
+
+ if os.path.exists(ipFile):
+ final_dic = {'status': 0, 'error_message': 'This destination already exists.'}
+ final_json = json.dumps(final_dic)
+ return HttpResponse(final_json)
+
+
+ try:
+ os.mkdir('/home/cyberpanel/sftp')
+ except:
+ pass
+
+
+ execPath = "/usr/local/CyberCP/bin/python2 " + virtualHostUtilities.cyberPanel + "/plogical/backupUtilities.py"
+ execPath = execPath + " submitDestinationCreation --ipAddress " + ipAddress + " --password " \
+ + password + " --port " + port
+
+ output = ProcessUtilities.outputExecutioner(execPath)
+
+ if output.find('1,') > -1:
+
+ content = '%s\n%s' % (ipAddress, port)
+ writeToFile = open(ipFile, 'w')
+ writeToFile.write(content)
+ writeToFile.close()
+
+ command = 'cat /root/.ssh/config'
+ currentConfig = ProcessUtilities.outputExecutioner(command)
+
+ tmpFile = '/home/cyberpanel/sshconfig'
+
+ writeToFile = open(tmpFile, 'w')
+ writeToFile.write(currentConfig)
+
+ content = """Host %s
+ IdentityFile ~/.ssh/cyberpanel
+ Port %s
+ """ % (ipAddress, port)
+ writeToFile.write(content)
+ writeToFile.close()
+
+
+ command = 'mv %s /root/.ssh/config' % (tmpFile)
+ ProcessUtilities.executioner(command)
+
+ command = 'chown root:root /root/.ssh/config'
+ ProcessUtilities.executioner(command)
+
+ final_dic = {'status': 1, 'error_message': 'None'}
+ final_json = json.dumps(final_dic)
+ return HttpResponse(final_json)
+
+
+ else:
+ final_dic = {'status': 0, 'error_message': output}
+ final_json = json.dumps(final_dic)
+ return HttpResponse(final_json)
+ else:
+ aws = '/home/cyberpanel/aws'
+
+ try:
+ os.mkdir(aws)
+ except:
+ pass
+
+ AWS_ACCESS_KEY_ID = data['AWS_ACCESS_KEY_ID']
+ AWS_SECRET_ACCESS_KEY = data['AWS_SECRET_ACCESS_KEY']
+
+ awsFile = '/home/cyberpanel/aws/%s' % (AWS_ACCESS_KEY_ID)
+
+ writeToFile = open(awsFile, 'w')
+ writeToFile.write(AWS_SECRET_ACCESS_KEY)
+ writeToFile.close()
+
+ final_dic = {'status': 1}
+ final_json = json.dumps(final_dic)
+ return HttpResponse(final_json)
+
+
+
+
+ except BaseException, msg:
+ final_dic = {'status': 0, 'error_message': str(msg)}
+ final_json = json.dumps(final_dic)
+ return HttpResponse(final_json)
+
+def populateCurrentRecords(request):
+ try:
+ userID = request.session['userID']
+ currentACL = ACLManager.loadedACL(userID)
+
+ if ACLManager.currentContextPermission(currentACL, 'addDeleteDestinations') == 0:
+ return ACLManager.loadErrorJson('fetchStatus', 0)
+
+ data = json.loads(request.body)
+
+ if data['type'] == 'SFTP':
+
+ path = '/home/cyberpanel/sftp'
+
+ if os.path.exists(path):
+
+ json_data = "["
+ checker = 0
+
+ for items in os.listdir(path):
+ fullPath = '/home/cyberpanel/sftp/%s' % (items)
+
+ data = open(fullPath, 'r').readlines()
+ dic = {
+ 'ip': data[0].strip('\n'),
+ 'port': data[1],
+ }
+
+ if checker == 0:
+ json_data = json_data + json.dumps(dic)
+ checker = 1
+ else:
+ json_data = json_data + ',' + json.dumps(dic)
+ else:
+ final_json = json.dumps({'status': 1, 'error_message': "None", "data": ''})
+ return HttpResponse(final_json)
+ else:
+ path = '/home/cyberpanel/aws'
+
+ if os.path.exists(path):
+
+ json_data = "["
+ checker = 0
+
+ for items in os.listdir(path):
+ dic = {
+ 'AWS_ACCESS_KEY_ID': items
+ }
+
+ if checker == 0:
+ json_data = json_data + json.dumps(dic)
+ checker = 1
+ else:
+ json_data = json_data + ',' + json.dumps(dic)
+ else:
+ final_json = json.dumps({'status': 1, 'error_message': "None", "data": ''})
+ return HttpResponse(final_json)
+
+ json_data = json_data + ']'
+ final_json = json.dumps({'status': 1, 'error_message': "None", "data": json_data})
+ return HttpResponse(final_json)
+
+ except BaseException, msg:
+ final_dic = {'status': 0, 'error_message': str(msg)}
+ final_json = json.dumps(final_dic)
+ return HttpResponse(final_json)
+
+def removeDestination(request):
+ try:
+ userID = request.session['userID']
+ currentACL = ACLManager.loadedACL(userID)
+
+ if ACLManager.currentContextPermission(currentACL, 'addDeleteDestinations') == 0:
+ return ACLManager.loadErrorJson('destStatus', 0)
+
+ data = json.loads(request.body)
+
+ ipAddress = data['IPAddress']
+
+ if data['type'] == 'SFTP':
+ ipFile = '/home/cyberpanel/sftp/%s' % (ipAddress)
+ else:
+ ipFile = '/home/cyberpanel/aws/%s' % (ipAddress)
+
+
+ os.remove(ipFile)
+
+ final_dic = {'status': 1, 'error_message': 'None'}
+ final_json = json.dumps(final_dic)
+ return HttpResponse(final_json)
+
+ except BaseException, msg:
+ final_dic = {'destStatus': 0, 'error_message': str(msg)}
+ final_json = json.dumps(final_dic)
+ return HttpResponse(final_json)
\ No newline at end of file
diff --git a/plogical/backupUtilities.py b/plogical/backupUtilities.py
index 1c0a170c5..1ac44073e 100755
--- a/plogical/backupUtilities.py
+++ b/plogical/backupUtilities.py
@@ -752,6 +752,7 @@ class backupUtilities:
expectation.append("password:")
expectation.append("Password:")
expectation.append("Permission denied")
+ expectation.append("100%")
command = "scp -o StrictHostKeyChecking=no -P "+ port +" /root/.ssh/cyberpanel.pub root@" + IPAddress + ":/root/.ssh/authorized_keys"
setupKeys = pexpect.spawn(command, timeout=3)
@@ -770,6 +771,8 @@ class backupUtilities:
setupKeys.wait()
elif index == 2:
return [0, 'Please enable password authentication on your remote server.']
+ elif index == 3:
+ pass
else:
raise BaseException
@@ -802,6 +805,7 @@ class backupUtilities:
expectation.append("password:")
expectation.append("Password:")
expectation.append("Permission denied")
+ expectation.append("File exists")
command = "ssh -o StrictHostKeyChecking=no -p "+ port +" root@"+IPAddress+' "mkdir /root/.ssh || rm -f /root/.ssh/temp && rm -f /root/.ssh/authorized_temp && cp /root/.ssh/authorized_keys /root/.ssh/temp"'
setupKeys = pexpect.spawn(command, timeout=3)
@@ -816,6 +820,8 @@ class backupUtilities:
setupKeys.sendline(password)
elif index == 2:
return [0, 'Please enable password authentication on your remote server.']
+ elif index == 3:
+ pass
else:
raise BaseException