2020-09-02 01:30:39 +00:00
|
|
|
import json
|
|
|
|
import logging
|
2021-08-19 20:50:18 +00:00
|
|
|
import tempfile
|
|
|
|
import zipfile
|
|
|
|
|
2020-09-02 01:30:39 +00:00
|
|
|
import tornado.web
|
|
|
|
import tornado.escape
|
|
|
|
import bleach
|
2021-01-15 19:59:58 +00:00
|
|
|
import os
|
2021-01-17 17:20:28 +00:00
|
|
|
import shutil
|
2021-06-02 18:47:08 +00:00
|
|
|
import html
|
2021-08-11 20:29:31 +00:00
|
|
|
import re
|
2020-09-02 01:30:39 +00:00
|
|
|
|
|
|
|
from app.classes.shared.console import console
|
|
|
|
from app.classes.shared.models import Users, installer
|
|
|
|
from app.classes.web.base_handler import BaseHandler
|
|
|
|
from app.classes.shared.models import db_helper
|
|
|
|
from app.classes.shared.helpers import helper
|
2021-08-10 20:17:56 +00:00
|
|
|
from app.classes.shared.server import ServerOutBuf
|
2020-09-02 01:30:39 +00:00
|
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
|
|
|
class AjaxHandler(BaseHandler):
|
|
|
|
|
|
|
|
def render_page(self, template, page_data):
|
|
|
|
self.render(
|
|
|
|
template,
|
2021-03-26 13:57:50 +00:00
|
|
|
data=page_data,
|
|
|
|
translate=self.translator.translate,
|
2020-09-02 01:30:39 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
@tornado.web.authenticated
|
|
|
|
def get(self, page):
|
|
|
|
user_data = json.loads(self.get_secure_cookie("user_data"))
|
|
|
|
error = bleach.clean(self.get_argument('error', "WTF Error!"))
|
|
|
|
|
|
|
|
template = "panel/denied.html"
|
|
|
|
|
|
|
|
page_data = {
|
|
|
|
'user_data': user_data,
|
|
|
|
'error': error
|
|
|
|
}
|
|
|
|
|
|
|
|
if page == "error":
|
|
|
|
template = "public/error.html"
|
|
|
|
self.render_page(template, page_data)
|
|
|
|
|
|
|
|
elif page == 'server_log':
|
|
|
|
server_id = self.get_argument('id', None)
|
2020-09-04 02:49:20 +00:00
|
|
|
full_log = self.get_argument('full', False)
|
2020-09-02 01:30:39 +00:00
|
|
|
|
|
|
|
if server_id is None:
|
|
|
|
logger.warning("Server ID not found in server_log ajax call")
|
|
|
|
self.redirect("/panel/error?error=Server ID Not Found")
|
2021-07-30 16:20:01 +00:00
|
|
|
return
|
2020-09-02 01:30:39 +00:00
|
|
|
|
|
|
|
server_id = bleach.clean(server_id)
|
|
|
|
|
|
|
|
server_data = db_helper.get_server_data_by_id(server_id)
|
|
|
|
if not server_data:
|
|
|
|
logger.warning("Server Data not found in server_log ajax call")
|
|
|
|
self.redirect("/panel/error?error=Server ID Not Found")
|
2021-08-10 20:17:56 +00:00
|
|
|
return
|
2020-09-02 01:30:39 +00:00
|
|
|
|
2021-03-22 04:02:18 +00:00
|
|
|
if not server_data['log_path']:
|
|
|
|
logger.warning("Log path not found in server_log ajax call ({})".format(server_id))
|
2020-09-02 01:30:39 +00:00
|
|
|
|
2020-09-04 02:49:20 +00:00
|
|
|
if full_log:
|
|
|
|
log_lines = helper.get_setting('max_log_lines')
|
2021-08-10 20:17:56 +00:00
|
|
|
data = helper.tail_file(server_data['log_path'], log_lines)
|
2020-09-04 02:49:20 +00:00
|
|
|
else:
|
2021-08-10 20:17:56 +00:00
|
|
|
data = ServerOutBuf.lines.get(server_id, [])
|
2020-09-04 02:49:20 +00:00
|
|
|
|
2020-09-02 01:30:39 +00:00
|
|
|
|
|
|
|
for d in data:
|
|
|
|
try:
|
2021-08-11 20:29:31 +00:00
|
|
|
d = re.sub('(\033\\[(0;)?[0-9]*[A-z]?(;[0-9])?m?)|(> )', '', d)
|
|
|
|
d = re.sub('[A-z]{2}\b\b', '', d)
|
2021-06-02 18:47:08 +00:00
|
|
|
line = helper.log_colors(html.escape(d))
|
2020-09-02 01:30:39 +00:00
|
|
|
self.write('{}<br />'.format(line))
|
|
|
|
# self.write(d.encode("utf-8"))
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
logger.warning("Skipping Log Line due to error: {}".format(e))
|
|
|
|
pass
|
|
|
|
|
2020-09-23 01:42:41 +00:00
|
|
|
elif page == "announcements":
|
|
|
|
data = helper.get_announcements()
|
|
|
|
page_data['notify_data'] = data
|
|
|
|
self.render_page('ajax/notify.html', page_data)
|
|
|
|
|
2021-01-15 19:59:58 +00:00
|
|
|
elif page == "get_file":
|
|
|
|
file_path = self.get_argument('file_path', None)
|
|
|
|
server_id = self.get_argument('id', None)
|
|
|
|
|
2021-07-30 16:20:01 +00:00
|
|
|
if not self.check_server_id(server_id, 'get_file'): return
|
2021-03-26 13:57:50 +00:00
|
|
|
else: server_id = bleach.clean(server_id)
|
2021-01-15 19:59:58 +00:00
|
|
|
|
|
|
|
if not helper.in_path(db_helper.get_server_data_by_id(server_id)['path'], file_path)\
|
2021-03-26 13:57:50 +00:00
|
|
|
or not helper.check_file_exists(os.path.abspath(file_path)):
|
2021-01-20 21:10:25 +00:00
|
|
|
logger.warning("Invalid path in get_file ajax call ({})".format(file_path))
|
|
|
|
console.warning("Invalid path in get_file ajax call ({})".format(file_path))
|
2021-07-30 16:20:01 +00:00
|
|
|
return
|
2021-03-26 13:57:50 +00:00
|
|
|
|
|
|
|
|
|
|
|
error = None
|
|
|
|
|
|
|
|
try:
|
|
|
|
with open(file_path) as file:
|
|
|
|
file_contents = file.read()
|
|
|
|
except UnicodeDecodeError:
|
|
|
|
file_contents = ''
|
|
|
|
error = 'UnicodeDecodeError'
|
|
|
|
|
|
|
|
self.write({
|
|
|
|
'content': file_contents,
|
|
|
|
'error': error
|
|
|
|
})
|
2021-01-15 19:59:58 +00:00
|
|
|
self.finish()
|
2020-09-23 01:42:41 +00:00
|
|
|
|
2021-01-17 17:20:28 +00:00
|
|
|
elif page == "get_tree":
|
|
|
|
server_id = self.get_argument('id', None)
|
|
|
|
|
2021-07-30 16:20:01 +00:00
|
|
|
if not self.check_server_id(server_id, 'get_tree'): return
|
2021-03-26 13:57:50 +00:00
|
|
|
else: server_id = bleach.clean(server_id)
|
2021-01-17 17:20:28 +00:00
|
|
|
|
|
|
|
self.write(db_helper.get_server_data_by_id(server_id)['path'] + '\n' +
|
|
|
|
helper.generate_tree(db_helper.get_server_data_by_id(server_id)['path']))
|
|
|
|
self.finish()
|
|
|
|
|
2021-01-18 15:02:38 +00:00
|
|
|
@tornado.web.authenticated
|
2020-09-22 02:01:16 +00:00
|
|
|
def post(self, page):
|
|
|
|
user_data = json.loads(self.get_secure_cookie("user_data"))
|
|
|
|
error = bleach.clean(self.get_argument('error', "WTF Error!"))
|
|
|
|
|
|
|
|
page_data = {
|
|
|
|
'user_data': user_data,
|
|
|
|
'error': error
|
|
|
|
}
|
|
|
|
|
|
|
|
if page == "send_command":
|
2021-01-17 17:20:28 +00:00
|
|
|
command = self.get_body_argument('command', default=None, strip=True)
|
|
|
|
server_id = self.get_argument('id')
|
2020-09-22 02:01:16 +00:00
|
|
|
|
|
|
|
if server_id is None:
|
|
|
|
logger.warning("Server ID not found in send_command ajax call")
|
2021-01-15 19:59:58 +00:00
|
|
|
console.warning("Server ID not found in send_command ajax call")
|
2020-09-22 02:01:16 +00:00
|
|
|
|
2021-03-22 04:02:18 +00:00
|
|
|
srv_obj = self.controller.get_server_obj(server_id)
|
2020-09-22 02:01:16 +00:00
|
|
|
|
|
|
|
if command:
|
|
|
|
if srv_obj.check_running():
|
|
|
|
srv_obj.send_command(command)
|
2020-09-02 01:30:39 +00:00
|
|
|
|
2021-01-17 17:20:28 +00:00
|
|
|
elif page == "create_file":
|
|
|
|
file_parent = self.get_body_argument('file_parent', default=None, strip=True)
|
|
|
|
file_name = self.get_body_argument('file_name', default=None, strip=True)
|
|
|
|
file_path = os.path.join(file_parent, file_name)
|
|
|
|
server_id = self.get_argument('id', None)
|
|
|
|
|
2021-07-30 16:20:01 +00:00
|
|
|
if not self.check_server_id(server_id, 'create_file'): return
|
2021-03-26 13:57:50 +00:00
|
|
|
else: server_id = bleach.clean(server_id)
|
2021-01-17 17:20:28 +00:00
|
|
|
|
|
|
|
if not helper.in_path(db_helper.get_server_data_by_id(server_id)['path'], file_path) \
|
2021-03-26 13:57:50 +00:00
|
|
|
or helper.check_file_exists(os.path.abspath(file_path)):
|
2021-01-20 21:10:25 +00:00
|
|
|
logger.warning("Invalid path in create_file ajax call ({})".format(file_path))
|
|
|
|
console.warning("Invalid path in create_file ajax call ({})".format(file_path))
|
2021-07-30 16:20:01 +00:00
|
|
|
return
|
2021-01-17 17:20:28 +00:00
|
|
|
|
|
|
|
# Create the file by opening it
|
|
|
|
with open(file_path, 'w') as file_object:
|
|
|
|
file_object.close()
|
|
|
|
|
|
|
|
elif page == "create_dir":
|
|
|
|
dir_parent = self.get_body_argument('dir_parent', default=None, strip=True)
|
|
|
|
dir_name = self.get_body_argument('dir_name', default=None, strip=True)
|
|
|
|
dir_path = os.path.join(dir_parent, dir_name)
|
|
|
|
server_id = self.get_argument('id', None)
|
|
|
|
|
2021-07-30 16:20:01 +00:00
|
|
|
if not self.check_server_id(server_id, 'create_dir'): return
|
2021-03-26 13:57:50 +00:00
|
|
|
else: server_id = bleach.clean(server_id)
|
2021-01-17 17:20:28 +00:00
|
|
|
|
|
|
|
if not helper.in_path(db_helper.get_server_data_by_id(server_id)['path'], dir_path) \
|
2021-03-26 13:57:50 +00:00
|
|
|
or helper.check_path_exists(os.path.abspath(dir_path)):
|
2021-01-20 21:10:25 +00:00
|
|
|
logger.warning("Invalid path in create_dir ajax call ({})".format(dir_path))
|
|
|
|
console.warning("Invalid path in create_dir ajax call ({})".format(dir_path))
|
2021-07-30 16:20:01 +00:00
|
|
|
return
|
2021-01-17 17:20:28 +00:00
|
|
|
# Create the directory
|
|
|
|
os.mkdir(dir_path)
|
|
|
|
|
2021-08-20 03:36:25 +00:00
|
|
|
elif page == "unzip_file":
|
|
|
|
server_id = self.get_argument('id', None)
|
|
|
|
path = self.get_argument('path', None)
|
|
|
|
helper.unzipFile(path)
|
2021-08-20 03:50:24 +00:00
|
|
|
self.redirect("/panel/server_detail?id={}&subpage=files".format(server_id))
|
2021-08-20 03:36:25 +00:00
|
|
|
return
|
|
|
|
|
|
|
|
|
2021-08-19 20:50:18 +00:00
|
|
|
elif page == "upload_files":
|
|
|
|
server_id = self.get_argument('id', None)
|
|
|
|
path = self.get_argument('path', None)
|
|
|
|
|
|
|
|
if helper.in_path(db_helper.get_server_data_by_id(server_id)['path'], path):
|
|
|
|
try:
|
|
|
|
files = self.request.files['files']
|
|
|
|
for file in files:
|
|
|
|
if file['filename'].split('.') is not None:
|
2021-08-20 03:36:25 +00:00
|
|
|
self._upload_file(file['body'], path, file['filename'])
|
2021-08-19 20:50:18 +00:00
|
|
|
else:
|
|
|
|
logger.error("Directory Detected. Skipping")
|
|
|
|
self.redirect("/panel/server_detail?id={}&subpage=files".format(server_id))
|
|
|
|
except Exception as e:
|
|
|
|
self.redirect("/panel/server_detail?id={}&subpage=files".format(server_id))
|
|
|
|
else:
|
|
|
|
logger.error("Invalid directory requested. Canceling upload")
|
2021-08-20 03:36:25 +00:00
|
|
|
return
|
2021-08-19 20:50:18 +00:00
|
|
|
|
2021-08-20 03:36:25 +00:00
|
|
|
def _upload_file(self, file_data, file_path, file_name):
|
2021-08-19 20:50:18 +00:00
|
|
|
error = ""
|
|
|
|
|
|
|
|
file_full_path = os.path.join(file_path, file_name)
|
|
|
|
if os.path.exists(file_full_path):
|
|
|
|
error = "A file with this name already exists."
|
|
|
|
|
|
|
|
if not helper.check_writeable(file_path):
|
|
|
|
error = "Unwritable Path"
|
|
|
|
|
|
|
|
if error != "":
|
|
|
|
logger.error("Unable to save uploaded file due to: {}".format(error))
|
|
|
|
return False
|
|
|
|
|
|
|
|
output_file = open(file_full_path, 'wb')
|
|
|
|
output_file.write(file_data)
|
|
|
|
logger.info('Saving File: {}'.format(file_full_path))
|
|
|
|
return True
|
|
|
|
|
2021-01-18 15:02:38 +00:00
|
|
|
@tornado.web.authenticated
|
2021-01-17 17:20:28 +00:00
|
|
|
def delete(self, page):
|
|
|
|
if page == "del_file":
|
|
|
|
file_path = self.get_body_argument('file_path', default=None, strip=True)
|
|
|
|
server_id = self.get_argument('id', None)
|
|
|
|
|
2021-03-26 13:57:50 +00:00
|
|
|
console.warning("delete {} for server {}".format(file_path, server_id))
|
2021-01-17 17:20:28 +00:00
|
|
|
|
2021-07-30 16:20:01 +00:00
|
|
|
if not self.check_server_id(server_id, 'del_file'): return
|
2021-03-26 13:57:50 +00:00
|
|
|
else: server_id = bleach.clean(server_id)
|
2021-01-17 17:20:28 +00:00
|
|
|
|
2021-03-22 04:02:18 +00:00
|
|
|
server_info = db_helper.get_server_data_by_id(server_id)
|
2021-03-26 13:57:50 +00:00
|
|
|
if not (helper.in_path(server_info['path'], file_path) \
|
|
|
|
or helper.in_path(server_info['backup_path'], file_path)) \
|
|
|
|
or not helper.check_file_exists(os.path.abspath(file_path)):
|
2021-01-20 21:10:25 +00:00
|
|
|
logger.warning("Invalid path in del_file ajax call ({})".format(file_path))
|
|
|
|
console.warning("Invalid path in del_file ajax call ({})".format(file_path))
|
2021-07-30 16:20:01 +00:00
|
|
|
return
|
2021-01-17 17:20:28 +00:00
|
|
|
|
|
|
|
# Delete the file
|
|
|
|
os.remove(file_path)
|
|
|
|
|
|
|
|
elif page == "del_dir":
|
|
|
|
dir_path = self.get_body_argument('dir_path', default=None, strip=True)
|
|
|
|
server_id = self.get_argument('id', None)
|
|
|
|
|
2021-08-10 00:48:22 +00:00
|
|
|
console.warning("delete {} for server {}".format(dir_path, server_id))
|
2021-01-17 17:20:28 +00:00
|
|
|
|
2021-07-30 16:20:01 +00:00
|
|
|
if not self.check_server_id(server_id, 'del_dir'): return
|
2021-03-26 13:57:50 +00:00
|
|
|
else: server_id = bleach.clean(server_id)
|
2021-01-17 17:20:28 +00:00
|
|
|
|
2021-03-22 04:02:18 +00:00
|
|
|
server_info = db_helper.get_server_data_by_id(server_id)
|
|
|
|
if not helper.in_path(server_info['path'], dir_path) \
|
2021-03-26 13:57:50 +00:00
|
|
|
or not helper.check_path_exists(os.path.abspath(dir_path)):
|
2021-01-20 21:10:25 +00:00
|
|
|
logger.warning("Invalid path in del_file ajax call ({})".format(dir_path))
|
|
|
|
console.warning("Invalid path in del_file ajax call ({})".format(dir_path))
|
2021-07-30 16:20:01 +00:00
|
|
|
return
|
2021-01-17 17:20:28 +00:00
|
|
|
|
2021-03-26 13:57:50 +00:00
|
|
|
# Delete the directory
|
|
|
|
# os.rmdir(dir_path) # Would only remove empty directories
|
2021-01-17 17:20:28 +00:00
|
|
|
shutil.rmtree(dir_path) # Removes also when there are contents
|
|
|
|
|
2021-08-18 22:50:53 +00:00
|
|
|
elif page == "delete_server":
|
|
|
|
server_id = self.get_argument('id', None)
|
|
|
|
logger.info(
|
|
|
|
"Removing server from panel for server: {}".format(db_helper.get_server_friendly_name(server_id)))
|
|
|
|
self.controller.remove_server(server_id, False)
|
|
|
|
|
|
|
|
elif page == "delete_server_files":
|
|
|
|
server_id = self.get_argument('id', None)
|
|
|
|
logger.info(
|
|
|
|
"Removing server and all associated files for server: {}".format(db_helper.get_server_friendly_name(server_id)))
|
|
|
|
self.controller.remove_server(server_id, True)
|
|
|
|
|
2021-01-18 15:02:38 +00:00
|
|
|
@tornado.web.authenticated
|
2021-01-17 17:20:28 +00:00
|
|
|
def put(self, page):
|
|
|
|
if page == "save_file":
|
|
|
|
file_contents = self.get_body_argument('file_contents', default=None, strip=True)
|
|
|
|
file_path = self.get_body_argument('file_path', default=None, strip=True)
|
2021-01-15 19:59:58 +00:00
|
|
|
server_id = self.get_argument('id', None)
|
|
|
|
|
2021-07-30 16:20:01 +00:00
|
|
|
if not self.check_server_id(server_id, 'save_file'): return
|
2021-03-26 13:57:50 +00:00
|
|
|
else: server_id = bleach.clean(server_id)
|
2021-01-15 19:59:58 +00:00
|
|
|
|
|
|
|
if not helper.in_path(db_helper.get_server_data_by_id(server_id)['path'], file_path)\
|
2021-03-26 13:57:50 +00:00
|
|
|
or not helper.check_file_exists(os.path.abspath(file_path)):
|
2021-01-20 21:10:25 +00:00
|
|
|
logger.warning("Invalid path in save_file ajax call ({})".format(file_path))
|
|
|
|
console.warning("Invalid path in save_file ajax call ({})".format(file_path))
|
2021-07-30 16:20:01 +00:00
|
|
|
return
|
2021-01-15 19:59:58 +00:00
|
|
|
|
|
|
|
# Open the file in write mode and store the content in file_object
|
|
|
|
with open(file_path, 'w') as file_object:
|
2021-01-17 17:20:28 +00:00
|
|
|
file_object.write(file_contents)
|
|
|
|
|
|
|
|
elif page == "rename_item":
|
|
|
|
item_path = self.get_body_argument('item_path', default=None, strip=True)
|
|
|
|
new_item_name = self.get_body_argument('new_item_name', default=None, strip=True)
|
|
|
|
server_id = self.get_argument('id', None)
|
|
|
|
|
2021-07-30 16:20:01 +00:00
|
|
|
if not self.check_server_id(server_id, 'rename_item'): return
|
2021-03-26 13:57:50 +00:00
|
|
|
else: server_id = bleach.clean(server_id)
|
2021-01-17 17:20:28 +00:00
|
|
|
|
|
|
|
if item_path is None or new_item_name is None:
|
2021-03-26 13:57:50 +00:00
|
|
|
logger.warning("Invalid path(s) in rename_item ajax call")
|
|
|
|
console.warning("Invalid path(s) in rename_item ajax call")
|
2021-07-30 16:20:01 +00:00
|
|
|
return
|
2021-01-17 17:20:28 +00:00
|
|
|
|
|
|
|
if not helper.in_path(db_helper.get_server_data_by_id(server_id)['path'], item_path) \
|
2021-03-26 13:57:50 +00:00
|
|
|
or not helper.check_path_exists(os.path.abspath(item_path)):
|
|
|
|
logger.warning("Invalid old name path in rename_item ajax call ({})".format(server_id))
|
|
|
|
console.warning("Invalid old name path in rename_item ajax call ({})".format(server_id))
|
2021-07-30 16:20:01 +00:00
|
|
|
return
|
2021-01-17 17:20:28 +00:00
|
|
|
|
|
|
|
new_item_path = os.path.join(os.path.split(item_path)[0], new_item_name)
|
|
|
|
|
|
|
|
if not helper.in_path(db_helper.get_server_data_by_id(server_id)['path'], new_item_path) \
|
2021-03-26 13:57:50 +00:00
|
|
|
or helper.check_path_exists(os.path.abspath(new_item_path)):
|
|
|
|
logger.warning("Invalid new name path in rename_item ajax call ({})".format(server_id))
|
|
|
|
console.warning("Invalid new name path in rename_item ajax call ({})".format(server_id))
|
2021-07-30 16:20:01 +00:00
|
|
|
return
|
2021-01-17 17:20:28 +00:00
|
|
|
|
|
|
|
# RENAME
|
|
|
|
os.rename(item_path, new_item_path)
|
2021-03-26 13:57:50 +00:00
|
|
|
def check_server_id(self, server_id, page_name):
|
|
|
|
if server_id is None:
|
|
|
|
logger.warning("Server ID not defined in {} ajax call ({})".format(page_name, server_id))
|
|
|
|
console.warning("Server ID not defined in {} ajax call ({})".format(page_name, server_id))
|
2021-07-30 16:20:01 +00:00
|
|
|
return
|
2021-03-26 13:57:50 +00:00
|
|
|
else:
|
|
|
|
server_id = bleach.clean(server_id)
|
|
|
|
|
|
|
|
# does this server id exist?
|
|
|
|
if not db_helper.server_id_exists(server_id):
|
|
|
|
logger.warning("Server ID not found in {} ajax call ({})".format(page_name, server_id))
|
|
|
|
console.warning("Server ID not found in {} ajax call ({})".format(page_name, server_id))
|
2021-07-30 16:20:01 +00:00
|
|
|
return
|
2021-03-26 13:57:50 +00:00
|
|
|
return True
|