diff --git a/app/classes/shared/controller.py b/app/classes/shared/controller.py index 7c5bf2a8..d486e22a 100644 --- a/app/classes/shared/controller.py +++ b/app/classes/shared/controller.py @@ -51,7 +51,7 @@ class Controller: continue # if this server path no longer exists - let's warn and bomb out - if not helper.check_path_exits(s['path']): + if not helper.check_path_exists(s['path']): logger.warning("Unable to find server {} at path {}. Skipping this server".format(s['server_name'], s['path'])) diff --git a/app/classes/shared/helpers.py b/app/classes/shared/helpers.py index 5784010f..68ddec24 100644 --- a/app/classes/shared/helpers.py +++ b/app/classes/shared/helpers.py @@ -9,6 +9,7 @@ import base64 import socket import random import logging +import html from datetime import datetime from socket import gethostname @@ -280,7 +281,7 @@ class Helpers: return "%.1f%s%s" % (num, 'Y', suffix) @staticmethod - def check_path_exits(path: str): + def check_path_exists(path: str): logger.debug('Looking for path: {}'.format(path)) if os.path.exists(path): @@ -463,6 +464,34 @@ class Helpers: return data + @staticmethod + def generate_tree(folder, output=""): + for raw_filename in os.listdir(folder): + print(raw_filename) + filename = html.escape(raw_filename) + print(filename) + rel = os.path.join(folder, raw_filename) + if os.path.isdir(rel): + output += \ + """
  • + \n
    {}
    + \n\n
  • ' + else: + console.debug('os.path.isdir(rel): "{}", rel: "{}"'.format(os.path.isdir(rel), rel)) + output += """
  • {}
  • """.format(os.path.join(folder, filename), filename, filename) + return output + + @staticmethod + def in_path(x, y): + return os.path.abspath(y).__contains__(os.path.abspath(x)) helper = Helpers() diff --git a/app/classes/shared/server.py b/app/classes/shared/server.py index d4518638..6f5c27ec 100644 --- a/app/classes/shared/server.py +++ b/app/classes/shared/server.py @@ -97,7 +97,7 @@ class Server: console.critical("Server executable path: {} does not seem to exist".format(full_path)) helper.do_exit() - if not helper.check_path_exits(self.server_path): + if not helper.check_path_exists(self.server_path): logger.critical("Server path: {} does not seem to exits".format(self.server_path)) console.critical("Server path: {} does not seem to exits".format(self.server_path)) helper.do_exit() diff --git a/app/classes/web/ajax_handler.py b/app/classes/web/ajax_handler.py index 03641140..5ec917a6 100644 --- a/app/classes/web/ajax_handler.py +++ b/app/classes/web/ajax_handler.py @@ -3,6 +3,8 @@ import logging import tornado.web import tornado.escape import bleach +import os +import shutil from app.classes.shared.console import console from app.classes.shared.models import Users, installer @@ -79,7 +81,58 @@ class AjaxHandler(BaseHandler): page_data['notify_data'] = data self.render_page('ajax/notify.html', page_data) + elif page == "get_file": + file_path = self.get_argument('file_path', None) + server_id = self.get_argument('id', None) + if server_id is None: + logger.warning("Server ID not found in get_file ajax call") + console.warning("Server ID not found in get_file ajax call") + return False + 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 get_file ajax call") + console.warning("Server ID not found in get_file ajax call") + return False + + if not helper.in_path(db_helper.get_server_data_by_id(server_id)['path'], file_path)\ + or not helper.check_file_exists(os.path.abspath(file_path)): + logger.warning("Invalid path in get_file ajax call") + console.warning("Invalid path in get_file ajax call") + return False + + file = open(file_path) + file_contents = file.read() + file.close() + + console.debug("Send file contents") + self.write(file_contents) + self.finish() + + elif page == "get_tree": + server_id = self.get_argument('id', None) + + if server_id is None: + logger.warning("Server ID not found in get_file ajax call") + console.warning("Server ID not found in get_file ajax call") + return False + 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 get_file ajax call") + console.warning("Server ID not found in get_file ajax call") + return False + + 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() + + @tornado.web.authenticated def post(self, page): user_data = json.loads(self.get_secure_cookie("user_data")) error = bleach.clean(self.get_argument('error', "WTF Error!")) @@ -90,11 +143,12 @@ class AjaxHandler(BaseHandler): } if page == "send_command": - command = bleach.clean(self.get_body_argument('command', default=None, strip=True)) - server_id = bleach.clean(self.get_argument('id')) + command = self.get_body_argument('command', default=None, strip=True) + server_id = self.get_argument('id') if server_id is None: logger.warning("Server ID not found in send_command ajax call") + console.warning("Server ID not found in send_command ajax call") srv_obj = controller.get_server_obj(server_id) @@ -102,3 +156,192 @@ class AjaxHandler(BaseHandler): if srv_obj.check_running(): srv_obj.send_command(command) + 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) + print(server_id) + + if server_id is None: + logger.warning("Server ID not found in create_file ajax call") + console.warning("Server ID not found in create_file ajax call") + return False + 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 create_file ajax call") + console.warning("Server ID not found in create_file ajax call") + return False + + if not helper.in_path(db_helper.get_server_data_by_id(server_id)['path'], file_path) \ + or helper.check_file_exists(os.path.abspath(file_path)): + logger.warning("Invalid path in create_file ajax call") + console.warning("Invalid path in create_file ajax call") + return False + + # 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) + print(server_id) + + if server_id is None: + logger.warning("Server ID not found in create_dir ajax call") + console.warning("Server ID not found in create_dir ajax call") + return False + 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 create_dir ajax call") + console.warning("Server ID not found in create_dir ajax call") + return False + + if not helper.in_path(db_helper.get_server_data_by_id(server_id)['path'], dir_path) \ + or helper.check_path_exists(os.path.abspath(dir_path)): + logger.warning("Invalid path in create_dir ajax call") + console.warning("Invalid path in create_dir ajax call") + return False + + # Create the directory + os.mkdir(dir_path) + + @tornado.web.authenticated + 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) + print(server_id) + + if server_id is None: + logger.warning("Server ID not found in del_file ajax call") + console.warning("Server ID not found in del_file ajax call") + return False + 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 del_file ajax call") + console.warning("Server ID not found in del_file ajax call") + return False + + if not helper.in_path(db_helper.get_server_data_by_id(server_id)['path'], file_path) \ + or not helper.check_file_exists(os.path.abspath(file_path)): + logger.warning("Invalid path in del_file ajax call") + console.warning("Invalid path in del_file ajax call") + return False + + # 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) + print(server_id) + + if server_id is None: + logger.warning("Server ID not found in del_file ajax call") + console.warning("Server ID not found in del_file ajax call") + return False + 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 del_file ajax call") + console.warning("Server ID not found in del_file ajax call") + return False + + if not helper.in_path(db_helper.get_server_data_by_id(server_id)['path'], dir_path) \ + or not helper.check_path_exists(os.path.abspath(dir_path)): + logger.warning("Invalid path in del_file ajax call") + console.warning("Invalid path in del_file ajax call") + return False + + # Delete the file + # os.rmdir(dir_path) + shutil.rmtree(dir_path) # Removes also when there are contents + + @tornado.web.authenticated + 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) + server_id = self.get_argument('id', None) + print(file_contents) + print(file_path) + print(server_id) + + if server_id is None: + logger.warning("Server ID not found in save_file ajax call") + console.warning("Server ID not found in save_file ajax call") + return False + 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 save_file ajax call") + console.warning("Server ID not found in save_file ajax call") + return False + + if not helper.in_path(db_helper.get_server_data_by_id(server_id)['path'], file_path)\ + or not helper.check_file_exists(os.path.abspath(file_path)): + logger.warning("Invalid path in save_file ajax call") + console.warning("Invalid path in save_file ajax call") + return False + + # Open the file in write mode and store the content in file_object + with open(file_path, 'w') as file_object: + 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) + print(server_id) + + if server_id is None: + logger.warning("Server ID not found in rename_item ajax call") + console.warning("Server ID not found in rename_item ajax call") + return False + 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 rename_item ajax call (1)") + console.warning("Server ID not found in rename_item ajax call (1)") + return False + + if item_path is None or new_item_name is None: + logger.warning("Invalid path in rename_item ajax call (2)") + console.warning("Invalid path in rename_item ajax call (2)") + return False + + if not helper.in_path(db_helper.get_server_data_by_id(server_id)['path'], item_path) \ + or not helper.check_path_exists(os.path.abspath(item_path)): + logger.warning("Invalid path in rename_item ajax call (3)") + console.warning("Invalid path in rename_item ajax call (3)") + return False + + 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) \ + or helper.check_path_exists(os.path.abspath(new_item_path)): + logger.warning("Invalid path 2 in rename_item ajax call") + console.warning("Invalid path 2 in rename_item ajax call") + return False + + # RENAME + os.rename(item_path, new_item_path) diff --git a/app/classes/web/panel_handler.py b/app/classes/web/panel_handler.py index 18deb21a..795fc129 100644 --- a/app/classes/web/panel_handler.py +++ b/app/classes/web/panel_handler.py @@ -68,9 +68,6 @@ class PanelHandler(BaseHandler): elif page == 'file_edit': template = "panel/file_edit.html" - elif page == 'files_menu': - template = "panel/files_menu.html" - elif page == "remove_server": server_id = self.get_argument('id', None) server_data = controller.get_server_data(server_id) @@ -112,10 +109,12 @@ class PanelHandler(BaseHandler): self.redirect("/panel/error?error=Invalid Server ID") return False - valid_subpages = ['term', 'logs', 'config'] + valid_subpages = ['term', 'logs', 'config', 'files'] if subpage not in valid_subpages: + console.debug('not a valid subpage') subpage = 'term' + console.debug('Subpage: "{}"'.format(subpage)) # server_data isn't needed since the server_stats also pulls server data # page_data['server_data'] = db_helper.get_server_data_by_id(server_id) diff --git a/app/frontend/templates/main_menu.html b/app/frontend/templates/main_menu.html index 8e6b6d97..3745a667 100644 --- a/app/frontend/templates/main_menu.html +++ b/app/frontend/templates/main_menu.html @@ -64,6 +64,14 @@ {% end %} + + diff --git a/app/frontend/templates/panel/files_menu.html b/app/frontend/templates/panel/files_menu.html deleted file mode 100644 index 0f883903..00000000 --- a/app/frontend/templates/panel/files_menu.html +++ /dev/null @@ -1,112 +0,0 @@ -{% extends ../base.html %} - -{% block meta %} - -{% end %} - -{% block title %}Crafty Controller - Looking at files in server -< server name >- (-< server path id >-){% end %} - -{% block content %} - -
    - - -
    -
    - -
    - -
    - - -
    - -
    -
    -
    - - - -
    -
    -
    -
    - - -
    - - -{% end %} - -{% block js %} - - - -{% end %} \ No newline at end of file diff --git a/app/frontend/templates/panel/server_files.html b/app/frontend/templates/panel/server_files.html new file mode 100644 index 00000000..d08e11ac --- /dev/null +++ b/app/frontend/templates/panel/server_files.html @@ -0,0 +1,657 @@ +{% extends ../base.html %} + +{% block meta %} + +{% end %} + +{% block title %}Crafty Controller - Server Details{% end %} + +{% block content %} + +
    + + +
    +
    + +
    + +
    + + + {% include "parts/details_stats.html %} + +
    + +
    +
    +
    + + +
    +
    + +
    + + + × + + + + +
    + +
      +
    • +
      Files
      +
        +
      • Error while getting files
      • + +
      +
    • +
    +
    + +
    + Editing file +
    file_contents
    +

    + +
    +
    + +
    +
    +
    +
    + + + +
    + + +{% end %} + +{% block js %} + + + + +{% end %} \ No newline at end of file