Refactored the yes to not pass objects in import

Merge Conflicts ᴙ Us
This commit is contained in:
computergeek125 2022-04-11 00:23:55 -05:00
parent f42a697837
commit 42ca4bb973
43 changed files with 1289 additions and 1525 deletions

View File

@ -1,7 +1,7 @@
import logging
from app.classes.models.crafty_permissions import (
crafty_permissions,
Permissions_Crafty,
Enum_Permissions_Crafty,
)
from app.classes.models.users import ApiKeys
@ -12,25 +12,25 @@ logger = logging.getLogger(__name__)
class Crafty_Perms_Controller:
@staticmethod
def list_defined_crafty_permissions():
permissions_list = crafty_permissions.get_permissions_list()
permissions_list = Permissions_Crafty.get_permissions_list()
return permissions_list
@staticmethod
def get_mask_crafty_permissions(user_id):
permissions_mask = crafty_permissions.get_crafty_permissions_mask(user_id)
permissions_mask = Permissions_Crafty.get_crafty_permissions_mask(user_id)
return permissions_mask
@staticmethod
def set_permission(
permission_mask, permission_tested: Enum_Permissions_Crafty, value
):
return crafty_permissions.set_permission(
return Permissions_Crafty.set_permission(
permission_mask, permission_tested, value
)
@staticmethod
def can_create_server(user_id):
return crafty_permissions.can_add_in_crafty(
return Permissions_Crafty.can_add_in_crafty(
user_id, Enum_Permissions_Crafty.Server_Creation
)
@ -52,22 +52,22 @@ class Crafty_Perms_Controller:
@staticmethod
def list_all_crafty_permissions_quantity_limits():
return crafty_permissions.get_all_permission_quantity_list()
return Permissions_Crafty.get_all_permission_quantity_list()
@staticmethod
def list_crafty_permissions_quantity_limits(user_id):
return crafty_permissions.get_permission_quantity_list(user_id)
return Permissions_Crafty.get_permission_quantity_list(user_id)
@staticmethod
def get_crafty_permissions_list(user_id):
permissions_mask = crafty_permissions.get_crafty_permissions_mask(user_id)
permissions_list = crafty_permissions.get_permissions(permissions_mask)
permissions_mask = Permissions_Crafty.get_crafty_permissions_mask(user_id)
permissions_list = Permissions_Crafty.get_permissions(permissions_mask)
return permissions_list
@staticmethod
def add_server_creation(user_id):
return crafty_permissions.add_server_creation(user_id)
return Permissions_Crafty.add_server_creation(user_id)
@staticmethod
def get_api_key_permissions_list(key: ApiKeys):
return crafty_permissions.get_api_key_permissions_list(key)
return Permissions_Crafty.get_api_key_permissions_list(key)

View File

@ -1,60 +1,59 @@
import logging
from app.classes.models.management import management_helper
from app.classes.models.servers import servers_helper
from app.classes.models.management import helpers_management
from app.classes.models.servers import helper_servers
logger = logging.getLogger(__name__)
class Management_Controller:
def __init__(self, management_helper):
self.management_helper = management_helper
# **********************************************************************************
# Host_Stats Methods
# **********************************************************************************
@staticmethod
def get_latest_hosts_stats():
return management_helper.get_latest_hosts_stats()
return helpers_management.get_latest_hosts_stats()
# **********************************************************************************
# Commands Methods
# **********************************************************************************
@staticmethod
def get_unactioned_commands():
return management_helper.get_unactioned_commands()
return helpers_management.get_unactioned_commands()
@staticmethod
def send_command(user_id, server_id, remote_ip, command):
server_name = servers_helper.get_server_friendly_name(server_id)
def send_command(self, user_id, server_id, remote_ip, command):
server_name = helper_servers.get_server_friendly_name(server_id)
# Example: Admin issued command start_server for server Survival
management_helper.add_to_audit_log(
self.management_helper.add_to_audit_log(
user_id,
f"issued command {command} for server {server_name}",
server_id,
remote_ip,
)
management_helper.add_command(server_id, user_id, remote_ip, command)
helpers_management.add_command(server_id, user_id, remote_ip, command)
@staticmethod
def mark_command_complete(command_id=None):
return management_helper.mark_command_complete(command_id)
return helpers_management.mark_command_complete(command_id)
# **********************************************************************************
# Audit_Log Methods
# **********************************************************************************
@staticmethod
def get_actity_log():
return management_helper.get_actity_log()
return helpers_management.get_actity_log()
@staticmethod
def add_to_audit_log(user_id, log_msg, server_id=None, source_ip=None):
return management_helper.add_to_audit_log(
def add_to_audit_log(self, user_id, log_msg, server_id=None, source_ip=None):
return self.management_helper.add_to_audit_log(
user_id, log_msg, server_id, source_ip
)
@staticmethod
def add_to_audit_log_raw(user_name, user_id, server_id, log_msg, source_ip):
return management_helper.add_to_audit_log_raw(
def add_to_audit_log_raw(self, user_name, user_id, server_id, log_msg, source_ip):
return self.management_helper.add_to_audit_log_raw(
user_name, user_id, server_id, log_msg, source_ip
)
@ -72,7 +71,7 @@ class Management_Controller:
comment=None,
enabled=True,
):
return management_helper.create_scheduled_task(
return helpers_management.create_scheduled_task(
server_id,
action,
interval,
@ -85,63 +84,61 @@ class Management_Controller:
@staticmethod
def delete_scheduled_task(schedule_id):
return management_helper.delete_scheduled_task(schedule_id)
return helpers_management.delete_scheduled_task(schedule_id)
@staticmethod
def update_scheduled_task(schedule_id, updates):
return management_helper.update_scheduled_task(schedule_id, updates)
return helpers_management.update_scheduled_task(schedule_id, updates)
@staticmethod
def get_scheduled_task(schedule_id):
return management_helper.get_scheduled_task(schedule_id)
return helpers_management.get_scheduled_task(schedule_id)
@staticmethod
def get_scheduled_task_model(schedule_id):
return management_helper.get_scheduled_task_model(schedule_id)
return helpers_management.get_scheduled_task_model(schedule_id)
@staticmethod
def get_child_schedules(sch_id):
return management_helper.get_child_schedules(sch_id)
return helpers_management.get_child_schedules(sch_id)
@staticmethod
def get_schedules_by_server(server_id):
return management_helper.get_schedules_by_server(server_id)
return helpers_management.get_schedules_by_server(server_id)
@staticmethod
def get_schedules_all():
return management_helper.get_schedules_all()
return helpers_management.get_schedules_all()
@staticmethod
def get_schedules_enabled():
return management_helper.get_schedules_enabled()
return helpers_management.get_schedules_enabled()
# **********************************************************************************
# Backups Methods
# **********************************************************************************
@staticmethod
def get_backup_config(server_id):
return management_helper.get_backup_config(server_id)
return helpers_management.get_backup_config(server_id)
@staticmethod
def set_backup_config(
self,
server_id: int,
backup_path: str = None,
max_backups: int = None,
excluded_dirs: list = None,
compress: bool = False,
):
return management_helper.set_backup_config(
return self.management_helper.set_backup_config(
server_id, backup_path, max_backups, excluded_dirs, compress
)
@staticmethod
def get_excluded_backup_dirs(server_id: int):
return management_helper.get_excluded_backup_dirs(server_id)
return helpers_management.get_excluded_backup_dirs(server_id)
@staticmethod
def add_excluded_backup_dir(server_id: int, dir_to_add: str):
management_helper.add_excluded_backup_dir(server_id, dir_to_add)
def add_excluded_backup_dir(self, server_id: int, dir_to_add: str):
self.management_helper.add_excluded_backup_dir(server_id, dir_to_add)
@staticmethod
def del_excluded_backup_dir(server_id: int, dir_to_del: str):
management_helper.del_excluded_backup_dir(server_id, dir_to_del)
def del_excluded_backup_dir(self, server_id: int, dir_to_del: str):
self.management_helper.del_excluded_backup_dir(server_id, dir_to_del)

View File

@ -1,25 +1,26 @@
import logging
from app.classes.models.roles import roles_helper
from app.classes.models.server_permissions import server_permissions
from app.classes.models.users import users_helper
from app.classes.shared.helpers import helper
from app.classes.models.roles import helper_roles
from app.classes.models.server_permissions import Permissions_Servers
from app.classes.shared.helpers import Helpers
logger = logging.getLogger(__name__)
class Roles_Controller:
def __init__(self, users_helper):
self.users_helper = users_helper
@staticmethod
def get_all_roles():
return roles_helper.get_all_roles()
return helper_roles.get_all_roles()
@staticmethod
def get_roleid_by_name(role_name):
return roles_helper.get_roleid_by_name(role_name)
return helper_roles.get_roleid_by_name(role_name)
@staticmethod
def get_role(role_id):
return roles_helper.get_role(role_id)
return helper_roles.get_role(role_id)
@staticmethod
def update_role(role_id: str, role_data=None, permissions_mask: str = "00000000"):
@ -37,41 +38,40 @@ class Roles_Controller:
removed_servers = base_data["servers"].difference(role_data["servers"])
elif base_data[key] != role_data[key]:
up_data[key] = role_data[key]
up_data["last_update"] = helper.get_time_as_string()
up_data["last_update"] = Helpers.get_time_as_string()
logger.debug(
f"role: {role_data} +server:{added_servers} -server{removed_servers}"
)
for server in added_servers:
server_permissions.get_or_create(role_id, server, permissions_mask)
Permissions_Servers.get_or_create(role_id, server, permissions_mask)
for server in base_data["servers"]:
server_permissions.update_role_permission(role_id, server, permissions_mask)
Permissions_Servers.update_role_permission(role_id, server, permissions_mask)
# TODO: This is horribly inefficient and we should be using bulk queries
# but im going for functionality at this point
server_permissions.delete_roles_permissions(role_id, removed_servers)
Permissions_Servers.delete_roles_permissions(role_id, removed_servers)
if up_data:
roles_helper.update_role(role_id, up_data)
helper_roles.update_role(role_id, up_data)
@staticmethod
def add_role(role_name):
return roles_helper.add_role(role_name)
return helper_roles.add_role(role_name)
@staticmethod
def remove_role(role_id):
def remove_role(self, role_id):
role_data = Roles_Controller.get_role_with_servers(role_id)
server_permissions.delete_roles_permissions(role_id, role_data["servers"])
users_helper.remove_roles_from_role_id(role_id)
return roles_helper.remove_role(role_id)
Permissions_Servers.delete_roles_permissions(role_id, role_data["servers"])
self.users_helper.remove_roles_from_role_id(role_id)
return helper_roles.remove_role(role_id)
@staticmethod
def role_id_exists(role_id):
return roles_helper.role_id_exists(role_id)
return helper_roles.role_id_exists(role_id)
@staticmethod
def get_role_with_servers(role_id):
role = roles_helper.get_role(role_id)
role = helper_roles.get_role(role_id)
if role:
servers_query = server_permissions.get_servers_from_role(role_id)
servers_query = Permissions_Servers.get_servers_from_role(role_id)
# TODO: this query needs to be narrower
servers = set()
for s in servers_query:

View File

@ -1,13 +1,13 @@
import logging
from app.classes.models.server_permissions import (
server_permissions,
Permissions_Servers,
Enum_Permissions_Server,
)
from app.classes.models.users import users_helper, ApiKeys
from app.classes.models.roles import roles_helper
from app.classes.models.servers import servers_helper
from app.classes.shared.main_models import db_helper
from app.classes.models.users import helper_users, ApiKeys
from app.classes.models.roles import helper_roles
from app.classes.models.servers import helper_servers
from app.classes.shared.main_models import db_shortcuts
logger = logging.getLogger(__name__)
@ -15,100 +15,100 @@ logger = logging.getLogger(__name__)
class Server_Perms_Controller:
@staticmethod
def get_server_user_list(server_id):
return server_permissions.get_server_user_list(server_id)
return Permissions_Servers.get_server_user_list(server_id)
@staticmethod
def list_defined_permissions():
permissions_list = server_permissions.get_permissions_list()
permissions_list = Permissions_Servers.get_permissions_list()
return permissions_list
@staticmethod
def get_mask_permissions(role_id, server_id):
permissions_mask = server_permissions.get_permissions_mask(role_id, server_id)
permissions_mask = Permissions_Servers.get_permissions_mask(role_id, server_id)
return permissions_mask
@staticmethod
def get_role_permissions(role_id):
permissions_list = server_permissions.get_role_permissions_list(role_id)
permissions_list = Permissions_Servers.get_role_permissions_list(role_id)
return permissions_list
@staticmethod
def add_role_server(server_id, role_id, rs_permissions="00000000"):
return server_permissions.add_role_server(server_id, role_id, rs_permissions)
return Permissions_Servers.add_role_server(server_id, role_id, rs_permissions)
@staticmethod
def get_server_roles(server_id):
return server_permissions.get_server_roles(server_id)
return Permissions_Servers.get_server_roles(server_id)
@staticmethod
def backup_role_swap(old_server_id, new_server_id):
role_list = server_permissions.get_server_roles(old_server_id)
role_list = Permissions_Servers.get_server_roles(old_server_id)
for role in role_list:
server_permissions.add_role_server(
Permissions_Servers.add_role_server(
new_server_id,
role.role_id,
server_permissions.get_permissions_mask(
Permissions_Servers.get_permissions_mask(
int(role.role_id), int(old_server_id)
),
)
# server_permissions.add_role_server(new_server_id, role.role_id,"00001000")
# Permissions_Servers.add_role_server(new_server_id, role.role_id,"00001000")
# **********************************************************************************
# Servers Permissions Methods
# **********************************************************************************
@staticmethod
def get_permissions_mask(role_id, server_id):
return server_permissions.get_permissions_mask(role_id, server_id)
return Permissions_Servers.get_permissions_mask(role_id, server_id)
@staticmethod
def set_permission(
permission_mask, permission_tested: Enum_Permissions_Server, value
):
return server_permissions.set_permission(
return Permissions_Servers.set_permission(
permission_mask, permission_tested, value
)
@staticmethod
def get_role_permissions_list(role_id):
return server_permissions.get_role_permissions_list(role_id)
return Permissions_Servers.get_role_permissions_list(role_id)
@staticmethod
def get_user_id_permissions_list(user_id: str, server_id: str):
return server_permissions.get_user_id_permissions_list(user_id, server_id)
return Permissions_Servers.get_user_id_permissions_list(user_id, server_id)
@staticmethod
def get_api_key_id_permissions_list(key_id: str, server_id: str):
key = users_helper.get_user_api_key(key_id)
return server_permissions.get_api_key_permissions_list(key, server_id)
key = helper_users.get_user_api_key(key_id)
return Permissions_Servers.get_api_key_permissions_list(key, server_id)
@staticmethod
def get_api_key_permissions_list(key: ApiKeys, server_id: str):
return server_permissions.get_api_key_permissions_list(key, server_id)
return Permissions_Servers.get_api_key_permissions_list(key, server_id)
@staticmethod
def get_authorized_servers_stats_from_roles(user_id):
user_roles = users_helper.get_user_roles_id(user_id)
user_roles = helper_users.get_user_roles_id(user_id)
roles_list = []
role_server = []
authorized_servers = []
server_data = []
for u in user_roles:
roles_list.append(roles_helper.get_role(u.role_id))
roles_list.append(helper_roles.get_role(u.role_id))
for r in roles_list:
role_test = server_permissions.get_role_servers_from_role_id(
role_test = Permissions_Servers.get_role_servers_from_role_id(
r.get("role_id")
)
for t in role_test:
role_server.append(t)
for s in role_server:
authorized_servers.append(servers_helper.get_server_data_by_id(s.server_id))
authorized_servers.append(helper_servers.get_server_data_by_id(s.server_id))
for s in authorized_servers:
latest = servers_helper.get_latest_server_stats(s.get("server_id"))
latest = helper_servers.get_latest_server_stats(s.get("server_id"))
server_data.append(
{"server_data": s, "stats": db_helper.return_rows(latest)[0]}
{"server_data": s, "stats": db_shortcuts.return_rows(latest)[0]}
)
return server_data

View File

@ -3,25 +3,27 @@ import logging
import json
from app.classes.controllers.roles_controller import Roles_Controller
from app.classes.models.servers import servers_helper
from app.classes.models.users import users_helper, ApiKeys
from app.classes.models.servers import helper_servers
from app.classes.models.users import helper_users, ApiKeys
from app.classes.models.server_permissions import (
server_permissions,
Permissions_Servers,
Enum_Permissions_Server,
)
from app.classes.shared.helpers import helper
from app.classes.shared.main_models import db_helper
from app.classes.shared.helpers import Helpers
from app.classes.shared.main_models import db_shortcuts
logger = logging.getLogger(__name__)
class Servers_Controller:
def __init__(self, servers_helper):
self.servers_helper = servers_helper
# **********************************************************************************
# Generic Servers Methods
# **********************************************************************************
@staticmethod
def create_server(
self,
name: str,
server_uuid: str,
server_dir: str,
@ -33,7 +35,7 @@ class Servers_Controller:
server_type: str,
server_port=25565,
):
return servers_helper.create_server(
return self.servers_helper.create_server(
name,
server_uuid,
server_dir,
@ -48,60 +50,59 @@ class Servers_Controller:
@staticmethod
def get_server_obj(server_id):
return servers_helper.get_server_obj(server_id)
return helper_servers.get_server_obj(server_id)
@staticmethod
def update_server(server_obj):
return servers_helper.update_server(server_obj)
return helper_servers.update_server(server_obj)
@staticmethod
def set_download(server_id):
return servers_helper.set_download(server_id)
return helper_servers.set_download(server_id)
@staticmethod
def finish_download(server_id):
return servers_helper.finish_download(server_id)
return helper_servers.finish_download(server_id)
@staticmethod
def get_download_status(server_id):
return servers_helper.get_download_status(server_id)
return helper_servers.get_download_status(server_id)
@staticmethod
def remove_server(server_id):
roles_list = server_permissions.get_roles_from_server(server_id)
def remove_server(self, server_id):
roles_list = Permissions_Servers.get_roles_from_server(server_id)
for role in roles_list:
role_id = role.role_id
role_data = Roles_Controller.get_role_with_servers(role_id)
role_data["servers"] = {server_id}
server_permissions.delete_roles_permissions(role_id, role_data["servers"])
server_permissions.remove_roles_of_server(server_id)
servers_helper.remove_server(server_id)
Permissions_Servers.delete_roles_permissions(role_id, role_data["servers"])
Permissions_Servers.remove_roles_of_server(server_id)
self.servers_helper.remove_server(server_id)
@staticmethod
def get_server_data_by_id(server_id):
return servers_helper.get_server_data_by_id(server_id)
return helper_servers.get_server_data_by_id(server_id)
# **********************************************************************************
# Servers Methods
# **********************************************************************************
@staticmethod
def get_all_defined_servers():
return servers_helper.get_all_defined_servers()
return helper_servers.get_all_defined_servers()
@staticmethod
def get_authorized_servers(user_id):
server_data = []
user_roles = users_helper.user_role_query(user_id)
user_roles = helper_users.user_role_query(user_id)
for us in user_roles:
role_servers = server_permissions.get_role_servers_from_role_id(us.role_id)
role_servers = Permissions_Servers.get_role_servers_from_role_id(us.role_id)
for role in role_servers:
server_data.append(servers_helper.get_server_data_by_id(role.server_id))
server_data.append(helper_servers.get_server_data_by_id(role.server_id))
return server_data
@staticmethod
def get_all_servers_stats():
return servers_helper.get_all_servers_stats()
return helper_servers.get_all_servers_stats()
@staticmethod
def get_authorized_servers_stats_api_key(api_key: ApiKeys):
@ -111,8 +112,8 @@ class Servers_Controller:
)
for s in authorized_servers:
latest = servers_helper.get_latest_server_stats(s.get("server_id"))
key_permissions = server_permissions.get_api_key_permissions_list(
latest = helper_servers.get_latest_server_stats(s.get("server_id"))
key_permissions = Permissions_Servers.get_api_key_permissions_list(
api_key, s.get("server_id")
)
if Enum_Permissions_Server.Commands in key_permissions:
@ -122,7 +123,7 @@ class Servers_Controller:
server_data.append(
{
"server_data": s,
"stats": db_helper.return_rows(latest)[0],
"stats": db_shortcuts.return_rows(latest)[0],
"user_command_permission": user_command_permission,
}
)
@ -134,9 +135,9 @@ class Servers_Controller:
authorized_servers = Servers_Controller.get_authorized_servers(user_id)
for s in authorized_servers:
latest = servers_helper.get_latest_server_stats(s.get("server_id"))
latest = helper_servers.get_latest_server_stats(s.get("server_id"))
# TODO
user_permissions = server_permissions.get_user_id_permissions_list(
user_permissions = Permissions_Servers.get_user_id_permissions_list(
user_id, s.get("server_id")
)
if Enum_Permissions_Server.Commands in user_permissions:
@ -146,7 +147,7 @@ class Servers_Controller:
server_data.append(
{
"server_data": s,
"stats": db_helper.return_rows(latest)[0],
"stats": db_shortcuts.return_rows(latest)[0],
"user_command_permission": user_command_permission,
}
)
@ -155,28 +156,28 @@ class Servers_Controller:
@staticmethod
def get_server_friendly_name(server_id):
return servers_helper.get_server_friendly_name(server_id)
return helper_servers.get_server_friendly_name(server_id)
# **********************************************************************************
# Servers_Stats Methods
# **********************************************************************************
@staticmethod
def get_server_stats_by_id(server_id):
return servers_helper.get_server_stats_by_id(server_id)
return helper_servers.get_server_stats_by_id(server_id)
@staticmethod
def server_id_exists(server_id):
return servers_helper.server_id_exists(server_id)
return helper_servers.server_id_exists(server_id)
@staticmethod
def get_server_type_by_id(server_id):
return servers_helper.get_server_type_by_id(server_id)
return helper_servers.get_server_type_by_id(server_id)
@staticmethod
def server_id_authorized(server_id_a, user_id):
user_roles = users_helper.user_role_query(user_id)
user_roles = helper_users.user_role_query(user_id)
for role in user_roles:
for server_id_b in server_permissions.get_role_servers_from_role_id(
for server_id_b in Permissions_Servers.get_role_servers_from_role_id(
role.role_id
):
if str(server_id_a) == str(server_id_b.server_id):
@ -185,7 +186,7 @@ class Servers_Controller:
@staticmethod
def is_crashed(server_id):
return servers_helper.is_crashed(server_id)
return helper_servers.is_crashed(server_id)
@staticmethod
def server_id_authorized_api_key(server_id: str, api_key: ApiKeys) -> bool:
@ -194,42 +195,40 @@ class Servers_Controller:
# There is no view server permission
# permission_helper.both_have_perm(api_key)
@staticmethod
def set_update(server_id, value):
return servers_helper.set_update(server_id, value)
def set_update(self, server_id, value):
return self.servers_helper.set_update(server_id, value)
@staticmethod
def get_TTL_without_player(server_id):
return servers_helper.get_TTL_without_player(server_id)
return helper_servers.get_TTL_without_player(server_id)
@staticmethod
def can_stop_no_players(server_id, time_limit):
return servers_helper.can_stop_no_players(server_id, time_limit)
return helper_servers.can_stop_no_players(server_id, time_limit)
@staticmethod
def set_waiting_start(server_id, value):
servers_helper.set_waiting_start(server_id, value)
def set_waiting_start(self, server_id, value):
self.servers_helper.set_waiting_start(server_id, value)
@staticmethod
def get_waiting_start(server_id):
return servers_helper.get_waiting_start(server_id)
return helper_servers.get_waiting_start(server_id)
@staticmethod
def get_update_status(server_id):
return servers_helper.get_update_status(server_id)
return helper_servers.get_update_status(server_id)
# **********************************************************************************
# Servers Helpers Methods
# **********************************************************************************
@staticmethod
def get_banned_players(server_id):
stats = servers_helper.get_server_stats_by_id(server_id)
stats = helper_servers.get_server_stats_by_id(server_id)
server_path = stats["server_id"]["path"]
path = os.path.join(server_path, "banned-players.json")
try:
with open(
helper.get_os_understandable_path(path), encoding="utf-8"
Helpers.get_os_understandable_path(path), encoding="utf-8"
) as file:
content = file.read()
file.close()
@ -240,7 +239,7 @@ class Servers_Controller:
return json.loads(content)
def check_for_old_logs(self):
servers = servers_helper.get_all_defined_servers()
servers = helper_servers.get_all_defined_servers()
for server in servers:
logs_path = os.path.split(server["log_path"])[0]
latest_log_file = os.path.split(server["log_path"])[1]
@ -253,9 +252,9 @@ class Servers_Controller:
)
for log_file in log_files:
log_file_path = os.path.join(logs_path, log_file)
if helper.check_file_exists(
if Helpers.check_file_exists(
log_file_path
) and helper.is_file_older_than_x_days(
) and Helpers.is_file_older_than_x_days(
log_file_path, logs_delete_after
):
os.remove(log_file_path)

View File

@ -1,61 +1,62 @@
import logging
from typing import Optional
from app.classes.models.users import users_helper
from app.classes.models.users import helper_users
from app.classes.models.crafty_permissions import (
crafty_permissions,
Permissions_Crafty,
Enum_Permissions_Crafty,
)
from app.classes.shared.helpers import helper
from app.classes.shared.authentication import authentication
logger = logging.getLogger(__name__)
class Users_Controller:
def __init__(self, helper, users_helper, authentication):
self.helper = helper
self.users_helper = users_helper
self.authentication = authentication
# **********************************************************************************
# Users Methods
# **********************************************************************************
@staticmethod
def get_all_users():
return users_helper.get_all_users()
return helper_users.get_all_users()
@staticmethod
def get_id_by_name(username):
return users_helper.get_user_id_by_name(username)
return helper_users.get_user_id_by_name(username)
@staticmethod
def get_user_lang_by_id(user_id):
return users_helper.get_user_lang_by_id(user_id)
return helper_users.get_user_lang_by_id(user_id)
@staticmethod
def get_user_by_id(user_id):
return users_helper.get_user(user_id)
return helper_users.get_user(user_id)
@staticmethod
def update_server_order(user_id, user_server_order):
users_helper.update_server_order(user_id, user_server_order)
helper_users.update_server_order(user_id, user_server_order)
@staticmethod
def get_server_order(user_id):
return users_helper.get_server_order(user_id)
return helper_users.get_server_order(user_id)
@staticmethod
def user_query(user_id):
return users_helper.user_query(user_id)
return helper_users.user_query(user_id)
@staticmethod
def set_support_path(user_id, support_path):
users_helper.set_support_path(user_id, support_path)
helper_users.set_support_path(user_id, support_path)
@staticmethod
def update_user(user_id: str, user_data=None, user_crafty_data=None):
def update_user(self, user_id: str, user_data=None, user_crafty_data=None):
if user_crafty_data is None:
user_crafty_data = {}
if user_data is None:
user_data = {}
base_data = users_helper.get_user(user_id)
base_data = helper_users.get_user(user_id)
up_data = {}
added_roles = set()
removed_roles = set()
@ -67,15 +68,15 @@ class Users_Controller:
removed_roles = base_data["roles"].difference(user_data["roles"])
elif key == "password":
if user_data["password"] is not None and user_data["password"] != "":
up_data["password"] = helper.encode_pass(user_data["password"])
up_data["password"] = self.helper.encode_pass(user_data["password"])
elif base_data[key] != user_data[key]:
up_data[key] = user_data[key]
up_data["last_update"] = helper.get_time_as_string()
up_data["last_update"] = self.helper.get_time_as_string()
up_data["lang"] = user_data["lang"]
up_data["hints"] = user_data["hints"]
logger.debug(f"user: {user_data} +role:{added_roles} -role:{removed_roles}")
for role in added_roles:
users_helper.get_or_create(user_id=user_id, role_id=role)
helper_users.get_or_create(user_id=user_id, role_id=role)
permissions_mask = user_crafty_data.get("permissions_mask", "000")
if "server_quantity" in user_crafty_data:
@ -94,7 +95,7 @@ class Users_Controller:
limit_user_creation = 0
limit_role_creation = 0
crafty_permissions.add_or_update_user(
Permissions_Crafty.add_or_update_user(
user_id,
permissions_mask,
limit_server_creation,
@ -102,19 +103,19 @@ class Users_Controller:
limit_role_creation,
)
users_helper.delete_user_roles(user_id, removed_roles)
self.users_helper.delete_user_roles(user_id, removed_roles)
users_helper.update_user(user_id, up_data)
self.users_helper.update_user(user_id, up_data)
@staticmethod
def add_user(
self,
username,
password,
email="default@example.com",
enabled: bool = True,
superuser: bool = False,
):
return users_helper.add_user(
return self.users_helper.add_user(
username,
password=password,
email=email,
@ -130,7 +131,7 @@ class Users_Controller:
enabled: bool = True,
superuser: bool = False,
):
return users_helper.add_rawpass_user(
return helper_users.add_rawpass_user(
username,
password=password,
email=email,
@ -138,35 +139,31 @@ class Users_Controller:
superuser=superuser,
)
@staticmethod
def remove_user(user_id):
return users_helper.remove_user(user_id)
def remove_user(self, user_id):
return self.users_helper.remove_user(user_id)
@staticmethod
def user_id_exists(user_id):
return users_helper.user_id_exists(user_id)
return helper_users.user_id_exists(user_id)
@staticmethod
def set_prepare(user_id):
return users_helper.set_prepare(user_id)
return helper_users.set_prepare(user_id)
@staticmethod
def stop_prepare(user_id):
return users_helper.stop_prepare(user_id)
return helper_users.stop_prepare(user_id)
@staticmethod
def get_user_id_by_api_token(token: str) -> str:
token_data = authentication.check_no_iat(token)
def get_user_id_by_api_token(self, token: str) -> str:
token_data = self.authentication.check_no_iat(token)
return token_data["user_id"]
@staticmethod
def get_user_by_api_token(token: str):
_, _, user = authentication.check(token)
def get_user_by_api_token(self, token: str):
_, _, user = self.authentication.check(token)
return user
@staticmethod
def get_api_key_by_token(token: str):
key, _, _ = authentication.check(token)
def get_api_key_by_token(self, token: str):
key, _, _ = self.authentication.check(token)
return key
# **********************************************************************************
@ -175,23 +172,21 @@ class Users_Controller:
@staticmethod
def get_user_roles_id(user_id):
return users_helper.get_user_roles_id(user_id)
return helper_users.get_user_roles_id(user_id)
@staticmethod
def get_user_roles_names(user_id):
return users_helper.get_user_roles_names(user_id)
return helper_users.get_user_roles_names(user_id)
@staticmethod
def add_role_to_user(user_id, role_id):
return users_helper.add_role_to_user(user_id, role_id)
def add_role_to_user(self, user_id, role_id):
return self.users_helper.add_role_to_user(user_id, role_id)
@staticmethod
def add_user_roles(user):
return users_helper.add_user_roles(user)
def add_user_roles(self, user):
return self.users_helper.add_user_roles(user)
@staticmethod
def user_role_query(user_id):
return users_helper.user_role_query(user_id)
return helper_users.user_role_query(user_id)
# **********************************************************************************
# Api Keys Methods
@ -199,28 +194,26 @@ class Users_Controller:
@staticmethod
def get_user_api_keys(user_id: str):
return users_helper.get_user_api_keys(user_id)
return helper_users.get_user_api_keys(user_id)
@staticmethod
def get_user_api_key(key_id: str):
return users_helper.get_user_api_key(key_id)
return helper_users.get_user_api_key(key_id)
@staticmethod
def add_user_api_key(
self,
name: str,
user_id: str,
superuser: bool = False,
server_permissions_mask: Optional[str] = None,
crafty_permissions_mask: Optional[str] = None,
):
return users_helper.add_user_api_key(
return self.users_helper.add_user_api_key(
name, user_id, superuser, server_permissions_mask, crafty_permissions_mask
)
@staticmethod
def delete_user_api_keys(user_id: str):
return users_helper.delete_user_api_keys(user_id)
def delete_user_api_keys(self, user_id: str):
return self.users_helper.delete_user_api_keys(user_id)
@staticmethod
def delete_user_api_key(key_id: str):
return users_helper.delete_user_api_key(key_id)
def delete_user_api_key(self, key_id: str):
return self.users_helper.delete_user_api_key(key_id)

View File

@ -9,13 +9,13 @@ import uuid
import random
from app.classes.minecraft.bedrock_ping import BedrockPing
from app.classes.shared.console import console
logger = logging.getLogger(__name__)
class Server:
def __init__(self, data):
def __init__(self, console, data):
self.console = console
self.description = data.get("description")
# print(self.description)
if isinstance(self.description, dict):
@ -32,19 +32,19 @@ class Server:
if "extra" in description.keys():
for e in description["extra"]:
# Conversion format code needed only for Java Version
lines.append(get_code_format("reset"))
lines.append(get_code_format(self.console, "reset"))
if "bold" in e.keys():
lines.append(get_code_format("bold"))
lines.append(get_code_format(self.console, "bold"))
if "italic" in e.keys():
lines.append(get_code_format("italic"))
lines.append(get_code_format(self.console, "italic"))
if "underlined" in e.keys():
lines.append(get_code_format("underlined"))
lines.append(get_code_format(self.console, "underlined"))
if "strikethrough" in e.keys():
lines.append(get_code_format("strikethrough"))
lines.append(get_code_format(self.console, "strikethrough"))
if "obfuscated" in e.keys():
lines.append(get_code_format("obfuscated"))
lines.append(get_code_format(self.console, "obfuscated"))
if "color" in e.keys():
lines.append(get_code_format(e["color"]))
lines.append(get_code_format(self.console, e["color"]))
# Then append the text
if "text" in e.keys():
if e["text"] == "\n":
@ -95,7 +95,7 @@ class Player:
return self.name
def get_code_format(format_name):
def get_code_format(console, format_name):
root_dir = os.path.abspath(os.path.curdir)
format_file = os.path.join(root_dir, "app", "config", "motd_format.json")
try:

View File

@ -3,24 +3,17 @@ import threading
import time
import shutil
import logging
import requests
from datetime import datetime
from app.classes.controllers.servers_controller import Servers_Controller
from app.classes.models.server_permissions import server_permissions
from app.classes.shared.helpers import helper
from app.classes.web.websocket_helper import websocket_helper
from app.classes.models.server_permissions import Permissions_Servers
logger = logging.getLogger(__name__)
try:
import requests
except ModuleNotFoundError as err:
helper.auto_installer_fix(err)
class ServerJars:
def __init__(self):
def __init__(self, helper):
self.helper = helper
self.base_url = "https://serverjars.com"
def _get_api_result(self, call_url: str):
@ -50,9 +43,8 @@ class ServerJars:
return api_response
@staticmethod
def _read_cache():
cache_file = helper.serverjar_cache
def _read_cache(self):
cache_file = self.helper.serverjar_cache
cache = {}
try:
with open(cache_file, "r", encoding="utf-8") as f:
@ -109,8 +101,8 @@ class ServerJars:
def refresh_cache(self):
cache_file = helper.serverjar_cache
cache_old = helper.is_file_older_than_x_days(cache_file)
cache_file = self.helper.serverjar_cache
cache_old = self.helper.is_file_older_than_x_days(cache_file)
# debug override
# cache_old = True
@ -166,6 +158,7 @@ class ServerJars:
def download_jar(self, server, version, path, server_id):
update_thread = threading.Thread(
name=f"server_download-{server_id}-{server}-{version}",
target=self.a_download_jar,
daemon=True,
args=(server, version, path, server_id),
@ -176,7 +169,7 @@ class ServerJars:
# delaying download for server register to finish
time.sleep(3)
fetch_url = f"{self.base_url}/api/fetchJar/{server}/{version}"
server_users = server_permissions.get_server_user_list(server_id)
server_users = Permissions_Servers.get_server_user_list(server_id)
# We need to make sure the server is registered before
# we submit a db update for it's stats.
@ -184,11 +177,11 @@ class ServerJars:
try:
Servers_Controller.set_download(server_id)
for user in server_users:
websocket_helper.broadcast_user(user, "send_start_reload", {})
self.helper.websocket_helper.broadcast_user(user, "send_start_reload", {})
break
except:
logger.debug("server not registered yet. Delaying download.")
except Exception as ex:
logger.debug(f"server not registered yet. Delaying download - {ex}")
# open a file stream
with requests.get(fetch_url, timeout=2, stream=True) as r:
@ -198,24 +191,21 @@ class ServerJars:
Servers_Controller.finish_download(server_id)
for user in server_users:
websocket_helper.broadcast_user(
self.helper.websocket_helper.broadcast_user(
user, "notification", "Executable download finished"
)
time.sleep(3)
websocket_helper.broadcast_user(user, "send_start_reload", {})
self.helper.websocket_helper.broadcast_user(user, "send_start_reload", {})
return True
except Exception as e:
logger.error(f"Unable to save jar to {path} due to error:{e}")
Servers_Controller.finish_download(server_id)
server_users = server_permissions.get_server_user_list(server_id)
server_users = Permissions_Servers.get_server_user_list(server_id)
for user in server_users:
websocket_helper.broadcast_user(
self.helper.websocket_helper.broadcast_user(
user, "notification", "Executable download finished"
)
time.sleep(3)
websocket_helper.broadcast_user(user, "send_start_reload", {})
self.helper.websocket_helper.broadcast_user(user, "send_start_reload", {})
return False
server_jar_obj = ServerJars()

View File

@ -6,14 +6,15 @@ import psutil
from app.classes.minecraft.mc_ping import ping
from app.classes.models.management import Host_Stats
from app.classes.models.servers import servers_helper
from app.classes.shared.helpers import helper
from app.classes.models.servers import helper_servers
from app.classes.shared.helpers import Helpers
logger = logging.getLogger(__name__)
class Stats:
def __init__(self, controller):
def __init__(self, helper, controller):
self.helper = helper
self.controller = controller
def get_node_stats(self):
@ -30,8 +31,8 @@ class Stats:
"cpu_cur_freq": round(cpu_freq[0], 2),
"cpu_max_freq": cpu_freq[2],
"mem_percent": psutil.virtual_memory()[2],
"mem_usage": helper.human_readable_file_size(psutil.virtual_memory()[3]),
"mem_total": helper.human_readable_file_size(psutil.virtual_memory()[0]),
"mem_usage": Helpers.human_readable_file_size(psutil.virtual_memory()[3]),
"mem_total": Helpers.human_readable_file_size(psutil.virtual_memory()[0]),
"disk_data": self._all_disk_usage(),
}
# server_stats = self.get_servers_stats()
@ -60,7 +61,7 @@ class Stats:
with p.oneshot():
process_stats = {
"cpu_usage": real_cpu,
"memory_usage": helper.human_readable_file_size(p.memory_info()[0]),
"memory_usage": Helpers.human_readable_file_size(p.memory_info()[0]),
"mem_percentage": round(p.memory_percent(), 0),
}
return process_stats
@ -84,7 +85,7 @@ class Stats:
# print(templ % ("Device", "Total", "Used", "Free", "Use ", "Type","Mount"))
for part in psutil.disk_partitions(all=False):
if helper.is_os_windows():
if Helpers.is_os_windows():
if "cdrom" in part.opts or part.fstype == "":
# skip cd-rom drives with no disk in it; they may raise
# ENOENT, pop-up a Windows GUI error for a non-ready
@ -94,9 +95,9 @@ class Stats:
disk_data.append(
{
"device": part.device,
"total": helper.human_readable_file_size(usage.total),
"used": helper.human_readable_file_size(usage.used),
"free": helper.human_readable_file_size(usage.free),
"total": Helpers.human_readable_file_size(usage.total),
"used": Helpers.human_readable_file_size(usage.used),
"free": Helpers.human_readable_file_size(usage.free),
"percent_used": int(usage.percent),
"fs": part.fstype,
"mount": part.mountpoint,
@ -110,15 +111,15 @@ class Stats:
total_size = 0
total_size = helper.get_dir_size(server_path)
total_size = Helpers.get_dir_size(server_path)
level_total_size = helper.human_readable_file_size(total_size)
level_total_size = Helpers.human_readable_file_size(total_size)
return level_total_size
def get_server_players(self, server_id):
server = servers_helper.get_server_data_by_id(server_id)
server = helper_servers.get_server_data_by_id(server_id)
logger.info(f"Getting players for server {server}")
@ -131,7 +132,7 @@ class Stats:
server_port = server["server_port"]
logger.debug("Pinging {internal_ip} on port {server_port}")
if servers_helper.get_server_type_by_id(server_id) != "minecraft-bedrock":
if helper_servers.get_server_type_by_id(server_id) != "minecraft-bedrock":
int_mc_ping = ping(internal_ip, int(server_port))
ping_data = {}
@ -232,7 +233,7 @@ class Stats:
# ).execute()
# delete old data
max_age = helper.get_setting("history_max_age")
max_age = self.helper.get_setting("history_max_age")
now = datetime.datetime.now()
last_week = now.day - max_age

View File

@ -0,0 +1,7 @@
import peewee
database_proxy = peewee.DatabaseProxy()
class BaseModel(peewee.Model):
class Meta:
database = database_proxy

View File

@ -1,35 +1,21 @@
import logging
from app.classes.shared.helpers import helper
from app.classes.shared.permission_helper import permission_helper
from app.classes.models.users import Users, ApiKeys, users_helper
try:
from peewee import (
SqliteDatabase,
Model,
ForeignKeyField,
CharField,
IntegerField,
DoesNotExist,
)
from enum import Enum
except ModuleNotFoundError as e:
helper.auto_installer_fix(e)
logger = logging.getLogger(__name__)
peewee_logger = logging.getLogger("peewee")
peewee_logger.setLevel(logging.INFO)
database = SqliteDatabase(
helper.db_path, pragmas={"journal_mode": "wal", "cache_size": -1024 * 10}
from enum import Enum
from peewee import (
ForeignKeyField,
CharField,
IntegerField,
DoesNotExist,
)
from app.classes.models.base_model import BaseModel
from app.classes.models.users import Users, ApiKeys, helper_users
logger = logging.getLogger(__name__)
# **********************************************************************************
# User_Crafty Class
# **********************************************************************************
class User_Crafty(Model):
class User_Crafty(BaseModel):
user_id = ForeignKeyField(Users, backref="users_crafty")
permissions = CharField(default="00000000")
limit_server_creation = IntegerField(default=-1)
@ -41,7 +27,6 @@ class User_Crafty(Model):
class Meta:
table_name = "user_crafty"
database = database
# **********************************************************************************
@ -68,7 +53,7 @@ class Permissions_Crafty:
def get_permissions(permissions_mask):
permissions_list = []
for member in Enum_Permissions_Crafty.__members__.items():
if crafty_permissions.has_permission(permissions_mask, member[1]):
if Permissions_Crafty.has_permission(permissions_mask, member[1]):
permissions_list.append(member[1])
return permissions_list
@ -95,7 +80,7 @@ class Permissions_Crafty:
@staticmethod
def get_crafty_permissions_mask(user_id):
permissions_mask = ""
user_crafty = crafty_permissions.get_User_Crafty(user_id)
user_crafty = Permissions_Crafty.get_User_Crafty(user_id)
permissions_mask = user_crafty.permissions
return permissions_mask
@ -110,7 +95,7 @@ class Permissions_Crafty:
@staticmethod
def get_permission_quantity_list(user_id):
user_crafty = crafty_permissions.get_User_Crafty(user_id)
user_crafty = Permissions_Crafty.get_User_Crafty(user_id)
quantity_list = {
Enum_Permissions_Crafty.Server_Creation.name: user_crafty.limit_server_creation, # pylint: disable=line-too-long
Enum_Permissions_Crafty.User_Config.name: user_crafty.limit_user_creation,
@ -140,7 +125,7 @@ class Permissions_Crafty:
User_Crafty.created_role: 0,
}
).execute()
user_crafty = crafty_permissions.get_User_Crafty(user_id)
user_crafty = Permissions_Crafty.get_User_Crafty(user_id)
return user_crafty
@staticmethod
@ -180,7 +165,7 @@ class Permissions_Crafty:
@staticmethod
def get_created_quantity_list(user_id):
user_crafty = crafty_permissions.get_User_Crafty(user_id)
user_crafty = Permissions_Crafty.get_User_Crafty(user_id)
quantity_list = {
Enum_Permissions_Crafty.Server_Creation.name: user_crafty.created_server,
Enum_Permissions_Crafty.User_Config.name: user_crafty.created_user,
@ -190,15 +175,15 @@ class Permissions_Crafty:
@staticmethod
def get_crafty_limit_value(user_id, permission):
quantity_list = crafty_permissions.get_permission_quantity_list(user_id)
quantity_list = Permissions_Crafty.get_permission_quantity_list(user_id)
return quantity_list[permission]
@staticmethod
def can_add_in_crafty(user_id, permission):
user_crafty = crafty_permissions.get_User_Crafty(user_id)
can = crafty_permissions.has_permission(user_crafty.permissions, permission)
limit_list = crafty_permissions.get_permission_quantity_list(user_id)
quantity_list = crafty_permissions.get_created_quantity_list(user_id)
user_crafty = Permissions_Crafty.get_User_Crafty(user_id)
can = Permissions_Crafty.has_permission(user_crafty.permissions, permission)
limit_list = Permissions_Crafty.get_permission_quantity_list(user_id)
quantity_list = Permissions_Crafty.get_created_quantity_list(user_id)
return can and (
(quantity_list[permission.name] < limit_list[permission.name])
or limit_list[permission.name] == -1
@ -206,29 +191,26 @@ class Permissions_Crafty:
@staticmethod
def add_server_creation(user_id):
user_crafty = crafty_permissions.get_User_Crafty(user_id)
user_crafty = Permissions_Crafty.get_User_Crafty(user_id)
user_crafty.created_server += 1
User_Crafty.save(user_crafty)
return user_crafty.created_server
@staticmethod
def get_api_key_permissions_list(key: ApiKeys):
user = users_helper.get_user(key.user_id)
user = helper_users.get_user(key.user_id)
if user["superuser"] and key.superuser:
return crafty_permissions.get_permissions_list()
return Permissions_Crafty.get_permissions_list()
else:
if user["superuser"]:
user_permissions_mask = "111"
else:
user_permissions_mask = crafty_permissions.get_crafty_permissions_mask(
user_permissions_mask = Permissions_Crafty.get_crafty_permissions_mask(
user["user_id"]
)
key_permissions_mask: str = key.crafty_permissions
permissions_mask = permission_helper.combine_masks(
permissions_mask = helper_users.combine_masks(
user_permissions_mask, key_permissions_mask
)
permissions_list = crafty_permissions.get_permissions(permissions_mask)
permissions_list = Permissions_Crafty.get_permissions(permissions_mask)
return permissions_list
crafty_permissions = Permissions_Crafty()

View File

@ -1,42 +1,29 @@
import logging
import datetime
from peewee import (
ForeignKeyField,
CharField,
IntegerField,
DateTimeField,
FloatField,
TextField,
AutoField,
BooleanField,
)
from playhouse.shortcuts import model_to_dict
from app.classes.models.users import Users, users_helper
from app.classes.models.base_model import BaseModel
from app.classes.models.users import Users, helper_users
from app.classes.models.servers import Servers
from app.classes.models.server_permissions import server_permissions
from app.classes.shared.helpers import helper
from app.classes.shared.main_models import db_helper
from app.classes.web.websocket_helper import websocket_helper
try:
from peewee import (
SqliteDatabase,
Model,
ForeignKeyField,
CharField,
IntegerField,
DateTimeField,
FloatField,
TextField,
AutoField,
BooleanField,
)
from playhouse.shortcuts import model_to_dict
except ModuleNotFoundError as e:
helper.auto_installer_fix(e)
from app.classes.models.server_permissions import Permissions_Servers
from app.classes.shared.main_models import db_shortcuts
logger = logging.getLogger(__name__)
peewee_logger = logging.getLogger("peewee")
peewee_logger.setLevel(logging.INFO)
database = SqliteDatabase(
helper.db_path, pragmas={"journal_mode": "wal", "cache_size": -1024 * 10}
)
# **********************************************************************************
# Audit_Log Class
# **********************************************************************************
class Audit_Log(Model):
class Audit_Log(BaseModel):
audit_id = AutoField()
created = DateTimeField(default=datetime.datetime.now)
user_name = CharField(default="")
@ -47,14 +34,11 @@ class Audit_Log(Model):
) # When auditing global events, use server ID 0
log_msg = TextField(default="")
class Meta:
database = database
# **********************************************************************************
# Host_Stats Class
# **********************************************************************************
class Host_Stats(Model):
class Host_Stats(BaseModel):
time = DateTimeField(default=datetime.datetime.now, index=True)
boot_time = CharField(default="")
cpu_usage = FloatField(default=0)
@ -68,13 +52,12 @@ class Host_Stats(Model):
class Meta:
table_name = "host_stats"
database = database
# **********************************************************************************
# Commands Class
# **********************************************************************************
class Commands(Model):
class Commands(BaseModel):
command_id = AutoField()
created = DateTimeField(default=datetime.datetime.now)
server_id = ForeignKeyField(Servers, backref="server", index=True)
@ -85,13 +68,12 @@ class Commands(Model):
class Meta:
table_name = "commands"
database = database
# **********************************************************************************
# Webhooks Class
# **********************************************************************************
class Webhooks(Model):
class Webhooks(BaseModel):
id = AutoField()
name = CharField(max_length=64, unique=True, index=True)
method = CharField(default="POST")
@ -101,13 +83,12 @@ class Webhooks(Model):
class Meta:
table_name = "webhooks"
database = database
# **********************************************************************************
# Schedules Class
# **********************************************************************************
class Schedules(Model):
class Schedules(BaseModel):
schedule_id = IntegerField(unique=True, primary_key=True)
server_id = ForeignKeyField(Servers, backref="schedule_server")
enabled = BooleanField()
@ -124,13 +105,12 @@ class Schedules(Model):
class Meta:
table_name = "schedules"
database = database
# **********************************************************************************
# Backups Class
# **********************************************************************************
class Backups(Model):
class Backups(BaseModel):
excluded_dirs = CharField(null=True)
max_backups = IntegerField()
server_id = ForeignKeyField(Servers, backref="backups_server")
@ -138,10 +118,12 @@ class Backups(Model):
class Meta:
table_name = "backups"
database = database
class helpers_management:
def __init__(self, database, helper):
self.database = database
self.helper = helper
# **********************************************************************************
# Host_Stats Methods
@ -185,18 +167,17 @@ class helpers_management:
@staticmethod
def get_actity_log():
q = Audit_Log.select()
return db_helper.return_db_rows(q)
return db_shortcuts.return_db_rows(q)
@staticmethod
def add_to_audit_log(user_id, log_msg, server_id=None, source_ip=None):
def add_to_audit_log(self, user_id, log_msg, server_id=None, source_ip=None):
logger.debug(f"Adding to audit log User:{user_id} - Message: {log_msg} ")
user_data = users_helper.get_user(user_id)
user_data = helper_users.get_user(user_id)
audit_msg = f"{str(user_data['username']).capitalize()} {log_msg}"
server_users = server_permissions.get_server_user_list(server_id)
server_users = Permissions_Servers.get_server_user_list(server_id)
for user in server_users:
websocket_helper.broadcast_user(user, "notification", audit_msg)
self.helper.websocket_helper.broadcast_user(user, "notification", audit_msg)
Audit_Log.insert(
{
@ -210,17 +191,16 @@ class helpers_management:
# deletes records when they're more than 100
ordered = Audit_Log.select().order_by(+Audit_Log.created)
for item in ordered:
if not helper.get_setting("max_audit_entries"):
if not self.helper.get_setting("max_audit_entries"):
max_entries = 300
else:
max_entries = helper.get_setting("max_audit_entries")
max_entries = self.helper.get_setting("max_audit_entries")
if Audit_Log.select().count() > max_entries:
Audit_Log.delete().where(Audit_Log.audit_id == item.audit_id).execute()
else:
return
@staticmethod
def add_to_audit_log_raw(user_name, user_id, server_id, log_msg, source_ip):
def add_to_audit_log_raw(self, user_name, user_id, server_id, log_msg, source_ip):
Audit_Log.insert(
{
Audit_Log.user_name: user_name,
@ -234,10 +214,10 @@ class helpers_management:
ordered = Audit_Log.select().order_by(+Audit_Log.created)
for item in ordered:
# configurable through app/config/config.json
if not helper.get_setting("max_audit_entries"):
if not self.helper.get_setting("max_audit_entries"):
max_entries = 300
else:
max_entries = helper.get_setting("max_audit_entries")
max_entries = self.helper.get_setting("max_audit_entries")
if Audit_Log.select().count() > max_entries:
Audit_Log.delete().where(Audit_Log.audit_id == item.audit_id).execute()
else:
@ -354,8 +334,8 @@ class helpers_management:
}
return conf
@staticmethod
def set_backup_config(
self,
server_id: int,
backup_path: str = None,
max_backups: int = None,
@ -381,7 +361,7 @@ class helpers_management:
conf["excluded_dirs"] = dirs_to_exclude
conf["compress"] = compress
if not new_row:
with database.atomic():
with self.database.atomic():
if backup_path is not None:
u1 = (
Servers.update(backup_path=backup_path)
@ -395,7 +375,7 @@ class helpers_management:
)
logger.debug(f"Updating existing backup record. {u1}+{u2} rows affected")
else:
with database.atomic():
with self.database.atomic():
conf["server_id"] = server_id
if backup_path is not None:
Servers.update(backup_path=backup_path).where(
@ -404,8 +384,9 @@ class helpers_management:
Backups.create(**conf)
logger.debug("Creating new backup record.")
def get_excluded_backup_dirs(self, server_id: int):
excluded_dirs = self.get_backup_config(server_id)["excluded_dirs"]
@staticmethod
def get_excluded_backup_dirs(server_id: int):
excluded_dirs = helpers_management.get_backup_config(server_id)["excluded_dirs"]
if excluded_dirs is not None and excluded_dirs != "":
dir_list = excluded_dirs.split(",")
else:
@ -441,6 +422,3 @@ class helpers_management:
Commands.update({Commands.executed: True}).where(
Commands.executed == False # pylint: disable=singleton-comparison
).execute()
management_helper = helpers_management()

View File

@ -1,33 +1,22 @@
import logging
import datetime
from peewee import (
CharField,
DoesNotExist,
AutoField,
DateTimeField,
)
from playhouse.shortcuts import model_to_dict
from app.classes.shared.helpers import helper
try:
from peewee import (
SqliteDatabase,
Model,
CharField,
DoesNotExist,
AutoField,
DateTimeField,
)
from playhouse.shortcuts import model_to_dict
except ModuleNotFoundError as e:
helper.auto_installer_fix(e)
from app.classes.models.base_model import BaseModel
from app.classes.shared.helpers import Helpers
logger = logging.getLogger(__name__)
peewee_logger = logging.getLogger("peewee")
peewee_logger.setLevel(logging.INFO)
database = SqliteDatabase(
helper.db_path, pragmas={"journal_mode": "wal", "cache_size": -1024 * 10}
)
# **********************************************************************************
# Roles Class
# **********************************************************************************
class Roles(Model):
class Roles(BaseModel):
role_id = AutoField()
created = DateTimeField(default=datetime.datetime.now)
last_update = DateTimeField(default=datetime.datetime.now)
@ -35,13 +24,15 @@ class Roles(Model):
class Meta:
table_name = "roles"
database = database
# **********************************************************************************
# Roles Helpers
# **********************************************************************************
class helper_roles:
def __init__(self, database):
self.database = database
@staticmethod
def get_all_roles():
query = Roles.select()
@ -63,7 +54,7 @@ class helper_roles:
role_id = Roles.insert(
{
Roles.role_name: role_name.lower(),
Roles.created: helper.get_time_as_string(),
Roles.created: Helpers.get_time_as_string(),
}
).execute()
return role_id
@ -72,17 +63,13 @@ class helper_roles:
def update_role(role_id, up_data):
return Roles.update(up_data).where(Roles.role_id == role_id).execute()
@staticmethod
def remove_role(role_id):
with database.atomic():
def remove_role(self, role_id):
with self.database.atomic():
role = Roles.get(Roles.role_id == role_id)
return role.delete_instance()
@staticmethod
def role_id_exists(role_id):
if not roles_helper.get_role(role_id):
if not helper_roles.get_role(role_id):
return False
return True
roles_helper = helper_roles()

View File

@ -1,36 +1,24 @@
from enum import Enum
import logging
from peewee import (
ForeignKeyField,
CharField,
CompositeKey,
JOIN,
)
from app.classes.models.base_model import BaseModel
from app.classes.models.servers import Servers
from app.classes.models.roles import Roles
from app.classes.models.users import User_Roles, users_helper, ApiKeys, Users
from app.classes.shared.helpers import helper
from app.classes.shared.permission_helper import permission_helper
try:
from peewee import (
SqliteDatabase,
Model,
ForeignKeyField,
CharField,
CompositeKey,
JOIN,
)
from enum import Enum
except ModuleNotFoundError as e:
helper.auto_installer_fix(e)
from app.classes.models.users import User_Roles, helper_users, ApiKeys, Users
from app.classes.shared.permission_helper import PermissionHelper
logger = logging.getLogger(__name__)
peewee_logger = logging.getLogger("peewee")
peewee_logger.setLevel(logging.INFO)
database = SqliteDatabase(
helper.db_path, pragmas={"journal_mode": "wal", "cache_size": -1024 * 10}
)
# **********************************************************************************
# Role Servers Class
# **********************************************************************************
class Role_Servers(Model):
class Role_Servers(BaseModel):
role_id = ForeignKeyField(Roles, backref="role_server")
server_id = ForeignKeyField(Servers, backref="role_server")
permissions = CharField(default="00000000")
@ -38,7 +26,6 @@ class Role_Servers(Model):
class Meta:
table_name = "role_servers"
primary_key = CompositeKey("role_id", "server_id")
database = database
# **********************************************************************************
@ -73,7 +60,7 @@ class Permissions_Servers:
def get_permissions(permissions_mask):
permissions_list = []
for member in Enum_Permissions_Server.__members__.items():
if server_permissions.has_permission(permissions_mask, member[1]):
if Permissions_Servers.has_permission(permissions_mask, member[1]):
permissions_list.append(member[1])
return permissions_list
@ -98,7 +85,7 @@ class Permissions_Servers:
def get_token_permissions(permissions_mask, api_permissions_mask):
permissions_list = []
for member in Enum_Permissions_Server.__members__.items():
if permission_helper.both_have_perm(
if PermissionHelper.both_have_perm(
permissions_mask, api_permissions_mask, member[1]
):
permissions_list.append(member[1])
@ -166,7 +153,7 @@ class Permissions_Servers:
role_server = Role_Servers.get_or_none(Role_Servers.role_id == role_id)
if role_server is not None:
permissions_mask = role_server.permissions
permissions_list = server_permissions.get_permissions(permissions_mask)
permissions_list = Permissions_Servers.get_permissions(permissions_mask)
return permissions_list
@staticmethod
@ -193,24 +180,23 @@ class Permissions_Servers:
@staticmethod
def remove_roles_of_server(server_id):
with database.atomic():
return (
Role_Servers.delete()
.where(Role_Servers.server_id == server_id)
.execute()
)
return (
Role_Servers.delete()
.where(Role_Servers.server_id == server_id)
.execute()
)
@staticmethod
def get_user_id_permissions_mask(user_id, server_id: str):
user = users_helper.get_user_model(user_id)
return server_permissions.get_user_permissions_mask(user, server_id)
user = helper_users.get_user_model(user_id)
return Permissions_Servers.get_user_permissions_mask(user, server_id)
@staticmethod
def get_user_permissions_mask(user: Users, server_id: str):
if user.superuser:
permissions_mask = "1" * len(server_permissions.get_permissions_list())
permissions_mask = "1" * len(Permissions_Servers.get_permissions_list())
else:
roles_list = users_helper.get_user_roles_id(user.user_id)
roles_list = helper_users.get_user_roles_id(user.user_id)
role_server = (
Role_Servers.select()
.where(Role_Servers.role_id.in_(roles_list))
@ -220,7 +206,7 @@ class Permissions_Servers:
try:
permissions_mask = role_server[0].permissions
except IndexError:
permissions_mask = "0" * len(server_permissions.get_permissions_list())
permissions_mask = "0" * len(Permissions_Servers.get_permissions_list())
return permissions_mask
@staticmethod
@ -242,32 +228,32 @@ class Permissions_Servers:
@staticmethod
def get_user_id_permissions_list(user_id, server_id: str):
user = users_helper.get_user_model(user_id)
return server_permissions.get_user_permissions_list(user, server_id)
user = helper_users.get_user_model(user_id)
return Permissions_Servers.get_user_permissions_list(user, server_id)
@staticmethod
def get_user_permissions_list(user: Users, server_id: str):
if user.superuser:
permissions_list = server_permissions.get_permissions_list()
permissions_list = Permissions_Servers.get_permissions_list()
else:
permissions_mask = server_permissions.get_user_permissions_mask(
permissions_mask = Permissions_Servers.get_user_permissions_mask(
user, server_id
)
permissions_list = server_permissions.get_permissions(permissions_mask)
permissions_list = Permissions_Servers.get_permissions(permissions_mask)
return permissions_list
@staticmethod
def get_api_key_id_permissions_list(key_id, server_id: str):
key = ApiKeys.get(ApiKeys.token_id == key_id)
return server_permissions.get_api_key_permissions_list(key, server_id)
return Permissions_Servers.get_api_key_permissions_list(key, server_id)
@staticmethod
def get_api_key_permissions_list(key: ApiKeys, server_id: str):
user = users_helper.get_user(key.user_id)
user = helper_users.get_user(key.user_id)
if user["superuser"] and key.superuser:
return server_permissions.get_permissions_list()
return Permissions_Servers.get_permissions_list()
else:
roles_list = users_helper.get_user_roles_id(user["user_id"])
roles_list = helper_users.get_user_roles_id(user["user_id"])
role_server = (
Role_Servers.select()
.where(Role_Servers.role_id.in_(roles_list))
@ -275,12 +261,9 @@ class Permissions_Servers:
.execute()
)
user_permissions_mask = role_server[0].permissions
key_permissions_mask = key.server_permissions
permissions_mask = permission_helper.combine_masks(
key_permissions_mask = key.Permissions_Servers
permissions_mask = PermissionHelper.combine_masks(
user_permissions_mask, key_permissions_mask
)
permissions_list = server_permissions.get_permissions(permissions_mask)
permissions_list = Permissions_Servers.get_permissions(permissions_mask)
return permissions_list
server_permissions = Permissions_Servers()

View File

@ -1,36 +1,24 @@
import logging
import datetime
from peewee import (
ForeignKeyField,
CharField,
AutoField,
DateTimeField,
BooleanField,
IntegerField,
FloatField,
)
from app.classes.shared.helpers import helper
from app.classes.shared.main_models import db_helper
try:
from peewee import (
SqliteDatabase,
Model,
ForeignKeyField,
CharField,
AutoField,
DateTimeField,
BooleanField,
IntegerField,
FloatField,
)
except ModuleNotFoundError as e:
helper.auto_installer_fix(e)
from app.classes.shared.main_models import db_shortcuts
from app.classes.models.base_model import BaseModel
logger = logging.getLogger(__name__)
peewee_logger = logging.getLogger("peewee")
peewee_logger.setLevel(logging.INFO)
database = SqliteDatabase(
helper.db_path, pragmas={"journal_mode": "wal", "cache_size": -1024 * 10}
)
# **********************************************************************************
# Servers Class
# **********************************************************************************
class Servers(Model):
class Servers(BaseModel):
server_id = AutoField()
created = DateTimeField(default=datetime.datetime.now)
server_uuid = CharField(default="", index=True)
@ -52,13 +40,12 @@ class Servers(Model):
class Meta:
table_name = "servers"
database = database
# **********************************************************************************
# Servers Stats Class
# **********************************************************************************
class Server_Stats(Model):
class Server_Stats(BaseModel):
stats_id = AutoField()
created = DateTimeField(default=datetime.datetime.now)
server_id = ForeignKeyField(Servers, backref="server", index=True)
@ -84,13 +71,14 @@ class Server_Stats(Model):
class Meta:
table_name = "server_stats"
database = database
# **********************************************************************************
# Servers Class
# **********************************************************************************
class helper_servers:
def __init__(self, database):
self.database = database
# **********************************************************************************
# Generic Servers Methods
@ -139,16 +127,15 @@ class helper_servers:
def update_server(server_obj):
return server_obj.save()
@staticmethod
def remove_server(server_id):
with database.atomic():
def remove_server(self, server_id):
with self.database.atomic():
Servers.delete().where(Servers.server_id == server_id).execute()
@staticmethod
def get_server_data_by_id(server_id):
query = Servers.select().where(Servers.server_id == server_id).limit(1)
try:
return db_helper.return_rows(query)[0]
return db_shortcuts.return_rows(query)[0]
except IndexError:
return {}
@ -158,11 +145,11 @@ class helper_servers:
@staticmethod
def get_all_defined_servers():
query = Servers.select()
return db_helper.return_rows(query)
return db_shortcuts.return_rows(query)
@staticmethod
def get_all_servers_stats():
servers = servers_helper.get_all_defined_servers()
servers = helper_servers.get_all_defined_servers()
server_data = []
try:
for s in servers:
@ -175,7 +162,7 @@ class helper_servers:
server_data.append(
{
"server_data": s,
"stats": db_helper.return_rows(latest)[0],
"stats": db_shortcuts.return_rows(latest)[0],
"user_command_permission": True,
}
)
@ -187,7 +174,7 @@ class helper_servers:
@staticmethod
def get_server_friendly_name(server_id):
server_data = servers_helper.get_server_data_by_id(server_id)
server_data = helper_servers.get_server_data_by_id(server_id)
friendly_name = (
f"{server_data.get('server_name', None)} "
f"with ID: {server_data.get('server_id', 0)}"
@ -214,34 +201,31 @@ class helper_servers:
.order_by(Server_Stats.created.desc())
.limit(1)
)
return db_helper.return_rows(stats)[0]
return db_shortcuts.return_rows(stats)[0]
@staticmethod
def server_id_exists(server_id):
if not servers_helper.get_server_data_by_id(server_id):
if not helper_servers.get_server_data_by_id(server_id):
return False
return True
@staticmethod
def sever_crashed(server_id):
with database.atomic():
Server_Stats.update(crashed=True).where(
Server_Stats.server_id == server_id
).execute()
Server_Stats.update(crashed=True).where(
Server_Stats.server_id == server_id
).execute()
@staticmethod
def set_download(server_id):
with database.atomic():
Server_Stats.update(downloading=True).where(
Server_Stats.server_id == server_id
).execute()
Server_Stats.update(downloading=True).where(
Server_Stats.server_id == server_id
).execute()
@staticmethod
def finish_download(server_id):
with database.atomic():
Server_Stats.update(downloading=False).where(
Server_Stats.server_id == server_id
).execute()
Server_Stats.update(downloading=False).where(
Server_Stats.server_id == server_id
).execute()
@staticmethod
def get_download_status(server_id):
@ -252,10 +236,9 @@ class helper_servers:
@staticmethod
def server_crash_reset(server_id):
with database.atomic():
Server_Stats.update(crashed=False).where(
Server_Stats.server_id == server_id
).execute()
Server_Stats.update(crashed=False).where(
Server_Stats.server_id == server_id
).execute()
@staticmethod
def is_crashed(server_id):
@ -272,10 +255,9 @@ class helper_servers:
Server_Stats.select().where(Server_Stats.server_id == server_id)
except Exception as ex:
logger.error(f"Database entry not found! {ex}")
with database.atomic():
Server_Stats.update(updating=value).where(
Server_Stats.server_id == server_id
).execute()
Server_Stats.update(updating=value).where(
Server_Stats.server_id == server_id
).execute()
@staticmethod
def get_update_status(server_id):
@ -293,10 +275,9 @@ class helper_servers:
except Exception as ex:
logger.error(f"Database entry not found! {ex}")
return
with database.atomic():
Server_Stats.update(first_run=False).where(
Server_Stats.server_id == server_id
).execute()
Server_Stats.update(first_run=False).where(
Server_Stats.server_id == server_id
).execute()
@staticmethod
def get_first_run(server_id):
@ -325,7 +306,7 @@ class helper_servers:
@staticmethod
def can_stop_no_players(server_id, time_limit):
can = False
ttl_no_players = servers_helper.get_TTL_without_player(server_id)
ttl_no_players = helper_servers.get_TTL_without_player(server_id)
if (time_limit == -1) or (ttl_no_players > time_limit):
can = True
return can
@ -337,10 +318,9 @@ class helper_servers:
Server_Stats.select().where(Server_Stats.server_id == server_id)
except Exception as ex:
logger.error(f"Database entry not found! {ex}")
with database.atomic():
Server_Stats.update(waiting_start=value).where(
Server_Stats.server_id == server_id
).execute()
Server_Stats.update(waiting_start=value).where(
Server_Stats.server_id == server_id
).execute()
@staticmethod
def get_waiting_start(server_id):
@ -348,6 +328,3 @@ class helper_servers:
Server_Stats.select().where(Server_Stats.server_id == server_id).get()
)
return waiting_start.waiting_start
servers_helper = helper_servers()

View File

@ -2,38 +2,28 @@ import logging
import datetime
from typing import Optional, Union
from app.classes.models.roles import Roles, roles_helper
from app.classes.shared.helpers import helper
from peewee import (
ForeignKeyField,
CharField,
AutoField,
DateTimeField,
BooleanField,
CompositeKey,
DoesNotExist,
JOIN,
)
from playhouse.shortcuts import model_to_dict
try:
from peewee import (
SqliteDatabase,
Model,
ForeignKeyField,
CharField,
AutoField,
DateTimeField,
BooleanField,
CompositeKey,
DoesNotExist,
JOIN,
)
from playhouse.shortcuts import model_to_dict
except ModuleNotFoundError as e:
helper.auto_installer_fix(e)
from app.classes.shared.helpers import Helpers
from app.classes.models.base_model import BaseModel
from app.classes.models.roles import Roles, helper_roles
logger = logging.getLogger(__name__)
peewee_logger = logging.getLogger("peewee")
peewee_logger.setLevel(logging.INFO)
database = SqliteDatabase(
helper.db_path, pragmas={"journal_mode": "wal", "cache_size": -1024 * 10}
)
# **********************************************************************************
# Users Class
# **********************************************************************************
class Users(Model):
class Users(BaseModel):
user_id = AutoField()
created = DateTimeField(default=datetime.datetime.now)
last_login = DateTimeField(default=datetime.datetime.now)
@ -53,13 +43,12 @@ class Users(Model):
class Meta:
table_name = "users"
database = database
# **********************************************************************************
# API Keys Class
# **********************************************************************************
class ApiKeys(Model):
class ApiKeys(BaseModel):
token_id = AutoField()
name = CharField(default="", unique=True, index=True)
created = DateTimeField(default=datetime.datetime.now)
@ -70,26 +59,28 @@ class ApiKeys(Model):
class Meta:
table_name = "api_keys"
database = database
# **********************************************************************************
# User Roles Class
# **********************************************************************************
class User_Roles(Model):
class User_Roles(BaseModel):
user_id = ForeignKeyField(Users, backref="user_role")
role_id = ForeignKeyField(Roles, backref="user_role")
class Meta:
table_name = "user_roles"
primary_key = CompositeKey("user_id", "role_id")
database = database
# **********************************************************************************
# Users Helpers
# **********************************************************************************
class helper_users:
def __init__(self, database, helper):
self.database = database
self.helper = helper
@staticmethod
def get_by_id(user_id):
return Users.get_by_id(user_id)
@ -137,7 +128,7 @@ class helper_users:
if user:
# I know it should apply it without setting it but I'm just making sure
user = users_helper.add_user_roles(user)
user = helper_users.add_user_roles(user)
return user
else:
# logger.debug("user: ({}) {}".format(user_id, {}))
@ -155,11 +146,11 @@ class helper_users:
@staticmethod
def get_user_model(user_id: str) -> Users:
user = Users.get(Users.user_id == user_id)
user = users_helper.add_user_roles(user)
user = helper_users.add_user_roles(user)
return user
@staticmethod
def add_user(
self,
username: str,
password: str = None,
email: Optional[str] = None,
@ -167,7 +158,7 @@ class helper_users:
superuser: bool = False,
) -> str:
if password is not None:
pw_enc = helper.encode_pass(password)
pw_enc = self.helper.encode_pass(password)
else:
pw_enc = None
user_id = Users.insert(
@ -177,7 +168,7 @@ class helper_users:
Users.email: email,
Users.enabled: enabled,
Users.superuser: superuser,
Users.created: helper.get_time_as_string(),
Users.created: Helpers.get_time_as_string(),
}
).execute()
return user_id
@ -197,7 +188,7 @@ class helper_users:
Users.email: email,
Users.enabled: enabled,
Users.superuser: superuser,
Users.created: helper.get_time_as_string(),
Users.created: Helpers.get_time_as_string(),
}
).execute()
return user_id
@ -230,9 +221,8 @@ class helper_users:
final_users.append(suser.user_id)
return final_users
@staticmethod
def remove_user(user_id):
with database.atomic():
def remove_user(self, user_id):
with self.database.atomic():
User_Roles.delete().where(User_Roles.user_id == user_id).execute()
user = Users.get(Users.user_id == user_id)
return user.delete_instance()
@ -259,7 +249,7 @@ class helper_users:
@staticmethod
def user_id_exists(user_id):
if not users_helper.get_user(user_id):
if not helper_users.get_user(user_id):
return False
return True
@ -276,7 +266,7 @@ class helper_users:
roles_list = []
roles = User_Roles.select().where(User_Roles.user_id == user_id)
for r in roles:
roles_list.append(roles_helper.get_role(r.role_id)["role_id"])
roles_list.append(helper_roles.get_role(r.role_id)["role_id"])
return roles_list
@staticmethod
@ -284,7 +274,7 @@ class helper_users:
roles_list = []
roles = User_Roles.select().where(User_Roles.user_id == user_id)
for r in roles:
roles_list.append(roles_helper.get_role(r.role_id)["role_name"])
roles_list.append(helper_roles.get_role(r.role_id)["role_name"])
return roles_list
@staticmethod
@ -384,6 +374,3 @@ class helper_users:
@staticmethod
def delete_user_api_key(key_id: str):
ApiKeys.delete().where(ApiKeys.token_id == key_id).execute()
users_helper = helper_users()

View File

@ -1,58 +1,50 @@
import logging
import time
from typing import Optional, Dict, Any, Tuple
import jwt
from jwt import PyJWTError
from app.classes.models.users import users_helper, ApiKeys
from app.classes.shared.helpers import helper
try:
import jwt
from jwt import PyJWTError
except ModuleNotFoundError as e:
helper.auto_installer_fix(e)
from app.classes.models.users import helper_users, ApiKeys
logger = logging.getLogger(__name__)
class Authentication:
def __init__(self):
def __init__(self, helper):
self.helper = helper
self.secret = "my secret"
self.secret = helper.get_setting("apikey_secret", None)
self.secret = self.helper.get_setting("apikey_secret", None)
if self.secret is None or self.secret == "random":
self.secret = helper.random_string_generator(64)
helper.set_setting("apikey_secret", self.secret)
self.secret = self.helper.random_string_generator(64)
self.helper.set_setting("apikey_secret", self.secret)
@staticmethod
def generate(user_id, extra=None):
def generate(self, user_id, extra=None):
if extra is None:
extra = {}
jwt_encoded = jwt.encode(
{"user_id": user_id, "iat": int(time.time()), **extra},
authentication.secret,
self.secret,
algorithm="HS256",
)
return jwt_encoded
@staticmethod
def read(token):
return jwt.decode(token, authentication.secret, algorithms=["HS256"])
def read(self, token):
return jwt.decode(token, self.secret, algorithms=["HS256"])
@staticmethod
def check_no_iat(token) -> Optional[Dict[str, Any]]:
def check_no_iat(self, token) -> Optional[Dict[str, Any]]:
try:
return jwt.decode(token, authentication.secret, algorithms=["HS256"])
return jwt.decode(token, self.secret, algorithms=["HS256"])
except PyJWTError as error:
logger.debug("Error while checking JWT token: ", exc_info=error)
return None
@staticmethod
def check(
self,
token,
) -> Optional[Tuple[Optional[ApiKeys], Dict[str, Any], Dict[str, Any]]]:
try:
data = jwt.decode(token, authentication.secret, algorithms=["HS256"])
data = jwt.decode(token, self.secret, algorithms=["HS256"])
except PyJWTError as error:
logger.debug("Error while checking JWT token: ", exc_info=error)
return None
@ -60,11 +52,11 @@ class Authentication:
key: Optional[ApiKeys] = None
if "token_id" in data:
key_id = data["token_id"]
key = users_helper.get_user_api_key(key_id)
key = helper_users.get_user_api_key(key_id)
if key is None:
return None
user_id: str = data["user_id"]
user = users_helper.get_user(user_id)
user = helper_users.get_user(user_id)
# TODO: Have a cache or something so we don't constantly
# have to query the database
if int(user.get("valid_tokens_from").timestamp()) < iat:
@ -73,9 +65,5 @@ class Authentication:
else:
return None
@staticmethod
def check_bool(token) -> bool:
return authentication.check(token) is not None
authentication = Authentication()
def check_bool(self, token) -> bool:
return self.check(token) is not None

View File

@ -4,22 +4,20 @@ import time
import threading
import logging
from app.classes.shared.console import console
from app.classes.shared.helpers import helper
from app.classes.shared.import3 import import3
from app.classes.web.websocket_helper import websocket_helper
logger = logging.getLogger(__name__)
class MainPrompt(cmd.Cmd):
def __init__(self, tasks_manager, migration_manager):
def __init__(self, helper, tasks_manager, migration_manager):
super().__init__()
self.helper = helper
self.console = self.helper.console
self.tasks_manager = tasks_manager
self.migration_manager = migration_manager
# overrides the default Prompt
prompt = f"Crafty Controller v{helper.get_version_string()} > "
# overrides the default Prompt
self.prompt = f"Crafty Controller v{self.helper.get_version_string()} > "
# see MR !233 for pylint exemptino reason
@staticmethod
@ -36,20 +34,20 @@ class MainPrompt(cmd.Cmd):
elif line == "down":
self.migration_manager.down()
elif line == "done":
console.info(self.migration_manager.done)
self.console.info(self.migration_manager.done)
elif line == "todo":
console.info(self.migration_manager.todo)
self.console.info(self.migration_manager.todo)
elif line == "diff":
console.info(self.migration_manager.diff)
self.console.info(self.migration_manager.diff)
elif line == "info":
console.info(f"Done: {self.migration_manager.done}")
console.info(f"FS: {self.migration_manager.todo}")
console.info(f"Todo: {self.migration_manager.diff}")
self.console.info(f"Done: {self.migration_manager.done}")
self.console.info(f"FS: {self.migration_manager.todo}")
self.console.info(f"Todo: {self.migration_manager.diff}")
elif line.startswith("add "):
migration_name = line[len("add ") :]
self.migration_manager.create(migration_name, False)
else:
console.info("Unknown migration command")
self.console.info("Unknown migration command")
@staticmethod
def do_threads(_line):
@ -67,24 +65,21 @@ class MainPrompt(cmd.Cmd):
def universal_exit(self):
logger.info("Stopping all server daemons / threads")
console.info(
self.console.info(
"Stopping all server daemons / threads - This may take a few seconds"
)
websocket_helper.disconnect_all()
console.info("Waiting for main thread to stop")
self.helper.websocket_helper.disconnect_all()
self.console.info("Waiting for main thread to stop")
while True:
if self.tasks_manager.get_main_thread_run_status():
sys.exit(0)
time.sleep(1)
@staticmethod
def help_exit():
console.help("Stops the server if running, Exits the program")
def help_exit(self):
self.console.help("Stops the server if running, Exits the program")
@staticmethod
def help_migrations():
console.help("Only for advanced users. Use with caution")
def help_migrations(self):
self.console.help("Only for advanced users. Use with caution")
@staticmethod
def help_import3():
console.help("Import users and servers from Crafty 3")
def help_import3(self):
self.console.help("Import users and servers from Crafty 3")

View File

@ -69,6 +69,3 @@ class Console:
def help(self, message):
dt = datetime.datetime.now().strftime("%Y-%m-%d %I:%M:%S %p")
self.green(f"[+] Crafty: {dt} - HELP:\t{message}")
console = Console()

View File

@ -10,12 +10,13 @@ logger = logging.getLogger(__name__)
class FileHelpers:
allowed_quotes = ['"', "'", "`"]
def del_dirs(self, path):
@staticmethod
def del_dirs(path):
path = pathlib.Path(path)
for sub in path.iterdir():
if sub.is_dir():
# Delete folder if it is a folder
self.del_dirs(sub)
FileHelpers.del_dirs(sub)
else:
# Delete file if it is a file:
sub.unlink()
@ -45,13 +46,15 @@ class FileHelpers:
def copy_file(src_path, dest_path):
shutil.copy(src_path, dest_path)
def move_dir(self, src_path, dest_path):
self.copy_dir(src_path, dest_path)
self.del_dirs(src_path)
@staticmethod
def move_dir(src_path, dest_path):
FileHelpers.copy_dir(src_path, dest_path)
FileHelpers.del_dirs(src_path)
def move_file(self, src_path, dest_path):
self.copy_file(src_path, dest_path)
self.del_file(src_path)
@staticmethod
def move_file(src_path, dest_path):
FileHelpers.copy_file(src_path, dest_path)
FileHelpers.del_file(src_path)
@staticmethod
def make_archive(path_to_destination, path_to_zip):
@ -110,6 +113,3 @@ class FileHelpers:
)
return True
file_helper = FileHelpers()

View File

@ -19,10 +19,10 @@ from socket import gethostname
from contextlib import suppress
import psutil
from app.classes.shared.console import console
from app.classes.shared.installer import installer
from app.classes.shared.file_helpers import file_helper
from app.classes.web.websocket_helper import websocket_helper
from app.classes.shared.file_helpers import FileHelpers
from app.classes.shared.translation import Translation
from app.classes.web.websocket_helper import WebSocketHelper
logger = logging.getLogger(__name__)
@ -41,7 +41,8 @@ except ModuleNotFoundError as err:
class Helpers:
allowed_quotes = ['"', "'", "`"]
def __init__(self):
def __init__(self, console):
self.console = console
self.root_dir = os.path.abspath(os.path.curdir)
self.config_dir = os.path.join(self.root_dir, "app", "config")
self.webroot = os.path.join(self.root_dir, "app", "frontend")
@ -61,17 +62,22 @@ class Helpers:
self.passhasher = PasswordHasher()
self.exiting = False
self.websocket_helper = WebSocketHelper(self)
self.translation = Translation(self)
@staticmethod
def auto_installer_fix(ex):
logger.critical(f"Import Error: Unable to load {ex.name} module", exc_info=True)
print(f"Import Error: Unable to load {ex.name} module")
installer.do_install()
def float_to_string(self, gbs: int):
@staticmethod
def float_to_string(gbs: int):
s = str(float(gbs) * 1000).rstrip("0").rstrip(".")
return s
def check_file_perms(self, path):
@staticmethod
def check_file_perms(path):
try:
open(path, "r", encoding="utf-8").close()
logger.info(f"{path} is readable")
@ -79,8 +85,9 @@ class Helpers:
except PermissionError:
return False
def is_file_older_than_x_days(self, file, days=1):
if self.check_file_exists(file):
@staticmethod
def is_file_older_than_x_days(file, days=1):
if Helpers.check_file_exists(file):
file_time = os.path.getmtime(file)
# Check against 24 hours
if (time.time() - file_time) / 3600 > 24 * days:
@ -193,14 +200,14 @@ class Helpers:
else:
logger.error(f"Config File Error: setting {key} does not exist")
console.error(f"Config File Error: setting {key} does not exist")
self.console.error(f"Config File Error: setting {key} does not exist")
return default_return
except Exception as e:
logger.critical(
f"Config File Error: Unable to read {self.settings_file} due to {e}"
)
console.critical(
self.console.critical(
f"Config File Error: Unable to read {self.settings_file} due to {e}"
)
@ -217,7 +224,7 @@ class Helpers:
else:
logger.error(f"Config File Error: setting {key} does not exist")
console.error(f"Config File Error: setting {key} does not exist")
self.console.error(f"Config File Error: setting {key} does not exist")
return default_return
with open(self.settings_file, "w", encoding="utf-8") as f:
@ -227,11 +234,12 @@ class Helpers:
logger.critical(
f"Config File Error: Unable to read {self.settings_file} due to {e}"
)
console.critical(
self.console.critical(
f"Config File Error: Unable to read {self.settings_file} due to {e}"
)
def get_local_ip(self):
@staticmethod
def get_local_ip():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
try:
# doesn't even have to be reachable
@ -252,7 +260,7 @@ class Helpers:
version_data = json.load(f)
except Exception as e:
console.critical(f"Unable to get version data! \n{e}")
self.console.critical(f"Unable to get version data! \n{e}")
return version_data
@ -274,7 +282,6 @@ class Helpers:
return data
def get_version_string(self):
version_data = self.get_version()
major = version_data.get("major", "?")
minor = version_data.get("minor", "?")
@ -331,7 +338,8 @@ class Helpers:
return line
def validate_traversal(self, base_path, filename):
@staticmethod
def validate_traversal(base_path, filename):
logger.debug(f'Validating traversal ("{base_path}", "{filename}")')
base = pathlib.Path(base_path).resolve()
file = pathlib.Path(filename)
@ -342,8 +350,9 @@ class Helpers:
else:
raise ValueError("Path traversal detected")
def tail_file(self, file_name, number_lines=20):
if not self.check_file_exists(file_name):
@staticmethod
def tail_file(file_name, number_lines=20):
if not Helpers.check_file_exists(file_name):
logger.warning(f"Unable to find file to tail: {file_name}")
return [f"Unable to find file to tail: {file_name}"]
@ -392,8 +401,9 @@ class Helpers:
logger.critical(f"Unable to write to {path} - Error: {e}")
return False
def checkRoot(self):
if self.is_os_windows():
@staticmethod
def checkRoot():
if Helpers.is_os_windows():
if ctypes.windll.shell32.IsUserAnAdmin() == 1:
return True
else:
@ -404,7 +414,8 @@ class Helpers:
else:
return False
def unzipFile(self, zip_path):
@staticmethod
def unzipFile(zip_path):
new_dir_list = zip_path.split("/")
new_dir = ""
for i in range(len(new_dir_list) - 1):
@ -413,8 +424,8 @@ class Helpers:
else:
new_dir += "/" + new_dir_list[i]
if helper.check_file_perms(zip_path) and os.path.isfile(zip_path):
helper.ensure_dir_exists(new_dir)
if Helpers.check_file_perms(zip_path) and os.path.isfile(zip_path):
Helpers.ensure_dir_exists(new_dir)
tempDir = tempfile.mkdtemp()
try:
with zipfile.ZipFile(zip_path, "r") as zip_ref:
@ -429,7 +440,7 @@ class Helpers:
for item in os.listdir(full_root_path):
try:
file_helper.move_dir(
FileHelpers.move_dir(
os.path.join(full_root_path, item),
os.path.join(new_dir, item),
)
@ -447,7 +458,7 @@ class Helpers:
logger.info("Checking app directory writable")
writeable = self.check_writeable(self.root_dir)
writeable = Helpers.check_writeable(self.root_dir)
# if not writeable, let's bomb out
if not writeable:
@ -459,13 +470,13 @@ class Helpers:
with suppress(FileExistsError):
os.makedirs(os.path.join(self.root_dir, "logs"))
except Exception as e:
console.error(f"Failed to make logs directory with error: {e} ")
self.console.error(f"Failed to make logs directory with error: {e} ")
# ensure the log file is there
try:
open(log_file, "a", encoding="utf-8").close()
except Exception as e:
console.critical(f"Unable to open log file! {e}")
self.console.critical(f"Unable to open log file! {e}")
sys.exit(1)
# del any old session.lock file as this is a new session
@ -565,7 +576,7 @@ class Helpers:
pid = data.get("pid")
started = data.get("started")
if psutil.pid_exists(pid):
console.critical(
self.console.critical(
f"Another Crafty Controller agent seems to be running..."
f"\npid: {pid} \nstarted on: {started}"
)
@ -580,7 +591,7 @@ class Helpers:
except Exception as e:
logger.error(f"Failed to locate existing session.lock with error: {e} ")
console.error(
self.console.error(
f"Failed to locate existing session.lock with error: {e} "
)
@ -595,11 +606,12 @@ class Helpers:
# because this is a recursive function, we will return bytes,
# and set human readable later
def get_dir_size(self, path: str):
@staticmethod
def get_dir_size(path: str):
total = 0
for entry in os.scandir(path):
if entry.is_dir(follow_symlinks=False):
total += self.get_dir_size(entry.path)
total += Helpers.get_dir_size(entry.path)
else:
total += entry.stat(follow_symlinks=False).st_size
return total
@ -613,11 +625,12 @@ class Helpers:
)
]
def get_human_readable_files_sizes(self, paths: list):
@staticmethod
def get_human_readable_files_sizes(paths: list):
sizes = []
for p in paths:
sizes.append(
{"path": p, "size": self.human_readable_file_size(os.stat(p).st_size)}
{"path": p, "size": Helpers.human_readable_file_size(os.stat(p).st_size)}
)
return sizes
@ -633,10 +646,12 @@ class Helpers:
b64_bytes = base64.decodebytes(s_bytes)
return b64_bytes.decode("utf-8")
def create_uuid(self):
@staticmethod
def create_uuid():
return str(uuid.uuid4())
def ensure_dir_exists(self, path):
@staticmethod
def ensure_dir_exists(path):
"""
ensures a directory exists
@ -662,7 +677,7 @@ class Helpers:
cert_dir = os.path.join(self.config_dir, "web", "certs")
# create a directory if needed
self.ensure_dir_exists(cert_dir)
Helpers.ensure_dir_exists(cert_dir)
cert_file = os.path.join(cert_dir, "commander.cert.pem")
key_file = os.path.join(cert_dir, "commander.key.pem")
@ -671,16 +686,16 @@ class Helpers:
logger.info(f"SSL Key File is set to: {key_file}")
# don't create new files if we already have them.
if self.check_file_exists(cert_file) and self.check_file_exists(key_file):
if Helpers.check_file_exists(cert_file) and Helpers.check_file_exists(key_file):
logger.info("Cert and Key files already exists, not creating them.")
return True
console.info("Generating a self signed SSL")
self.console.info("Generating a self signed SSL")
logger.info("Generating a self signed SSL")
# create a key pair
logger.info("Generating a key pair. This might take a moment.")
console.info("Generating a key pair. This might take a moment.")
self.console.info("Generating a key pair. This might take a moment.")
k = crypto.PKey()
k.generate_key(crypto.TYPE_RSA, 4096)
@ -756,11 +771,11 @@ class Helpers:
default_file = os.path.join(self.root_dir, "default.json")
data = {}
if self.check_file_exists(default_file):
if Helpers.check_file_exists(default_file):
with open(default_file, "r", encoding="utf-8") as f:
data = json.load(f)
del_json = helper.get_setting("delete_default_json")
del_json = self.get_setting("delete_default_json")
if del_json:
os.remove(default_file)
@ -885,27 +900,25 @@ class Helpers:
</input></div><li>"""
return output
@staticmethod
def unzipServer(zip_path, user_id):
if helper.check_file_perms(zip_path):
def unzipServer(self, zip_path, user_id):
if Helpers.check_file_perms(zip_path):
tempDir = tempfile.mkdtemp()
with zipfile.ZipFile(zip_path, "r") as zip_ref:
# extracts archive to temp directory
zip_ref.extractall(tempDir)
if user_id:
websocket_helper.broadcast_user(
self.websocket_helper.broadcast_user(
user_id, "send_temp_path", {"path": tempDir}
)
@staticmethod
def backup_select(path, user_id):
def backup_select(self, path, user_id):
if user_id:
websocket_helper.broadcast_user(user_id, "send_temp_path", {"path": path})
self.websocket_helper.broadcast_user(user_id, "send_temp_path", {"path": path})
@staticmethod
def unzip_backup_archive(backup_path, zip_name):
zip_path = os.path.join(backup_path, zip_name)
if helper.check_file_perms(zip_path):
if Helpers.check_file_perms(zip_path):
tempDir = tempfile.mkdtemp()
with zipfile.ZipFile(zip_path, "r") as zip_ref:
# extracts archive to temp directory
@ -937,7 +950,7 @@ class Helpers:
@staticmethod
def copy_files(source, dest):
if os.path.isfile(source):
file_helper.copy_file(source, dest)
FileHelpers.copy_file(source, dest)
logger.info("Copying jar %s to %s", source, dest)
else:
logger.info("Source jar does not exist.")
@ -974,6 +987,3 @@ class Helpers:
return "en"
else:
return lang + "-" + region
helper = Helpers()

View File

@ -2,16 +2,17 @@ import json
import os
import logging
from app.classes.controllers.users_controller import users_helper
from app.classes.shared.main_controller import Controller
from app.classes.shared.console import console
from app.classes.controllers.users_controller import helper_users
logger = logging.getLogger(__name__)
class import3:
def __init__(self):
self.controller = Controller()
def __init__(self, helper, controller):
self.helper = helper
self.console = self.helper.console
self.controller = controller
def start_import(self):
folder = os.path.normpath(
@ -21,11 +22,11 @@ class import3:
)
)
if not os.path.exists(folder):
console.info(
self.console.info(
"Crafty cannot find the path you entered. "
"Does Crafty's user have permission to access it?"
)
console.info("Please run the import3 command again and enter a valid path.")
self.console.info("Please run the import3 command again and enter a valid path.")
else:
with open(os.path.join(folder, "users.json"), encoding="utf-8") as f:
user_json = json.loads(f.read())
@ -34,16 +35,15 @@ class import3:
self.import_users(user_json)
self.import_servers(servers_json, self.controller)
@staticmethod
def import_users(json_data):
def import_users(self, json_data):
# If there is only one user to import json needs to call the data differently
if isinstance(json_data, list):
for user in json_data:
users_helper.add_rawpass_user(user["username"], user["password"])
console.info(f"Imported user {user['username']} from Crafty 3")
helper_users.add_rawpass_user(user["username"], user["password"])
self.console.info(f"Imported user {user['username']} from Crafty 3")
logger.info(f"Imported user {user['username']} from Crafty 3")
else:
console.info(
self.console.info(
"There is only one user detected. "
"Cannot create duplicate Admin account."
)
@ -52,8 +52,7 @@ class import3:
"Cannot create duplicate Admin account."
)
@staticmethod
def import_servers(json_data, controller):
def import_servers(self, json_data, controller):
# If there is only one server to import json needs to call the data differently
if isinstance(json_data, list):
for server in json_data:
@ -65,7 +64,7 @@ class import3:
max_mem=(int(server["memory_max"]) / 1000),
port=server["server_port"],
)
console.info(
self.console.info(
f"Imported server {server['server_name']}[{server['id']}] "
f"from Crafty 3 to new server id {new_server_id}"
)
@ -82,7 +81,7 @@ class import3:
max_mem=(int(json_data["memory_max"]) / 1000),
port=json_data["server_port"],
)
console.info(
self.console.info(
f"Imported server {json_data['server_name']}[{json_data['id']}] "
f"from Crafty 3 to new server id {new_server_id}"
)
@ -90,6 +89,3 @@ class import3:
f"Imported server {json_data['server_name']}[{json_data['id']}] "
f"from Crafty 3 to new server id {new_server_id}"
)
import3 = import3()

View File

@ -6,6 +6,10 @@ import time
import logging
import tempfile
from typing import Union
from peewee import DoesNotExist
# TZLocal is set as a hidden import on win pipeline
from tzlocal import get_localzone
from apscheduler.schedulers.background import BackgroundScheduler
from app.classes.controllers.crafty_perms_controller import Crafty_Perms_Controller
from app.classes.controllers.management_controller import Management_Controller
@ -16,39 +20,34 @@ from app.classes.controllers.servers_controller import Servers_Controller
from app.classes.models.server_permissions import Enum_Permissions_Server
from app.classes.models.users import helper_users
from app.classes.models.management import helpers_management
from app.classes.models.servers import servers_helper
from app.classes.shared.console import console
from app.classes.shared.helpers import helper
from app.classes.models.servers import helper_servers
from app.classes.shared.authentication import Authentication
from app.classes.shared.helpers import Helpers
from app.classes.shared.server import Server
from app.classes.shared.file_helpers import file_helper
from app.classes.shared.file_helpers import FileHelpers
from app.classes.minecraft.server_props import ServerProps
from app.classes.minecraft.serverjars import server_jar_obj
from app.classes.minecraft.serverjars import ServerJars
from app.classes.minecraft.stats import Stats
from app.classes.web.websocket_helper import websocket_helper
try:
from peewee import DoesNotExist
# TZLocal is set as a hidden import on win pipeline
from tzlocal import get_localzone
from apscheduler.schedulers.background import BackgroundScheduler
except ModuleNotFoundError as err:
helper.auto_installer_fix(err)
logger = logging.getLogger(__name__)
class Controller:
def __init__(self):
def __init__(self, database, helper):
self.helper = helper
self.console = self.helper.console
self.server_jars = ServerJars(helper)
self.users_helper = helper_users(database, self.helper)
self.servers_helper = helper_servers(database)
self.management_helper = helpers_management(database, self.helper)
self.authentication = Authentication(self.helper)
self.servers_list = []
self.stats = Stats(self)
self.stats = Stats(self.helper, self)
self.crafty_perms = Crafty_Perms_Controller()
self.management = Management_Controller()
self.roles = Roles_Controller()
self.management = Management_Controller(self.management_helper)
self.roles = Roles_Controller(self.users_helper)
self.server_perms = Server_Perms_Controller()
self.servers = Servers_Controller()
self.users = Users_Controller()
self.servers = Servers_Controller(self.servers_helper)
self.users = Users_Controller(self.helper, self.users_helper, self.authentication)
tz = get_localzone()
self.support_scheduler = BackgroundScheduler(timezone=str(tz))
self.support_scheduler.start()
@ -83,28 +82,28 @@ class Controller:
continue
# if this server path no longer exists - let's warn and bomb out
if not helper.check_path_exists(
helper.get_os_understandable_path(s["path"])
if not Helpers.check_path_exists(
Helpers.get_os_understandable_path(s["path"])
):
logger.warning(
f"Unable to find server {s['server_name']} at path {s['path']}. "
f"Skipping this server"
)
console.warning(
self.console.warning(
f"Unable to find server {s['server_name']} at path {s['path']}. "
f"Skipping this server"
)
continue
settings_file = os.path.join(
helper.get_os_understandable_path(s["path"]), "server.properties"
Helpers.get_os_understandable_path(s["path"]), "server.properties"
)
# if the properties file isn't there, let's warn
if not helper.check_file_exists(settings_file):
if not Helpers.check_file_exists(settings_file):
logger.error(f"Unable to find {settings_file}. Skipping this server.")
console.error(f"Unable to find {settings_file}. Skipping this server.")
self.console.error(f"Unable to find {settings_file}. Skipping this server.")
continue
settings = ServerProps(settings_file)
@ -112,7 +111,7 @@ class Controller:
temp_server_dict = {
"server_id": s.get("server_id"),
"server_data_obj": s,
"server_obj": Server(self.stats),
"server_obj": Server(self.helper, self.management_helper, self.stats),
"server_settings": settings.props,
}
@ -127,7 +126,7 @@ class Controller:
self.refresh_server_settings(s["server_id"])
console.info(
self.console.info(
f"Loaded Server: ID {s['server_id']}"
+ f" | Name: {s['server_name']}"
+ f" | Autostart: {s['auto_start']}"
@ -154,7 +153,7 @@ class Controller:
self.users.set_prepare(exec_user["user_id"])
# pausing so on screen notifications can run for user
time.sleep(7)
websocket_helper.broadcast_user(
self.helper.websocket_helper.broadcast_user(
exec_user["user_id"], "notification", "Preparing your support logs"
)
tempDir = tempfile.mkdtemp()
@ -195,12 +194,12 @@ class Controller:
final_path += "_" + server["server_uuid"]
os.mkdir(final_path)
try:
file_helper.copy_file(server["log_path"], final_path)
FileHelpers.copy_file(server["log_path"], final_path)
except Exception as e:
logger.warning(f"Failed to copy file with error: {e}")
# Copy crafty logs to archive dir
full_log_name = os.path.join(crafty_path, "logs")
file_helper.copy_dir(os.path.join(self.project_root, "logs"), full_log_name)
FileHelpers.copy_dir(os.path.join(self.project_root, "logs"), full_log_name)
self.support_scheduler.add_job(
self.log_status,
"interval",
@ -208,17 +207,17 @@ class Controller:
id="logs_" + str(exec_user["user_id"]),
args=[full_temp, tempZipStorage + ".zip", exec_user],
)
file_helper.make_archive(tempZipStorage, tempDir)
FileHelpers.make_archive(tempZipStorage, tempDir)
if len(websocket_helper.clients) > 0:
websocket_helper.broadcast_user(
if len(self.helper.websocket_helper.clients) > 0:
self.helper.websocket_helper.broadcast_user(
exec_user["user_id"],
"support_status_update",
helper.calc_percent(full_temp, tempZipStorage + ".zip"),
Helpers.calc_percent(full_temp, tempZipStorage + ".zip"),
)
tempZipStorage += ".zip"
websocket_helper.broadcast_user(exec_user["user_id"], "send_logs_bootbox", {})
self.helper.websocket_helper.broadcast_user(exec_user["user_id"], "send_logs_bootbox", {})
self.users.set_support_path(exec_user["user_id"], tempZipStorage)
@ -229,7 +228,7 @@ class Controller:
def add_system_user():
helper_users.add_user(
"system",
helper.random_string_generator(64),
Helpers.random_string_generator(64),
"default@example.com",
False,
False,
@ -254,11 +253,11 @@ class Controller:
svr.stop_crash_detection()
def log_status(self, source_path, dest_path, exec_user):
results = helper.calc_percent(source_path, dest_path)
results = Helpers.calc_percent(source_path, dest_path)
self.log_stats = results
if len(websocket_helper.clients) > 0:
websocket_helper.broadcast_user(
if len(self.helper.websocket_helper.clients) > 0:
self.helper.websocket_helper.broadcast_user(
exec_user["user_id"], "support_status_update", results
)
@ -286,7 +285,7 @@ class Controller:
@staticmethod
def list_defined_servers():
servers = servers_helper.get_all_defined_servers()
servers = helper_servers.get_all_defined_servers()
return servers
def list_running_servers(self):
@ -307,14 +306,14 @@ class Controller:
def stop_all_servers(self):
servers = self.list_running_servers()
logger.info(f"Found {len(servers)} running server(s)")
console.info(f"Found {len(servers)} running server(s)")
self.console.info(f"Found {len(servers)} running server(s)")
logger.info("Stopping All Servers")
console.info("Stopping All Servers")
self.console.info("Stopping All Servers")
for s in servers:
logger.info(f"Stopping Server ID {s['id']} - {s['name']}")
console.info(f"Stopping Server ID {s['id']} - {s['name']}")
self.console.info(f"Stopping Server ID {s['id']} - {s['name']}")
self.stop_server(s["id"])
@ -322,7 +321,7 @@ class Controller:
time.sleep(2)
logger.info("All Servers Stopped")
console.info("All Servers Stopped")
self.console.info("All Servers Stopped")
def stop_server(self, server_id):
# issue the stop command
@ -338,12 +337,12 @@ class Controller:
max_mem: int,
port: int,
):
server_id = helper.create_uuid()
server_dir = os.path.join(helper.servers_dir, server_id)
backup_path = os.path.join(helper.backup_path, server_id)
if helper.is_os_windows():
server_dir = helper.wtol_path(server_dir)
backup_path = helper.wtol_path(backup_path)
server_id = Helpers.create_uuid()
server_dir = os.path.join(self.helper.servers_dir, server_id)
backup_path = os.path.join(self.helper.backup_path, server_id)
if Helpers.is_os_windows():
server_dir = Helpers.wtol_path(server_dir)
backup_path = Helpers.wtol_path(backup_path)
server_dir.replace(" ", "^ ")
backup_path.replace(" ", "^ ")
@ -351,8 +350,8 @@ class Controller:
full_jar_path = os.path.join(server_dir, server_file)
# make the dir - perhaps a UUID?
helper.ensure_dir_exists(server_dir)
helper.ensure_dir_exists(backup_path)
Helpers.ensure_dir_exists(server_dir)
Helpers.ensure_dir_exists(backup_path)
try:
# do a eula.txt
@ -371,16 +370,16 @@ class Controller:
logger.error(f"Unable to create required server files due to :{e}")
return False
if helper.is_os_windows():
if Helpers.is_os_windows():
server_command = (
f"java -Xms{helper.float_to_string(min_mem)}M "
f"-Xmx{helper.float_to_string(max_mem)}M "
f"java -Xms{Helpers.float_to_string(min_mem)}M "
f"-Xmx{Helpers.float_to_string(max_mem)}M "
f'-jar "{full_jar_path}" nogui'
)
else:
server_command = (
f"java -Xms{helper.float_to_string(min_mem)}M "
f"-Xmx{helper.float_to_string(max_mem)}M "
f"java -Xms{Helpers.float_to_string(min_mem)}M "
f"-Xmx{Helpers.float_to_string(max_mem)}M "
f"-jar {full_jar_path} nogui"
)
server_log_file = f"{server_dir}/logs/latest.log"
@ -400,23 +399,23 @@ class Controller:
)
# download the jar
server_jar_obj.download_jar(server, version, full_jar_path, new_id)
self.server_jars.download_jar(server, version, full_jar_path, new_id)
return new_id
@staticmethod
def verify_jar_server(server_path: str, server_jar: str):
server_path = helper.get_os_understandable_path(server_path)
path_check = helper.check_path_exists(server_path)
jar_check = helper.check_file_exists(os.path.join(server_path, server_jar))
server_path = Helpers.get_os_understandable_path(server_path)
path_check = Helpers.check_path_exists(server_path)
jar_check = Helpers.check_file_exists(os.path.join(server_path, server_jar))
if not path_check or not jar_check:
return False
return True
@staticmethod
def verify_zip_server(zip_path: str):
zip_path = helper.get_os_understandable_path(zip_path)
zip_check = helper.check_file_exists(zip_path)
zip_path = Helpers.get_os_understandable_path(zip_path)
zip_check = Helpers.check_file_exists(zip_path)
if not zip_check:
return False
return True
@ -430,20 +429,20 @@ class Controller:
max_mem: int,
port: int,
):
server_id = helper.create_uuid()
new_server_dir = os.path.join(helper.servers_dir, server_id)
backup_path = os.path.join(helper.backup_path, server_id)
if helper.is_os_windows():
new_server_dir = helper.wtol_path(new_server_dir)
backup_path = helper.wtol_path(backup_path)
server_id = Helpers.create_uuid()
new_server_dir = os.path.join(Helpers.servers_dir, server_id)
backup_path = os.path.join(Helpers.backup_path, server_id)
if Helpers.is_os_windows():
new_server_dir = Helpers.wtol_path(new_server_dir)
backup_path = Helpers.wtol_path(backup_path)
new_server_dir.replace(" ", "^ ")
backup_path.replace(" ", "^ ")
helper.ensure_dir_exists(new_server_dir)
helper.ensure_dir_exists(backup_path)
server_path = helper.get_os_understandable_path(server_path)
Helpers.ensure_dir_exists(new_server_dir)
Helpers.ensure_dir_exists(backup_path)
server_path = Helpers.get_os_understandable_path(server_path)
try:
file_helper.copy_dir(server_path, new_server_dir, True)
FileHelpers.copy_dir(server_path, new_server_dir, True)
except shutil.Error as ex:
logger.error(f"Server import failed with error: {ex}")
@ -464,16 +463,16 @@ class Controller:
full_jar_path = os.path.join(new_server_dir, server_jar)
if helper.is_os_windows():
if Helpers.is_os_windows():
server_command = (
f"java -Xms{helper.float_to_string(min_mem)}M "
f"-Xmx{helper.float_to_string(max_mem)}M "
f"java -Xms{Helpers.float_to_string(min_mem)}M "
f"-Xmx{Helpers.float_to_string(max_mem)}M "
f'-jar "{full_jar_path}" nogui'
)
else:
server_command = (
f"java -Xms{helper.float_to_string(min_mem)}M "
f"-Xmx{helper.float_to_string(max_mem)}M "
f"java -Xms{Helpers.float_to_string(min_mem)}M "
f"-Xmx{Helpers.float_to_string(max_mem)}M "
f"-jar {full_jar_path} nogui"
)
server_log_file = f"{new_server_dir}/logs/latest.log"
@ -502,18 +501,18 @@ class Controller:
max_mem: int,
port: int,
):
server_id = helper.create_uuid()
new_server_dir = os.path.join(helper.servers_dir, server_id)
backup_path = os.path.join(helper.backup_path, server_id)
if helper.is_os_windows():
new_server_dir = helper.wtol_path(new_server_dir)
backup_path = helper.wtol_path(backup_path)
server_id = Helpers.create_uuid()
new_server_dir = os.path.join(self.helper.servers_dir, server_id)
backup_path = os.path.join(self.helper.backup_path, server_id)
if Helpers.is_os_windows():
new_server_dir = Helpers.wtol_path(new_server_dir)
backup_path = Helpers.wtol_path(backup_path)
new_server_dir.replace(" ", "^ ")
backup_path.replace(" ", "^ ")
tempDir = helper.get_os_understandable_path(zip_path)
helper.ensure_dir_exists(new_server_dir)
helper.ensure_dir_exists(backup_path)
tempDir = Helpers.get_os_understandable_path(zip_path)
Helpers.ensure_dir_exists(new_server_dir)
Helpers.ensure_dir_exists(backup_path)
has_properties = False
# extracts archive to temp directory
for item in os.listdir(tempDir):
@ -521,11 +520,11 @@ class Controller:
has_properties = True
try:
if not os.path.isdir(os.path.join(tempDir, item)):
file_helper.move_file(
FileHelpers.move_file(
os.path.join(tempDir, item), os.path.join(new_server_dir, item)
)
else:
file_helper.move_dir(
FileHelpers.move_dir(
os.path.join(tempDir, item), os.path.join(new_server_dir, item)
)
except Exception as ex:
@ -543,16 +542,16 @@ class Controller:
full_jar_path = os.path.join(new_server_dir, server_jar)
if helper.is_os_windows():
if Helpers.is_os_windows():
server_command = (
f"java -Xms{helper.float_to_string(min_mem)}M "
f"-Xmx{helper.float_to_string(max_mem)}M "
f"java -Xms{Helpers.float_to_string(min_mem)}M "
f"-Xmx{Helpers.float_to_string(max_mem)}M "
f'-jar "{full_jar_path}" nogui'
)
else:
server_command = (
f"java -Xms{helper.float_to_string(min_mem)}M "
f"-Xmx{helper.float_to_string(max_mem)}M "
f"java -Xms{Helpers.float_to_string(min_mem)}M "
f"-Xmx{Helpers.float_to_string(max_mem)}M "
f"-jar {full_jar_path} nogui"
)
logger.debug("command: " + server_command)
@ -580,20 +579,20 @@ class Controller:
def import_bedrock_server(
self, server_name: str, server_path: str, server_exe: str, port: int
):
server_id = helper.create_uuid()
new_server_dir = os.path.join(helper.servers_dir, server_id)
backup_path = os.path.join(helper.backup_path, server_id)
if helper.is_os_windows():
new_server_dir = helper.wtol_path(new_server_dir)
backup_path = helper.wtol_path(backup_path)
server_id = Helpers.create_uuid()
new_server_dir = os.path.join(self.helper.servers_dir, server_id)
backup_path = os.path.join(self.helper.backup_path, server_id)
if Helpers.is_os_windows():
new_server_dir = Helpers.wtol_path(new_server_dir)
backup_path = Helpers.wtol_path(backup_path)
new_server_dir.replace(" ", "^ ")
backup_path.replace(" ", "^ ")
helper.ensure_dir_exists(new_server_dir)
helper.ensure_dir_exists(backup_path)
server_path = helper.get_os_understandable_path(server_path)
Helpers.ensure_dir_exists(new_server_dir)
Helpers.ensure_dir_exists(backup_path)
server_path = Helpers.get_os_understandable_path(server_path)
try:
file_helper.copy_dir(server_path, new_server_dir, True)
FileHelpers.copy_dir(server_path, new_server_dir, True)
except shutil.Error as ex:
logger.error(f"Server import failed with error: {ex}")
@ -614,7 +613,7 @@ class Controller:
full_jar_path = os.path.join(new_server_dir, server_exe)
if helper.is_os_windows():
if Helpers.is_os_windows():
server_command = f'"{full_jar_path}"'
else:
server_command = f"./{server_exe}"
@ -635,25 +634,25 @@ class Controller:
server_type="minecraft-bedrock",
)
if os.name != "nt":
if helper.check_file_exists(full_jar_path):
if Helpers.check_file_exists(full_jar_path):
os.chmod(full_jar_path, 0o2775)
return new_id
def import_bedrock_zip_server(
self, server_name: str, zip_path: str, server_exe: str, port: int
):
server_id = helper.create_uuid()
new_server_dir = os.path.join(helper.servers_dir, server_id)
backup_path = os.path.join(helper.backup_path, server_id)
if helper.is_os_windows():
new_server_dir = helper.wtol_path(new_server_dir)
backup_path = helper.wtol_path(backup_path)
server_id = Helpers.create_uuid()
new_server_dir = os.path.join(self.helper.servers_dir, server_id)
backup_path = os.path.join(self.helper.backup_path, server_id)
if Helpers.is_os_windows():
new_server_dir = Helpers.wtol_path(new_server_dir)
backup_path = Helpers.wtol_path(backup_path)
new_server_dir.replace(" ", "^ ")
backup_path.replace(" ", "^ ")
tempDir = helper.get_os_understandable_path(zip_path)
helper.ensure_dir_exists(new_server_dir)
helper.ensure_dir_exists(backup_path)
tempDir = Helpers.get_os_understandable_path(zip_path)
Helpers.ensure_dir_exists(new_server_dir)
Helpers.ensure_dir_exists(backup_path)
has_properties = False
# extracts archive to temp directory
for item in os.listdir(tempDir):
@ -661,11 +660,11 @@ class Controller:
has_properties = True
try:
if not os.path.isdir(os.path.join(tempDir, item)):
file_helper.move_file(
FileHelpers.move_file(
os.path.join(tempDir, item), os.path.join(new_server_dir, item)
)
else:
file_helper.move_dir(
FileHelpers.move_dir(
os.path.join(tempDir, item), os.path.join(new_server_dir, item)
)
except Exception as ex:
@ -683,7 +682,7 @@ class Controller:
full_jar_path = os.path.join(new_server_dir, server_exe)
if helper.is_os_windows():
if Helpers.is_os_windows():
server_command = f'"{full_jar_path}"'
else:
server_command = f"./{server_exe}"
@ -704,7 +703,7 @@ class Controller:
server_type="minecraft-bedrock",
)
if os.name != "nt":
if helper.check_file_exists(full_jar_path):
if Helpers.check_file_exists(full_jar_path):
os.chmod(full_jar_path, 0o2775)
return new_id
@ -717,20 +716,20 @@ class Controller:
server_data = self.servers.get_server_data_by_id(old_server_id)
old_bu_path = server_data["backup_path"]
Server_Perms_Controller.backup_role_swap(old_server_id, new_server_id)
if not helper.is_os_windows():
backup_path = helper.validate_traversal(helper.backup_path, old_bu_path)
if helper.is_os_windows():
backup_path = helper.validate_traversal(
helper.wtol_path(helper.backup_path), helper.wtol_path(old_bu_path)
if not Helpers.is_os_windows():
backup_path = Helpers.validate_traversal(self.helper.backup_path, old_bu_path)
if Helpers.is_os_windows():
backup_path = Helpers.validate_traversal(
Helpers.wtol_path(self.helper.backup_path), Helpers.wtol_path(old_bu_path)
)
backup_path = helper.wtol_path(str(backup_path))
backup_path = Helpers.wtol_path(str(backup_path))
backup_path.replace(" ", "^ ")
backup_path = Path(backup_path)
backup_path_components = list(backup_path.parts)
backup_path_components[-1] = new_uuid
new_bu_path = pathlib.PurePath(os.path.join(*backup_path_components))
if os.path.isdir(new_bu_path):
if helper.validate_traversal(helper.backup_path, new_bu_path):
if Helpers.validate_traversal(self.helper.backup_path, new_bu_path):
os.rmdir(new_bu_path)
backup_path.rename(new_bu_path)
@ -762,7 +761,7 @@ class Controller:
server_port,
)
if not helper.check_file_exists(os.path.join(server_dir, "crafty_managed.txt")):
if not Helpers.check_file_exists(os.path.join(server_dir, "crafty_managed.txt")):
try:
# place a file in the dir saying it's owned by crafty
with open(
@ -795,7 +794,7 @@ class Controller:
server_name = server_data["server_name"]
logger.info(f"Deleting Server: ID {server_id} | Name: {server_name} ")
console.info(f"Deleting Server: ID {server_id} | Name: {server_name} ")
self.console.info(f"Deleting Server: ID {server_id} | Name: {server_name} ")
srv_obj = s["server_obj"]
running = srv_obj.check_running()
@ -804,8 +803,8 @@ class Controller:
self.stop_server(server_id)
if files:
try:
file_helper.del_dirs(
helper.get_os_understandable_path(
FileHelpers.del_dirs(
Helpers.get_os_understandable_path(
self.servers.get_server_data_by_id(server_id)["path"]
)
)
@ -814,11 +813,11 @@ class Controller:
f"Unable to delete server files for server with ID: "
f"{server_id} with error logged: {e}"
)
if helper.check_path_exists(
if Helpers.check_path_exists(
self.servers.get_server_data_by_id(server_id)["backup_path"]
):
file_helper.del_dirs(
helper.get_os_understandable_path(
FileHelpers.del_dirs(
Helpers.get_os_understandable_path(
self.servers.get_server_data_by_id(server_id)[
"backup_path"
]

View File

@ -1,51 +1,35 @@
import logging
from playhouse.shortcuts import model_to_dict
from app.classes.models.users import Users, users_helper
from app.classes.shared.helpers import helper
from app.classes.shared.console import console
# To disable warning about unused import ; Users is imported from here in other places
# pylint: disable=self-assigning-variable
Users = Users
try:
# pylint: disable=unused-import
from peewee import SqliteDatabase
from playhouse.shortcuts import model_to_dict
except ModuleNotFoundError as err:
helper.auto_installer_fix(err)
# pylint: disable=unused-import
from app.classes.shared.helpers import Helpers
logger = logging.getLogger(__name__)
peewee_logger = logging.getLogger("peewee")
peewee_logger.setLevel(logging.INFO)
database = SqliteDatabase(
helper.db_path,
pragmas={"journal_mode": "wal", "cache_size": -1024 * 10}
)
class db_builder:
@staticmethod
def default_settings():
def __init__(self, database, helper, users_helper):
self.database = database
self.helper = helper
self.users_helper = users_helper
def default_settings(self):
logger.info("Fresh Install Detected - Creating Default Settings")
console.info("Fresh Install Detected - Creating Default Settings")
default_data = helper.find_default_password()
self.helper.console.info("Fresh Install Detected - Creating Default Settings")
default_data = self.helper.find_default_password()
username = default_data.get("username", "admin")
password = default_data.get("password", "crafty")
users_helper.add_user(
self.users_helper.add_user(
username=username,
password=password,
email="default@example.com",
superuser=True,
)
@staticmethod
def is_fresh_install():
def is_fresh_install(self):
try:
user = users_helper.get_by_id(1)
user = self.users_helper.get_by_id(1)
if user:
return False
except:
@ -53,7 +37,6 @@ class db_builder:
class db_shortcuts:
# **********************************************************************************
# Generic Databse Methods
# **********************************************************************************
@ -74,10 +57,3 @@ class db_shortcuts:
def return_db_rows(model):
data = [model_to_dict(row) for row in model]
return data
# **********************************************************************************
# Static Accessors
# **********************************************************************************
installer = db_builder()
db_helper = db_shortcuts()

View File

@ -7,22 +7,16 @@ import os
import re
from functools import wraps
from functools import cached_property
import peewee
from playhouse.migrate import (
SqliteMigrator,
Operation,
SQL,
SqliteDatabase,
make_index_name,
)
from app.classes.shared.helpers import helper
from app.classes.shared.console import console
try:
import peewee
from playhouse.migrate import (
SqliteMigrator,
Operation,
SQL,
SqliteDatabase,
make_index_name,
)
except ModuleNotFoundError as e:
helper.auto_installer_fix(e)
from app.classes.shared.helpers import Helpers
logger = logging.getLogger(__name__)
@ -303,13 +297,14 @@ class Migrator(object):
class MigrationManager(object):
filemask = re.compile(r"[\d]+_[^\.]+\.py$")
def __init__(self, database: t.Union[peewee.Database, peewee.Proxy]):
def __init__(self, database: t.Union[peewee.Database, peewee.Proxy], helper):
"""
Initializes the migration manager.
"""
if not isinstance(database, (peewee.Database, peewee.Proxy)):
raise RuntimeError("Invalid database: {}".format(database))
self.database = database
self.helper = helper
@cached_property
def model(self) -> t.Type[MigrateHistory]:
@ -334,13 +329,13 @@ class MigrationManager(object):
"""
Scans migrations in the file system.
"""
if not os.path.exists(helper.migration_dir):
if not os.path.exists(self.helper.migration_dir):
logger.warning(
"Migration directory: {} does not exist.".format(helper.migration_dir)
"Migration directory: {} does not exist.".format(self.helper.migration_dir)
)
os.makedirs(helper.migration_dir)
os.makedirs(self.helper.migration_dir)
return sorted(
f[:-3] for f in os.listdir(helper.migration_dir) if self.filemask.match(f)
f[:-3] for f in os.listdir(self.helper.migration_dir) if self.filemask.match(f)
)
@property
@ -367,7 +362,7 @@ class MigrationManager(object):
"""
name = datetime.utcnow().strftime("%Y%m%d%H%M%S") + "_" + name
filename = name + ".py"
path = os.path.join(helper.migration_dir, filename)
path = os.path.join(self.helper.migration_dir, filename)
with open(path, "w") as f:
f.write(
MIGRATE_TEMPLATE.format(
@ -399,13 +394,13 @@ class MigrationManager(object):
Runs all unapplied migrations.
"""
logger.info("Starting migrations")
console.info("Starting migrations")
self.helper.console.info("Starting migrations")
done = []
diff = self.diff
if not diff:
logger.info("There is nothing to migrate")
console.info("There is nothing to migrate")
self.helper.console.info("There is nothing to migrate")
return done
migrator = self.migrator
@ -421,10 +416,10 @@ class MigrationManager(object):
Reads a migration from a file.
"""
call_params = dict()
if helper.is_os_windows() and sys.version_info >= (3, 0):
if Helpers.is_os_windows() and sys.version_info >= (3, 0):
# if system is windows - force utf-8 encoding
call_params["encoding"] = "utf-8"
with open(os.path.join(helper.migration_dir, name + ".py"), **call_params) as f:
with open(os.path.join(self.helper.migration_dir, name + ".py"), **call_params) as f:
code = f.read()
scope = {}
code = compile(code, "<string>", "exec", dont_inherit=True)

View File

@ -4,7 +4,7 @@ from enum import Enum
class PermissionHelper:
@staticmethod
def both_have_perm(a: str, b: str, permission_tested: Enum):
return permission_helper.combine_perm_bool(
return PermissionHelper.combine_perm_bool(
a[permission_tested.value], b[permission_tested.value]
)
@ -20,8 +20,5 @@ class PermissionHelper:
def combine_masks(permission_mask_a: str, permission_mask_b: str) -> str:
both_masks = zip(list(permission_mask_a), list(permission_mask_b))
return "".join(
map(lambda x: permission_helper.combine_perm(x[0], x[1]), both_masks)
map(lambda x: PermissionHelper.combine_perm(x[0], x[1]), both_masks)
)
permission_helper = PermissionHelper()

View File

@ -8,28 +8,19 @@ import logging.config
import subprocess
import html
import tempfile
import psutil
# TZLocal is set as a hidden import on win pipeline
from tzlocal import get_localzone
from apscheduler.schedulers.background import BackgroundScheduler
from app.classes.minecraft.stats import Stats
from app.classes.minecraft.mc_ping import ping, ping_bedrock
from app.classes.models.servers import Server_Stats, servers_helper
from app.classes.models.management import management_helper
from app.classes.models.users import users_helper
from app.classes.models.server_permissions import server_permissions
from app.classes.shared.helpers import helper
from app.classes.shared.console import console
from app.classes.shared.translation import translation
from app.classes.shared.file_helpers import file_helper
from app.classes.web.websocket_helper import websocket_helper
try:
import psutil
# TZLocal is set as a hidden import on win pipeline
from tzlocal import get_localzone
from apscheduler.schedulers.background import BackgroundScheduler
except ModuleNotFoundError as e:
helper.auto_installer_fix(e)
from app.classes.models.servers import Server_Stats, helper_servers
from app.classes.models.management import helpers_management
from app.classes.models.users import helper_users
from app.classes.models.server_permissions import Permissions_Servers
from app.classes.shared.helpers import Helpers
from app.classes.shared.file_helpers import FileHelpers
logger = logging.getLogger(__name__)
@ -37,11 +28,12 @@ logger = logging.getLogger(__name__)
class ServerOutBuf:
lines = {}
def __init__(self, proc, server_id):
def __init__(self, helper, proc, server_id):
self.helper = helper
self.proc = proc
self.server_id = str(server_id)
# Buffers text for virtual_terminal_lines config number of lines
self.max_lines = helper.get_setting("virtual_terminal_lines")
self.max_lines = self.helper.get_setting("virtual_terminal_lines")
self.line_buffer = ""
ServerOutBuf.lines[self.server_id] = []
self.lsi = 0
@ -79,13 +71,13 @@ class ServerOutBuf:
def new_line_handler(self, new_line):
new_line = re.sub("(\033\\[(0;)?[0-9]*[A-z]?(;[0-9])?m?)", " ", new_line)
new_line = re.sub("[A-z]{2}\b\b", "", new_line)
highlighted = helper.log_colors(html.escape(new_line))
highlighted = self.helper.log_colors(html.escape(new_line))
logger.debug("Broadcasting new virtual terminal line")
# TODO: Do not send data to clients who do not have permission to view
# this server's console
websocket_helper.broadcast_page_params(
self.helper.websocket_helper.broadcast_page_params(
"/panel/server_detail",
{"id": self.server_id},
"vterm_new_line",
@ -97,7 +89,10 @@ class ServerOutBuf:
# Minecraft Server Class
# **********************************************************************************
class Server:
def __init__(self, stats):
def __init__(self, helper, management_helper, stats):
self.helper = helper
self.management_helper = management_helper
self.console = self.helper.console
# holders for our process
self.process = None
self.line = False
@ -121,14 +116,14 @@ class Server:
)
self.is_backingup = False
# Reset crash and update at initialization
servers_helper.server_crash_reset(self.server_id)
servers_helper.set_update(self.server_id, False)
helper_servers.server_crash_reset(self.server_id)
helper_servers.set_update(self.server_id, False)
# **********************************************************************************
# Minecraft Server Management
# **********************************************************************************
def reload_server_settings(self):
server_data = servers_helper.get_server_data_by_id(self.server_id)
server_data = helper_servers.get_server_data_by_id(self.server_id)
self.settings = server_data
def do_server_setup(self, server_data_obj):
@ -153,7 +148,7 @@ class Server:
delay = int(self.settings["auto_start_delay"])
logger.info(f"Scheduling server {self.name} to start in {delay} seconds")
console.info(f"Scheduling server {self.name} to start in {delay} seconds")
self.console.info(f"Scheduling server {self.name} to start in {delay} seconds")
self.server_scheduler.add_job(
self.run_scheduled_server,
@ -163,10 +158,10 @@ class Server:
)
def run_scheduled_server(self):
console.info(f"Starting server ID: {self.server_id} - {self.name}")
self.console.info(f"Starting server ID: {self.server_id} - {self.name}")
logger.info(f"Starting server ID: {self.server_id} - {self.name}")
# Sets waiting start to false since we're attempting to start the server.
servers_helper.set_waiting_start(self.server_id, False)
helper_servers.set_waiting_start(self.server_id, False)
self.run_threaded_server(None)
# remove the scheduled job since it's ran
@ -184,7 +179,7 @@ class Server:
# Register an shedule for polling server stats when running
logger.info(f"Polling server statistics {self.name} every {5} seconds")
console.info(f"Polling server statistics {self.name} every {5} seconds")
self.console.info(f"Polling server statistics {self.name} every {5} seconds")
try:
self.server_scheduler.add_job(
self.realtime_stats,
@ -203,43 +198,43 @@ class Server:
def setup_server_run_command(self):
# configure the server
server_exec_path = helper.get_os_understandable_path(
server_exec_path = Helpers.get_os_understandable_path(
self.settings["executable"]
)
self.server_command = helper.cmdparse(self.settings["execution_command"])
self.server_path = helper.get_os_understandable_path(self.settings["path"])
self.server_command = Helpers.cmdparse(self.settings["execution_command"])
self.server_path = Helpers.get_os_understandable_path(self.settings["path"])
# let's do some quick checking to make sure things actually exists
full_path = os.path.join(self.server_path, server_exec_path)
if not helper.check_file_exists(full_path):
if not Helpers.check_file_exists(full_path):
logger.critical(
f"Server executable path: {full_path} does not seem to exist"
)
console.critical(
self.console.critical(
f"Server executable path: {full_path} does not seem to exist"
)
if not helper.check_path_exists(self.server_path):
if not Helpers.check_path_exists(self.server_path):
logger.critical(f"Server path: {self.server_path} does not seem to exits")
console.critical(f"Server path: {self.server_path} does not seem to exits")
self.console.critical(f"Server path: {self.server_path} does not seem to exits")
if not helper.check_writeable(self.server_path):
if not Helpers.check_writeable(self.server_path):
logger.critical(f"Unable to write/access {self.server_path}")
console.warning(f"Unable to write/access {self.server_path}")
self.console.critical(f"Unable to write/access {self.server_path}")
def start_server(self, user_id):
if not user_id:
user_lang = helper.get_setting("language")
user_lang = self.helper.get_setting("language")
else:
user_lang = users_helper.get_user_lang_by_id(user_id)
user_lang = helper_users.get_user_lang_by_id(user_id)
if servers_helper.get_download_status(self.server_id):
if helper_servers.get_download_status(self.server_id):
if user_id:
websocket_helper.broadcast_user(
self.helper.websocket_helper.broadcast_user(
user_id,
"send_start_error",
{
"error": translation.translate(
"error": self.helper.translation.translate(
"error", "not-downloaded", user_lang
)
},
@ -253,18 +248,18 @@ class Server:
# fail safe in case we try to start something already running
if self.check_running():
logger.error("Server is already running - Cancelling Startup")
console.error("Server is already running - Cancelling Startup")
self.console.error("Server is already running - Cancelling Startup")
return False
if self.check_update():
logger.error("Server is updating. Terminating startup.")
return False
logger.info(f"Launching Server {self.name} with command {self.server_command}")
console.info(f"Launching Server {self.name} with command {self.server_command}")
self.console.info(f"Launching Server {self.name} with command {self.server_command}")
# Checks for eula. Creates one if none detected.
# If EULA is detected and not set to true we offer to set it true.
if helper.check_file_exists(os.path.join(self.settings["path"], "eula.txt")):
if Helpers.check_file_exists(os.path.join(self.settings["path"], "eula.txt")):
f = open(
os.path.join(self.settings["path"], "eula.txt"), "r", encoding="utf-8"
)
@ -288,7 +283,7 @@ class Server:
if not e_flag:
if user_id:
websocket_helper.broadcast_user(
self.helper.websocket_helper.broadcast_user(
user_id, "send_eula_bootbox", {"id": self.server_id}
)
else:
@ -299,7 +294,7 @@ class Server:
return False
return False
f.close()
if helper.is_os_windows():
if Helpers.is_os_windows():
logger.info("Windows Detected")
else:
logger.info("Unix Detected")
@ -313,7 +308,7 @@ class Server:
f = open(
os.path.join(
self.server_path,
servers_helper.get_server_data_by_id(self.server_id)["executable"],
helper_servers.get_server_data_by_id(self.server_id)["executable"],
),
"r",
encoding="utf-8",
@ -322,11 +317,11 @@ class Server:
except:
if user_id:
websocket_helper.broadcast_user(
self.helper.websocket_helper.broadcast_user(
user_id,
"send_start_error",
{
"error": translation.translate(
"error": self.helper.translation.translate(
"error", "not-downloaded", user_lang
)
},
@ -334,8 +329,8 @@ class Server:
return
if (
not helper.is_os_windows()
and servers_helper.get_server_type_by_id(self.server_id)
not Helpers.is_os_windows()
and helper_servers.get_server_type_by_id(self.server_id)
== "minecraft-bedrock"
):
logger.info(
@ -358,11 +353,11 @@ class Server:
f"Server {self.name} failed to start with error code: {ex}"
)
if user_id:
websocket_helper.broadcast_user(
self.helper.websocket_helper.broadcast_user(
user_id,
"send_start_error",
{
"error": translation.translate(
"error": self.helper.translation.translate(
"error", "start-error", user_lang
).format(self.name, ex)
},
@ -382,11 +377,11 @@ class Server:
# Checks for java on initial fail
if os.system("java -version") == 32512:
if user_id:
websocket_helper.broadcast_user(
self.helper.websocket_helper.broadcast_user(
user_id,
"send_start_error",
{
"error": translation.translate(
"error": self.helper.translation.translate(
"error", "noJava", user_lang
).format(self.name)
},
@ -397,18 +392,18 @@ class Server:
f"Server {self.name} failed to start with error code: {ex}"
)
if user_id:
websocket_helper.broadcast_user(
self.helper.websocket_helper.broadcast_user(
user_id,
"send_start_error",
{
"error": translation.translate(
"error": self.helper.translation.translate(
"error", "start-error", user_lang
).format(self.name, ex)
},
)
return False
out_buf = ServerOutBuf(self.process, self.server_id)
out_buf = ServerOutBuf(self.helper, self.process, self.server_id)
logger.debug(f"Starting virtual terminal listener for server {self.name}")
threading.Thread(
@ -416,15 +411,15 @@ class Server:
).start()
self.is_crashed = False
servers_helper.server_crash_reset(self.server_id)
helper_servers.server_crash_reset(self.server_id)
self.start_time = str(datetime.datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S"))
if self.process.poll() is None:
logger.info(f"Server {self.name} running with PID {self.process.pid}")
console.info(f"Server {self.name} running with PID {self.process.pid}")
self.console.info(f"Server {self.name} running with PID {self.process.pid}")
self.is_crashed = False
servers_helper.server_crash_reset(self.server_id)
helper_servers.server_crash_reset(self.server_id)
self.record_server_stats()
check_internet_thread = threading.Thread(
target=self.check_internet_thread,
@ -437,35 +432,35 @@ class Server:
)
check_internet_thread.start()
# Checks if this is the servers first run.
if servers_helper.get_first_run(self.server_id):
servers_helper.set_first_run(self.server_id)
loc_server_port = servers_helper.get_server_stats_by_id(self.server_id)[
if helper_servers.get_first_run(self.server_id):
helper_servers.set_first_run(self.server_id)
loc_server_port = helper_servers.get_server_stats_by_id(self.server_id)[
"server_port"
]
# Sends port reminder message.
websocket_helper.broadcast_user(
self.helper.websocket_helper.broadcast_user(
user_id,
"send_start_error",
{
"error": translation.translate(
"error": self.helper.translation.translate(
"error", "portReminder", user_lang
).format(self.name, loc_server_port)
},
)
server_users = server_permissions.get_server_user_list(self.server_id)
server_users = Permissions_Servers.get_server_user_list(self.server_id)
for user in server_users:
if user != user_id:
websocket_helper.broadcast_user(user, "send_start_reload", {})
self.helper.websocket_helper.broadcast_user(user, "send_start_reload", {})
else:
server_users = server_permissions.get_server_user_list(self.server_id)
server_users = Permissions_Servers.get_server_user_list(self.server_id)
for user in server_users:
websocket_helper.broadcast_user(user, "send_start_reload", {})
self.helper.websocket_helper.broadcast_user(user, "send_start_reload", {})
else:
logger.warning(
f"Server PID {self.process.pid} died right after starting "
f"- is this a server config issue?"
)
console.warning(
self.console.critical(
f"Server PID {self.process.pid} died right after starting "
f"- is this a server config issue?"
)
@ -475,7 +470,7 @@ class Server:
f"Server {self.name} has crash detection enabled "
f"- starting watcher task"
)
console.info(
self.console.info(
f"Server {self.name} has crash detection enabled "
f"- starting watcher task"
)
@ -486,11 +481,11 @@ class Server:
def check_internet_thread(self, user_id, user_lang):
if user_id:
if not helper.check_internet():
websocket_helper.broadcast_user(
if not Helpers.check_internet():
self.helper.websocket_helper.broadcast_user(
user_id,
"send_start_error",
{"error": translation.translate("error", "internet", user_lang)},
{"error": self.helper.translation.translate("error", "internet", user_lang)},
)
def stop_crash_detection(self):
@ -514,7 +509,7 @@ class Server:
f"Server {self.name} has crash detection enabled "
f"- starting watcher task"
)
console.info(
self.console.info(
f"Server {self.name} has crash detection enabled "
"- starting watcher task"
)
@ -547,7 +542,7 @@ class Server:
running = self.check_running()
if not running:
logger.info(f"Can't stop server {self.name} if it's not running")
console.info(f"Can't stop server {self.name} if it's not running")
self.console.info(f"Can't stop server {self.name} if it's not running")
return
x = 0
@ -563,7 +558,7 @@ class Server:
f"seconds until force close)"
)
logger.info(logstr)
console.info(logstr)
self.console.info(logstr)
running = self.check_running()
time.sleep(2)
@ -572,17 +567,17 @@ class Server:
logger.info(
f"Server {server_name} is still running - Forcing the process down"
)
console.info(
self.console.info(
f"Server {server_name} is still running - Forcing the process down"
)
self.kill()
logger.info(f"Stopped Server {server_name} with PID {server_pid}")
console.info(f"Stopped Server {server_name} with PID {server_pid}")
self.console.info(f"Stopped Server {server_name} with PID {server_pid}")
# massive resetting of variables
self.cleanup_server_object()
server_users = server_permissions.get_server_user_list(self.server_id)
server_users = Permissions_Servers.get_server_user_list(self.server_id)
# remove the stats polling job since server is stopped
self.server_scheduler.remove_job("stats_" + str(self.server_id))
@ -590,7 +585,7 @@ class Server:
self.record_server_stats()
for user in server_users:
websocket_helper.broadcast_user(user, "send_start_reload", {})
self.helper.websocket_helper.broadcast_user(user, "send_start_reload", {})
def restart_threaded_server(self, user_id):
# if not already running, let's just start
@ -623,7 +618,7 @@ class Server:
if not self.check_running() and command.lower() != "start":
logger.warning(f'Server not running, unable to send command "{command}"')
return False
console.info(f"COMMAND TIME: {command}")
self.console.info(f"COMMAND TIME: {command}")
logger.debug(f"Sending command {command} to server")
# send it
@ -647,7 +642,7 @@ class Server:
f"The server {name} has crashed and will be restarted. "
f"Restarting server"
)
console.warning(
self.console.critical(
f"The server {name} has crashed and will be restarted. "
f"Restarting server"
)
@ -658,7 +653,7 @@ class Server:
f"The server {name} has crashed, "
f"crash detection is disabled and it will not be restarted"
)
console.critical(
self.console.critical(
f"The server {name} has crashed, "
f"crash detection is disabled and it will not be restarted"
)
@ -710,7 +705,7 @@ class Server:
self.server_scheduler.remove_job("c_" + str(self.server_id))
return
servers_helper.sever_crashed(self.server_id)
helper_servers.sever_crashed(self.server_id)
# if we haven't tried to restart more 3 or more times
if self.restart_count <= 3:
@ -727,21 +722,21 @@ class Server:
f"Server {self.name} has been restarted {self.restart_count}"
f" times. It has crashed, not restarting."
)
console.critical(
self.console.critical(
f"Server {self.name} has been restarted {self.restart_count}"
f" times. It has crashed, not restarting."
)
self.restart_count = 0
self.is_crashed = True
servers_helper.sever_crashed(self.server_id)
helper_servers.sever_crashed(self.server_id)
# cancel the watcher task
self.server_scheduler.remove_job("c_" + str(self.server_id))
def remove_watcher_thread(self):
logger.info("Removing old crash detection watcher thread")
console.info("Removing old crash detection watcher thread")
self.console.info("Removing old crash detection watcher thread")
self.server_scheduler.remove_job("c_" + str(self.server_id))
def agree_eula(self, user_id):
@ -765,7 +760,7 @@ class Server:
f"Starting Backup Thread for server {self.settings['server_name']}."
)
if self.server_path is None:
self.server_path = helper.get_os_understandable_path(self.settings["path"])
self.server_path = Helpers.get_os_understandable_path(self.settings["path"])
logger.info(
"Backup Thread - Local server path not defined. "
"Setting local server path variable."
@ -787,26 +782,26 @@ class Server:
logger.info(f"Backup Thread started for server {self.settings['server_name']}.")
def a_backup_server(self):
if len(websocket_helper.clients) > 0:
websocket_helper.broadcast_page_params(
if len(self.helper.websocket_helper.clients) > 0:
self.helper.websocket_helper.broadcast_page_params(
"/panel/server_detail",
{"id": str(self.server_id)},
"backup_reload",
{"percent": 0, "total_files": 0},
)
logger.info(f"Starting server {self.name} (ID {self.server_id}) backup")
server_users = server_permissions.get_server_user_list(self.server_id)
server_users = Permissions_Servers.get_server_user_list(self.server_id)
for user in server_users:
websocket_helper.broadcast_user(
self.helper.websocket_helper.broadcast_user(
user,
"notification",
translation.translate(
"notify", "backupStarted", users_helper.get_user_lang_by_id(user)
self.helper.translation.translate(
"notify", "backupStarted", helper_users.get_user_lang_by_id(user)
).format(self.name),
)
time.sleep(3)
conf = management_helper.get_backup_config(self.server_id)
helper.ensure_dir_exists(self.settings["backup_path"])
conf = helpers_management.get_backup_config(self.server_id)
self.helper.ensure_dir_exists(self.settings["backup_path"])
try:
backup_filename = (
f"{self.settings['backup_path']}/"
@ -827,23 +822,23 @@ class Server:
args=[tempDir + "/", backup_filename + ".zip"],
)
# pylint: disable=unexpected-keyword-arg
file_helper.copy_dir(self.server_path, tempDir, dirs_exist_ok=True)
excluded_dirs = management_helper.get_excluded_backup_dirs(self.server_id)
server_dir = helper.get_os_understandable_path(self.settings["path"])
FileHelpers.copy_dir(self.server_path, tempDir, dirs_exist_ok=True)
excluded_dirs = helpers_management.get_excluded_backup_dirs(self.server_id)
server_dir = Helpers.get_os_understandable_path(self.settings["path"])
for my_dir in excluded_dirs:
# Take the full path of the excluded dir and replace the
# server path with the temp path, this is so that we're
# only deleting excluded dirs from the temp path
# and not the server path
excluded_dir = helper.get_os_understandable_path(my_dir).replace(
server_dir, helper.get_os_understandable_path(tempDir)
excluded_dir = Helpers.get_os_understandable_path(my_dir).replace(
server_dir, Helpers.get_os_understandable_path(tempDir)
)
# Next, check to see if it is a directory
if os.path.isdir(excluded_dir):
# If it is a directory,
# recursively delete the entire directory from the backup
file_helper.del_dirs(excluded_dir)
FileHelpers.del_dirs(excluded_dir)
else:
# If not, just remove the file
os.remove(excluded_dir)
@ -851,15 +846,15 @@ class Server:
logger.debug(
"Found compress backup to be true. Calling compressed archive"
)
file_helper.make_compressed_archive(
helper.get_os_understandable_path(backup_filename), tempDir
FileHelpers.make_compressed_archive(
Helpers.get_os_understandable_path(backup_filename), tempDir
)
else:
logger.debug(
"Found compress backup to be false. Calling NON-compressed archive"
)
file_helper.make_archive(
helper.get_os_understandable_path(backup_filename), tempDir
FileHelpers.make_archive(
Helpers.get_os_understandable_path(backup_filename), tempDir
)
while (
@ -870,29 +865,29 @@ class Server:
oldfile = backup_list[0]
oldfile_path = f"{conf['backup_path']}/{oldfile['path']}"
logger.info(f"Removing old backup '{oldfile['path']}'")
os.remove(helper.get_os_understandable_path(oldfile_path))
os.remove(Helpers.get_os_understandable_path(oldfile_path))
self.is_backingup = False
file_helper.del_dirs(tempDir)
FileHelpers.del_dirs(tempDir)
logger.info(f"Backup of server: {self.name} completed")
self.server_scheduler.remove_job("backup_" + str(self.server_id))
results = {"percent": 100, "total_files": 0, "current_file": 0}
if len(websocket_helper.clients) > 0:
websocket_helper.broadcast_page_params(
if len(self.helper.websocket_helper.clients) > 0:
self.helper.websocket_helper.broadcast_page_params(
"/panel/server_detail",
{"id": str(self.server_id)},
"backup_status",
results,
)
server_users = server_permissions.get_server_user_list(self.server_id)
server_users = Permissions_Servers.get_server_user_list(self.server_id)
for user in server_users:
websocket_helper.broadcast_user(
self.helper.websocket_helper.broadcast_user(
user,
"notification",
translation.translate(
self.helper.translation.translate(
"notify",
"backupComplete",
users_helper.get_user_lang_by_id(user),
helper_users.get_user_lang_by_id(user),
).format(self.name),
)
time.sleep(3)
@ -903,8 +898,8 @@ class Server:
)
self.server_scheduler.remove_job("backup_" + str(self.server_id))
results = {"percent": 100, "total_files": 0, "current_file": 0}
if len(websocket_helper.clients) > 0:
websocket_helper.broadcast_page_params(
if len(self.helper.websocket_helper.clients) > 0:
self.helper.websocket_helper.broadcast_page_params(
"/panel/server_detail",
{"id": str(self.server_id)},
"backup_status",
@ -914,10 +909,10 @@ class Server:
return
def backup_status(self, source_path, dest_path):
results = helper.calc_percent(source_path, dest_path)
results = Helpers.calc_percent(source_path, dest_path)
self.backup_stats = results
if len(websocket_helper.clients) > 0:
websocket_helper.broadcast_page_params(
if len(self.helper.websocket_helper.clients) > 0:
self.helper.websocket_helper.broadcast_page_params(
"/panel/server_detail",
{"id": str(self.server_id)},
"backup_status",
@ -932,19 +927,19 @@ class Server:
def list_backups(self):
if self.settings["backup_path"]:
if helper.check_path_exists(
helper.get_os_understandable_path(self.settings["backup_path"])
if Helpers.check_path_exists(
Helpers.get_os_understandable_path(self.settings["backup_path"])
):
files = helper.get_human_readable_files_sizes(
helper.list_dir_by_date(
helper.get_os_understandable_path(self.settings["backup_path"])
files = Helpers.get_human_readable_files_sizes(
Helpers.list_dir_by_date(
Helpers.get_os_understandable_path(self.settings["backup_path"])
)
)
return [
{
"path": os.path.relpath(
f["path"],
start=helper.get_os_understandable_path(
start=Helpers.get_os_understandable_path(
self.settings["backup_path"]
),
),
@ -961,7 +956,7 @@ class Server:
return []
def jar_update(self):
servers_helper.set_update(self.server_id, True)
helper_servers.set_update(self.server_id, True)
update_thread = threading.Thread(
target=self.a_jar_update, daemon=True, name=f"exe_update_{self.name}"
)
@ -969,7 +964,7 @@ class Server:
def check_update(self):
if servers_helper.get_server_stats_by_id(self.server_id)["updating"]:
if helper_servers.get_server_stats_by_id(self.server_id)["updating"]:
return True
else:
return False
@ -987,13 +982,13 @@ class Server:
self.stop_threaded_server()
else:
wasStarted = False
if len(websocket_helper.clients) > 0:
if len(self.helper.websocket_helper.clients) > 0:
# There are clients
self.check_update()
message = (
'<a data-id="' + str(self.server_id) + '" class=""> UPDATING...</i></a>'
)
websocket_helper.broadcast_page(
self.helper.websocket_helper.broadcast_page(
"/panel/server_detail",
"update_button_status",
{
@ -1003,9 +998,9 @@ class Server:
"string": message,
},
)
websocket_helper.broadcast_page("/panel/dashboard", "send_start_reload", {})
self.helper.websocket_helper.broadcast_page("/panel/dashboard", "send_start_reload", {})
backup_dir = os.path.join(
helper.get_os_understandable_path(self.settings["path"]),
Helpers.get_os_understandable_path(self.settings["path"]),
"crafty_executable_backups",
)
# checks if backup directory already exists
@ -1028,37 +1023,37 @@ class Server:
logger.info(f"No old backups found for server: {self.name}")
current_executable = os.path.join(
helper.get_os_understandable_path(self.settings["path"]),
Helpers.get_os_understandable_path(self.settings["path"]),
self.settings["executable"],
)
# copies to backup dir
helper.copy_files(current_executable, backup_executable)
Helpers.copy_files(current_executable, backup_executable)
# boolean returns true for false for success
downloaded = helper.download_file(
downloaded = Helpers.download_file(
self.settings["executable_update_url"], current_executable
)
while servers_helper.get_server_stats_by_id(self.server_id)["updating"]:
while helper_servers.get_server_stats_by_id(self.server_id)["updating"]:
if downloaded and not self.is_backingup:
logger.info("Executable updated successfully. Starting Server")
servers_helper.set_update(self.server_id, False)
if len(websocket_helper.clients) > 0:
helper_servers.set_update(self.server_id, False)
if len(self.helper.websocket_helper.clients) > 0:
# There are clients
self.check_update()
server_users = server_permissions.get_server_user_list(
server_users = Permissions_Servers.get_server_user_list(
self.server_id
)
for user in server_users:
websocket_helper.broadcast_user(
self.helper.websocket_helper.broadcast_user(
user,
"notification",
"Executable update finished for " + self.name,
)
time.sleep(3)
websocket_helper.broadcast_page(
self.helper.websocket_helper.broadcast_page(
"/panel/server_detail",
"update_button_status",
{
@ -1067,18 +1062,18 @@ class Server:
"wasRunning": wasStarted,
},
)
websocket_helper.broadcast_page(
self.helper.websocket_helper.broadcast_page(
"/panel/dashboard", "send_start_reload", {}
)
server_users = server_permissions.get_server_user_list(self.server_id)
server_users = Permissions_Servers.get_server_user_list(self.server_id)
for user in server_users:
websocket_helper.broadcast_user(
self.helper.websocket_helper.broadcast_user(
user,
"notification",
"Executable update finished for " + self.name,
)
management_helper.add_to_audit_log_raw(
self.management_helper.add_to_audit_log_raw(
"Alert",
"-1",
self.server_id,
@ -1089,9 +1084,9 @@ class Server:
self.start_server()
elif not downloaded and not self.is_backingup:
time.sleep(5)
server_users = server_permissions.get_server_user_list(self.server_id)
server_users = Permissions_Servers.get_server_user_list(self.server_id)
for user in server_users:
websocket_helper.broadcast_user(
self.helper.websocket_helper.broadcast_user(
user,
"notification",
"Executable update failed for "
@ -1134,8 +1129,8 @@ class Server:
"icon": raw_ping_result.get("icon"),
}
)
if len(websocket_helper.clients) > 0:
websocket_helper.broadcast_page_params(
if len(self.helper.websocket_helper.clients) > 0:
self.helper.websocket_helper.broadcast_page_params(
"/panel/server_detail",
{"id": str(self.server_id)},
"update_server_details",
@ -1163,16 +1158,16 @@ class Server:
self.record_server_stats()
if (len(servers_ping) > 0) & (len(websocket_helper.clients) > 0):
if (len(servers_ping) > 0) & (len(self.helper.websocket_helper.clients) > 0):
try:
websocket_helper.broadcast_page(
self.helper.websocket_helper.broadcast_page(
"/panel/dashboard", "update_server_status", servers_ping
)
websocket_helper.broadcast_page(
self.helper.websocket_helper.broadcast_page(
"/status", "update_server_status", servers_ping
)
except:
console.warning("Can't broadcast server status to websocket")
self.console.critical("Can't broadcast server status to websocket")
def get_servers_stats(self):
@ -1181,7 +1176,7 @@ class Server:
logger.info("Getting Stats for Server " + self.name + " ...")
server_id = self.server_id
server = servers_helper.get_server_data_by_id(server_id)
server = helper_servers.get_server_data_by_id(server_id)
logger.debug(f"Getting stats for server: {server_id}")
@ -1200,7 +1195,7 @@ class Server:
server_name = server.get("server_name", f"ID#{server_id}")
logger.debug("Pinging server '{server}' on {internal_ip}:{server_port}")
if servers_helper.get_server_type_by_id(server_id) == "minecraft-bedrock":
if helper_servers.get_server_type_by_id(server_id) == "minecraft-bedrock":
int_mc_ping = ping_bedrock(internal_ip, int(server_port))
else:
int_mc_ping = ping(internal_ip, int(server_port))
@ -1212,7 +1207,7 @@ class Server:
if int_mc_ping:
int_data = True
if (
servers_helper.get_server_type_by_id(server["server_id"])
helper_servers.get_server_type_by_id(server["server_id"])
== "minecraft-bedrock"
):
ping_data = Stats.parse_server_RakNet_ping(int_mc_ping)
@ -1261,7 +1256,7 @@ class Server:
def get_server_players(self):
server = servers_helper.get_server_data_by_id(self.server_id)
server = helper_servers.get_server_data_by_id(self.server_id)
logger.info(f"Getting players for server {server}")
@ -1274,7 +1269,7 @@ class Server:
server_port = server["server_port"]
logger.debug("Pinging {internal_ip} on port {server_port}")
if servers_helper.get_server_type_by_id(self.server_id) != "minecraft-bedrock":
if helper_servers.get_server_type_by_id(self.server_id) != "minecraft-bedrock":
int_mc_ping = ping(internal_ip, int(server_port))
ping_data = {}
@ -1288,7 +1283,7 @@ class Server:
def get_raw_server_stats(self, server_id):
try:
server = servers_helper.get_server_obj(server_id)
server = helper_servers.get_server_obj(server_id)
except:
return {
"id": server_id,
@ -1310,10 +1305,10 @@ class Server:
}
server_stats = {}
server = servers_helper.get_server_obj(server_id)
server = helper_servers.get_server_obj(server_id)
if not server:
return {}
server_dt = servers_helper.get_server_data_by_id(server_id)
server_dt = helper_servers.get_server_data_by_id(server_id)
logger.debug(f"Getting stats for server: {server_id}")
@ -1334,7 +1329,7 @@ class Server:
server_port = server_dt["server_port"]
logger.debug(f"Pinging server '{self.name}' on {internal_ip}:{server_port}")
if servers_helper.get_server_type_by_id(server_id) == "minecraft-bedrock":
if helper_servers.get_server_type_by_id(server_id) == "minecraft-bedrock":
int_mc_ping = ping_bedrock(internal_ip, int(server_port))
else:
int_mc_ping = ping(internal_ip, int(server_port))
@ -1345,7 +1340,7 @@ class Server:
# otherwise people have gotten confused.
if self.check_running():
# if we got a good ping return, let's parse it
if servers_helper.get_server_type_by_id(server_id) != "minecraft-bedrock":
if helper_servers.get_server_type_by_id(server_id) != "minecraft-bedrock":
if int_mc_ping:
int_data = True
ping_data = Stats.parse_server_ping(int_mc_ping)
@ -1461,7 +1456,7 @@ class Server:
).execute()
# delete old data
max_age = helper.get_setting("history_max_age")
max_age = self.helper.get_setting("history_max_age")
now = datetime.datetime.now()
last_week = now.day - max_age

View File

@ -4,24 +4,14 @@ import logging
import threading
import asyncio
import datetime
from tzlocal import get_localzone
from apscheduler.events import EVENT_JOB_EXECUTED
from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.triggers.cron import CronTrigger
from app.classes.controllers.users_controller import Users_Controller
from app.classes.minecraft.serverjars import server_jar_obj
from app.classes.models.management import management_helper
from app.classes.models.users import users_helper
from app.classes.shared.helpers import helper
from app.classes.shared.console import console
from app.classes.models.management import helpers_management
from app.classes.models.users import helper_users
from app.classes.web.tornado_handler import Webserver
from app.classes.web.websocket_helper import websocket_helper
try:
from tzlocal import get_localzone
from apscheduler.events import EVENT_JOB_EXECUTED
from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.triggers.cron import CronTrigger
except ModuleNotFoundError as err:
helper.auto_installer_fix(err)
logger = logging.getLogger("apscheduler")
scheduler_intervals = {
@ -41,14 +31,15 @@ scheduler_intervals = {
class TasksManager:
def __init__(self, controller):
def __init__(self, helper, controller):
self.helper = helper
self.controller = controller
self.tornado = Webserver(controller, self)
self.tornado = Webserver(helper, controller, self)
self.tz = get_localzone()
self.scheduler = BackgroundScheduler(timezone=str(self.tz))
self.users_controller = Users_Controller()
self.users_controller = self.controller.users
self.webserver_thread = threading.Thread(
target=self.tornado.run_tornado, daemon=True, name="tornado_thread"
@ -78,7 +69,7 @@ class TasksManager:
return self.main_thread_exiting
def reload_schedule_from_db(self):
jobs = management_helper.get_schedules_enabled()
jobs = helpers_management.get_schedules_enabled()
logger.info("Reload from DB called. Current enabled schedules: ")
for item in jobs:
logger.info(f"JOB: {item}")
@ -86,7 +77,7 @@ class TasksManager:
def command_watcher(self):
while True:
# select any commands waiting to be processed
commands = management_helper.get_unactioned_commands()
commands = helpers_management.get_unactioned_commands()
for c in commands:
try:
svr = self.controller.get_server_obj(c.server_id)
@ -95,7 +86,7 @@ class TasksManager:
"Server value requested does note exist! "
"Purging item from waiting commands."
)
management_helper.mark_command_complete(c.command_id)
helpers_management.mark_command_complete(c.command_id)
user_id = c.user_id
command = c.command
@ -116,19 +107,19 @@ class TasksManager:
svr.jar_update()
else:
svr.send_command(command)
management_helper.mark_command_complete(c.command_id)
helpers_management.mark_command_complete(c.command_id)
time.sleep(1)
def _main_graceful_exit(self):
try:
os.remove(helper.session_file)
os.remove(self.helper.session_file)
self.controller.stop_all_servers()
except:
logger.info("Caught error during shutdown", exc_info=True)
logger.info("***** Crafty Shutting Down *****\n\n")
console.info("***** Crafty Shutting Down *****\n\n")
self.helper.console.info("***** Crafty Shutting Down *****\n\n")
self.main_thread_exiting = True
def start_webserver(self):
@ -136,7 +127,7 @@ class TasksManager:
def reload_webserver(self):
self.tornado.stop_web_server()
console.info("Waiting 3 seconds")
self.helper.console.info("Waiting 3 seconds")
time.sleep(3)
self.webserver_thread = threading.Thread(
target=self.tornado.run_tornado, daemon=True, name="tornado_thread"
@ -148,20 +139,20 @@ class TasksManager:
def start_scheduler(self):
logger.info("Launching Scheduler Thread...")
console.info("Launching Scheduler Thread...")
self.helper.console.info("Launching Scheduler Thread...")
self.schedule_thread.start()
logger.info("Launching command thread...")
console.info("Launching command thread...")
self.helper.console.info("Launching command thread...")
self.command_thread.start()
logger.info("Launching log watcher...")
console.info("Launching log watcher...")
self.helper.console.info("Launching log watcher...")
self.log_watcher_thread.start()
logger.info("Launching realtime thread...")
console.info("Launching realtime thread...")
self.helper.console.info("Launching realtime thread...")
self.realtime_thread.start()
def scheduler_thread(self):
schedules = management_helper.get_schedules_enabled()
schedules = helpers_management.get_schedules_enabled()
self.scheduler.add_listener(self.schedule_watcher, mask=EVENT_JOB_EXECUTED)
# self.scheduler.add_job(
# self.scheduler.print_jobs, "interval", seconds=10, id="-1"
@ -173,7 +164,7 @@ class TasksManager:
if schedule.cron_string != "":
try:
self.scheduler.add_job(
management_helper.add_command,
helpers_management.add_command,
CronTrigger.from_crontab(
schedule.cron_string, timezone=str(self.tz)
),
@ -186,16 +177,16 @@ class TasksManager:
],
)
except Exception as e:
console.error(f"Failed to schedule task with error: {e}.")
console.warning("Removing failed task from DB.")
self.helper.console.error(f"Failed to schedule task with error: {e}.")
self.helper.console.warning("Removing failed task from DB.")
logger.error(f"Failed to schedule task with error: {e}.")
logger.warning("Removing failed task from DB.")
# remove items from DB if task fails to add to apscheduler
management_helper.delete_scheduled_task(schedule.schedule_id)
self.controller.management_helper.delete_scheduled_task(schedule.schedule_id)
else:
if schedule.interval_type == "hours":
self.scheduler.add_job(
management_helper.add_command,
helpers_management.add_command,
"cron",
minute=0,
hour="*/" + str(schedule.interval),
@ -209,7 +200,7 @@ class TasksManager:
)
elif schedule.interval_type == "minutes":
self.scheduler.add_job(
management_helper.add_command,
helpers_management.add_command,
"cron",
minute="*/" + str(schedule.interval),
id=str(schedule.schedule_id),
@ -223,7 +214,7 @@ class TasksManager:
elif schedule.interval_type == "days":
curr_time = schedule.start_time.split(":")
self.scheduler.add_job(
management_helper.add_command,
helpers_management.add_command,
"cron",
day="*/" + str(schedule.interval),
hour=curr_time[0],
@ -243,7 +234,7 @@ class TasksManager:
logger.info(f"JOB: {item}")
def schedule_job(self, job_data):
sch_id = management_helper.create_scheduled_task(
sch_id = helpers_management.create_scheduled_task(
job_data["server_id"],
job_data["action"],
job_data["interval"],
@ -260,13 +251,13 @@ class TasksManager:
# Checks to make sure some doofus didn't actually make the newly
# created task a child of itself.
if str(job_data["parent"]) == str(sch_id):
management_helper.update_scheduled_task(sch_id, {"parent": None})
helpers_management.update_scheduled_task(sch_id, {"parent": None})
# Check to see if it's enabled and is not a chain reaction.
if job_data["enabled"] and job_data["interval_type"] != "reaction":
if job_data["cron_string"] != "":
try:
self.scheduler.add_job(
management_helper.add_command,
helpers_management.add_command,
CronTrigger.from_crontab(
job_data["cron_string"], timezone=str(self.tz)
),
@ -279,16 +270,16 @@ class TasksManager:
],
)
except Exception as e:
console.error(f"Failed to schedule task with error: {e}.")
console.warning("Removing failed task from DB.")
self.helper.console.error(f"Failed to schedule task with error: {e}.")
self.helper.console.warning("Removing failed task from DB.")
logger.error(f"Failed to schedule task with error: {e}.")
logger.warning("Removing failed task from DB.")
# remove items from DB if task fails to add to apscheduler
management_helper.delete_scheduled_task(sch_id)
self.controller.management_helper.delete_scheduled_task(sch_id)
else:
if job_data["interval_type"] == "hours":
self.scheduler.add_job(
management_helper.add_command,
helpers_management.add_command,
"cron",
minute=0,
hour="*/" + str(job_data["interval"]),
@ -302,7 +293,7 @@ class TasksManager:
)
elif job_data["interval_type"] == "minutes":
self.scheduler.add_job(
management_helper.add_command,
helpers_management.add_command,
"cron",
minute="*/" + str(job_data["interval"]),
id=str(sch_id),
@ -316,7 +307,7 @@ class TasksManager:
elif job_data["interval_type"] == "days":
curr_time = job_data["start_time"].split(":")
self.scheduler.add_job(
management_helper.add_command,
helpers_management.add_command,
"cron",
day="*/" + str(job_data["interval"]),
hour=curr_time[0],
@ -335,18 +326,18 @@ class TasksManager:
logger.info(f"JOB: {item}")
def remove_all_server_tasks(self, server_id):
schedules = management_helper.get_schedules_by_server(server_id)
schedules = helpers_management.get_schedules_by_server(server_id)
for schedule in schedules:
if schedule.interval != "reaction":
self.remove_job(schedule.schedule_id)
def remove_job(self, sch_id):
job = management_helper.get_scheduled_task_model(sch_id)
for schedule in management_helper.get_child_schedules(sch_id):
management_helper.update_scheduled_task(
job = helpers_management.get_scheduled_task_model(sch_id)
for schedule in helpers_management.get_child_schedules(sch_id):
self.controller.management_helper.update_scheduled_task(
schedule.schedule_id, {"parent": None}
)
management_helper.delete_scheduled_task(sch_id)
self.controller.management_helper.delete_scheduled_task(sch_id)
if job.enabled and job.interval_type != "reaction":
self.scheduler.remove_job(str(sch_id))
logger.info(f"Job with ID {sch_id} was deleted.")
@ -358,11 +349,11 @@ class TasksManager:
)
def update_job(self, sch_id, job_data):
management_helper.update_scheduled_task(sch_id, job_data)
helpers_management.update_scheduled_task(sch_id, job_data)
# Checks to make sure some doofus didn't actually make the newly
# created task a child of itself.
if str(job_data["parent"]) == str(sch_id):
management_helper.update_scheduled_task(sch_id, {"parent": None})
helpers_management.update_scheduled_task(sch_id, {"parent": None})
try:
if job_data["interval"] != "reaction":
self.scheduler.remove_job(str(sch_id))
@ -377,7 +368,7 @@ class TasksManager:
if job_data["cron_string"] != "":
try:
self.scheduler.add_job(
management_helper.add_command,
helpers_management.add_command,
CronTrigger.from_crontab(
job_data["cron_string"], timezone=str(self.tz)
),
@ -390,13 +381,13 @@ class TasksManager:
],
)
except Exception as e:
console.error(f"Failed to schedule task with error: {e}.")
console.info("Removing failed task from DB.")
management_helper.delete_scheduled_task(sch_id)
self.helper.console.error(f"Failed to schedule task with error: {e}.")
self.helper.console.info("Removing failed task from DB.")
self.controller.management_helper.delete_scheduled_task(sch_id)
else:
if job_data["interval_type"] == "hours":
self.scheduler.add_job(
management_helper.add_command,
helpers_management.add_command,
"cron",
minute=0,
hour="*/" + str(job_data["interval"]),
@ -410,7 +401,7 @@ class TasksManager:
)
elif job_data["interval_type"] == "minutes":
self.scheduler.add_job(
management_helper.add_command,
helpers_management.add_command,
"cron",
minute="*/" + str(job_data["interval"]),
id=str(sch_id),
@ -424,7 +415,7 @@ class TasksManager:
elif job_data["interval_type"] == "days":
curr_time = job_data["start_time"].split(":")
self.scheduler.add_job(
management_helper.add_command,
helpers_management.add_command,
"cron",
day="*/" + str(job_data["interval"]),
hour=curr_time[0],
@ -450,10 +441,10 @@ class TasksManager:
def schedule_watcher(self, event):
if not event.exception:
if str(event.job_id).isnumeric():
task = management_helper.get_scheduled_task_model(int(event.job_id))
management_helper.add_to_audit_log_raw(
task = helpers_management.get_scheduled_task_model(int(event.job_id))
helpers_management.add_to_audit_log_raw(
"system",
users_helper.get_user_id_by_name("system"),
helper_users.get_user_id_by_name("system"),
task.server_id,
f"Task with id {task.schedule_id} completed successfully",
"127.0.0.1",
@ -465,7 +456,7 @@ class TasksManager:
# check for any child tasks for this. It's kind of backward,
# but this makes DB management a lot easier. One to one
# instead of one to many.
for schedule in management_helper.get_child_schedules_by_server(
for schedule in helpers_management.get_child_schedules_by_server(
task.schedule_id, task.server_id
):
# event job ID's are strings so we need to look at
@ -476,7 +467,7 @@ class TasksManager:
seconds=schedule.delay
)
self.scheduler.add_job(
management_helper.add_command,
helpers_management.add_command,
"date",
run_date=delaytime,
id=str(schedule.schedule_id),
@ -496,11 +487,11 @@ class TasksManager:
logger.error(f"Task failed with error: {event.exception}")
def start_stats_recording(self):
stats_update_frequency = helper.get_setting("stats_update_frequency")
stats_update_frequency = self.helper.get_setting("stats_update_frequency")
logger.info(
f"Stats collection frequency set to {stats_update_frequency} seconds"
)
console.info(
self.helper.console.info(
f"Stats collection frequency set to {stats_update_frequency} seconds"
)
@ -516,36 +507,36 @@ class TasksManager:
def serverjar_cache_refresher(self):
logger.info("Refreshing serverjars.com cache on start")
server_jar_obj.refresh_cache()
self.controller.server_jars.refresh_cache()
logger.info("Scheduling Serverjars.com cache refresh service every 12 hours")
self.scheduler.add_job(
server_jar_obj.refresh_cache, "interval", hours=12, id="serverjars"
self.controller.server_jars.refresh_cache, "interval", hours=12, id="serverjars"
)
def realtime(self):
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
host_stats = management_helper.get_latest_hosts_stats()
host_stats = helpers_management.get_latest_hosts_stats()
while True:
if host_stats.get(
"cpu_usage"
) != management_helper.get_latest_hosts_stats().get(
) != helpers_management.get_latest_hosts_stats().get(
"cpu_usage"
) or host_stats.get(
"mem_percent"
) != management_helper.get_latest_hosts_stats().get(
) != helpers_management.get_latest_hosts_stats().get(
"mem_percent"
):
# Stats are different
host_stats = management_helper.get_latest_hosts_stats()
if len(websocket_helper.clients) > 0:
host_stats = helpers_management.get_latest_hosts_stats()
if len(self.helper.websocket_helper.clients) > 0:
# There are clients
websocket_helper.broadcast_page(
self.helper.websocket_helper.broadcast_page(
"/panel/dashboard",
"update_host_stats",
{

View File

@ -3,15 +3,13 @@ import logging
import os
import typing as t
from app.classes.shared.console import console
from app.classes.shared.helpers import helper
logger = logging.getLogger(__name__)
class Translation:
def __init__(self):
self.translations_path = os.path.join(helper.root_dir, "app", "translations")
def __init__(self, helper):
self.helper = helper
self.translations_path = os.path.join(self.helper.root_dir, "app", "translations")
self.cached_translation = None
self.cached_translation_lang = None
@ -59,7 +57,7 @@ class Translation:
f"Translation File Error: page {page} "
f"does not exist for lang {language}"
)
console.error(
self.helper.console.error(
f"Translation File Error: page {page} "
f"does not exist for lang {language}"
)
@ -73,7 +71,7 @@ class Translation:
f"Translation File Error: word {word} does not exist on page "
f"{page} for lang {language}"
)
console.error(
self.helper.console.error(
f"Translation File Error: word {word} does not exist on page "
f"{page} for lang {language}"
)
@ -83,10 +81,7 @@ class Translation:
logger.critical(
f"Translation File Error: Unable to read {language_file} due to {e}"
)
console.critical(
self.helper.console.critical(
f"Translation File Error: Unable to read {language_file} due to {e}"
)
return None
translation = Translation()

View File

@ -3,23 +3,15 @@ import html
import re
import logging
import time
import bleach
import tornado.web
import tornado.escape
from app.classes.models.server_permissions import Enum_Permissions_Server
from app.classes.shared.console import console
from app.classes.shared.helpers import helper
from app.classes.shared.translation import translation
from app.classes.shared.helpers import Helpers
from app.classes.shared.server import ServerOutBuf
from app.classes.web.websocket_helper import websocket_helper
from app.classes.web.base_handler import BaseHandler
try:
import bleach
import tornado.web
import tornado.escape
except ModuleNotFoundError as ex:
helper.auto_installer_fix(ex)
logger = logging.getLogger(__name__)
@ -67,9 +59,9 @@ class AjaxHandler(BaseHandler):
)
if full_log:
log_lines = helper.get_setting("max_log_lines")
data = helper.tail_file(
helper.get_os_understandable_path(server_data["log_path"]),
log_lines = self.helper.get_setting("max_log_lines")
data = Helpers.tail_file(
Helpers.get_os_understandable_path(server_data["log_path"]),
log_lines,
)
else:
@ -79,7 +71,7 @@ class AjaxHandler(BaseHandler):
try:
d = re.sub("(\033\\[(0;)?[0-9]*[A-z]?(;[0-9])?m?)|(> )", "", d)
d = re.sub("[A-z]{2}\b\b", "", d)
line = helper.log_colors(html.escape(d))
line = self.helper.log_colors(html.escape(d))
self.write(f"{line}<br />")
# self.write(d.encode("utf-8"))
@ -87,7 +79,7 @@ class AjaxHandler(BaseHandler):
logger.warning(f"Skipping Log Line due to error: {e}")
elif page == "announcements":
data = helper.get_announcements()
data = Helpers.get_announcements()
page_data["notify_data"] = data
self.render_page("ajax/notify.html", page_data)
@ -95,9 +87,9 @@ class AjaxHandler(BaseHandler):
path = self.get_argument("path", None)
self.write(
helper.get_os_understandable_path(path)
Helpers.get_os_understandable_path(path)
+ "\n"
+ helper.generate_zip_tree(path)
+ Helpers.generate_zip_tree(path)
)
self.finish()
@ -105,9 +97,9 @@ class AjaxHandler(BaseHandler):
path = self.get_argument("path", None)
self.write(
helper.get_os_understandable_path(path)
Helpers.get_os_understandable_path(path)
+ "\n"
+ helper.generate_zip_dir(path)
+ Helpers.generate_zip_dir(path)
)
self.finish()
@ -175,7 +167,7 @@ class AjaxHandler(BaseHandler):
onclick=""><input type='checkbox' class="checkBoxClass" name='root_path' value="{dpath}">
<span style="margin-right: 6px;"><i class="far fa-file">
</i></span></input>{filename}</li>"""
self.write(helper.get_os_understandable_path(folder) + "\n" + output)
self.write(Helpers.get_os_understandable_path(folder) + "\n" + output)
self.finish()
elif page == "get_backup_dir":
@ -240,7 +232,7 @@ class AjaxHandler(BaseHandler):
<span style="margin-right: 6px;"><i class="far fa-file">
</i></span></input>{filename}</li>"""
self.write(helper.get_os_understandable_path(folder) + "\n" + output)
self.write(Helpers.get_os_understandable_path(folder) + "\n" + output)
self.finish()
elif page == "get_dir":
@ -252,13 +244,13 @@ class AjaxHandler(BaseHandler):
else:
server_id = bleach.clean(server_id)
if helper.validate_traversal(
if Helpers.validate_traversal(
self.controller.servers.get_server_data_by_id(server_id)["path"], path
):
self.write(
helper.get_os_understandable_path(path)
Helpers.get_os_understandable_path(path)
+ "\n"
+ helper.generate_dir(path)
+ Helpers.generate_dir(path)
)
self.finish()
@ -291,7 +283,7 @@ class AjaxHandler(BaseHandler):
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")
self.helper.console.warning("Server ID not found in send_command ajax call")
srv_obj = self.controller.get_server_obj(server_id)
@ -390,8 +382,8 @@ class AjaxHandler(BaseHandler):
server_data = self.controller.servers.get_server_data_by_id(server_id)
if server_data["type"] == "minecraft-java":
backup_path = svr_obj.backup_path
if helper.validate_traversal(backup_path, zip_name):
tempDir = helper.unzip_backup_archive(backup_path, zip_name)
if Helpers.validate_traversal(backup_path, zip_name):
tempDir = Helpers.unzip_backup_archive(backup_path, zip_name)
new_server = self.controller.import_zip_server(
svr_obj.server_name,
tempDir,
@ -410,8 +402,8 @@ class AjaxHandler(BaseHandler):
else:
backup_path = svr_obj.backup_path
if helper.validate_traversal(backup_path, zip_name):
tempDir = helper.unzip_backup_archive(backup_path, zip_name)
if Helpers.validate_traversal(backup_path, zip_name):
tempDir = Helpers.unzip_backup_archive(backup_path, zip_name)
new_server = self.controller.import_bedrock_zip_server(
svr_obj.server_name,
tempDir,
@ -428,23 +420,23 @@ class AjaxHandler(BaseHandler):
elif page == "unzip_server":
path = self.get_argument("path", None)
if helper.check_file_exists(path):
helper.unzipServer(path, exec_user["user_id"])
if Helpers.check_file_exists(path):
Helpers.unzipServer(path, exec_user["user_id"])
else:
user_id = exec_user["user_id"]
if user_id:
time.sleep(5)
user_lang = self.controller.users.get_user_lang_by_id(user_id)
websocket_helper.broadcast_user(
self.helper.websocket_helper.broadcast_user(
user_id,
"send_start_error",
{"error": translation.translate("error", "no-file", user_lang)},
{"error": self.helper.translation.translate("error", "no-file", user_lang)},
)
return
elif page == "backup_select":
path = self.get_argument("path", None)
helper.backup_select(path, exec_user["user_id"])
self.helper.backup_select(path, exec_user["user_id"])
return
@tornado.web.authenticated
@ -481,12 +473,12 @@ class AjaxHandler(BaseHandler):
if not superuser:
self.redirect("/panel/error?error=Unauthorized access to Backups")
return
file_path = helper.get_os_understandable_path(
file_path = Helpers.get_os_understandable_path(
self.get_body_argument("file_path", default=None, strip=True)
)
server_id = self.get_argument("id", None)
console.warning(f"Delete {file_path} for server {server_id}")
self.helper.console.warning(f"Delete {file_path} for server {server_id}")
if not self.check_server_id(server_id, "del_backup"):
return
@ -495,21 +487,21 @@ class AjaxHandler(BaseHandler):
server_info = self.controller.servers.get_server_data_by_id(server_id)
if not (
helper.in_path(
helper.get_os_understandable_path(server_info["path"]), file_path
Helpers.in_path(
Helpers.get_os_understandable_path(server_info["path"]), file_path
)
or helper.in_path(
helper.get_os_understandable_path(server_info["backup_path"]),
or Helpers.in_path(
Helpers.get_os_understandable_path(server_info["backup_path"]),
file_path,
)
) or not helper.check_file_exists(os.path.abspath(file_path)):
) or not Helpers.check_file_exists(os.path.abspath(file_path)):
logger.warning(f"Invalid path in del_backup ajax call ({file_path})")
console.warning(f"Invalid path in del_backup ajax call ({file_path})")
self.helper.console.warning(f"Invalid path in del_backup ajax call ({file_path})")
return
# Delete the file
if helper.validate_traversal(
helper.get_os_understandable_path(server_info["backup_path"]), file_path
if Helpers.validate_traversal(
Helpers.get_os_understandable_path(server_info["backup_path"]), file_path
):
os.remove(file_path)
@ -566,7 +558,7 @@ class AjaxHandler(BaseHandler):
logger.warning(
f"Server ID not defined in {page_name} ajax call ({server_id})"
)
console.warning(
self.helper.console.warning(
f"Server ID not defined in {page_name} ajax call ({server_id})"
)
return
@ -578,7 +570,7 @@ class AjaxHandler(BaseHandler):
logger.warning(
f"Server ID not found in {page_name} ajax call ({server_id})"
)
console.warning(
self.helper.console.warning(
f"Server ID not found in {page_name} ajax call ({server_id})"
)
return

View File

@ -1,21 +1,12 @@
import logging
from typing import Union, List, Optional, Tuple, Dict, Any
import bleach
import tornado.web
from app.classes.models.users import ApiKeys
from app.classes.shared.authentication import authentication
from app.classes.shared.main_controller import Controller
from app.classes.shared.helpers import helper
try:
import tornado.web
import bleach
except ModuleNotFoundError as e:
helper.auto_installer_fix(e)
logger = logging.getLogger(__name__)
class BaseHandler(tornado.web.RequestHandler):
nobleach = {bool, type(None)}
@ -23,8 +14,9 @@ class BaseHandler(tornado.web.RequestHandler):
# noinspection PyAttributeOutsideInit
def initialize(
self, controller: Controller = None, tasks_manager=None, translator=None
self, helper=None, controller=None, tasks_manager=None, translator=None
):
self.helper = helper
self.controller = controller
self.tasks_manager = tasks_manager
self.translator = translator
@ -42,7 +34,7 @@ class BaseHandler(tornado.web.RequestHandler):
def get_current_user(
self,
) -> Optional[Tuple[Optional[ApiKeys], Dict[str, Any], Dict[str, Any]]]:
return authentication.check(self.get_cookie("token"))
return self.controller.authentication.check(self.get_cookie("token"))
def autobleach(self, name, text):
for r in self.redactables:

View File

@ -1,23 +1,16 @@
import os
import logging
import bleach
import tornado.web
import tornado.escape
from app.classes.models.server_permissions import Enum_Permissions_Server
from app.classes.shared.console import console
from app.classes.shared.helpers import helper
from app.classes.shared.file_helpers import file_helper
from app.classes.shared.helpers import Helpers
from app.classes.shared.file_helpers import FileHelpers
from app.classes.web.base_handler import BaseHandler
try:
import bleach
import tornado.web
import tornado.escape
except ModuleNotFoundError as e:
helper.auto_installer_fix(e)
logger = logging.getLogger(__name__)
class FileHandler(BaseHandler):
def render_page(self, template, page_data):
self.render(
@ -54,7 +47,7 @@ class FileHandler(BaseHandler):
if not superuser:
self.redirect("/panel/error?error=Unauthorized access to Files")
return
file_path = helper.get_os_understandable_path(
file_path = Helpers.get_os_understandable_path(
self.get_argument("file_path", None)
)
@ -63,16 +56,16 @@ class FileHandler(BaseHandler):
else:
server_id = bleach.clean(server_id)
if not helper.in_path(
helper.get_os_understandable_path(
if not Helpers.in_path(
Helpers.get_os_understandable_path(
self.controller.servers.get_server_data_by_id(server_id)["path"]
),
file_path,
) or not helper.check_file_exists(os.path.abspath(file_path)):
) or not Helpers.check_file_exists(os.path.abspath(file_path)):
logger.warning(
f"Invalid path in get_file file file ajax call ({file_path})"
)
console.warning(
self.helper.self.helper.console.warning(
f"Invalid path in get_file file file ajax call ({file_path})"
)
return
@ -101,13 +94,13 @@ class FileHandler(BaseHandler):
else:
server_id = bleach.clean(server_id)
if helper.validate_traversal(
if Helpers.validate_traversal(
self.controller.servers.get_server_data_by_id(server_id)["path"], path
):
self.write(
helper.get_os_understandable_path(path)
Helpers.get_os_understandable_path(path)
+ "\n"
+ helper.generate_tree(path)
+ Helpers.generate_tree(path)
)
self.finish()
@ -123,13 +116,13 @@ class FileHandler(BaseHandler):
else:
server_id = bleach.clean(server_id)
if helper.validate_traversal(
if Helpers.validate_traversal(
self.controller.servers.get_server_data_by_id(server_id)["path"], path
):
self.write(
helper.get_os_understandable_path(path)
Helpers.get_os_understandable_path(path)
+ "\n"
+ helper.generate_dir(path)
+ Helpers.generate_dir(path)
)
self.finish()
@ -161,7 +154,7 @@ class FileHandler(BaseHandler):
if not superuser:
self.redirect("/panel/error?error=Unauthorized access to Files")
return
file_parent = helper.get_os_understandable_path(
file_parent = Helpers.get_os_understandable_path(
self.get_body_argument("file_parent", default=None, strip=True)
)
file_name = self.get_body_argument("file_name", default=None, strip=True)
@ -172,16 +165,16 @@ class FileHandler(BaseHandler):
else:
server_id = bleach.clean(server_id)
if not helper.in_path(
helper.get_os_understandable_path(
if not Helpers.in_path(
Helpers.get_os_understandable_path(
self.controller.servers.get_server_data_by_id(server_id)["path"]
),
file_path,
) or helper.check_file_exists(os.path.abspath(file_path)):
) or Helpers.check_file_exists(os.path.abspath(file_path)):
logger.warning(
f"Invalid path in create_file file ajax call ({file_path})"
)
console.warning(
self.helper.self.helper.console.warning(
f"Invalid path in create_file file ajax call ({file_path})"
)
return
@ -195,7 +188,7 @@ class FileHandler(BaseHandler):
if not superuser:
self.redirect("/panel/error?error=Unauthorized access to Files")
return
dir_parent = helper.get_os_understandable_path(
dir_parent = Helpers.get_os_understandable_path(
self.get_body_argument("dir_parent", default=None, strip=True)
)
dir_name = self.get_body_argument("dir_name", default=None, strip=True)
@ -206,16 +199,16 @@ class FileHandler(BaseHandler):
else:
server_id = bleach.clean(server_id)
if not helper.in_path(
helper.get_os_understandable_path(
if not Helpers.in_path(
Helpers.get_os_understandable_path(
self.controller.servers.get_server_data_by_id(server_id)["path"]
),
dir_path,
) or helper.check_path_exists(os.path.abspath(dir_path)):
) or Helpers.check_path_exists(os.path.abspath(dir_path)):
logger.warning(
f"Invalid path in create_dir file ajax call ({dir_path})"
)
console.warning(
self.helper.self.helper.console.warning(
f"Invalid path in create_dir file ajax call ({dir_path})"
)
return
@ -227,8 +220,8 @@ class FileHandler(BaseHandler):
if not superuser:
self.redirect("/panel/error?error=Unauthorized access to Files")
return
path = helper.get_os_understandable_path(self.get_argument("path", None))
helper.unzipFile(path)
path = Helpers.get_os_understandable_path(self.get_argument("path", None))
Helpers.unzipFile(path)
self.redirect(f"/panel/server_detail?id={server_id}&subpage=files")
return
@ -259,11 +252,11 @@ class FileHandler(BaseHandler):
if not superuser:
self.redirect("/panel/error?error=Unauthorized access to Files")
return
file_path = helper.get_os_understandable_path(
file_path = Helpers.get_os_understandable_path(
self.get_body_argument("file_path", default=None, strip=True)
)
console.warning(f"Delete {file_path} for server {server_id}")
self.helper.self.helper.console.warning(f"Delete {file_path} for server {server_id}")
if not self.check_server_id(server_id, "del_file"):
return
@ -272,33 +265,33 @@ class FileHandler(BaseHandler):
server_info = self.controller.servers.get_server_data_by_id(server_id)
if not (
helper.in_path(
helper.get_os_understandable_path(server_info["path"]), file_path
Helpers.in_path(
Helpers.get_os_understandable_path(server_info["path"]), file_path
)
or helper.in_path(
helper.get_os_understandable_path(server_info["backup_path"]),
or Helpers.in_path(
Helpers.get_os_understandable_path(server_info["backup_path"]),
file_path,
)
) or not helper.check_file_exists(os.path.abspath(file_path)):
) or not Helpers.check_file_exists(os.path.abspath(file_path)):
logger.warning(f"Invalid path in del_file file ajax call ({file_path})")
console.warning(
self.helper.console.warning(
f"Invalid path in del_file file ajax call ({file_path})"
)
return
# Delete the file
file_helper.del_file(file_path)
FileHelpers.del_file(file_path)
elif page == "del_dir":
if not permissions["Files"] in user_perms:
if not superuser:
self.redirect("/panel/error?error=Unauthorized access to Files")
return
dir_path = helper.get_os_understandable_path(
dir_path = Helpers.get_os_understandable_path(
self.get_body_argument("dir_path", default=None, strip=True)
)
console.warning(f"Delete {dir_path} for server {server_id}")
self.helper.console.warning(f"Delete {dir_path} for server {server_id}")
if not self.check_server_id(server_id, "del_dir"):
return
@ -306,20 +299,20 @@ class FileHandler(BaseHandler):
server_id = bleach.clean(server_id)
server_info = self.controller.servers.get_server_data_by_id(server_id)
if not helper.in_path(
helper.get_os_understandable_path(server_info["path"]), dir_path
) or not helper.check_path_exists(os.path.abspath(dir_path)):
if not Helpers.in_path(
Helpers.get_os_understandable_path(server_info["path"]), dir_path
) or not Helpers.check_path_exists(os.path.abspath(dir_path)):
logger.warning(f"Invalid path in del_file file ajax call ({dir_path})")
console.warning(f"Invalid path in del_file file ajax call ({dir_path})")
self.helper.console.warning(f"Invalid path in del_file file ajax call ({dir_path})")
return
# Delete the directory
# os.rmdir(dir_path) # Would only remove empty directories
if helper.validate_traversal(
helper.get_os_understandable_path(server_info["path"]), dir_path
if Helpers.validate_traversal(
Helpers.get_os_understandable_path(server_info["path"]), dir_path
):
# Removes also when there are contents
file_helper.del_dirs(dir_path)
FileHelpers.del_dirs(dir_path)
@tornado.web.authenticated
def put(self, page):
@ -350,7 +343,7 @@ class FileHandler(BaseHandler):
file_contents = self.get_body_argument(
"file_contents", default=None, strip=True
)
file_path = helper.get_os_understandable_path(
file_path = Helpers.get_os_understandable_path(
self.get_body_argument("file_path", default=None, strip=True)
)
@ -359,16 +352,16 @@ class FileHandler(BaseHandler):
else:
server_id = bleach.clean(server_id)
if not helper.in_path(
helper.get_os_understandable_path(
if not Helpers.in_path(
Helpers.get_os_understandable_path(
self.controller.servers.get_server_data_by_id(server_id)["path"]
),
file_path,
) or not helper.check_file_exists(os.path.abspath(file_path)):
) or not Helpers.check_file_exists(os.path.abspath(file_path)):
logger.warning(
f"Invalid path in save_file file ajax call ({file_path})"
)
console.warning(
self.helper.console.warning(
f"Invalid path in save_file file ajax call ({file_path})"
)
return
@ -382,7 +375,7 @@ class FileHandler(BaseHandler):
if not superuser:
self.redirect("/panel/error?error=Unauthorized access to Files")
return
item_path = helper.get_os_understandable_path(
item_path = Helpers.get_os_understandable_path(
self.get_body_argument("item_path", default=None, strip=True)
)
new_item_name = self.get_body_argument(
@ -396,35 +389,35 @@ class FileHandler(BaseHandler):
if item_path is None or new_item_name is None:
logger.warning("Invalid path(s) in rename_file file ajax call")
console.warning("Invalid path(s) in rename_file file ajax call")
self.helper.console.warning("Invalid path(s) in rename_file file ajax call")
return
if not helper.in_path(
helper.get_os_understandable_path(
if not Helpers.in_path(
Helpers.get_os_understandable_path(
self.controller.servers.get_server_data_by_id(server_id)["path"]
),
item_path,
) or not helper.check_path_exists(os.path.abspath(item_path)):
) or not Helpers.check_path_exists(os.path.abspath(item_path)):
logger.warning(
f"Invalid old name path in rename_file file ajax call ({server_id})"
)
console.warning(
self.helper.console.warning(
f"Invalid old name path in rename_file file ajax call ({server_id})"
)
return
new_item_path = os.path.join(os.path.split(item_path)[0], new_item_name)
if not helper.in_path(
helper.get_os_understandable_path(
if not Helpers.in_path(
Helpers.get_os_understandable_path(
self.controller.servers.get_server_data_by_id(server_id)["path"]
),
new_item_path,
) or helper.check_path_exists(os.path.abspath(new_item_path)):
) or Helpers.check_path_exists(os.path.abspath(new_item_path)):
logger.warning(
f"Invalid new name path in rename_file file ajax call ({server_id})"
)
console.warning(
self.helper.console.warning(
f"Invalid new name path in rename_file file ajax call ({server_id})"
)
return
@ -458,7 +451,7 @@ class FileHandler(BaseHandler):
if not superuser:
self.redirect("/panel/error?error=Unauthorized access to Files")
return
item_path = helper.get_os_understandable_path(
item_path = Helpers.get_os_understandable_path(
self.get_body_argument("item_path", default=None, strip=True)
)
new_item_name = self.get_body_argument(
@ -472,35 +465,35 @@ class FileHandler(BaseHandler):
if item_path is None or new_item_name is None:
logger.warning("Invalid path(s) in rename_file file ajax call")
console.warning("Invalid path(s) in rename_file file ajax call")
self.helper.console.warning("Invalid path(s) in rename_file file ajax call")
return
if not helper.in_path(
helper.get_os_understandable_path(
if not Helpers.in_path(
Helpers.get_os_understandable_path(
self.controller.servers.get_server_data_by_id(server_id)["path"]
),
item_path,
) or not helper.check_path_exists(os.path.abspath(item_path)):
) or not Helpers.check_path_exists(os.path.abspath(item_path)):
logger.warning(
f"Invalid old name path in rename_file file ajax call ({server_id})"
)
console.warning(
self.helper.console.warning(
f"Invalid old name path in rename_file file ajax call ({server_id})"
)
return
new_item_path = os.path.join(os.path.split(item_path)[0], new_item_name)
if not helper.in_path(
helper.get_os_understandable_path(
if not Helpers.in_path(
Helpers.get_os_understandable_path(
self.controller.servers.get_server_data_by_id(server_id)["path"]
),
new_item_path,
) or helper.check_path_exists(os.path.abspath(new_item_path)):
) or Helpers.check_path_exists(os.path.abspath(new_item_path)):
logger.warning(
f"Invalid new name path in rename_file file ajax call ({server_id})"
)
console.warning(
self.helper.console.warning(
f"Invalid new name path in rename_file file ajax call ({server_id})"
)
return
@ -513,7 +506,7 @@ class FileHandler(BaseHandler):
logger.warning(
f"Server ID not defined in {page_name} file ajax call ({server_id})"
)
console.warning(
self.helper.console.warning(
f"Server ID not defined in {page_name} file ajax call ({server_id})"
)
return
@ -525,7 +518,7 @@ class FileHandler(BaseHandler):
logger.warning(
f"Server ID not found in {page_name} file ajax call ({server_id})"
)
console.warning(
self.helper.console.warning(
f"Server ID not found in {page_name} file ajax call ({server_id})"
)
return

View File

@ -1,14 +1,8 @@
import logging
import requests
from app.classes.shared.helpers import helper
from app.classes.web.base_handler import BaseHandler
try:
import requests
except ModuleNotFoundError as e:
helper.auto_installer_fix(e)
logger = logging.getLogger(__name__)
@ -21,7 +15,7 @@ class HTTPHandler(BaseHandler):
url = "https://" + url_list[0]
else:
url = "https://" + url
db_port = helper.get_setting("https_port")
db_port = self.helper.get_setting("https_port")
try:
resp = requests.get(url + ":" + str(port))
resp.raise_for_status()
@ -39,7 +33,7 @@ class HTTPHandlerPage(BaseHandler):
url = "https://" + url_list[0]
else:
url = "https://" + url
db_port = helper.get_setting("https_port")
db_port = self.helper.get_setting("https_port")
try:
resp = requests.get(url + ":" + str(port))
resp.raise_for_status()

View File

@ -6,29 +6,23 @@ from typing import Dict, Any, Tuple
import json
import logging
import threading
import bleach
import libgravatar
import requests
import tornado.web
import tornado.escape
from tornado import iostream
# TZLocal is set as a hidden import on win pipeline
from tzlocal import get_localzone
from cron_validator import CronValidator
from app.classes.models.server_permissions import Enum_Permissions_Server
from app.classes.models.crafty_permissions import Enum_Permissions_Crafty
from app.classes.models.management import management_helper
from app.classes.shared.authentication import authentication
from app.classes.shared.helpers import helper
from app.classes.models.management import helpers_management
from app.classes.shared.helpers import Helpers
from app.classes.web.base_handler import BaseHandler
try:
import bleach
import libgravatar
import requests
import tornado.web
import tornado.escape
from tornado import iostream
# TZLocal is set as a hidden import on win pipeline
from tzlocal import get_localzone
from cron_validator import CronValidator
except ModuleNotFoundError as ex:
helper.auto_installer_fix(ex)
logger = logging.getLogger(__name__)
@ -268,7 +262,7 @@ class PanelHandler(BaseHandler):
# todo: make this actually pull and compare version data
"update_available": False,
"serverTZ": get_localzone(),
"version_data": helper.get_version_string(),
"version_data": self.helper.get_version_string(),
"user_data": exec_user,
"user_role": exec_user_role,
"user_crafty_permissions": exec_user_crafty_permissions,
@ -287,11 +281,11 @@ class PanelHandler(BaseHandler):
},
"menu_servers": defined_servers,
"hosts_data": self.controller.management.get_latest_hosts_stats(),
"show_contribute": helper.get_setting("show_contribute_link", True),
"show_contribute": self.helper.get_setting("show_contribute_link", True),
"error": error,
"time": formatted_time,
"lang": self.controller.users.get_user_lang_by_id(exec_user["user_id"]),
"lang_page": helper.getLangPage(
"lang_page": Helpers.getLangPage(
self.controller.users.get_user_lang_by_id(exec_user["user_id"])
),
"super_user": superuser,
@ -306,7 +300,7 @@ class PanelHandler(BaseHandler):
else None,
"superuser": superuser,
}
if helper.get_setting("allow_nsfw_profile_pictures"):
if self.helper.get_setting("allow_nsfw_profile_pictures"):
rating = "x"
else:
rating = "g"
@ -341,7 +335,7 @@ class PanelHandler(BaseHandler):
template = "public/error.html"
elif page == "credits":
with open(helper.credits_cache, encoding="utf-8") as credits_default_local:
with open(self.helper.credits_cache, encoding="utf-8") as credits_default_local:
try:
remote = requests.get(
"https://craftycontrol.com/credits", allow_redirects=True
@ -585,7 +579,7 @@ class PanelHandler(BaseHandler):
"/panel/error?error=Unauthorized access To Schedules"
)
return
page_data["schedules"] = management_helper.get_schedules_by_server(
page_data["schedules"] = helpers_management.get_schedules_by_server(
server_id
)
@ -635,7 +629,7 @@ class PanelHandler(BaseHandler):
).send_backup_status()
# makes it so relative path is the only thing shown
for file in page_data["exclusions"]:
if helper.is_os_windows():
if Helpers.is_os_windows():
exclusions.append(file.replace(server_info["path"] + "\\", ""))
else:
exclusions.append(file.replace(server_info["path"] + "/", ""))
@ -645,7 +639,7 @@ class PanelHandler(BaseHandler):
page_data["backup_list"] = server.list_backups()
except:
page_data["backup_list"] = []
page_data["backup_path"] = helper.wtol_path(server_info["backup_path"])
page_data["backup_path"] = Helpers.wtol_path(server_info["backup_path"])
def get_banned_players_html():
banned_players = self.controller.servers.get_banned_players(server_id)
@ -688,11 +682,11 @@ class PanelHandler(BaseHandler):
server_info = self.controller.servers.get_server_data_by_id(server_id)
backup_file = os.path.abspath(
os.path.join(
helper.get_os_understandable_path(server_info["backup_path"]), file
Helpers.get_os_understandable_path(server_info["backup_path"]), file
)
)
if not helper.in_path(
helper.get_os_understandable_path(server_info["backup_path"]),
if not Helpers.in_path(
Helpers.get_os_understandable_path(server_info["backup_path"]),
backup_file,
) or not os.path.isfile(backup_file):
self.redirect("/panel/error?error=Invalid path detected")
@ -799,10 +793,10 @@ class PanelHandler(BaseHandler):
else:
page_data["super-disabled"] = "disabled"
for file in sorted(
os.listdir(os.path.join(helper.root_dir, "app", "translations"))
os.listdir(os.path.join(self.helper.root_dir, "app", "translations"))
):
if file.endswith(".json"):
if file not in helper.get_setting("disabled_language_files"):
if file not in self.helper.get_setting("disabled_language_files"):
if file != str(page_data["languages"][0] + ".json"):
page_data["languages"].append(file.split(".")[0])
@ -810,7 +804,7 @@ class PanelHandler(BaseHandler):
elif page == "add_schedule":
server_id = self.get_argument("id", None)
page_data["schedules"] = management_helper.get_schedules_by_server(
page_data["schedules"] = helpers_management.get_schedules_by_server(
server_id
)
page_data["get_players"] = lambda: self.controller.stats.get_server_players(
@ -867,7 +861,7 @@ class PanelHandler(BaseHandler):
elif page == "edit_schedule":
server_id = self.get_argument("id", None)
page_data["schedules"] = management_helper.get_schedules_by_server(
page_data["schedules"] = helpers_management.get_schedules_by_server(
server_id
)
sch_id = self.get_argument("sch_id", None)
@ -979,10 +973,10 @@ class PanelHandler(BaseHandler):
page_data["super-disabled"] = "disabled"
for file in sorted(
os.listdir(os.path.join(helper.root_dir, "app", "translations"))
os.listdir(os.path.join(self.helper.root_dir, "app", "translations"))
):
if file.endswith(".json"):
if file not in helper.get_setting("disabled_language_files"):
if file not in self.helper.get_setting("disabled_language_files"):
if file != str(page_data["languages"][0] + ".json"):
page_data["languages"].append(file.split(".")[0])
@ -1150,7 +1144,7 @@ class PanelHandler(BaseHandler):
template = "panel/activity_logs.html"
elif page == "download_file":
file = helper.get_os_understandable_path(self.get_argument("path", ""))
file = Helpers.get_os_understandable_path(self.get_argument("path", ""))
name = self.get_argument("name", "")
server_id = self.check_server_id()
@ -1159,8 +1153,8 @@ class PanelHandler(BaseHandler):
server_info = self.controller.servers.get_server_data_by_id(server_id)
if not helper.in_path(
helper.get_os_understandable_path(server_info["path"]), file
if not Helpers.in_path(
Helpers.get_os_understandable_path(server_info["path"]), file
) or not os.path.isfile(file):
self.redirect("/panel/error?error=Invalid path detected")
return
@ -1275,13 +1269,13 @@ class PanelHandler(BaseHandler):
server_obj = self.controller.servers.get_server_obj(server_id)
if superuser:
server_path = self.get_argument("server_path", None)
if helper.is_os_windows():
if Helpers.is_os_windows():
server_path.replace(" ", "^ ")
server_path = helper.wtol_path(server_path)
server_path = Helpers.wtol_path(server_path)
log_path = self.get_argument("log_path", None)
if helper.is_os_windows():
if Helpers.is_os_windows():
log_path.replace(" ", "^ ")
log_path = helper.wtol_path(log_path)
log_path = Helpers.wtol_path(log_path)
executable = self.get_argument("executable", None)
execution_command = self.get_argument("execution_command", None)
server_ip = self.get_argument("server_ip", None)
@ -1312,12 +1306,12 @@ class PanelHandler(BaseHandler):
server_obj.server_name = server_name
if superuser:
if helper.validate_traversal(
helper.get_servers_root_dir(), server_path
if Helpers.validate_traversal(
self.helper.get_servers_root_dir(), server_path
):
server_obj.path = server_path
server_obj.log_path = log_path
if helper.validate_traversal(helper.get_servers_root_dir(), executable):
if Helpers.validate_traversal(self.helper.get_servers_root_dir(), executable):
server_obj.executable = executable
server_obj.execution_command = execution_command
server_obj.server_ip = server_ip
@ -1362,9 +1356,9 @@ class PanelHandler(BaseHandler):
checked = self.controller.management.get_excluded_backup_dirs(server_id)
if superuser:
backup_path = bleach.clean(self.get_argument("backup_path", None))
if helper.is_os_windows():
if Helpers.is_os_windows():
backup_path.replace(" ", "^ ")
backup_path = helper.wtol_path(backup_path)
backup_path = Helpers.wtol_path(backup_path)
else:
backup_path = server_obj.backup_path
max_backups = bleach.clean(self.get_argument("max_backups", None))
@ -1741,7 +1735,7 @@ class PanelHandler(BaseHandler):
except:
hints = False
lang = bleach.clean(
self.get_argument("language"), helper.get_setting("language")
self.get_argument("language"), self.helper.get_setting("language")
)
if superuser:
@ -1895,7 +1889,7 @@ class PanelHandler(BaseHandler):
)
self.write(
authentication.generate(key.user_id.user_id, {"token_id": key.token_id})
self.controller.authentication.generate(key.user_id.user_id, {"token_id": key.token_id})
)
self.finish()
@ -1914,7 +1908,7 @@ class PanelHandler(BaseHandler):
enabled = int(float(self.get_argument("enabled", "0")))
hints = True
lang = bleach.clean(
self.get_argument("lang", helper.get_setting("language"))
self.get_argument("lang", self.helper.get_setting("language"))
)
# We don't want a non-super user to be able to create a super user.
if superuser:
@ -2056,8 +2050,8 @@ class PanelHandler(BaseHandler):
else:
self.set_status(404)
page_data = {
"lang": helper.get_setting("language"),
"lang_page": helper.getLangPage(helper.get_setting("language")),
"lang": self.helper.get_setting("language"),
"lang_page": Helpers.getLangPage(self.helper.get_setting("language")),
}
self.render(
"public/404.html", translate=self.translator.translate, data=page_data
@ -2073,12 +2067,12 @@ class PanelHandler(BaseHandler):
page_data = {
# todo: make this actually pull and compare version data
"update_available": False,
"version_data": helper.get_version_string(),
"version_data": self.helper.get_version_string(),
"user_data": exec_user,
"hosts_data": self.controller.management.get_latest_hosts_stats(),
"show_contribute": helper.get_setting("show_contribute_link", True),
"show_contribute": self.helper.get_setting("show_contribute_link", True),
"lang": self.controller.users.get_user_lang_by_id(exec_user["user_id"]),
"lang_page": helper.getLangPage(
"lang_page": Helpers.getLangPage(
self.controller.users.get_user_lang_by_id(exec_user["user_id"])
),
}

View File

@ -1,23 +1,17 @@
import logging
import bleach
from app.classes.shared.helpers import Helpers
from app.classes.models.users import helper_users
from app.classes.shared.authentication import authentication
from app.classes.shared.helpers import helper
from app.classes.web.base_handler import BaseHandler
try:
import bleach
except ModuleNotFoundError as e:
helper.auto_installer_fix(e)
logger = logging.getLogger(__name__)
class PublicHandler(BaseHandler):
def set_current_user(self, user_id: str = None):
expire_days = helper.get_setting("cookie_expire")
expire_days = self.helper.get_setting("cookie_expire")
# if helper comes back with false
if not expire_days:
@ -25,7 +19,7 @@ class PublicHandler(BaseHandler):
if user_id is not None:
self.set_cookie(
"token", authentication.generate(user_id), expires_days=int(expire_days)
"token", self.controller.authentication.generate(user_id), expires_days=int(expire_days)
)
else:
self.clear_cookie("token")
@ -38,10 +32,10 @@ class PublicHandler(BaseHandler):
error_msg = bleach.clean(self.get_argument("error_msg", ""))
page_data = {
"version": helper.get_version_string(),
"version": self.helper.get_version_string(),
"error": error,
"lang": helper.get_setting("language"),
"lang_page": helper.getLangPage(helper.get_setting("language")),
"lang": self.helper.get_setting("language"),
"lang_page": self.helper.getLangPage(self.helper.get_setting("language")),
"query": "",
}
if self.request.query:
@ -87,10 +81,10 @@ class PublicHandler(BaseHandler):
error_msg = bleach.clean(self.get_argument("error_msg", ""))
page_data = {
"version": helper.get_version_string(),
"version": self.helper.get_version_string(),
"error": error,
"lang": helper.get_setting("language"),
"lang_page": helper.getLangPage(helper.get_setting("language")),
"lang": self.helper.get_setting("language"),
"lang_page": self.helper.getLangPage(self.helper.get_setting("language")),
"query": "",
}
if self.request.query:
@ -140,7 +134,7 @@ class PublicHandler(BaseHandler):
self.redirect(f"/public/login?error_msg={error_msg}")
return
login_result = helper.verify_pass(entered_password, user_data.password)
login_result = self.helper.verify_pass(entered_password, user_data.password)
# Valid Login
if login_result:
@ -151,7 +145,7 @@ class PublicHandler(BaseHandler):
# record this login
user_data.last_ip = self.get_remote_ip()
user_data.last_login = helper.get_time_as_string()
user_data.last_login = Helpers.get_time_as_string()
user_data.save()
# log this login

View File

@ -1,23 +1,17 @@
import json
import logging
import os
import tornado.web
import tornado.escape
import bleach
import libgravatar
import requests
from app.classes.minecraft.serverjars import server_jar_obj
from app.classes.models.crafty_permissions import Enum_Permissions_Crafty
from app.classes.shared.helpers import helper
from app.classes.shared.file_helpers import file_helper
from app.classes.shared.helpers import Helpers
from app.classes.shared.file_helpers import FileHelpers
from app.classes.web.base_handler import BaseHandler
try:
import tornado.web
import tornado.escape
import bleach
import libgravatar
import requests
except ModuleNotFoundError as e:
helper.auto_installer_fix(e)
logger = logging.getLogger(__name__)
@ -58,7 +52,7 @@ class ServerHandler(BaseHandler):
template = "public/404.html"
page_data = {
"version_data": helper.get_version_string(),
"version_data": self.helper.get_version_string(),
"user_data": exec_user,
"user_role": exec_user_role,
"roles": list_roles,
@ -78,9 +72,9 @@ class ServerHandler(BaseHandler):
},
"hosts_data": self.controller.management.get_latest_hosts_stats(),
"menu_servers": defined_servers,
"show_contribute": helper.get_setting("show_contribute_link", True),
"show_contribute": self.helper.get_setting("show_contribute_link", True),
"lang": self.controller.users.get_user_lang_by_id(exec_user["user_id"]),
"lang_page": helper.getLangPage(
"lang_page": Helpers.getLangPage(
self.controller.users.get_user_lang_by_id(exec_user["user_id"])
),
"api_key": {
@ -95,7 +89,7 @@ class ServerHandler(BaseHandler):
"superuser": superuser,
}
if helper.get_setting("allow_nsfw_profile_pictures"):
if self.helper.get_setting("allow_nsfw_profile_pictures"):
rating = "x"
else:
rating = "g"
@ -134,10 +128,10 @@ class ServerHandler(BaseHandler):
)
return
page_data["online"] = helper.check_internet()
page_data["server_types"] = server_jar_obj.get_serverjar_data()
page_data["online"] = Helpers.check_internet()
page_data["server_types"] = self.controller.server_jars.get_serverjar_data()
page_data["js_server_types"] = json.dumps(
server_jar_obj.get_serverjar_data()
self.controller.server_jars.get_serverjar_data()
)
template = "server/wizard.html"
@ -171,9 +165,9 @@ class ServerHandler(BaseHandler):
page_data = {
"version_data": "version_data_here", # TODO
"user_data": exec_user,
"show_contribute": helper.get_setting("show_contribute_link", True),
"show_contribute": self.helper.get_setting("show_contribute_link", True),
"lang": self.controller.users.get_user_lang_by_id(exec_user["user_id"]),
"lang_page": helper.getLangPage(
"lang_page": Helpers.getLangPage(
self.controller.users.get_user_lang_by_id(exec_user["user_id"])
),
}
@ -204,15 +198,15 @@ class ServerHandler(BaseHandler):
server_data.get("server_name") + f" (Copy {name_counter})"
)
new_server_uuid = helper.create_uuid()
new_server_uuid = Helpers.create_uuid()
while os.path.exists(
os.path.join(helper.servers_dir, new_server_uuid)
os.path.join(self.helper.servers_dir, new_server_uuid)
):
new_server_uuid = helper.create_uuid()
new_server_path = os.path.join(helper.servers_dir, new_server_uuid)
new_server_uuid = Helpers.create_uuid()
new_server_path = os.path.join(self.helper.servers_dir, new_server_uuid)
# copy the old server
file_helper.copy_dir(server_data.get("path"), new_server_path)
FileHelpers.copy_dir(server_data.get("path"), new_server_path)
# TODO get old server DB data to individual variables
stop_command = server_data.get("stop_command")
@ -221,7 +215,7 @@ class ServerHandler(BaseHandler):
).replace(server_uuid, new_server_uuid)
new_executable = server_data.get("executable")
new_server_log_file = str(
helper.get_os_understandable_path(server_data.get("log_path"))
Helpers.get_os_understandable_path(server_data.get("log_path"))
).replace(server_uuid, new_server_uuid)
server_port = server_data.get("server_port")
server_type = server_data.get("type")
@ -299,7 +293,7 @@ class ServerHandler(BaseHandler):
elif import_type == "import_zip":
# here import_server_path means the zip path
zip_path = bleach.clean(self.get_argument("root_path"))
good_path = helper.check_path_exists(zip_path)
good_path = Helpers.check_path_exists(zip_path)
if not good_path:
self.redirect("/panel/error?error=Temp path not found!")
return
@ -322,7 +316,7 @@ class ServerHandler(BaseHandler):
self.get_remote_ip(),
)
# deletes temp dir
file_helper.del_dirs(zip_path)
FileHelpers.del_dirs(zip_path)
else:
if len(server_parts) != 2:
self.redirect("/panel/error?error=Invalid server data")
@ -417,7 +411,7 @@ class ServerHandler(BaseHandler):
elif import_type == "import_zip":
# here import_server_path means the zip path
zip_path = bleach.clean(self.get_argument("root_path"))
good_path = helper.check_path_exists(zip_path)
good_path = Helpers.check_path_exists(zip_path)
if not good_path:
self.redirect("/panel/error?error=Temp path not found!")
return
@ -440,7 +434,7 @@ class ServerHandler(BaseHandler):
self.get_remote_ip(),
)
# deletes temp dir
file_helper.del_dirs(zip_path)
FileHelpers.del_dirs(zip_path)
else:
if len(server_parts) != 2:
self.redirect("/panel/error?error=Invalid server data")

View File

@ -1,6 +1,5 @@
import logging
from app.classes.shared.helpers import helper
from app.classes.web.base_handler import BaseHandler
logger = logging.getLogger(__name__)
@ -9,8 +8,8 @@ logger = logging.getLogger(__name__)
class StatusHandler(BaseHandler):
def get(self):
page_data = {}
page_data["lang"] = helper.get_setting("language")
page_data["lang_page"] = helper.getLangPage(helper.get_setting("language"))
page_data["lang"] = self.helper.get_setting("language")
page_data["lang_page"] = self.helper.getLangPage(self.helper.get_setting("language"))
page_data["servers"] = self.controller.servers.get_all_servers_stats()
running = 0
for srv in page_data["servers"]:

View File

@ -3,10 +3,15 @@ import sys
import json
import asyncio
import logging
import tornado.web
import tornado.ioloop
import tornado.log
import tornado.template
import tornado.escape
import tornado.locale
import tornado.httpserver
from app.classes.shared.translation import translation
from app.classes.shared.console import console
from app.classes.shared.helpers import helper
from app.classes.shared.helpers import Helpers
from app.classes.web.file_handler import FileHandler
from app.classes.web.public_handler import PublicHandler
from app.classes.web.panel_handler import PanelHandler
@ -31,26 +36,16 @@ from app.classes.web.upload_handler import UploadHandler
from app.classes.web.http_handler import HTTPHandler, HTTPHandlerPage
from app.classes.web.status_handler import StatusHandler
try:
import tornado.web
import tornado.ioloop
import tornado.log
import tornado.template
import tornado.escape
import tornado.locale
import tornado.httpserver
except ModuleNotFoundError as e:
helper.auto_installer_fix(e)
logger = logging.getLogger(__name__)
class Webserver:
def __init__(self, controller, tasks_manager):
def __init__(self, helper, controller, tasks_manager):
self.ioloop = None
self.HTTP_Server = None
self.HTTPS_Server = None
self.helper = helper
self.controller = controller
self.tasks_manager = tasks_manager
self._asyncio_patch()
@ -103,16 +98,16 @@ class Webserver:
def run_tornado(self):
# let's verify we have an SSL cert
helper.create_self_signed_cert()
self.helper.create_self_signed_cert()
http_port = helper.get_setting("http_port")
https_port = helper.get_setting("https_port")
http_port = self.helper.get_setting("http_port")
https_port = self.helper.get_setting("https_port")
debug_errors = helper.get_setting("show_errors")
cookie_secret = helper.get_setting("cookie_secret")
debug_errors = self.helper.get_setting("show_errors")
cookie_secret = self.helper.get_setting("cookie_secret")
if cookie_secret is False:
cookie_secret = helper.random_string_generator(32)
cookie_secret = self.helper.random_string_generator(32)
if not http_port:
http_port = 8000
@ -122,10 +117,10 @@ class Webserver:
cert_objects = {
"certfile": os.path.join(
helper.config_dir, "web", "certs", "commander.cert.pem"
self.helper.config_dir, "web", "certs", "commander.cert.pem"
),
"keyfile": os.path.join(
helper.config_dir, "web", "certs", "commander.key.pem"
self.helper.config_dir, "web", "certs", "commander.key.pem"
),
}
@ -139,9 +134,10 @@ class Webserver:
tornado.locale.set_default_locale("en_EN")
handler_args = {
"helper": self.helper,
"controller": self.controller,
"tasks_manager": self.tasks_manager,
"translator": translation,
"translator": self.helper.translation,
}
handlers = [
(r"/", DefaultHandler, handler_args),
@ -168,8 +164,8 @@ class Webserver:
app = tornado.web.Application(
handlers,
template_path=os.path.join(helper.webroot, "templates"),
static_path=os.path.join(helper.webroot, "static"),
template_path=os.path.join(self.helper.webroot, "templates"),
static_path=os.path.join(self.helper.webroot, "static"),
debug=debug_errors,
cookie_secret=cookie_secret,
xsrf_cookies=True,
@ -193,8 +189,8 @@ class Webserver:
]
HTTPapp = tornado.web.Application(
HTTPhanders,
template_path=os.path.join(helper.webroot, "templates"),
static_path=os.path.join(helper.webroot, "static"),
template_path=os.path.join(self.helper.webroot, "templates"),
static_path=os.path.join(self.helper.webroot, "static"),
debug=debug_errors,
cookie_secret=cookie_secret,
xsrf_cookies=True,
@ -212,24 +208,24 @@ class Webserver:
self.HTTPS_Server.listen(https_port)
logger.info(
f"https://{helper.get_local_ip()}:{https_port} "
f"https://{Helpers.get_local_ip()}:{https_port} "
f"is up and ready for connections."
)
console.info(
f"https://{helper.get_local_ip()}:{https_port} "
self.helper.console.info(
f"https://{Helpers.get_local_ip()}:{https_port} "
f"is up and ready for connections."
)
console.info("Server Init Complete: Listening For Connections:")
self.helper.console.info("Server Init Complete: Listening For Connections:")
self.ioloop = tornado.ioloop.IOLoop.current()
self.ioloop.start()
def stop_web_server(self):
logger.info("Shutting Down Web Server")
console.info("Shutting Down Web Server")
self.helper.console.info("Shutting Down Web Server")
self.ioloop.stop()
self.HTTP_Server.stop()
self.HTTPS_Server.stop()
logger.info("Web Server Stopped")
console.info("Web Server Stopped")
self.helper.console.info("Web Server Stopped")

View File

@ -1,22 +1,14 @@
import logging
import os
import time
import tornado.web
import tornado.options
import tornado.httpserver
from app.classes.models.server_permissions import Enum_Permissions_Server
from app.classes.shared.helpers import helper
from app.classes.shared.console import console
from app.classes.shared.helpers import Helpers
from app.classes.shared.main_controller import Controller
from app.classes.web.websocket_helper import websocket_helper
from app.classes.web.base_handler import BaseHandler
from app.classes.shared.translation import translation
try:
import tornado.web
import tornado.options
import tornado.httpserver
except ModuleNotFoundError as ex:
helper.auto_installer_fix(ex)
logger = logging.getLogger(__name__)
@ -26,8 +18,9 @@ class UploadHandler(BaseHandler):
# noinspection PyAttributeOutsideInit
def initialize(
self, controller: Controller = None, tasks_manager=None, translator=None
self, helper: Helpers = None, controller: Controller = None, tasks_manager=None, translator=None
):
self.helper = helper
self.controller = controller
self.tasks_manager = tasks_manager
self.translator = translator
@ -40,7 +33,7 @@ class UploadHandler(BaseHandler):
if api_key is not None:
superuser = superuser and api_key.superuser
user_id = exec_user["user_id"]
stream_size_value = helper.get_setting("stream_size_GB")
stream_size_value = self.helper.get_setting("stream_size_GB")
MAX_STREAMED_SIZE = (1024 * 1024 * 1024) * stream_size_value
@ -50,11 +43,11 @@ class UploadHandler(BaseHandler):
f"User with ID {user_id} attempted to upload a file that"
f" exceeded the max body size."
)
websocket_helper.broadcast_user(
self.helper.websocket_helper.broadcast_user(
user_id,
"send_start_error",
{
"error": translation.translate(
"error": self.helper.translation.translate(
"error",
"fileTooLarge",
self.controller.users.get_user_lang_by_id(user_id),
@ -85,12 +78,12 @@ class UploadHandler(BaseHandler):
if user_id is None:
logger.warning("User ID not found in upload handler call")
console.warning("User ID not found in upload handler call")
self.helper.console.warning("User ID not found in upload handler call")
self.do_upload = False
if server_id is None:
logger.warning("Server ID not found in upload handler call")
console.warning("Server ID not found in upload handler call")
self.helper.console.warning("Server ID not found in upload handler call")
self.do_upload = False
if Enum_Permissions_Server.Files not in exec_user_server_permissions:
@ -98,7 +91,7 @@ class UploadHandler(BaseHandler):
f"User {user_id} tried to upload a file to "
f"{server_id} without permissions!"
)
console.warning(
self.helper.console.warning(
f"User {user_id} tried to upload a file to "
f"{server_id} without permissions!"
)
@ -108,8 +101,8 @@ class UploadHandler(BaseHandler):
filename = self.request.headers.get("X-FileName", None)
full_path = os.path.join(path, filename)
if not helper.in_path(
helper.get_os_understandable_path(
if not Helpers.in_path(
Helpers.get_os_understandable_path(
self.controller.servers.get_server_data_by_id(server_id)["path"]
),
full_path,
@ -117,7 +110,7 @@ class UploadHandler(BaseHandler):
print(
user_id,
server_id,
helper.get_os_understandable_path(
Helpers.get_os_understandable_path(
self.controller.servers.get_server_data_by_id(server_id)["path"]
),
full_path,
@ -126,7 +119,7 @@ class UploadHandler(BaseHandler):
f"User {user_id} tried to upload a file to {server_id} "
f"but the path is not inside of the server!"
)
console.warning(
self.helper.console.warning(
f"User {user_id} tried to upload a file to {server_id} "
f"but the path is not inside of the server!"
)
@ -148,13 +141,13 @@ class UploadHandler(BaseHandler):
if self.do_upload:
time.sleep(5)
if files_left == 0:
websocket_helper.broadcast("close_upload_box", "success")
self.helper.websocket_helper.broadcast("close_upload_box", "success")
self.finish("success") # Nope, I'm sending "success"
self.f.close()
else:
time.sleep(5)
if files_left == 0:
websocket_helper.broadcast("close_upload_box", "error")
self.helper.websocket_helper.broadcast("close_upload_box", "error")
self.finish("error")
def data_received(self, chunk):

View File

@ -2,16 +2,9 @@ import json
import logging
import asyncio
from urllib.parse import parse_qsl
import tornado.websocket
from app.classes.shared.authentication import authentication
from app.classes.shared.helpers import helper
from app.classes.web.websocket_helper import websocket_helper
try:
import tornado.websocket
except ModuleNotFoundError as e:
helper.auto_installer_fix(e)
from app.classes.shared.helpers import Helpers
logger = logging.getLogger(__name__)
@ -24,7 +17,8 @@ class SocketHandler(tornado.websocket.WebSocketHandler):
translator = None
io_loop = None
def initialize(self, controller=None, tasks_manager=None, translator=None):
def initialize(self, helper=None, controller=None, tasks_manager=None, translator=None):
self.helper = helper
self.controller = controller
self.tasks_manager = tasks_manager
self.translator = translator
@ -39,11 +33,11 @@ class SocketHandler(tornado.websocket.WebSocketHandler):
return remote_ip
def get_user_id(self):
_, _, user = authentication.check(self.get_cookie("token"))
_, _, user = self.controller.authentication.check(self.get_cookie("token"))
return user["user_id"]
def check_auth(self):
return authentication.check_bool(self.get_cookie("token"))
return self.controller.authentication.check_bool(self.get_cookie("token"))
# pylint: disable=arguments-differ
def open(self):
@ -51,7 +45,7 @@ class SocketHandler(tornado.websocket.WebSocketHandler):
if self.check_auth():
self.handle()
else:
websocket_helper.send_message(
self.helper.websocket_helper.send_message(
self, "notification", "Not authenticated for WebSocket connection"
)
self.close()
@ -62,7 +56,7 @@ class SocketHandler(tornado.websocket.WebSocketHandler):
"Someone tried to connect via WebSocket without proper authentication",
self.get_remote_ip(),
)
websocket_helper.broadcast(
self.helper.websocket_helper.broadcast(
"notification",
"Someone tried to connect via WebSocket without proper authentication",
)
@ -74,10 +68,10 @@ class SocketHandler(tornado.websocket.WebSocketHandler):
self.page = self.get_query_argument("page")
self.page_query_params = dict(
parse_qsl(
helper.remove_prefix(self.get_query_argument("page_query_params"), "?")
Helpers.remove_prefix(self.get_query_argument("page_query_params"), "?")
)
)
websocket_helper.add_client(self)
self.helper.websocket_helper.add_client(self)
logger.debug("Opened WebSocket connection")
# pylint: disable=arguments-renamed
@ -89,7 +83,7 @@ class SocketHandler(tornado.websocket.WebSocketHandler):
logger.debug(f"Event Type: {message['event']}, Data: {message['data']}")
def on_close(self):
websocket_helper.remove_client(self)
self.helper.websocket_helper.remove_client(self)
logger.debug("Closed WebSocket connection")
async def write_message_int(self, message):

View File

@ -1,13 +1,12 @@
import json
import logging
from app.classes.shared.console import console
logger = logging.getLogger(__name__)
class WebSocketHelper:
def __init__(self):
def __init__(self, helper):
self.helper = helper
self.clients = set()
def add_client(self, client):
@ -101,10 +100,7 @@ class WebSocketHelper:
)
def disconnect_all(self):
console.info("Disconnecting WebSocket clients")
self.helper.console.info("Disconnecting WebSocket clients")
for client in self.clients:
client.close()
console.info("Disconnected WebSocket clients")
websocket_helper = WebSocketHelper()
self.helper.console.info("Disconnected WebSocket clients")

42
main.py
View File

@ -5,9 +5,13 @@ import time
import argparse
import logging.config
import signal
from app.classes.shared.console import console
from app.classes.shared.helpers import helper
import peewee
from app.classes.models.users import helper_users
from app.classes.shared.console import Console
from app.classes.shared.helpers import Helpers
console = Console()
helper = Helpers(console)
if helper.checkRoot():
console.critical(
"Root detected. Root/Admin access denied. "
@ -17,12 +21,15 @@ if helper.checkRoot():
console.critical("Crafty shutting down. Root/Admin access denied.")
sys.exit(0)
# pylint: disable=wrong-import-position
from app.classes.shared.main_models import installer, database
from app.classes.shared.tasks import TasksManager
from app.classes.shared.main_controller import Controller
from app.classes.shared.migration import MigrationManager
from app.classes.shared.command import MainPrompt
try:
from app.classes.models.base_model import database_proxy
from app.classes.shared.main_models import db_builder
from app.classes.shared.tasks import TasksManager
from app.classes.shared.main_controller import Controller
from app.classes.shared.migration import MigrationManager
from app.classes.shared.command import MainPrompt
except ModuleNotFoundError as err:
helper.auto_installer_fix(err)
def do_intro():
@ -88,6 +95,8 @@ if __name__ == "__main__":
# setting up the logger object
logger = logging.getLogger(__name__)
console.cyan(f"Logging set to: {logger.level}")
peewee_logger = logging.getLogger("peewee")
peewee_logger.setLevel(logging.INFO)
# print our pretty start message
do_intro()
@ -95,10 +104,19 @@ if __name__ == "__main__":
# our session file, helps prevent multiple controller agents on the same machine.
helper.create_session_file(ignore=args.ignore)
migration_manager = MigrationManager(database)
# start the database
database = peewee.SqliteDatabase(
helper.db_path,
pragmas={"journal_mode": "wal", "cache_size": -1024 * 10}
)
database_proxy.initialize(database)
migration_manager = MigrationManager(database, helper)
migration_manager.up() # Automatically runs migrations
# do our installer stuff
user_helper = helper_users(database, helper)
installer = db_builder(database, helper, user_helper)
fresh_install = installer.is_fresh_install()
if fresh_install:
@ -114,8 +132,8 @@ if __name__ == "__main__":
console.debug("Existing install detected")
# now the tables are created, we can load the tasks_manger and server controller
controller = Controller()
tasks_manager = TasksManager(controller)
controller = Controller(database, helper)
tasks_manager = TasksManager(helper, controller)
tasks_manager.start_webserver()
# slowing down reporting just for a 1/2 second so messages look cleaner
@ -151,7 +169,7 @@ if __name__ == "__main__":
if not controller.check_system_user():
controller.add_system_user()
Crafty = MainPrompt(tasks_manager, migration_manager)
Crafty = MainPrompt(helper, tasks_manager, migration_manager)
project_root = os.path.dirname(__file__)
controller.set_project_root(project_root)

View File

@ -5,7 +5,7 @@ bleach==4.1
cached_property==1.5.2
colorama==0.4
cron-validator==1.0.3
cryptography==3.4
cryptography==3.4.8
libgravatar==1.0.0
peewee==3.13
pexpect==4.8