mirror of
https://gitlab.com/crafty-controller/crafty-4.git
synced 2024-08-30 18:23:09 +00:00
Merge branch 'dev' into bugfix/fix-forge-install
This commit is contained in:
commit
49fce1b5c4
@ -2,10 +2,15 @@
|
|||||||
## --- [4.2.4] - 2023/TBD
|
## --- [4.2.4] - 2023/TBD
|
||||||
### New features
|
### New features
|
||||||
TBD
|
TBD
|
||||||
|
### Refactor
|
||||||
|
- Refactor remote file downloads ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/719))
|
||||||
### Bug fixes
|
### Bug fixes
|
||||||
TBD
|
- Fix Bedrock cert issues ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/719))
|
||||||
|
- Make sure default.json is read from correct location ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/714))
|
||||||
|
- Do not allow users at server limit to clone servers ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/718))
|
||||||
|
- Fix bug where you cannot get to config with unloaded server ([Commit](https://gitlab.com/crafty-controller/crafty-4/-/commit/9de08973b6bb2ddf91283c5c6b0e189ff34f7e24))
|
||||||
### Tweaks
|
### Tweaks
|
||||||
TBD
|
- Bump pyOpenSSL & cryptography for CVE-2024-0727, CVE-2023-50782 ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/716))
|
||||||
### Lang
|
### Lang
|
||||||
TBD
|
TBD
|
||||||
<br><br>
|
<br><br>
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
|
import os
|
||||||
import json
|
import json
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
import shutil
|
|
||||||
import logging
|
import logging
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
from app.classes.controllers.servers_controller import ServersController
|
from app.classes.controllers.servers_controller import ServersController
|
||||||
from app.classes.models.server_permissions import PermissionsServers
|
from app.classes.models.server_permissions import PermissionsServers
|
||||||
|
from app.classes.shared.file_helpers import FileHelpers
|
||||||
from app.classes.shared.websocket_manager import WebSocketManager
|
from app.classes.shared.websocket_manager import WebSocketManager
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@ -24,6 +25,113 @@ class ServerJars:
|
|||||||
def get_paper_jars():
|
def get_paper_jars():
|
||||||
return PAPERJARS
|
return PAPERJARS
|
||||||
|
|
||||||
|
def get_paper_versions(self, project):
|
||||||
|
"""
|
||||||
|
Retrieves a list of versions for a specified project from the PaperMC API.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
project (str): The project name to query for available versions.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
list: A list of version strings available for the project. Returns an empty
|
||||||
|
list if the API call fails or if no versions are found.
|
||||||
|
|
||||||
|
This function makes a GET request to the PaperMC API to fetch available project
|
||||||
|
versions, The versions are returned in reverse order, with the most recent
|
||||||
|
version first.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
response = requests.get(
|
||||||
|
f"{self.paper_base}/v2/projects/{project}/", timeout=2
|
||||||
|
)
|
||||||
|
response.raise_for_status()
|
||||||
|
api_data = response.json()
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error loading project versions for {project}: {e}")
|
||||||
|
return []
|
||||||
|
|
||||||
|
versions = api_data.get("versions", [])
|
||||||
|
versions.reverse() # Ensure the most recent version comes first
|
||||||
|
return versions
|
||||||
|
|
||||||
|
def get_paper_build(self, project, version):
|
||||||
|
"""
|
||||||
|
Fetches the latest build for a specified project and version from PaperMC API.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
project (str): Project name, typically a server software like 'paper'.
|
||||||
|
version (str): Project version to fetch the build number for.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
int or None: Latest build number if successful, None if not or on error.
|
||||||
|
|
||||||
|
This method attempts to query the PaperMC API for the latest build and
|
||||||
|
handles exceptions by logging errors and returning None.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
response = requests.get(
|
||||||
|
f"{self.paper_base}/v2/projects/{project}/versions/{version}/builds/",
|
||||||
|
timeout=2,
|
||||||
|
)
|
||||||
|
response.raise_for_status()
|
||||||
|
api_data = response.json()
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error fetching build for {project} {version}: {e}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
builds = api_data.get("builds", [])
|
||||||
|
return builds[-1] if builds else None
|
||||||
|
|
||||||
|
def get_fetch_url(self, jar, server, version):
|
||||||
|
"""
|
||||||
|
Constructs the URL for downloading a server JAR file based on the server type.
|
||||||
|
|
||||||
|
Supports two main types of server JAR sources:
|
||||||
|
- ServerJars API for servers not in PAPERJARS.
|
||||||
|
- Paper API for servers available through the Paper project.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
jar (str): Name of the JAR file.
|
||||||
|
server (str): Server software name (e.g., "paper").
|
||||||
|
version (str): Server version.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str or None: URL for downloading the JAR file, or None if URL cannot be
|
||||||
|
constructed or an error occurs.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
# Check if the server type is not specifically handled by Paper.
|
||||||
|
if server not in PAPERJARS:
|
||||||
|
return f"{self.base_url}/api/fetchJar/{jar}/{server}/{version}"
|
||||||
|
|
||||||
|
# For Paper servers, attempt to get the build for the specified version.
|
||||||
|
paper_build_info = self.get_paper_build(server, version)
|
||||||
|
if paper_build_info is None:
|
||||||
|
# Log an error or handle the case where paper_build_info is None
|
||||||
|
logger.error(
|
||||||
|
"Error: Unable to get build information for server:"
|
||||||
|
f" {server}, version: {version}"
|
||||||
|
)
|
||||||
|
return None
|
||||||
|
|
||||||
|
build = paper_build_info.get("build")
|
||||||
|
if not build:
|
||||||
|
# Log an error or handle the case where build is None or not found
|
||||||
|
logger.error(
|
||||||
|
f"Error: Build number not found for server:"
|
||||||
|
f" {server}, version: {version}"
|
||||||
|
)
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Construct and return the URL for downloading the Paper server JAR.
|
||||||
|
return (
|
||||||
|
f"{self.paper_base}/v2/projects/{server}/versions/{version}/"
|
||||||
|
f"builds/{build}/downloads/{server}-{version}-{build}.jar"
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"An error occurred while constructing fetch URL: {e}")
|
||||||
|
return None
|
||||||
|
|
||||||
def _get_api_result(self, call_url: str):
|
def _get_api_result(self, call_url: str):
|
||||||
full_url = f"{self.base_url}{call_url}"
|
full_url = f"{self.base_url}{call_url}"
|
||||||
|
|
||||||
@ -44,40 +152,6 @@ class ServerJars:
|
|||||||
|
|
||||||
return api_response
|
return api_response
|
||||||
|
|
||||||
def get_paper_versions(self, project):
|
|
||||||
try:
|
|
||||||
response = requests.get(
|
|
||||||
f"{self.paper_base}/v2/projects/{project}/", timeout=2
|
|
||||||
)
|
|
||||||
response.raise_for_status()
|
|
||||||
api_data = json.loads(response.content)
|
|
||||||
except Exception as e:
|
|
||||||
logger.error(
|
|
||||||
f"Unable to load https://api.papermc.io/v2/projects/{project}/"
|
|
||||||
f"api due to error: {e}"
|
|
||||||
)
|
|
||||||
return {}
|
|
||||||
versions = api_data.get("versions", [])
|
|
||||||
versions.reverse()
|
|
||||||
return versions
|
|
||||||
|
|
||||||
def get_paper_build(self, project, version):
|
|
||||||
try:
|
|
||||||
response = requests.get(
|
|
||||||
f"{self.paper_base}/v2/projects/{project}/versions/{version}/builds/",
|
|
||||||
timeout=2,
|
|
||||||
)
|
|
||||||
response.raise_for_status()
|
|
||||||
api_data = json.loads(response.content)
|
|
||||||
except Exception as e:
|
|
||||||
logger.error(
|
|
||||||
f"Unable to load https://api.papermc.io/v2/projects/{project}/"
|
|
||||||
f"api due to error: {e}"
|
|
||||||
)
|
|
||||||
return {}
|
|
||||||
build = api_data.get("builds", [])[-1]
|
|
||||||
return build
|
|
||||||
|
|
||||||
def _read_cache(self):
|
def _read_cache(self):
|
||||||
cache_file = self.helper.serverjar_cache
|
cache_file = self.helper.serverjar_cache
|
||||||
cache = {}
|
cache = {}
|
||||||
@ -213,55 +287,75 @@ class ServerJars:
|
|||||||
update_thread.start()
|
update_thread.start()
|
||||||
|
|
||||||
def a_download_jar(self, jar, server, version, path, server_id):
|
def a_download_jar(self, jar, server, version, path, server_id):
|
||||||
|
"""
|
||||||
|
Downloads a server JAR file and performs post-download actions including
|
||||||
|
notifying users and setting import status.
|
||||||
|
|
||||||
|
This method waits for the server registration to complete, retrieves the
|
||||||
|
download URL for the specified server JAR file.
|
||||||
|
|
||||||
|
Upon successful download, it either runs the installer for
|
||||||
|
Forge servers or simply finishes the import process for other types. It
|
||||||
|
notifies server users about the completion of the download.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
- jar (str): The name of the JAR file to download.
|
||||||
|
- server (str): The type of server software (e.g., 'forge', 'paper').
|
||||||
|
- version (str): The version of the server software.
|
||||||
|
- path (str): The local filesystem path where the JAR file will be saved.
|
||||||
|
- server_id (str): The unique identifier for the server being updated or
|
||||||
|
imported, used for notifying users and setting the import status.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
- bool: True if the JAR file was successfully downloaded and saved;
|
||||||
|
False otherwise.
|
||||||
|
|
||||||
|
The method ensures that the server is properly registered before proceeding
|
||||||
|
with the download and handles exceptions by logging errors and reverting
|
||||||
|
the import status if necessary.
|
||||||
|
"""
|
||||||
# delaying download for server register to finish
|
# delaying download for server register to finish
|
||||||
time.sleep(3)
|
time.sleep(3)
|
||||||
if server not in PAPERJARS:
|
|
||||||
fetch_url = f"{self.base_url}/api/fetchJar/{jar}/{server}/{version}"
|
fetch_url = self.get_fetch_url(jar, server, version)
|
||||||
else:
|
if not fetch_url:
|
||||||
build = self.get_paper_build(server, version).get("build", None)
|
return False
|
||||||
if not build:
|
|
||||||
return
|
|
||||||
fetch_url = (
|
|
||||||
f"{self.paper_base}/v2/projects"
|
|
||||||
f"/{server}/versions/{version}/builds/{build}/downloads/"
|
|
||||||
f"{server}-{version}-{build}.jar"
|
|
||||||
)
|
|
||||||
server_users = PermissionsServers.get_server_user_list(server_id)
|
server_users = PermissionsServers.get_server_user_list(server_id)
|
||||||
|
|
||||||
# We need to make sure the server is registered before
|
# Make sure the server is registered before updating its stats
|
||||||
# we submit a db update for it's stats.
|
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
ServersController.set_import(server_id)
|
ServersController.set_import(server_id)
|
||||||
for user in server_users:
|
for user in server_users:
|
||||||
WebSocketManager().broadcast_user(user, "send_start_reload", {})
|
WebSocketManager().broadcast_user(user, "send_start_reload", {})
|
||||||
|
|
||||||
break
|
break
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
logger.debug(f"server not registered yet. Delaying download - {ex}")
|
logger.debug(f"Server not registered yet. Delaying download - {ex}")
|
||||||
|
|
||||||
# open a file stream
|
# Initiate Download
|
||||||
with requests.get(fetch_url, timeout=2, stream=True) as r:
|
jar_dir = os.path.dirname(path)
|
||||||
success = False
|
jar_name = os.path.basename(path)
|
||||||
try:
|
logger.info(fetch_url)
|
||||||
with open(path, "wb") as output:
|
success = FileHelpers.ssl_get_file(fetch_url, jar_dir, jar_name)
|
||||||
shutil.copyfileobj(r.raw, output)
|
|
||||||
# If this is the newer forge version we will run the installer
|
|
||||||
if server == "forge":
|
|
||||||
ServersController.finish_import(server_id, True)
|
|
||||||
else:
|
|
||||||
ServersController.finish_import(server_id)
|
|
||||||
|
|
||||||
success = True
|
# Post-download actions
|
||||||
except Exception as e:
|
if success:
|
||||||
logger.error(f"Unable to save jar to {path} due to error:{e}")
|
if server == "forge":
|
||||||
|
# If this is the newer Forge version, run the installer
|
||||||
|
ServersController.finish_import(server_id, True)
|
||||||
|
else:
|
||||||
ServersController.finish_import(server_id)
|
ServersController.finish_import(server_id)
|
||||||
server_users = PermissionsServers.get_server_user_list(server_id)
|
|
||||||
|
|
||||||
|
# Notify users
|
||||||
for user in server_users:
|
for user in server_users:
|
||||||
WebSocketManager().broadcast_user(
|
WebSocketManager().broadcast_user(
|
||||||
user, "notification", "Executable download finished"
|
user, "notification", "Executable download finished"
|
||||||
)
|
)
|
||||||
time.sleep(3)
|
time.sleep(3) # Delay for user notification
|
||||||
WebSocketManager().broadcast_user(user, "send_start_reload", {})
|
WebSocketManager().broadcast_user(user, "send_start_reload", {})
|
||||||
return success
|
else:
|
||||||
|
logger.error(f"Unable to save jar to {path} due to download failure.")
|
||||||
|
ServersController.finish_import(server_id)
|
||||||
|
|
||||||
|
return success
|
||||||
|
@ -172,9 +172,9 @@ class PermissionsServers:
|
|||||||
RoleServers.server_id, RoleServers.permissions
|
RoleServers.server_id, RoleServers.permissions
|
||||||
).where(RoleServers.role_id == role_id)
|
).where(RoleServers.role_id == role_id)
|
||||||
for role_server in role_servers:
|
for role_server in role_servers:
|
||||||
permissions_dict[
|
permissions_dict[role_server.server_id_id] = (
|
||||||
role_server.server_id_id
|
PermissionsServers.get_permissions(role_server.permissions)
|
||||||
] = PermissionsServers.get_permissions(role_server.permissions)
|
)
|
||||||
return permissions_dict
|
return permissions_dict
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -5,6 +5,10 @@ import pathlib
|
|||||||
import tempfile
|
import tempfile
|
||||||
import zipfile
|
import zipfile
|
||||||
from zipfile import ZipFile, ZIP_DEFLATED
|
from zipfile import ZipFile, ZIP_DEFLATED
|
||||||
|
import urllib.request
|
||||||
|
import ssl
|
||||||
|
import time
|
||||||
|
import certifi
|
||||||
|
|
||||||
from app.classes.shared.helpers import Helpers
|
from app.classes.shared.helpers import Helpers
|
||||||
from app.classes.shared.console import Console
|
from app.classes.shared.console import Console
|
||||||
@ -19,6 +23,92 @@ class FileHelpers:
|
|||||||
def __init__(self, helper):
|
def __init__(self, helper):
|
||||||
self.helper: Helpers = helper
|
self.helper: Helpers = helper
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def ssl_get_file(
|
||||||
|
url, out_path, out_file, max_retries=3, backoff_factor=2, headers=None
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Downloads a file from a given URL using HTTPS with SSL context verification,
|
||||||
|
retries with exponential backoff and providing download progress feedback.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
- url (str): The URL of the file to download. Must start with "https".
|
||||||
|
- out_path (str): The local path where the file will be saved.
|
||||||
|
- out_file (str): The name of the file to save the downloaded content as.
|
||||||
|
- max_retries (int, optional): The maximum number of retry attempts
|
||||||
|
in case of download failure. Defaults to 3.
|
||||||
|
- backoff_factor (int, optional): The factor by which the wait time
|
||||||
|
increases after each failed attempt. Defaults to 2.
|
||||||
|
- headers (dict, optional):
|
||||||
|
A dictionary of HTTP headers to send with the request.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
- bool: True if the download was successful, False otherwise.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
- urllib.error.URLError: If a URL error occurs during the download.
|
||||||
|
- ssl.SSLError: If an SSL error occurs during the download.
|
||||||
|
Exception: If an unexpected error occurs during the download.
|
||||||
|
|
||||||
|
Note:
|
||||||
|
This method logs critical errors and download progress information.
|
||||||
|
Ensure that the logger is properly configured to capture this information.
|
||||||
|
"""
|
||||||
|
if not url.lower().startswith("https"):
|
||||||
|
logger.error("SSL File Get - Error: URL must start with https.")
|
||||||
|
return False
|
||||||
|
|
||||||
|
ssl_context = ssl.create_default_context(cafile=certifi.where())
|
||||||
|
|
||||||
|
if not headers:
|
||||||
|
headers = {
|
||||||
|
"User-Agent": (
|
||||||
|
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
|
||||||
|
"AppleWebKit/537.36 (KHTML, like Gecko) "
|
||||||
|
"Chrome/58.0.3029.110 Safari/537.3"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
req = urllib.request.Request(url, headers=headers)
|
||||||
|
|
||||||
|
write_path = os.path.join(out_path, out_file)
|
||||||
|
attempt = 0
|
||||||
|
|
||||||
|
logger.info(f"SSL File Get - Requesting remote: {url}")
|
||||||
|
file_path_full = os.path.join(out_path, out_file)
|
||||||
|
logger.info(f"SSL File Get - Download Destination: {file_path_full}")
|
||||||
|
|
||||||
|
while attempt < max_retries:
|
||||||
|
try:
|
||||||
|
with urllib.request.urlopen(req, context=ssl_context) as response:
|
||||||
|
total_size = response.getheader("Content-Length")
|
||||||
|
if total_size:
|
||||||
|
total_size = int(total_size)
|
||||||
|
downloaded = 0
|
||||||
|
with open(write_path, "wb") as file:
|
||||||
|
while True:
|
||||||
|
chunk = response.read(1024 * 1024) # 1 MB
|
||||||
|
if not chunk:
|
||||||
|
break
|
||||||
|
file.write(chunk)
|
||||||
|
downloaded += len(chunk)
|
||||||
|
if total_size:
|
||||||
|
progress = (downloaded / total_size) * 100
|
||||||
|
logger.info(
|
||||||
|
f"SSL File Get - Download progress: {progress:.2f}%"
|
||||||
|
)
|
||||||
|
return True
|
||||||
|
except (urllib.error.URLError, ssl.SSLError) as e:
|
||||||
|
logger.warning(f"SSL File Get - Attempt {attempt+1} failed: {e}")
|
||||||
|
time.sleep(backoff_factor**attempt)
|
||||||
|
except Exception as e:
|
||||||
|
logger.critical(f"SSL File Get - Unexpected error: {e}")
|
||||||
|
return False
|
||||||
|
finally:
|
||||||
|
attempt += 1
|
||||||
|
|
||||||
|
logger.error("SSL File Get - Maximum retries reached. Download failed.")
|
||||||
|
return False
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def del_dirs(path):
|
def del_dirs(path):
|
||||||
path = pathlib.Path(path)
|
path = pathlib.Path(path)
|
||||||
|
@ -1112,7 +1112,7 @@ class Helpers:
|
|||||||
return os.path.normpath(path)
|
return os.path.normpath(path)
|
||||||
|
|
||||||
def find_default_password(self):
|
def find_default_password(self):
|
||||||
default_file = os.path.join(self.root_dir, "default.json")
|
default_file = os.path.join(self.root_dir, "app", "config", "default.json")
|
||||||
data = {}
|
data = {}
|
||||||
|
|
||||||
if Helpers.check_file_exists(default_file):
|
if Helpers.check_file_exists(default_file):
|
||||||
@ -1180,25 +1180,6 @@ class Helpers:
|
|||||||
return temp_dir
|
return temp_dir
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def download_file(executable_url, jar_path):
|
|
||||||
try:
|
|
||||||
response = requests.get(executable_url, timeout=5)
|
|
||||||
except Exception as ex:
|
|
||||||
logger.error("Could not download executable: %s", ex)
|
|
||||||
return False
|
|
||||||
if response.status_code != 200:
|
|
||||||
logger.error("Unable to download file from %s", executable_url)
|
|
||||||
return False
|
|
||||||
|
|
||||||
try:
|
|
||||||
with open(jar_path, "wb") as jar_file:
|
|
||||||
jar_file.write(response.content)
|
|
||||||
except Exception as e:
|
|
||||||
logger.error("Unable to finish executable download. Error: %s", e)
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def remove_prefix(text, prefix):
|
def remove_prefix(text, prefix):
|
||||||
if text.startswith(prefix):
|
if text.startswith(prefix):
|
||||||
|
@ -3,7 +3,6 @@ import time
|
|||||||
import shutil
|
import shutil
|
||||||
import logging
|
import logging
|
||||||
import threading
|
import threading
|
||||||
import urllib
|
|
||||||
|
|
||||||
from app.classes.controllers.server_perms_controller import PermissionsServers
|
from app.classes.controllers.server_perms_controller import PermissionsServers
|
||||||
from app.classes.controllers.servers_controller import ServersController
|
from app.classes.controllers.servers_controller import ServersController
|
||||||
@ -227,25 +226,39 @@ class ImportHelpers:
|
|||||||
download_thread.start()
|
download_thread.start()
|
||||||
|
|
||||||
def download_threaded_bedrock_server(self, path, new_id):
|
def download_threaded_bedrock_server(self, path, new_id):
|
||||||
# downloads zip from remote url
|
"""
|
||||||
|
Downloads the latest Bedrock server, unzips it, sets necessary permissions.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
path (str): The directory path to download and unzip the Bedrock server.
|
||||||
|
new_id (str): The identifier for the new server import operation.
|
||||||
|
|
||||||
|
This method handles exceptions and logs errors for each step of the process.
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
bedrock_url = Helpers.get_latest_bedrock_url()
|
bedrock_url = Helpers.get_latest_bedrock_url()
|
||||||
if bedrock_url.lower().startswith("https"):
|
if bedrock_url:
|
||||||
urllib.request.urlretrieve(
|
file_path = os.path.join(path, "bedrock_server.zip")
|
||||||
bedrock_url,
|
|
||||||
os.path.join(path, "bedrock_server.zip"),
|
success = FileHelpers.ssl_get_file(
|
||||||
|
bedrock_url, path, "bedrock_server.zip"
|
||||||
)
|
)
|
||||||
|
if not success:
|
||||||
|
logger.error("Failed to download the Bedrock server zip.")
|
||||||
|
return
|
||||||
|
|
||||||
unzip_path = os.path.join(path, "bedrock_server.zip")
|
unzip_path = self.helper.wtol_path(file_path)
|
||||||
unzip_path = self.helper.wtol_path(unzip_path)
|
# unzips archive that was downloaded.
|
||||||
# unzips archive that was downloaded.
|
FileHelpers.unzip_file(unzip_path)
|
||||||
FileHelpers.unzip_file(unzip_path)
|
# adjusts permissions for execution if os is not windows
|
||||||
# adjusts permissions for execution if os is not windows
|
|
||||||
if not self.helper.is_os_windows():
|
|
||||||
os.chmod(os.path.join(path, "bedrock_server"), 0o0744)
|
|
||||||
|
|
||||||
# we'll delete the zip we downloaded now
|
if not self.helper.is_os_windows():
|
||||||
os.remove(os.path.join(path, "bedrock_server.zip"))
|
os.chmod(os.path.join(path, "bedrock_server"), 0o0744)
|
||||||
|
|
||||||
|
# we'll delete the zip we downloaded now
|
||||||
|
os.remove(file_path)
|
||||||
|
else:
|
||||||
|
logger.error("Bedrock download URL issue!")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.critical(
|
logger.critical(
|
||||||
f"Failed to download bedrock executable during server creation! \n{e}"
|
f"Failed to download bedrock executable during server creation! \n{e}"
|
||||||
|
@ -10,7 +10,6 @@ import threading
|
|||||||
import logging.config
|
import logging.config
|
||||||
import subprocess
|
import subprocess
|
||||||
import html
|
import html
|
||||||
import urllib.request
|
|
||||||
import glob
|
import glob
|
||||||
import json
|
import json
|
||||||
|
|
||||||
@ -1454,33 +1453,45 @@ class ServerInstance:
|
|||||||
|
|
||||||
# lets download the files
|
# lets download the files
|
||||||
if HelperServers.get_server_type_by_id(self.server_id) != "minecraft-bedrock":
|
if HelperServers.get_server_type_by_id(self.server_id) != "minecraft-bedrock":
|
||||||
# boolean returns true for false for success
|
|
||||||
downloaded = Helpers.download_file(
|
jar_dir = os.path.dirname(current_executable)
|
||||||
self.settings["executable_update_url"], current_executable
|
jar_file_name = os.path.basename(current_executable)
|
||||||
|
|
||||||
|
downloaded = FileHelpers.ssl_get_file(
|
||||||
|
self.settings["executable_update_url"], jar_dir, jar_file_name
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
# downloads zip from remote url
|
# downloads zip from remote url
|
||||||
try:
|
try:
|
||||||
bedrock_url = Helpers.get_latest_bedrock_url()
|
bedrock_url = Helpers.get_latest_bedrock_url()
|
||||||
if bedrock_url.lower().startswith("https"):
|
if bedrock_url:
|
||||||
urllib.request.urlretrieve(
|
# Use the new method for secure download
|
||||||
bedrock_url,
|
download_path = os.path.join(
|
||||||
os.path.join(self.settings["path"], "bedrock_server.zip"),
|
self.settings["path"], "bedrock_server.zip"
|
||||||
|
)
|
||||||
|
downloaded = FileHelpers.ssl_get_file(
|
||||||
|
bedrock_url, self.settings["path"], "bedrock_server.zip"
|
||||||
)
|
)
|
||||||
|
|
||||||
unzip_path = os.path.join(self.settings["path"], "bedrock_server.zip")
|
if downloaded:
|
||||||
unzip_path = self.helper.wtol_path(unzip_path)
|
unzip_path = download_path
|
||||||
# unzips archive that was downloaded.
|
unzip_path = self.helper.wtol_path(unzip_path)
|
||||||
FileHelpers.unzip_file(unzip_path, server_update=True)
|
|
||||||
# adjusts permissions for execution if os is not windows
|
|
||||||
if not self.helper.is_os_windows():
|
|
||||||
os.chmod(
|
|
||||||
os.path.join(self.settings["path"], "bedrock_server"), 0o0744
|
|
||||||
)
|
|
||||||
|
|
||||||
# we'll delete the zip we downloaded now
|
# unzips archive that was downloaded.
|
||||||
os.remove(os.path.join(self.settings["path"], "bedrock_server.zip"))
|
FileHelpers.unzip_file(unzip_path, server_update=True)
|
||||||
downloaded = True
|
|
||||||
|
# adjusts permissions for execution if os is not windows
|
||||||
|
if not self.helper.is_os_windows():
|
||||||
|
os.chmod(
|
||||||
|
os.path.join(self.settings["path"], "bedrock_server"),
|
||||||
|
0o0744,
|
||||||
|
)
|
||||||
|
|
||||||
|
# we'll delete the zip we downloaded now
|
||||||
|
os.remove(download_path)
|
||||||
|
else:
|
||||||
|
logger.error("Failed to download the Bedrock server zip.")
|
||||||
|
downloaded = False
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.critical(
|
logger.critical(
|
||||||
f"Failed to download bedrock executable for update \n{e}"
|
f"Failed to download bedrock executable for update \n{e}"
|
||||||
|
@ -345,15 +345,17 @@ class PanelHandler(BaseHandler):
|
|||||||
self.controller.users.get_user_lang_by_id(exec_user["user_id"])
|
self.controller.users.get_user_lang_by_id(exec_user["user_id"])
|
||||||
),
|
),
|
||||||
"super_user": superuser,
|
"super_user": superuser,
|
||||||
"api_key": {
|
"api_key": (
|
||||||
"name": api_key.name,
|
{
|
||||||
"created": api_key.created,
|
"name": api_key.name,
|
||||||
"server_permissions": api_key.server_permissions,
|
"created": api_key.created,
|
||||||
"crafty_permissions": api_key.crafty_permissions,
|
"server_permissions": api_key.server_permissions,
|
||||||
"superuser": api_key.superuser,
|
"crafty_permissions": api_key.crafty_permissions,
|
||||||
}
|
"superuser": api_key.superuser,
|
||||||
if api_key is not None
|
}
|
||||||
else None,
|
if api_key is not None
|
||||||
|
else None
|
||||||
|
),
|
||||||
"superuser": superuser,
|
"superuser": superuser,
|
||||||
}
|
}
|
||||||
try:
|
try:
|
||||||
@ -417,14 +419,14 @@ class PanelHandler(BaseHandler):
|
|||||||
self.controller.first_login = False
|
self.controller.first_login = False
|
||||||
if superuser: # TODO: Figure out a better solution
|
if superuser: # TODO: Figure out a better solution
|
||||||
try:
|
try:
|
||||||
page_data[
|
page_data["servers"] = (
|
||||||
"servers"
|
self.controller.servers.get_all_servers_stats()
|
||||||
] = self.controller.servers.get_all_servers_stats()
|
)
|
||||||
except IndexError:
|
except IndexError:
|
||||||
self.controller.servers.stats.record_stats()
|
self.controller.servers.stats.record_stats()
|
||||||
page_data[
|
page_data["servers"] = (
|
||||||
"servers"
|
self.controller.servers.get_all_servers_stats()
|
||||||
] = self.controller.servers.get_all_servers_stats()
|
)
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
user_auth = self.controller.servers.get_authorized_servers_stats(
|
user_auth = self.controller.servers.get_authorized_servers_stats(
|
||||||
@ -454,19 +456,19 @@ class PanelHandler(BaseHandler):
|
|||||||
for server_id in user_order[:]:
|
for server_id in user_order[:]:
|
||||||
for server in un_used_servers[:]:
|
for server in un_used_servers[:]:
|
||||||
if flag == 0:
|
if flag == 0:
|
||||||
server["stats"][
|
server["stats"]["importing"] = (
|
||||||
"importing"
|
self.controller.servers.get_import_status(
|
||||||
] = self.controller.servers.get_import_status(
|
str(server["stats"]["server_id"]["server_id"])
|
||||||
str(server["stats"]["server_id"]["server_id"])
|
)
|
||||||
)
|
)
|
||||||
server["stats"]["crashed"] = self.controller.servers.is_crashed(
|
server["stats"]["crashed"] = self.controller.servers.is_crashed(
|
||||||
str(server["stats"]["server_id"]["server_id"])
|
str(server["stats"]["server_id"]["server_id"])
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
server["stats"][
|
server["stats"]["waiting_start"] = (
|
||||||
"waiting_start"
|
self.controller.servers.get_waiting_start(
|
||||||
] = self.controller.servers.get_waiting_start(
|
str(server["stats"]["server_id"]["server_id"])
|
||||||
str(server["stats"]["server_id"]["server_id"])
|
)
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Failed to get server waiting to start: {e}")
|
logger.error(f"Failed to get server waiting to start: {e}")
|
||||||
@ -543,9 +545,9 @@ class PanelHandler(BaseHandler):
|
|||||||
server_id
|
server_id
|
||||||
)
|
)
|
||||||
if not self.failed_server:
|
if not self.failed_server:
|
||||||
page_data[
|
page_data["server_stats"] = (
|
||||||
"server_stats"
|
self.controller.servers.get_server_stats_by_id(server_id)
|
||||||
] = self.controller.servers.get_server_stats_by_id(server_id)
|
)
|
||||||
else:
|
else:
|
||||||
server_temp_obj = self.controller.servers.get_server_data_by_id(
|
server_temp_obj = self.controller.servers.get_server_data_by_id(
|
||||||
server_id
|
server_id
|
||||||
@ -572,6 +574,7 @@ class PanelHandler(BaseHandler):
|
|||||||
"crash_detection": server_temp_obj["crash_detection"],
|
"crash_detection": server_temp_obj["crash_detection"],
|
||||||
"show_status": server_temp_obj["show_status"],
|
"show_status": server_temp_obj["show_status"],
|
||||||
"ignored_exits": server_temp_obj["ignored_exits"],
|
"ignored_exits": server_temp_obj["ignored_exits"],
|
||||||
|
"count_players": server_temp_obj["count_players"],
|
||||||
},
|
},
|
||||||
"running": False,
|
"running": False,
|
||||||
"crashed": False,
|
"crashed": False,
|
||||||
@ -611,19 +614,19 @@ class PanelHandler(BaseHandler):
|
|||||||
"Config": EnumPermissionsServer.CONFIG,
|
"Config": EnumPermissionsServer.CONFIG,
|
||||||
"Players": EnumPermissionsServer.PLAYERS,
|
"Players": EnumPermissionsServer.PLAYERS,
|
||||||
}
|
}
|
||||||
page_data[
|
page_data["user_permissions"] = (
|
||||||
"user_permissions"
|
self.controller.server_perms.get_user_id_permissions_list(
|
||||||
] = self.controller.server_perms.get_user_id_permissions_list(
|
exec_user["user_id"], server_id
|
||||||
exec_user["user_id"], server_id
|
)
|
||||||
)
|
)
|
||||||
if not self.failed_server:
|
if not self.failed_server:
|
||||||
page_data["server_stats"][
|
page_data["server_stats"]["crashed"] = (
|
||||||
"crashed"
|
self.controller.servers.is_crashed(server_id)
|
||||||
] = self.controller.servers.is_crashed(server_id)
|
)
|
||||||
if not self.failed_server:
|
if not self.failed_server:
|
||||||
page_data["server_stats"][
|
page_data["server_stats"]["server_type"] = (
|
||||||
"server_type"
|
self.controller.servers.get_server_type_by_id(server_id)
|
||||||
] = self.controller.servers.get_server_type_by_id(server_id)
|
)
|
||||||
|
|
||||||
if not subpage:
|
if not subpage:
|
||||||
for spage, perm in SUBPAGE_PERMS.items():
|
for spage, perm in SUBPAGE_PERMS.items():
|
||||||
@ -674,23 +677,23 @@ class PanelHandler(BaseHandler):
|
|||||||
page_data["java_versions"] = page_java
|
page_data["java_versions"] = page_java
|
||||||
if subpage == "backup":
|
if subpage == "backup":
|
||||||
server_info = self.controller.servers.get_server_data_by_id(server_id)
|
server_info = self.controller.servers.get_server_data_by_id(server_id)
|
||||||
page_data[
|
page_data["backup_config"] = (
|
||||||
"backup_config"
|
self.controller.management.get_backup_config(server_id)
|
||||||
] = self.controller.management.get_backup_config(server_id)
|
)
|
||||||
exclusions = []
|
exclusions = []
|
||||||
page_data[
|
page_data["exclusions"] = (
|
||||||
"exclusions"
|
self.controller.management.get_excluded_backup_dirs(server_id)
|
||||||
] = self.controller.management.get_excluded_backup_dirs(server_id)
|
)
|
||||||
page_data[
|
page_data["backing_up"] = (
|
||||||
"backing_up"
|
self.controller.servers.get_server_instance_by_id(
|
||||||
] = self.controller.servers.get_server_instance_by_id(
|
server_id
|
||||||
server_id
|
).is_backingup
|
||||||
).is_backingup
|
)
|
||||||
page_data[
|
page_data["backup_stats"] = (
|
||||||
"backup_stats"
|
self.controller.servers.get_server_instance_by_id(
|
||||||
] = self.controller.servers.get_server_instance_by_id(
|
server_id
|
||||||
server_id
|
).send_backup_status()
|
||||||
).send_backup_status()
|
)
|
||||||
# makes it so relative path is the only thing shown
|
# makes it so relative path is the only thing shown
|
||||||
for file in page_data["exclusions"]:
|
for file in page_data["exclusions"]:
|
||||||
if Helpers.is_os_windows():
|
if Helpers.is_os_windows():
|
||||||
@ -723,10 +726,10 @@ class PanelHandler(BaseHandler):
|
|||||||
server_id, hours=(days * 24)
|
server_id, hours=(days * 24)
|
||||||
)
|
)
|
||||||
if subpage == "webhooks":
|
if subpage == "webhooks":
|
||||||
page_data[
|
page_data["webhooks"] = (
|
||||||
"webhooks"
|
self.controller.management.get_webhooks_by_server(
|
||||||
] = self.controller.management.get_webhooks_by_server(
|
server_id, model=True
|
||||||
server_id, model=True
|
)
|
||||||
)
|
)
|
||||||
page_data["triggers"] = WebhookFactory.get_monitored_events()
|
page_data["triggers"] = WebhookFactory.get_monitored_events()
|
||||||
|
|
||||||
@ -758,9 +761,9 @@ class PanelHandler(BaseHandler):
|
|||||||
if not superuser:
|
if not superuser:
|
||||||
self.redirect("/panel/error?error=Unauthorized access")
|
self.redirect("/panel/error?error=Unauthorized access")
|
||||||
page_data["banned_players_html"] = get_banned_players_html()
|
page_data["banned_players_html"] = get_banned_players_html()
|
||||||
page_data[
|
page_data["banned_players"] = (
|
||||||
"banned_players"
|
self.controller.servers.get_banned_players(server_id)
|
||||||
] = self.controller.servers.get_banned_players(server_id)
|
)
|
||||||
server_instance = self.controller.servers.get_server_instance_by_id(
|
server_instance = self.controller.servers.get_server_instance_by_id(
|
||||||
server_id
|
server_id
|
||||||
)
|
)
|
||||||
@ -925,9 +928,9 @@ class PanelHandler(BaseHandler):
|
|||||||
if item not in page_data["backgrounds"]:
|
if item not in page_data["backgrounds"]:
|
||||||
page_data["backgrounds"].append(item)
|
page_data["backgrounds"].append(item)
|
||||||
page_data["background"] = self.controller.cached_login
|
page_data["background"] = self.controller.cached_login
|
||||||
page_data[
|
page_data["login_opacity"] = (
|
||||||
"login_opacity"
|
self.controller.management.get_login_opacity()
|
||||||
] = self.controller.management.get_login_opacity()
|
)
|
||||||
|
|
||||||
page_data["active_link"] = "custom_login"
|
page_data["active_link"] = "custom_login"
|
||||||
template = "panel/custom_login.html"
|
template = "panel/custom_login.html"
|
||||||
@ -959,13 +962,11 @@ class PanelHandler(BaseHandler):
|
|||||||
page_data["servers"] = []
|
page_data["servers"] = []
|
||||||
page_data["servers_all"] = self.controller.servers.get_all_defined_servers()
|
page_data["servers_all"] = self.controller.servers.get_all_defined_servers()
|
||||||
page_data["role-servers"] = []
|
page_data["role-servers"] = []
|
||||||
page_data[
|
page_data["permissions_all"] = (
|
||||||
"permissions_all"
|
self.controller.crafty_perms.list_defined_crafty_permissions()
|
||||||
] = self.controller.crafty_perms.list_defined_crafty_permissions()
|
)
|
||||||
page_data["permissions_list"] = set()
|
page_data["permissions_list"] = set()
|
||||||
page_data[
|
page_data["quantity_server"] = (
|
||||||
"quantity_server"
|
|
||||||
] = (
|
|
||||||
self.controller.crafty_perms.list_all_crafty_permissions_quantity_limits() # pylint: disable=line-too-long
|
self.controller.crafty_perms.list_all_crafty_permissions_quantity_limits() # pylint: disable=line-too-long
|
||||||
)
|
)
|
||||||
page_data["languages"] = []
|
page_data["languages"] = []
|
||||||
@ -1007,10 +1008,10 @@ class PanelHandler(BaseHandler):
|
|||||||
page_data["server_data"] = self.controller.servers.get_server_data_by_id(
|
page_data["server_data"] = self.controller.servers.get_server_data_by_id(
|
||||||
server_id
|
server_id
|
||||||
)
|
)
|
||||||
page_data[
|
page_data["user_permissions"] = (
|
||||||
"user_permissions"
|
self.controller.server_perms.get_user_id_permissions_list(
|
||||||
] = self.controller.server_perms.get_user_id_permissions_list(
|
exec_user["user_id"], server_id
|
||||||
exec_user["user_id"], server_id
|
)
|
||||||
)
|
)
|
||||||
page_data["permissions"] = {
|
page_data["permissions"] = {
|
||||||
"Commands": EnumPermissionsServer.COMMANDS,
|
"Commands": EnumPermissionsServer.COMMANDS,
|
||||||
@ -1025,9 +1026,9 @@ class PanelHandler(BaseHandler):
|
|||||||
page_data["server_stats"] = self.controller.servers.get_server_stats_by_id(
|
page_data["server_stats"] = self.controller.servers.get_server_stats_by_id(
|
||||||
server_id
|
server_id
|
||||||
)
|
)
|
||||||
page_data["server_stats"][
|
page_data["server_stats"]["server_type"] = (
|
||||||
"server_type"
|
self.controller.servers.get_server_type_by_id(server_id)
|
||||||
] = self.controller.servers.get_server_type_by_id(server_id)
|
)
|
||||||
page_data["new_webhook"] = True
|
page_data["new_webhook"] = True
|
||||||
page_data["webhook"] = {}
|
page_data["webhook"] = {}
|
||||||
page_data["webhook"]["webhook_type"] = "Custom"
|
page_data["webhook"]["webhook_type"] = "Custom"
|
||||||
@ -1061,10 +1062,10 @@ class PanelHandler(BaseHandler):
|
|||||||
page_data["server_data"] = self.controller.servers.get_server_data_by_id(
|
page_data["server_data"] = self.controller.servers.get_server_data_by_id(
|
||||||
server_id
|
server_id
|
||||||
)
|
)
|
||||||
page_data[
|
page_data["user_permissions"] = (
|
||||||
"user_permissions"
|
self.controller.server_perms.get_user_id_permissions_list(
|
||||||
] = self.controller.server_perms.get_user_id_permissions_list(
|
exec_user["user_id"], server_id
|
||||||
exec_user["user_id"], server_id
|
)
|
||||||
)
|
)
|
||||||
page_data["permissions"] = {
|
page_data["permissions"] = {
|
||||||
"Commands": EnumPermissionsServer.COMMANDS,
|
"Commands": EnumPermissionsServer.COMMANDS,
|
||||||
@ -1079,9 +1080,9 @@ class PanelHandler(BaseHandler):
|
|||||||
page_data["server_stats"] = self.controller.servers.get_server_stats_by_id(
|
page_data["server_stats"] = self.controller.servers.get_server_stats_by_id(
|
||||||
server_id
|
server_id
|
||||||
)
|
)
|
||||||
page_data["server_stats"][
|
page_data["server_stats"]["server_type"] = (
|
||||||
"server_type"
|
self.controller.servers.get_server_type_by_id(server_id)
|
||||||
] = self.controller.servers.get_server_type_by_id(server_id)
|
)
|
||||||
page_data["new_webhook"] = False
|
page_data["new_webhook"] = False
|
||||||
page_data["webhook"] = self.controller.management.get_webhook_by_id(
|
page_data["webhook"] = self.controller.management.get_webhook_by_id(
|
||||||
webhook_id
|
webhook_id
|
||||||
@ -1121,10 +1122,10 @@ class PanelHandler(BaseHandler):
|
|||||||
"Config": EnumPermissionsServer.CONFIG,
|
"Config": EnumPermissionsServer.CONFIG,
|
||||||
"Players": EnumPermissionsServer.PLAYERS,
|
"Players": EnumPermissionsServer.PLAYERS,
|
||||||
}
|
}
|
||||||
page_data[
|
page_data["user_permissions"] = (
|
||||||
"user_permissions"
|
self.controller.server_perms.get_user_id_permissions_list(
|
||||||
] = self.controller.server_perms.get_user_id_permissions_list(
|
exec_user["user_id"], server_id
|
||||||
exec_user["user_id"], server_id
|
)
|
||||||
)
|
)
|
||||||
page_data["server_data"] = self.controller.servers.get_server_data_by_id(
|
page_data["server_data"] = self.controller.servers.get_server_data_by_id(
|
||||||
server_id
|
server_id
|
||||||
@ -1132,9 +1133,9 @@ class PanelHandler(BaseHandler):
|
|||||||
page_data["server_stats"] = self.controller.servers.get_server_stats_by_id(
|
page_data["server_stats"] = self.controller.servers.get_server_stats_by_id(
|
||||||
server_id
|
server_id
|
||||||
)
|
)
|
||||||
page_data["server_stats"][
|
page_data["server_stats"]["server_type"] = (
|
||||||
"server_type"
|
self.controller.servers.get_server_type_by_id(server_id)
|
||||||
] = self.controller.servers.get_server_type_by_id(server_id)
|
)
|
||||||
page_data["new_schedule"] = True
|
page_data["new_schedule"] = True
|
||||||
page_data["schedule"] = {}
|
page_data["schedule"] = {}
|
||||||
page_data["schedule"]["children"] = []
|
page_data["schedule"]["children"] = []
|
||||||
@ -1189,10 +1190,10 @@ class PanelHandler(BaseHandler):
|
|||||||
"Config": EnumPermissionsServer.CONFIG,
|
"Config": EnumPermissionsServer.CONFIG,
|
||||||
"Players": EnumPermissionsServer.PLAYERS,
|
"Players": EnumPermissionsServer.PLAYERS,
|
||||||
}
|
}
|
||||||
page_data[
|
page_data["user_permissions"] = (
|
||||||
"user_permissions"
|
self.controller.server_perms.get_user_id_permissions_list(
|
||||||
] = self.controller.server_perms.get_user_id_permissions_list(
|
exec_user["user_id"], server_id
|
||||||
exec_user["user_id"], server_id
|
)
|
||||||
)
|
)
|
||||||
page_data["server_data"] = self.controller.servers.get_server_data_by_id(
|
page_data["server_data"] = self.controller.servers.get_server_data_by_id(
|
||||||
server_id
|
server_id
|
||||||
@ -1200,9 +1201,9 @@ class PanelHandler(BaseHandler):
|
|||||||
page_data["server_stats"] = self.controller.servers.get_server_stats_by_id(
|
page_data["server_stats"] = self.controller.servers.get_server_stats_by_id(
|
||||||
server_id
|
server_id
|
||||||
)
|
)
|
||||||
page_data["server_stats"][
|
page_data["server_stats"]["server_type"] = (
|
||||||
"server_type"
|
self.controller.servers.get_server_type_by_id(server_id)
|
||||||
] = self.controller.servers.get_server_type_by_id(server_id)
|
)
|
||||||
page_data["new_schedule"] = False
|
page_data["new_schedule"] = False
|
||||||
page_data["schedule"] = {}
|
page_data["schedule"] = {}
|
||||||
page_data["schedule"]["server_id"] = server_id
|
page_data["schedule"]["server_id"] = server_id
|
||||||
@ -1212,9 +1213,9 @@ class PanelHandler(BaseHandler):
|
|||||||
page_data["schedule"]["name"] = schedule.name
|
page_data["schedule"]["name"] = schedule.name
|
||||||
else:
|
else:
|
||||||
page_data["schedule"]["name"] = ""
|
page_data["schedule"]["name"] = ""
|
||||||
page_data["schedule"][
|
page_data["schedule"]["children"] = (
|
||||||
"children"
|
self.controller.management.get_child_schedules(sch_id)
|
||||||
] = self.controller.management.get_child_schedules(sch_id)
|
)
|
||||||
# We check here to see if the command is any of the default ones.
|
# We check here to see if the command is any of the default ones.
|
||||||
# We do not want a user changing to a custom command
|
# We do not want a user changing to a custom command
|
||||||
# and seeing our command there.
|
# and seeing our command there.
|
||||||
@ -1280,16 +1281,16 @@ class PanelHandler(BaseHandler):
|
|||||||
}
|
}
|
||||||
if exec_user["superuser"]:
|
if exec_user["superuser"]:
|
||||||
page_data["users"] = self.controller.users.get_all_users()
|
page_data["users"] = self.controller.users.get_all_users()
|
||||||
page_data[
|
page_data["permissions_all"] = (
|
||||||
"permissions_all"
|
self.controller.crafty_perms.list_defined_crafty_permissions()
|
||||||
] = self.controller.crafty_perms.list_defined_crafty_permissions()
|
)
|
||||||
page_data[
|
page_data["permissions_list"] = (
|
||||||
"permissions_list"
|
self.controller.crafty_perms.get_crafty_permissions_list(user_id)
|
||||||
] = self.controller.crafty_perms.get_crafty_permissions_list(user_id)
|
)
|
||||||
page_data[
|
page_data["quantity_server"] = (
|
||||||
"quantity_server"
|
self.controller.crafty_perms.list_crafty_permissions_quantity_limits(
|
||||||
] = self.controller.crafty_perms.list_crafty_permissions_quantity_limits(
|
user_id
|
||||||
user_id
|
)
|
||||||
)
|
)
|
||||||
page_data["languages"] = []
|
page_data["languages"] = []
|
||||||
page_data["languages"].append(
|
page_data["languages"].append(
|
||||||
@ -1349,12 +1350,12 @@ class PanelHandler(BaseHandler):
|
|||||||
page_data["user"] = self.controller.users.get_user_by_id(user_id)
|
page_data["user"] = self.controller.users.get_user_by_id(user_id)
|
||||||
page_data["api_keys"] = self.controller.users.get_user_api_keys(user_id)
|
page_data["api_keys"] = self.controller.users.get_user_api_keys(user_id)
|
||||||
# self.controller.crafty_perms.list_defined_crafty_permissions()
|
# self.controller.crafty_perms.list_defined_crafty_permissions()
|
||||||
page_data[
|
page_data["server_permissions_all"] = (
|
||||||
"server_permissions_all"
|
self.controller.server_perms.list_defined_permissions()
|
||||||
] = self.controller.server_perms.list_defined_permissions()
|
)
|
||||||
page_data[
|
page_data["crafty_permissions_all"] = (
|
||||||
"crafty_permissions_all"
|
self.controller.crafty_perms.list_defined_crafty_permissions()
|
||||||
] = self.controller.crafty_perms.list_defined_crafty_permissions()
|
)
|
||||||
|
|
||||||
if user_id is None:
|
if user_id is None:
|
||||||
self.redirect("/panel/error?error=Invalid User ID")
|
self.redirect("/panel/error?error=Invalid User ID")
|
||||||
@ -1442,9 +1443,9 @@ class PanelHandler(BaseHandler):
|
|||||||
DatabaseShortcuts.get_data_obj(server.server_object)
|
DatabaseShortcuts.get_data_obj(server.server_object)
|
||||||
)
|
)
|
||||||
page_data["servers_all"] = page_servers
|
page_data["servers_all"] = page_servers
|
||||||
page_data[
|
page_data["permissions_all"] = (
|
||||||
"permissions_all"
|
self.controller.server_perms.list_defined_permissions()
|
||||||
] = self.controller.server_perms.list_defined_permissions()
|
)
|
||||||
page_data["permissions_dict"] = {}
|
page_data["permissions_dict"] = {}
|
||||||
template = "panel/panel_edit_role.html"
|
template = "panel/panel_edit_role.html"
|
||||||
|
|
||||||
@ -1467,12 +1468,12 @@ class PanelHandler(BaseHandler):
|
|||||||
DatabaseShortcuts.get_data_obj(server.server_object)
|
DatabaseShortcuts.get_data_obj(server.server_object)
|
||||||
)
|
)
|
||||||
page_data["servers_all"] = page_servers
|
page_data["servers_all"] = page_servers
|
||||||
page_data[
|
page_data["permissions_all"] = (
|
||||||
"permissions_all"
|
self.controller.server_perms.list_defined_permissions()
|
||||||
] = self.controller.server_perms.list_defined_permissions()
|
)
|
||||||
page_data[
|
page_data["permissions_dict"] = (
|
||||||
"permissions_dict"
|
self.controller.server_perms.get_role_permissions_dict(role_id)
|
||||||
] = self.controller.server_perms.get_role_permissions_dict(role_id)
|
)
|
||||||
page_data["user-roles"] = user_roles
|
page_data["user-roles"] = user_roles
|
||||||
page_data["users"] = self.controller.users.get_all_users()
|
page_data["users"] = self.controller.users.get_all_users()
|
||||||
|
|
||||||
|
@ -80,9 +80,13 @@ class ApiCraftyConfigIndexHandler(BaseApiHandler):
|
|||||||
200,
|
200,
|
||||||
{
|
{
|
||||||
"status": "ok",
|
"status": "ok",
|
||||||
"data": self.controller.roles.get_all_role_ids()
|
"data": (
|
||||||
if get_only_ids
|
self.controller.roles.get_all_role_ids()
|
||||||
else [model_to_dict(r) for r in self.controller.roles.get_all_roles()],
|
if get_only_ids
|
||||||
|
else [
|
||||||
|
model_to_dict(r) for r in self.controller.roles.get_all_roles()
|
||||||
|
]
|
||||||
|
),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -158,9 +162,13 @@ class ApiCraftyCustomizeIndexHandler(BaseApiHandler):
|
|||||||
200,
|
200,
|
||||||
{
|
{
|
||||||
"status": "ok",
|
"status": "ok",
|
||||||
"data": self.controller.roles.get_all_role_ids()
|
"data": (
|
||||||
if get_only_ids
|
self.controller.roles.get_all_role_ids()
|
||||||
else [model_to_dict(r) for r in self.controller.roles.get_all_roles()],
|
if get_only_ids
|
||||||
|
else [
|
||||||
|
model_to_dict(r) for r in self.controller.roles.get_all_roles()
|
||||||
|
]
|
||||||
|
),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -36,9 +36,13 @@ class ApiCraftyConfigServerDirHandler(BaseApiHandler):
|
|||||||
200,
|
200,
|
||||||
{
|
{
|
||||||
"status": "ok",
|
"status": "ok",
|
||||||
"data": self.controller.roles.get_all_role_ids()
|
"data": (
|
||||||
if get_only_ids
|
self.controller.roles.get_all_role_ids()
|
||||||
else [model_to_dict(r) for r in self.controller.roles.get_all_roles()],
|
if get_only_ids
|
||||||
|
else [
|
||||||
|
model_to_dict(r) for r in self.controller.roles.get_all_roles()
|
||||||
|
]
|
||||||
|
),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -87,9 +87,13 @@ class ApiRolesIndexHandler(BaseApiHandler):
|
|||||||
200,
|
200,
|
||||||
{
|
{
|
||||||
"status": "ok",
|
"status": "ok",
|
||||||
"data": self.controller.roles.get_all_role_ids()
|
"data": (
|
||||||
if get_only_ids
|
self.controller.roles.get_all_role_ids()
|
||||||
else [model_to_dict(r) for r in self.controller.roles.get_all_roles()],
|
if get_only_ids
|
||||||
|
else [
|
||||||
|
model_to_dict(r) for r in self.controller.roles.get_all_roles()
|
||||||
|
]
|
||||||
|
),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -25,8 +25,12 @@ class ApiRolesRoleServersHandler(BaseApiHandler):
|
|||||||
200,
|
200,
|
||||||
{
|
{
|
||||||
"status": "ok",
|
"status": "ok",
|
||||||
"data": PermissionsServers.get_server_ids_from_role(role_id)
|
"data": (
|
||||||
if get_only_ids
|
PermissionsServers.get_server_ids_from_role(role_id)
|
||||||
else self.controller.roles.get_server_ids_and_perms_from_role(role_id),
|
if get_only_ids
|
||||||
|
else self.controller.roles.get_server_ids_and_perms_from_role(
|
||||||
|
role_id
|
||||||
|
)
|
||||||
|
),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -30,7 +30,15 @@ class ApiServersServerActionHandler(BaseApiHandler):
|
|||||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||||
|
|
||||||
if action == "clone_server":
|
if action == "clone_server":
|
||||||
return self._clone_server(server_id, auth_data[4]["user_id"])
|
if (
|
||||||
|
self.controller.crafty_perms.can_create_server(auth_data[4]["user_id"])
|
||||||
|
or auth_data[4]["superuser"]
|
||||||
|
):
|
||||||
|
self._clone_server(server_id, auth_data[4]["user_id"])
|
||||||
|
return self.finish_json(200, {"status": "ok"})
|
||||||
|
return self.finish_json(
|
||||||
|
200, {"status": "error", "error": "SERVER_LIMIT_REACHED"}
|
||||||
|
)
|
||||||
if action == "eula":
|
if action == "eula":
|
||||||
return self._agree_eula(server_id, auth_data[4]["user_id"])
|
return self._agree_eula(server_id, auth_data[4]["user_id"])
|
||||||
|
|
||||||
@ -94,6 +102,13 @@ class ApiServersServerActionHandler(BaseApiHandler):
|
|||||||
user_id,
|
user_id,
|
||||||
server_data.get("server_port"),
|
server_data.get("server_port"),
|
||||||
)
|
)
|
||||||
|
for role in self.controller.server_perms.get_server_roles(server_id):
|
||||||
|
mask = self.controller.server_perms.get_permissions_mask(
|
||||||
|
role.role_id, server_id
|
||||||
|
)
|
||||||
|
self.controller.server_perms.add_role_server(
|
||||||
|
new_server_id, role.role_id, mask
|
||||||
|
)
|
||||||
|
|
||||||
self.controller.servers.init_all_servers()
|
self.controller.servers.init_all_servers()
|
||||||
|
|
||||||
|
@ -118,15 +118,17 @@ class ServerHandler(BaseHandler):
|
|||||||
"lang_page": Helpers.get_lang_page(
|
"lang_page": Helpers.get_lang_page(
|
||||||
self.controller.users.get_user_lang_by_id(exec_user["user_id"])
|
self.controller.users.get_user_lang_by_id(exec_user["user_id"])
|
||||||
),
|
),
|
||||||
"api_key": {
|
"api_key": (
|
||||||
"name": api_key.name,
|
{
|
||||||
"created": api_key.created,
|
"name": api_key.name,
|
||||||
"server_permissions": api_key.server_permissions,
|
"created": api_key.created,
|
||||||
"crafty_permissions": api_key.crafty_permissions,
|
"server_permissions": api_key.server_permissions,
|
||||||
"superuser": api_key.superuser,
|
"crafty_permissions": api_key.crafty_permissions,
|
||||||
}
|
"superuser": api_key.superuser,
|
||||||
if api_key is not None
|
}
|
||||||
else None,
|
if api_key is not None
|
||||||
|
else None
|
||||||
|
),
|
||||||
"superuser": superuser,
|
"superuser": superuser,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -598,26 +598,30 @@
|
|||||||
</script>
|
</script>
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
function send_command(server_id, command) {
|
async function send_command(server_id, command) {
|
||||||
/* this getCookie function is in base.html */
|
/* this getCookie function is in base.html */
|
||||||
const token = getCookie("_xsrf");
|
const token = getCookie("_xsrf");
|
||||||
$.ajax({
|
let res = await fetch(`/api/v2/servers/${server_id}/action/${command}`, {
|
||||||
type: "POST",
|
method: 'POST',
|
||||||
headers: { 'X-XSRFToken': token },
|
headers: {
|
||||||
url: `/api/v2/servers/${server_id}/action/${command}`,
|
'token': token,
|
||||||
success: function (data) {
|
},
|
||||||
console.log("got response:");
|
|
||||||
console.log(data);
|
|
||||||
if (command === "clone_server" && data.status === "ok") {
|
|
||||||
window.location.reload();
|
|
||||||
}
|
|
||||||
/*setTimeout(function () {
|
|
||||||
if (command != 'start_server') {
|
|
||||||
location.reload();
|
|
||||||
}
|
|
||||||
}, 10000);*/
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
let responseData = await res.json();
|
||||||
|
if (responseData.status === "ok") {
|
||||||
|
if (command === "clone_server"){
|
||||||
|
window.location.reload()
|
||||||
|
}
|
||||||
|
console.log("Command received successfully")
|
||||||
|
} else {
|
||||||
|
setTimeout(function(){
|
||||||
|
$('.modal').modal('hide');
|
||||||
|
bootbox.alert({
|
||||||
|
title: responseData.status,
|
||||||
|
message: responseData.error
|
||||||
|
});
|
||||||
|
}, 2000)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -4,13 +4,13 @@ argon2-cffi==23.1.0
|
|||||||
cached_property==1.5.2
|
cached_property==1.5.2
|
||||||
colorama==0.4.6
|
colorama==0.4.6
|
||||||
croniter==1.4.1
|
croniter==1.4.1
|
||||||
cryptography==41.0.7
|
cryptography==42.0.2
|
||||||
libgravatar==1.0.4
|
libgravatar==1.0.4
|
||||||
nh3==0.2.14
|
nh3==0.2.14
|
||||||
packaging==23.2
|
packaging==23.2
|
||||||
peewee==3.13
|
peewee==3.13
|
||||||
psutil==5.9.5
|
psutil==5.9.5
|
||||||
pyOpenSSL==23.3.0
|
pyOpenSSL==24.0.0
|
||||||
pyjwt==2.8.0
|
pyjwt==2.8.0
|
||||||
PyYAML==6.0.1
|
PyYAML==6.0.1
|
||||||
requests==2.31.0
|
requests==2.31.0
|
||||||
|
Loading…
Reference in New Issue
Block a user