mirror of
https://gitlab.com/crafty-controller/crafty-4.git
synced 2024-08-30 18:23:09 +00:00
Merge branch 'dev' into lang/czech-updates
This commit is contained in:
commit
31f7d88c3a
@ -3,16 +3,16 @@
|
|||||||
- **Install Type:** Git Cloned(Manual) / Installer / WinPackage / Docker
|
- **Install Type:** Git Cloned(Manual) / Installer / WinPackage / Docker
|
||||||
|
|
||||||
## What Happened?
|
## What Happened?
|
||||||
*A brief description of what happened when you tried to perform an action*
|
<!-- A brief description of what happened when you tried to perform an action -->
|
||||||
|
|
||||||
## Expected result
|
## Expected result
|
||||||
*What should have happened when you performed the actions*
|
<!-- What should have happened when you performed the actions -->
|
||||||
|
|
||||||
## Steps to reproduce
|
## Steps to reproduce
|
||||||
*List the steps required to produce the error. These should be as few as possible*
|
<!-- List the steps required to produce the error. These should be as few as possible -->
|
||||||
|
|
||||||
## Screenshots
|
## Screenshots
|
||||||
Any relevant screenshots which show the issue* !-->*
|
<!-- Any relevant screenshots which show the issue -->
|
||||||
|
|
||||||
## Priority/Severity
|
## Priority/Severity
|
||||||
- [ ] High (anything that impacts the normal user flow or blocks app usage)
|
- [ ] High (anything that impacts the normal user flow or blocks app usage)
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
## Summary
|
## Summary
|
||||||
*Outline the issue being faced, and why this needs to change*
|
<!-- Outline the issue being faced, and why this needs to change -->
|
||||||
|
|
||||||
## Area of the system
|
## Area of the system
|
||||||
*This might only be one part, but may involve multiple sections, Login/Dashboad/Terminal/Config*
|
<!-- This might only be one part, but may involve multiple sections, Login/Dashboad/Terminal/Config -->
|
||||||
|
|
||||||
## How does this currently work?
|
## How does this currently work?
|
||||||
|
<!-- A brief description of how the functionality currently operates -->
|
||||||
|
|
||||||
## What is the desired way of working?
|
## What is the desired way of working?
|
||||||
*After the change, what should the process/operation be?*
|
<!-- After the change, what should the process/operation be? -->
|
||||||
|
|
||||||
## Priority/Severity
|
## Priority/Severity
|
||||||
- [ ] High (This will bring a huge increase in performance/productivity/usability)
|
- [ ] High (This will bring a huge increase in performance/productivity/usability)
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
## Problem Statement
|
## Problem Statement
|
||||||
*What is the issue being faced and needs addressing?*
|
<!-- What is the issue being faced and needs addressing? -->
|
||||||
|
|
||||||
## Who will benefit?
|
## Who will benefit?
|
||||||
*Will this fix a problem that only one user has, or will it benefit a lot of people*
|
<!-- Will this fix a problem that only one user has, or will it benefit a lot of people -->
|
||||||
|
|
||||||
## Benefits and risks
|
## Benefits and risks
|
||||||
What benefits does this bring?
|
What benefits does this bring?
|
||||||
@ -16,10 +16,10 @@
|
|||||||
|
|
||||||
|
|
||||||
## Proposed solution
|
## Proposed solution
|
||||||
*How would you like to see this issue resolved?*
|
<!-- How would you like to see this issue resolved? -->
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
*Are there any examples of this which exist in other software?*
|
<!-- Are there any examples of this which exist in other software? -->
|
||||||
|
|
||||||
## Priority/Severity
|
## Priority/Severity
|
||||||
- [ ] High (This will bring a huge increase in performance/productivity/usability)
|
- [ ] High (This will bring a huge increase in performance/productivity/usability)
|
||||||
|
@ -5,7 +5,7 @@ yamllint:
|
|||||||
stage: lint
|
stage: lint
|
||||||
image: registry.gitlab.com/pipeline-components/yamllint:latest
|
image: registry.gitlab.com/pipeline-components/yamllint:latest
|
||||||
tags:
|
tags:
|
||||||
- docker
|
- saas-linux-medium-amd64
|
||||||
rules:
|
rules:
|
||||||
- if: "$CODE_QUALITY_DISABLED"
|
- if: "$CODE_QUALITY_DISABLED"
|
||||||
when: never
|
when: never
|
||||||
@ -18,7 +18,7 @@ jsonlint:
|
|||||||
stage: lint
|
stage: lint
|
||||||
image: registry.gitlab.com/pipeline-components/jsonlint:latest
|
image: registry.gitlab.com/pipeline-components/jsonlint:latest
|
||||||
tags:
|
tags:
|
||||||
- docker
|
- saas-linux-medium-amd64
|
||||||
rules:
|
rules:
|
||||||
- if: "$CODE_QUALITY_DISABLED"
|
- if: "$CODE_QUALITY_DISABLED"
|
||||||
when: never
|
when: never
|
||||||
@ -33,7 +33,7 @@ black:
|
|||||||
stage: lint
|
stage: lint
|
||||||
image: registry.gitlab.com/pipeline-components/black:latest
|
image: registry.gitlab.com/pipeline-components/black:latest
|
||||||
tags:
|
tags:
|
||||||
- docker
|
- saas-linux-medium-amd64
|
||||||
rules:
|
rules:
|
||||||
- if: "$CODE_QUALITY_DISABLED"
|
- if: "$CODE_QUALITY_DISABLED"
|
||||||
when: never
|
when: never
|
||||||
@ -46,7 +46,7 @@ pylint:
|
|||||||
stage: lint
|
stage: lint
|
||||||
image: registry.gitlab.com/pipeline-components/pylint:latest
|
image: registry.gitlab.com/pipeline-components/pylint:latest
|
||||||
tags:
|
tags:
|
||||||
- docker
|
- saas-linux-medium-amd64
|
||||||
rules:
|
rules:
|
||||||
- if: "$CODE_QUALITY_DISABLED"
|
- if: "$CODE_QUALITY_DISABLED"
|
||||||
when: never
|
when: never
|
||||||
@ -69,7 +69,7 @@ sonarcloud-check:
|
|||||||
name: sonarsource/sonar-scanner-cli:latest
|
name: sonarsource/sonar-scanner-cli:latest
|
||||||
entrypoint: [""]
|
entrypoint: [""]
|
||||||
tags:
|
tags:
|
||||||
- docker
|
- saas-linux-medium-amd64
|
||||||
rules:
|
rules:
|
||||||
- if: "$SONAR_TOKEN == null"
|
- if: "$SONAR_TOKEN == null"
|
||||||
when: never
|
when: never
|
||||||
@ -91,7 +91,7 @@ lang-check:
|
|||||||
stage: lint
|
stage: lint
|
||||||
image: alpine:latest
|
image: alpine:latest
|
||||||
tags:
|
tags:
|
||||||
- docker
|
- saas-linux-medium-amd64
|
||||||
rules:
|
rules:
|
||||||
- if: "$CODE_QUALITY_DISABLED"
|
- if: "$CODE_QUALITY_DISABLED"
|
||||||
when: never
|
when: never
|
||||||
|
@ -1,22 +1,22 @@
|
|||||||
## What does this MR do and why?
|
## What does this MR do and why?
|
||||||
|
|
||||||
___Describe in detail what your merge request does and why.___<br>
|
<!-- Describe in detail what your merge request does and why. -->
|
||||||
> *Please keep this description updated with any discussion that takes place so*<br>
|
<!-- Please keep this description updated with any discussion that takes place so -->
|
||||||
*that reviewers can understand your intent. Keeping the description updated is*<br>
|
<!-- that reviewers can understand your intent. Keeping the description updated is -->
|
||||||
*especially important if they didn't participate in the discussion.*<br>
|
<!-- especially important if they didn't participate in the discussion. -->
|
||||||
|
|
||||||
|
|
||||||
## Screenshots or screen recordings
|
## Screenshots or screen recordings
|
||||||
|
|
||||||
___These are strongly recommended to assist reviewers and reduce the time to merge your change.___<br>
|
<!-- These are strongly recommended to assist reviewers and reduce the time to merge your change. -->
|
||||||
> *Please include any relevant screenshots or screen recordings that will assist*<br>
|
<!-- Please include any relevant screenshots or screen recordings that will assist, -->
|
||||||
*reviewers and future readers. If you need help visually verifying the change,*<br>
|
<!-- reviewers and future readers. If you need help visually verifying the change, -->
|
||||||
*please leave a comment and ping a GitLab reviewer, maintainer, or MR coach.*<br>
|
<!-- please leave a comment and ping a GitLab reviewer, maintainer, or MR coach. -->
|
||||||
|
|
||||||
|
|
||||||
## How to set up and validate locally
|
## How to set up and validate locally
|
||||||
|
|
||||||
___Numbered steps to set up and validate the change are strongly suggested.___
|
<!-- Numbered steps to set up and validate the change are strongly suggested. -->
|
||||||
|
|
||||||
|
|
||||||
## MR acceptance checklist
|
## MR acceptance checklist
|
||||||
|
@ -3,13 +3,46 @@
|
|||||||
# Prompt the user for the directory path
|
# Prompt the user for the directory path
|
||||||
read -p "Enter the directory path to set permissions (/var/opt/minecraft/crafty): " directory_path
|
read -p "Enter the directory path to set permissions (/var/opt/minecraft/crafty): " directory_path
|
||||||
|
|
||||||
|
# Count the total number of directories
|
||||||
|
total_dirs=$(find "$directory_path" -type d 2>/dev/null | wc -l)
|
||||||
|
|
||||||
|
# Count the total number of files
|
||||||
|
total_files=$(find "$directory_path" -type f 2>/dev/null | wc -l)
|
||||||
|
|
||||||
|
# Initialize a counter for directories and files
|
||||||
|
dir_count=0
|
||||||
|
file_count=0
|
||||||
|
|
||||||
|
# Function to print progress
|
||||||
|
print_progress() {
|
||||||
|
echo -ne "\rDirectories: $dir_count/$total_dirs Files: $file_count/$total_files"
|
||||||
|
}
|
||||||
|
|
||||||
# Check if the script is running within a Docker container
|
# Check if the script is running within a Docker container
|
||||||
if [ -f "/.dockerenv" ]; then
|
if [ -f "/.dockerenv" ]; then
|
||||||
echo "Script is running within a Docker container. Exiting with error."
|
echo "Script is running within a Docker container. Exiting with error."
|
||||||
exit 1 # Exit with an error code if running in Docker
|
exit 1 # Exit with an error code if running in Docker
|
||||||
else
|
else
|
||||||
echo "Script is not running within a Docker container. Executing permissions changes..."
|
echo "Script is not running within a Docker container. Executing permissions changes..."
|
||||||
# Run the commands to set permissions
|
|
||||||
sudo chmod 700 $(find "$directory_path" -type d)
|
# Run the commands to set permissions for directories
|
||||||
sudo chmod 644 $(find "$directory_path" -type f)
|
echo "Changing permissions for directories:"
|
||||||
fi
|
for dir in $(find "$directory_path" -type d 2>/dev/null); do
|
||||||
|
if [ -e "$dir" ]; then
|
||||||
|
sudo chmod 700 "$dir" && ((dir_count++))
|
||||||
|
fi
|
||||||
|
print_progress
|
||||||
|
done
|
||||||
|
|
||||||
|
# Run the commands to set permissions for files
|
||||||
|
echo -e "\nChanging permissions for files:"
|
||||||
|
for file in $(find "$directory_path" -type f 2>/dev/null); do
|
||||||
|
if [ -e "$file" ]; then
|
||||||
|
sudo chmod 644 "$file" && ((file_count++))
|
||||||
|
fi
|
||||||
|
print_progress
|
||||||
|
done
|
||||||
|
echo "You will now need to execute a chmod +x on all bedrock executables"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "" # Adding a new line after the loop for better readability
|
24
CHANGELOG.md
24
CHANGELOG.md
@ -1,15 +1,35 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
## --- [4.3.2] - 2024/TBD
|
## --- [4.3.3] - 2024/TBD
|
||||||
|
### Refactor
|
||||||
|
- Refactor API keys "super user" to "full access" ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/731))
|
||||||
### New features
|
### New features
|
||||||
TBD
|
TBD
|
||||||
### Bug fixes
|
### Bug fixes
|
||||||
TBD
|
TBD
|
||||||
### Tweaks
|
### Tweaks
|
||||||
TBD
|
- Add link to go back to dashboard on error page ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/743))
|
||||||
### Lang
|
### Lang
|
||||||
TBD
|
TBD
|
||||||
<br><br>
|
<br><br>
|
||||||
|
|
||||||
|
## --- [4.3.2] - 2024/04/07
|
||||||
|
### Refactor
|
||||||
|
- Refactor ServerJars caching and move to api.serverjars.com ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/744) | [Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/746))
|
||||||
|
### Bug fixes
|
||||||
|
- Fix migrator issue when jumping versions ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/734))
|
||||||
|
- Fix backend issue causing error when restoring backups in 4.3.x ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/736))
|
||||||
|
- Fix backend issue causing error when cloning servers in 4.3.x ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/741))
|
||||||
|
- Bump orjson for CVE-2024-27454 ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/747))
|
||||||
|
- Fix calling of orjson JSONDecodeError class ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/747))
|
||||||
|
- Fix stack on Crafty permissions route request in API ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/745))
|
||||||
|
### Tweaks
|
||||||
|
- Clean up remaining http handler references ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/733))
|
||||||
|
- Remove version disclosure on login page ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/737))
|
||||||
|
- Add openjdk-21 for recent versions of MC ([Commit](https://gitlab.com/crafty-controller/crafty-4/-/commit/77b0c2c9d2eac124a7504a3d3916fa22d29fa9d1))
|
||||||
|
### Lang
|
||||||
|
- Update `it_IT, cs_CS` ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/739) | [Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/742))
|
||||||
|
<br><br>
|
||||||
|
|
||||||
## --- [4.3.1] - 2024/03/18
|
## --- [4.3.1] - 2024/03/18
|
||||||
### Bug fixes
|
### Bug fixes
|
||||||
- Fix Server ID Rework for backups, schedules, and roles (INT ID to UUID migration) ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/729))
|
- Fix Server ID Rework for backups, schedules, and roles (INT ID to UUID migration) ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/729))
|
||||||
|
@ -25,6 +25,7 @@ RUN apt-get update \
|
|||||||
openjdk-8-jre-headless \
|
openjdk-8-jre-headless \
|
||||||
openjdk-11-jre-headless \
|
openjdk-11-jre-headless \
|
||||||
openjdk-17-jre-headless \
|
openjdk-17-jre-headless \
|
||||||
|
openjdk-21-jre-headless \
|
||||||
tzdata \
|
tzdata \
|
||||||
&& apt-get autoremove \
|
&& apt-get autoremove \
|
||||||
&& apt-get clean
|
&& apt-get clean
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
[![Crafty Logo](app/frontend/static/assets/images/logo_long.svg)](https://craftycontrol.com)
|
[![Crafty Logo](app/frontend/static/assets/images/logo_long.svg)](https://craftycontrol.com)
|
||||||
# Crafty Controller 4.3.2
|
# Crafty Controller 4.3.3
|
||||||
> Python based Control Panel for your Minecraft Server
|
> Python based Control Panel for your Minecraft Server
|
||||||
|
|
||||||
## What is Crafty Controller?
|
## What is Crafty Controller?
|
||||||
|
@ -17,6 +17,10 @@ class ServerPermsController:
|
|||||||
def get_server_user_list(server_id):
|
def get_server_user_list(server_id):
|
||||||
return PermissionsServers.get_server_user_list(server_id)
|
return PermissionsServers.get_server_user_list(server_id)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_permissions(permissions_mask):
|
||||||
|
return PermissionsServers.get_permissions(permissions_mask)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def list_defined_permissions():
|
def list_defined_permissions():
|
||||||
permissions_list = PermissionsServers.get_permissions_list()
|
permissions_list = PermissionsServers.get_permissions_list()
|
||||||
@ -47,7 +51,7 @@ class ServerPermsController:
|
|||||||
new_server_id,
|
new_server_id,
|
||||||
role.role_id,
|
role.role_id,
|
||||||
PermissionsServers.get_permissions_mask(
|
PermissionsServers.get_permissions_mask(
|
||||||
int(role.role_id), int(old_server_id)
|
int(role.role_id), old_server_id
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
# Permissions_Servers.add_role_server(
|
# Permissions_Servers.add_role_server(
|
||||||
@ -61,6 +65,22 @@ class ServerPermsController:
|
|||||||
def get_permissions_mask(role_id, server_id):
|
def get_permissions_mask(role_id, server_id):
|
||||||
return PermissionsServers.get_permissions_mask(role_id, server_id)
|
return PermissionsServers.get_permissions_mask(role_id, server_id)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_lowest_api_perm_mask(user_server_permissions_mask, api_key_permssions_mask):
|
||||||
|
mask = ""
|
||||||
|
# If this isn't an API key we'll know the request came from basic
|
||||||
|
# authentication and ignore the API key permissions mask.
|
||||||
|
if not api_key_permssions_mask:
|
||||||
|
return user_server_permissions_mask
|
||||||
|
for _index, (user_perm, api_perm) in enumerate(
|
||||||
|
zip(user_server_permissions_mask, api_key_permssions_mask)
|
||||||
|
):
|
||||||
|
if user_perm == "1" and api_perm == "1":
|
||||||
|
mask += "1"
|
||||||
|
else:
|
||||||
|
mask += "0"
|
||||||
|
return mask
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def set_permission(
|
def set_permission(
|
||||||
permission_mask, permission_tested: EnumPermissionsServer, value
|
permission_mask, permission_tested: EnumPermissionsServer, value
|
||||||
@ -82,6 +102,11 @@ class ServerPermsController:
|
|||||||
def get_api_key_permissions_list(key: ApiKeys, server_id: str):
|
def get_api_key_permissions_list(key: ApiKeys, server_id: str):
|
||||||
return PermissionsServers.get_api_key_permissions_list(key, server_id)
|
return PermissionsServers.get_api_key_permissions_list(key, server_id)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_user_permissions_mask(user_id: str, server_id: str):
|
||||||
|
user = HelperUsers.get_user_model(user_id)
|
||||||
|
return PermissionsServers.get_user_permissions_mask(user, server_id)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_authorized_servers_stats_from_roles(user_id):
|
def get_authorized_servers_stats_from_roles(user_id):
|
||||||
user_roles = HelperUsers.get_user_roles_id(user_id)
|
user_roles = HelperUsers.get_user_roles_id(user_id)
|
||||||
|
@ -12,13 +12,15 @@ 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__)
|
||||||
|
# Temp type var until sjars restores generic fetchTypes0
|
||||||
|
SERVERJARS_TYPES = ["modded", "proxies", "servers", "vanilla"]
|
||||||
PAPERJARS = ["paper", "folia"]
|
PAPERJARS = ["paper", "folia"]
|
||||||
|
|
||||||
|
|
||||||
class ServerJars:
|
class ServerJars:
|
||||||
def __init__(self, helper):
|
def __init__(self, helper):
|
||||||
self.helper = helper
|
self.helper = helper
|
||||||
self.base_url = "https://serverjars.com"
|
self.base_url = "https://api.serverjars.com"
|
||||||
self.paper_base = "https://api.papermc.io"
|
self.paper_base = "https://api.papermc.io"
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@ -82,6 +84,183 @@ class ServerJars:
|
|||||||
builds = api_data.get("builds", [])
|
builds = api_data.get("builds", [])
|
||||||
return builds[-1] if builds else None
|
return builds[-1] if builds else None
|
||||||
|
|
||||||
|
def _read_cache(self):
|
||||||
|
cache_file = self.helper.serverjar_cache
|
||||||
|
cache = {}
|
||||||
|
try:
|
||||||
|
with open(cache_file, "r", encoding="utf-8") as f:
|
||||||
|
cache = json.load(f)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Unable to read serverjars.com cache file: {e}")
|
||||||
|
|
||||||
|
return cache
|
||||||
|
|
||||||
|
def get_serverjar_data(self):
|
||||||
|
data = self._read_cache()
|
||||||
|
return data.get("types")
|
||||||
|
|
||||||
|
def _check_sjars_api_alive(self):
|
||||||
|
logger.info("Checking serverjars.com API status")
|
||||||
|
|
||||||
|
check_url = f"{self.base_url}"
|
||||||
|
try:
|
||||||
|
response = requests.get(check_url, timeout=2)
|
||||||
|
response_json = response.json()
|
||||||
|
|
||||||
|
if (
|
||||||
|
response.status_code in [200, 201]
|
||||||
|
and response_json.get("status") == "success"
|
||||||
|
and response_json.get("response", {}).get("status") == "ok"
|
||||||
|
):
|
||||||
|
logger.info("Serverjars.com API is alive and responding as expected")
|
||||||
|
return True
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Unable to connect to serverjar.com API due to error: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
logger.error(
|
||||||
|
"Serverjars.com API is not responding as expected or unable to contact"
|
||||||
|
)
|
||||||
|
return False
|
||||||
|
|
||||||
|
def _fetch_projects_for_type(self, server_type):
|
||||||
|
"""
|
||||||
|
Fetches projects for a given server type from the ServerJars API.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
response = requests.get(
|
||||||
|
f"{self.base_url}/api/fetchTypes/{server_type}", timeout=5
|
||||||
|
)
|
||||||
|
response.raise_for_status() # Ensure HTTP errors are caught
|
||||||
|
data = response.json()
|
||||||
|
if data.get("status") == "success":
|
||||||
|
return data["response"].get("servers", [])
|
||||||
|
except requests.RequestException as e:
|
||||||
|
print(f"Error fetching projects for type {server_type}: {e}")
|
||||||
|
return []
|
||||||
|
|
||||||
|
def _get_server_type_list(self):
|
||||||
|
"""
|
||||||
|
Builds the type structure with projects fetched for each type.
|
||||||
|
"""
|
||||||
|
type_structure = {}
|
||||||
|
for server_type in SERVERJARS_TYPES:
|
||||||
|
projects = self._fetch_projects_for_type(server_type)
|
||||||
|
type_structure[server_type] = {project: [] for project in projects}
|
||||||
|
return type_structure
|
||||||
|
|
||||||
|
def _get_jar_versions(self, server_type, project_name, max_ver=50):
|
||||||
|
"""
|
||||||
|
Grabs available versions for specified project
|
||||||
|
|
||||||
|
Args:
|
||||||
|
server_type (str): Server Type Category (modded, servers, etc)
|
||||||
|
project_name (str): Target project (paper, forge, magma, etc)
|
||||||
|
max (int, optional): Max versions returned. Defaults to 50.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
list: An array of versions
|
||||||
|
"""
|
||||||
|
url = f"{self.base_url}/api/fetchAll/{server_type}/{project_name}?max={max_ver}"
|
||||||
|
try:
|
||||||
|
response = requests.get(url, timeout=5)
|
||||||
|
response.raise_for_status() # Ensure HTTP errors are caught
|
||||||
|
data = response.json()
|
||||||
|
logger.debug(f"Received data for {server_type}/{project_name}: {data}")
|
||||||
|
|
||||||
|
if data.get("status") == "success":
|
||||||
|
versions = [
|
||||||
|
item.get("version")
|
||||||
|
for item in data.get("response", [])
|
||||||
|
if "version" in item
|
||||||
|
]
|
||||||
|
versions.reverse() # Reverse so versions are newest -> oldest
|
||||||
|
logger.debug(f"Versions extracted: {versions}")
|
||||||
|
return versions
|
||||||
|
except requests.RequestException as e:
|
||||||
|
logger.error(
|
||||||
|
f"Error fetching jar versions for {server_type}/{project_name}: {e}"
|
||||||
|
)
|
||||||
|
|
||||||
|
return []
|
||||||
|
|
||||||
|
def _refresh_cache(self):
|
||||||
|
"""
|
||||||
|
Contains the shared logic for refreshing the cache.
|
||||||
|
This method is called by both manual_refresh_cache and refresh_cache methods.
|
||||||
|
"""
|
||||||
|
now = datetime.now()
|
||||||
|
cache_data = {
|
||||||
|
"last_refreshed": now.strftime("%m/%d/%Y, %H:%M:%S"),
|
||||||
|
"types": self._get_server_type_list(),
|
||||||
|
}
|
||||||
|
|
||||||
|
for server_type, projects in cache_data["types"].items():
|
||||||
|
for project_name in projects:
|
||||||
|
versions = self._get_jar_versions(server_type, project_name)
|
||||||
|
cache_data["types"][server_type][project_name] = versions
|
||||||
|
|
||||||
|
for paper_project in PAPERJARS:
|
||||||
|
cache_data["types"]["servers"][paper_project] = self.get_paper_versions(
|
||||||
|
paper_project
|
||||||
|
)
|
||||||
|
|
||||||
|
return cache_data
|
||||||
|
|
||||||
|
def manual_refresh_cache(self):
|
||||||
|
"""
|
||||||
|
Manually triggers the cache refresh process.
|
||||||
|
"""
|
||||||
|
if not self._check_sjars_api_alive():
|
||||||
|
logger.error("ServerJars API is not available.")
|
||||||
|
return False
|
||||||
|
|
||||||
|
logger.info("Manual cache refresh requested.")
|
||||||
|
cache_data = self._refresh_cache()
|
||||||
|
|
||||||
|
# Save the updated cache data
|
||||||
|
try:
|
||||||
|
with open(self.helper.serverjar_cache, "w", encoding="utf-8") as cache_file:
|
||||||
|
json.dump(cache_data, cache_file, indent=4)
|
||||||
|
logger.info("Cache file successfully refreshed manually.")
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Failed to update cache file manually: {e}")
|
||||||
|
|
||||||
|
def refresh_cache(self):
|
||||||
|
"""
|
||||||
|
Automatically trigger cache refresh process based age.
|
||||||
|
|
||||||
|
This method checks if the cache file is older than a specified number of days
|
||||||
|
before deciding to refresh.
|
||||||
|
"""
|
||||||
|
cache_file_path = self.helper.serverjar_cache
|
||||||
|
|
||||||
|
# Determine if the cache is old and needs refreshing
|
||||||
|
cache_old = self.helper.is_file_older_than_x_days(cache_file_path)
|
||||||
|
|
||||||
|
# debug override
|
||||||
|
# cache_old = True
|
||||||
|
|
||||||
|
if not self._check_sjars_api_alive():
|
||||||
|
logger.error("ServerJars API is not available.")
|
||||||
|
return False
|
||||||
|
|
||||||
|
if not cache_old:
|
||||||
|
logger.info("Cache file is not old enough to require automatic refresh.")
|
||||||
|
return False
|
||||||
|
|
||||||
|
logger.info("Automatic cache refresh initiated due to old cache.")
|
||||||
|
cache_data = self._refresh_cache()
|
||||||
|
|
||||||
|
# Save the updated cache data
|
||||||
|
try:
|
||||||
|
with open(cache_file_path, "w", encoding="utf-8") as cache_file:
|
||||||
|
json.dump(cache_data, cache_file, indent=4)
|
||||||
|
logger.info("Cache file successfully refreshed automatically.")
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Failed to update cache file automatically: {e}")
|
||||||
|
|
||||||
def get_fetch_url(self, jar, server, version):
|
def get_fetch_url(self, jar, server, version):
|
||||||
"""
|
"""
|
||||||
Constructs the URL for downloading a server JAR file based on the server type.
|
Constructs the URL for downloading a server JAR file based on the server type.
|
||||||
@ -132,151 +311,6 @@ class ServerJars:
|
|||||||
logger.error(f"An error occurred while constructing fetch URL: {e}")
|
logger.error(f"An error occurred while constructing fetch URL: {e}")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def _get_api_result(self, call_url: str):
|
|
||||||
full_url = f"{self.base_url}{call_url}"
|
|
||||||
|
|
||||||
try:
|
|
||||||
response = requests.get(full_url, timeout=2)
|
|
||||||
response.raise_for_status()
|
|
||||||
api_data = json.loads(response.content)
|
|
||||||
except Exception as e:
|
|
||||||
logger.error(f"Unable to load {full_url} api due to error: {e}")
|
|
||||||
return {}
|
|
||||||
|
|
||||||
api_result = api_data.get("status")
|
|
||||||
api_response = api_data.get("response", {})
|
|
||||||
|
|
||||||
if api_result != "success":
|
|
||||||
logger.error(f"Api returned a failed status: {api_result}")
|
|
||||||
return {}
|
|
||||||
|
|
||||||
return api_response
|
|
||||||
|
|
||||||
def _read_cache(self):
|
|
||||||
cache_file = self.helper.serverjar_cache
|
|
||||||
cache = {}
|
|
||||||
try:
|
|
||||||
with open(cache_file, "r", encoding="utf-8") as f:
|
|
||||||
cache = json.load(f)
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
logger.error(f"Unable to read serverjars.com cache file: {e}")
|
|
||||||
|
|
||||||
return cache
|
|
||||||
|
|
||||||
def get_serverjar_data(self):
|
|
||||||
data = self._read_cache()
|
|
||||||
return data.get("types")
|
|
||||||
|
|
||||||
def _check_api_alive(self):
|
|
||||||
logger.info("Checking serverjars.com API status")
|
|
||||||
|
|
||||||
check_url = f"{self.base_url}/api/fetchTypes"
|
|
||||||
try:
|
|
||||||
response = requests.get(check_url, timeout=2)
|
|
||||||
|
|
||||||
if response.status_code in [200, 201]:
|
|
||||||
logger.info("Serverjars.com API is alive")
|
|
||||||
return True
|
|
||||||
except Exception as e:
|
|
||||||
logger.error(f"Unable to connect to serverjar.com api due to error: {e}")
|
|
||||||
return {}
|
|
||||||
|
|
||||||
logger.error("unable to contact serverjars.com api")
|
|
||||||
return False
|
|
||||||
|
|
||||||
def manual_refresh_cache(self):
|
|
||||||
cache_file = self.helper.serverjar_cache
|
|
||||||
|
|
||||||
# debug override
|
|
||||||
# cache_old = True
|
|
||||||
|
|
||||||
# if the API is down... we bomb out
|
|
||||||
if not self._check_api_alive():
|
|
||||||
return False
|
|
||||||
|
|
||||||
logger.info("Manual Refresh requested.")
|
|
||||||
now = datetime.now()
|
|
||||||
data = {
|
|
||||||
"last_refreshed": now.strftime("%m/%d/%Y, %H:%M:%S"),
|
|
||||||
"types": {},
|
|
||||||
}
|
|
||||||
|
|
||||||
jar_types = self._get_server_type_list()
|
|
||||||
data["types"].update(jar_types)
|
|
||||||
for s in data["types"]:
|
|
||||||
data["types"].update({s: dict.fromkeys(data["types"].get(s), {})})
|
|
||||||
for j in data["types"].get(s):
|
|
||||||
versions = self._get_jar_details(j, s)
|
|
||||||
data["types"][s].update({j: versions})
|
|
||||||
for item in PAPERJARS:
|
|
||||||
data["types"]["servers"][item] = self.get_paper_versions(item)
|
|
||||||
# save our cache
|
|
||||||
try:
|
|
||||||
with open(cache_file, "w", encoding="utf-8") as f:
|
|
||||||
f.write(json.dumps(data, indent=4))
|
|
||||||
logger.info("Cache file refreshed")
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
logger.error(f"Unable to update serverjars.com cache file: {e}")
|
|
||||||
|
|
||||||
def refresh_cache(self):
|
|
||||||
cache_file = self.helper.serverjar_cache
|
|
||||||
cache_old = self.helper.is_file_older_than_x_days(cache_file)
|
|
||||||
|
|
||||||
# debug override
|
|
||||||
# cache_old = True
|
|
||||||
|
|
||||||
# if the API is down... we bomb out
|
|
||||||
if not self._check_api_alive():
|
|
||||||
return False
|
|
||||||
|
|
||||||
logger.info("Checking Cache file age")
|
|
||||||
# if file is older than 1 day
|
|
||||||
|
|
||||||
if cache_old:
|
|
||||||
logger.info("Cache file is over 1 day old, refreshing")
|
|
||||||
now = datetime.now()
|
|
||||||
data = {
|
|
||||||
"last_refreshed": now.strftime("%m/%d/%Y, %H:%M:%S"),
|
|
||||||
"types": {},
|
|
||||||
}
|
|
||||||
|
|
||||||
jar_types = self._get_server_type_list()
|
|
||||||
data["types"].update(jar_types)
|
|
||||||
for s in data["types"]:
|
|
||||||
data["types"].update({s: dict.fromkeys(data["types"].get(s), {})})
|
|
||||||
for j in data["types"].get(s):
|
|
||||||
versions = self._get_jar_details(j, s)
|
|
||||||
data["types"][s].update({j: versions})
|
|
||||||
for item in PAPERJARS:
|
|
||||||
data["types"]["servers"][item] = self.get_paper_versions(item)
|
|
||||||
# save our cache
|
|
||||||
try:
|
|
||||||
with open(cache_file, "w", encoding="utf-8") as f:
|
|
||||||
f.write(json.dumps(data, indent=4))
|
|
||||||
logger.info("Cache file refreshed")
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
logger.error(f"Unable to update serverjars.com cache file: {e}")
|
|
||||||
|
|
||||||
def _get_jar_details(self, server_type, jar_type="servers"):
|
|
||||||
url = f"/api/fetchAll/{jar_type}/{server_type}"
|
|
||||||
response = self._get_api_result(url)
|
|
||||||
temp = []
|
|
||||||
for v in response:
|
|
||||||
temp.append(v.get("version"))
|
|
||||||
time.sleep(0.5)
|
|
||||||
return temp
|
|
||||||
|
|
||||||
def _get_server_type_list(self):
|
|
||||||
url = "/api/fetchTypes/"
|
|
||||||
response = self._get_api_result(url)
|
|
||||||
if "bedrock" in response.keys():
|
|
||||||
# remove pocketmine from options
|
|
||||||
del response["bedrock"]
|
|
||||||
return response
|
|
||||||
|
|
||||||
def download_jar(self, jar, server, version, path, server_id):
|
def download_jar(self, jar, server, version, path, server_id):
|
||||||
update_thread = threading.Thread(
|
update_thread = threading.Thread(
|
||||||
name=f"server_download-{server_id}-{server}-{version}",
|
name=f"server_download-{server_id}-{server}-{version}",
|
||||||
|
@ -187,7 +187,7 @@ class PermissionsCrafty:
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def get_api_key_permissions_list(key: ApiKeys):
|
def get_api_key_permissions_list(key: ApiKeys):
|
||||||
user = HelperUsers.get_user(key.user_id)
|
user = HelperUsers.get_user(key.user_id)
|
||||||
if user["superuser"] and key.superuser:
|
if user["superuser"] and key.full_access:
|
||||||
return PermissionsCrafty.get_permissions_list()
|
return PermissionsCrafty.get_permissions_list()
|
||||||
if user["superuser"]:
|
if user["superuser"]:
|
||||||
# User is superuser but API key isn't
|
# User is superuser but API key isn't
|
||||||
|
@ -264,7 +264,7 @@ class PermissionsServers:
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def get_api_key_permissions_list(key: ApiKeys, server_id: str):
|
def get_api_key_permissions_list(key: ApiKeys, server_id: str):
|
||||||
user = HelperUsers.get_user(key.user_id)
|
user = HelperUsers.get_user(key.user_id)
|
||||||
if user["superuser"] and key.superuser:
|
if user["superuser"] and key.full_access:
|
||||||
return PermissionsServers.get_permissions_list()
|
return PermissionsServers.get_permissions_list()
|
||||||
roles_list = HelperUsers.get_user_roles_id(user["user_id"])
|
roles_list = HelperUsers.get_user_roles_id(user["user_id"])
|
||||||
role_server = (
|
role_server = (
|
||||||
|
@ -71,7 +71,7 @@ class ApiKeys(BaseModel):
|
|||||||
user_id = ForeignKeyField(Users, backref="api_token", index=True)
|
user_id = ForeignKeyField(Users, backref="api_token", index=True)
|
||||||
server_permissions = CharField(default="00000000")
|
server_permissions = CharField(default="00000000")
|
||||||
crafty_permissions = CharField(default="000")
|
crafty_permissions = CharField(default="000")
|
||||||
superuser = BooleanField(default=False)
|
full_access = BooleanField(default=False)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
table_name = "api_keys"
|
table_name = "api_keys"
|
||||||
@ -408,7 +408,7 @@ class HelperUsers:
|
|||||||
def add_user_api_key(
|
def add_user_api_key(
|
||||||
name: str,
|
name: str,
|
||||||
user_id: str,
|
user_id: str,
|
||||||
superuser: bool = False,
|
full_access: bool = False,
|
||||||
server_permissions_mask: t.Optional[str] = None,
|
server_permissions_mask: t.Optional[str] = None,
|
||||||
crafty_permissions_mask: t.Optional[str] = None,
|
crafty_permissions_mask: t.Optional[str] = None,
|
||||||
):
|
):
|
||||||
@ -426,7 +426,7 @@ class HelperUsers:
|
|||||||
if crafty_permissions_mask is not None
|
if crafty_permissions_mask is not None
|
||||||
else {}
|
else {}
|
||||||
),
|
),
|
||||||
ApiKeys.superuser: superuser,
|
ApiKeys.full_access: full_access,
|
||||||
}
|
}
|
||||||
).execute()
|
).execute()
|
||||||
|
|
||||||
|
@ -575,7 +575,7 @@ class Controller:
|
|||||||
):
|
):
|
||||||
server_obj = self.servers.get_server_obj(new_server_id)
|
server_obj = self.servers.get_server_obj(new_server_id)
|
||||||
url = (
|
url = (
|
||||||
"https://serverjars.com/api/fetchJar/"
|
"https://api.serverjars.com/api/fetchJar/"
|
||||||
f"{create_data['category']}"
|
f"{create_data['category']}"
|
||||||
f"/{create_data['type']}/{create_data['version']}"
|
f"/{create_data['type']}/{create_data['version']}"
|
||||||
)
|
)
|
||||||
@ -1131,7 +1131,7 @@ class Controller:
|
|||||||
server_obj.path = new_local_server_path
|
server_obj.path = new_local_server_path
|
||||||
failed = False
|
failed = False
|
||||||
for s in self.servers.failed_servers:
|
for s in self.servers.failed_servers:
|
||||||
if int(s["server_id"]) == int(server.get("server_id")):
|
if s["server_id"] == server.get("server_id"):
|
||||||
failed = True
|
failed = True
|
||||||
if not failed:
|
if not failed:
|
||||||
self.servers.update_server(server_obj)
|
self.servers.update_server(server_obj)
|
||||||
|
@ -372,11 +372,11 @@ class MigrationManager(object):
|
|||||||
Create migrator
|
Create migrator
|
||||||
"""
|
"""
|
||||||
migrator = Migrator(self.database)
|
migrator = Migrator(self.database)
|
||||||
# Removing the up_one to prevent running all
|
# Running false migrations to retrives the schemes of
|
||||||
# migrations each time we got a new one.
|
# the precedents created tables in the table_dict element
|
||||||
# It's handled by migration.up() function.
|
# It's useful to run the new migrations
|
||||||
# for name in self.done:
|
for name in self.done:
|
||||||
# self.up_one(name, migrator, True)
|
self.up_one(name, migrator, True)
|
||||||
return migrator
|
return migrator
|
||||||
|
|
||||||
def compile(self, name, migrate="", rollback=""):
|
def compile(self, name, migrate="", rollback=""):
|
||||||
|
@ -182,6 +182,7 @@ class BaseHandler(tornado.web.RequestHandler):
|
|||||||
t.List[str],
|
t.List[str],
|
||||||
bool,
|
bool,
|
||||||
t.Dict[str, t.Any],
|
t.Dict[str, t.Any],
|
||||||
|
str,
|
||||||
]
|
]
|
||||||
]:
|
]:
|
||||||
try:
|
try:
|
||||||
@ -190,9 +191,10 @@ class BaseHandler(tornado.web.RequestHandler):
|
|||||||
)
|
)
|
||||||
|
|
||||||
superuser = user["superuser"]
|
superuser = user["superuser"]
|
||||||
|
server_permissions_api_mask = ""
|
||||||
if api_key is not None:
|
if api_key is not None:
|
||||||
superuser = superuser and api_key.superuser
|
superuser = superuser and api_key.full_access
|
||||||
|
server_permissions_api_mask = api_key.server_permissions
|
||||||
exec_user_role = set()
|
exec_user_role = set()
|
||||||
if superuser:
|
if superuser:
|
||||||
authorized_servers = self.controller.servers.get_all_defined_servers()
|
authorized_servers = self.controller.servers.get_all_defined_servers()
|
||||||
@ -214,6 +216,7 @@ class BaseHandler(tornado.web.RequestHandler):
|
|||||||
user["user_id"]
|
user["user_id"]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
logger.debug(user["roles"])
|
logger.debug(user["roles"])
|
||||||
for r in user["roles"]:
|
for r in user["roles"]:
|
||||||
role = self.controller.roles.get_role(r)
|
role = self.controller.roles.get_role(r)
|
||||||
@ -234,6 +237,7 @@ class BaseHandler(tornado.web.RequestHandler):
|
|||||||
exec_user_role,
|
exec_user_role,
|
||||||
superuser,
|
superuser,
|
||||||
user,
|
user,
|
||||||
|
server_permissions_api_mask,
|
||||||
)
|
)
|
||||||
logging.debug("Auth unsuccessful")
|
logging.debug("Auth unsuccessful")
|
||||||
auth_log.error(
|
auth_log.error(
|
||||||
|
@ -168,7 +168,7 @@ class PanelHandler(BaseHandler):
|
|||||||
# Commented out because there is no server access control for API keys,
|
# Commented out because there is no server access control for API keys,
|
||||||
# they just inherit from the host user
|
# they just inherit from the host user
|
||||||
# if api_key is not None:
|
# if api_key is not None:
|
||||||
# superuser = superuser and api_key.superuser
|
# superuser = superuser and api_key.full_access
|
||||||
|
|
||||||
if server_id is None:
|
if server_id is None:
|
||||||
self.redirect("/panel/error?error=Invalid Server ID")
|
self.redirect("/panel/error?error=Invalid Server ID")
|
||||||
@ -242,7 +242,7 @@ class PanelHandler(BaseHandler):
|
|||||||
api_key, _token_data, exec_user = self.current_user
|
api_key, _token_data, exec_user = self.current_user
|
||||||
superuser = exec_user["superuser"]
|
superuser = exec_user["superuser"]
|
||||||
if api_key is not None:
|
if api_key is not None:
|
||||||
superuser = superuser and api_key.superuser
|
superuser = superuser and api_key.full_access
|
||||||
|
|
||||||
if superuser: # TODO: Figure out a better solution
|
if superuser: # TODO: Figure out a better solution
|
||||||
defined_servers = self.controller.servers.list_defined_servers()
|
defined_servers = self.controller.servers.list_defined_servers()
|
||||||
@ -351,7 +351,7 @@ class PanelHandler(BaseHandler):
|
|||||||
"created": api_key.created,
|
"created": api_key.created,
|
||||||
"server_permissions": api_key.server_permissions,
|
"server_permissions": api_key.server_permissions,
|
||||||
"crafty_permissions": api_key.crafty_permissions,
|
"crafty_permissions": api_key.crafty_permissions,
|
||||||
"superuser": api_key.superuser,
|
"full_access": api_key.full_access,
|
||||||
}
|
}
|
||||||
if api_key is not None
|
if api_key is not None
|
||||||
else None
|
else None
|
||||||
@ -1356,6 +1356,9 @@ class PanelHandler(BaseHandler):
|
|||||||
page_data["crafty_permissions_all"] = (
|
page_data["crafty_permissions_all"] = (
|
||||||
self.controller.crafty_perms.list_defined_crafty_permissions()
|
self.controller.crafty_perms.list_defined_crafty_permissions()
|
||||||
)
|
)
|
||||||
|
page_data["user_crafty_permissions"] = (
|
||||||
|
self.controller.crafty_perms.get_crafty_permissions_list(user_id)
|
||||||
|
)
|
||||||
|
|
||||||
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")
|
||||||
@ -1403,7 +1406,7 @@ class PanelHandler(BaseHandler):
|
|||||||
self.controller.management.add_to_audit_log(
|
self.controller.management.add_to_audit_log(
|
||||||
exec_user["user_id"],
|
exec_user["user_id"],
|
||||||
f"Removed user {target_user['username']} (UID:{user_id})",
|
f"Removed user {target_user['username']} (UID:{user_id})",
|
||||||
server_id=0,
|
server_id=None,
|
||||||
source_ip=self.get_remote_ip(),
|
source_ip=self.get_remote_ip(),
|
||||||
)
|
)
|
||||||
self.redirect("/panel/panel_config")
|
self.redirect("/panel/panel_config")
|
||||||
|
@ -228,7 +228,7 @@ class PublicHandler(BaseHandler):
|
|||||||
)
|
)
|
||||||
# log this login
|
# log this login
|
||||||
self.controller.management.add_to_audit_log(
|
self.controller.management.add_to_audit_log(
|
||||||
user_data.user_id, "Logged in", 0, self.get_remote_ip()
|
user_data.user_id, "Logged in", None, self.get_remote_ip()
|
||||||
)
|
)
|
||||||
|
|
||||||
return self.finish_json(
|
return self.finish_json(
|
||||||
@ -254,7 +254,7 @@ class PublicHandler(BaseHandler):
|
|||||||
)
|
)
|
||||||
# log this failed login attempt
|
# log this failed login attempt
|
||||||
self.controller.management.add_to_audit_log(
|
self.controller.management.add_to_audit_log(
|
||||||
user_data.user_id, "Tried to log in", 0, self.get_remote_ip()
|
user_data.user_id, "Tried to log in", None, self.get_remote_ip()
|
||||||
)
|
)
|
||||||
return self.finish_json(
|
return self.finish_json(
|
||||||
403,
|
403,
|
||||||
|
@ -101,7 +101,7 @@ class ApiAuthLoginHandler(BaseApiHandler):
|
|||||||
|
|
||||||
# log this login
|
# log this login
|
||||||
self.controller.management.add_to_audit_log(
|
self.controller.management.add_to_audit_log(
|
||||||
user_data.user_id, "logged in via the API", 0, self.get_remote_ip()
|
user_data.user_id, "logged in via the API", None, self.get_remote_ip()
|
||||||
)
|
)
|
||||||
|
|
||||||
self.finish_json(
|
self.finish_json(
|
||||||
@ -119,7 +119,7 @@ class ApiAuthLoginHandler(BaseApiHandler):
|
|||||||
else:
|
else:
|
||||||
# log this failed login attempt
|
# log this failed login attempt
|
||||||
self.controller.management.add_to_audit_log(
|
self.controller.management.add_to_audit_log(
|
||||||
user_data.user_id, "Tried to log in", 0, self.get_remote_ip()
|
user_data.user_id, "Tried to log in", None, self.get_remote_ip()
|
||||||
)
|
)
|
||||||
self.finish_json(
|
self.finish_json(
|
||||||
401,
|
401,
|
||||||
|
@ -9,7 +9,6 @@ from app.classes.web.base_api_handler import BaseApiHandler
|
|||||||
config_json_schema = {
|
config_json_schema = {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"http_port": {"type": "integer"},
|
|
||||||
"https_port": {"type": "integer"},
|
"https_port": {"type": "integer"},
|
||||||
"language": {
|
"language": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
@ -107,7 +106,7 @@ class ApiCraftyConfigIndexHandler(BaseApiHandler):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
data = orjson.loads(self.request.body)
|
data = orjson.loads(self.request.body)
|
||||||
except orjson.decoder.JSONDecodeError as e:
|
except orjson.JSONDecodeError as e:
|
||||||
return self.finish_json(
|
return self.finish_json(
|
||||||
400, {"status": "error", "error": "INVALID_JSON", "error_data": str(e)}
|
400, {"status": "error", "error": "INVALID_JSON", "error_data": str(e)}
|
||||||
)
|
)
|
||||||
@ -129,7 +128,7 @@ class ApiCraftyConfigIndexHandler(BaseApiHandler):
|
|||||||
self.controller.management.add_to_audit_log(
|
self.controller.management.add_to_audit_log(
|
||||||
user["user_id"],
|
user["user_id"],
|
||||||
"edited config.json",
|
"edited config.json",
|
||||||
server_id=0,
|
server_id=None,
|
||||||
source_ip=self.get_remote_ip(),
|
source_ip=self.get_remote_ip(),
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -188,7 +187,7 @@ class ApiCraftyCustomizeIndexHandler(BaseApiHandler):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
data = orjson.loads(self.request.body)
|
data = orjson.loads(self.request.body)
|
||||||
except orjson.decoder.JSONDecodeError as e:
|
except orjson.JSONDecodeError as e:
|
||||||
return self.finish_json(
|
return self.finish_json(
|
||||||
400, {"status": "error", "error": "INVALID_JSON", "error_data": str(e)}
|
400, {"status": "error", "error": "INVALID_JSON", "error_data": str(e)}
|
||||||
)
|
)
|
||||||
@ -226,7 +225,7 @@ class ApiCraftyCustomizeIndexHandler(BaseApiHandler):
|
|||||||
self.controller.management.add_to_audit_log(
|
self.controller.management.add_to_audit_log(
|
||||||
user["user_id"],
|
user["user_id"],
|
||||||
f"customized login photo: {data['photo']}/{data['opacity']}",
|
f"customized login photo: {data['photo']}/{data['opacity']}",
|
||||||
server_id=0,
|
server_id=None,
|
||||||
source_ip=self.get_remote_ip(),
|
source_ip=self.get_remote_ip(),
|
||||||
)
|
)
|
||||||
self.controller.management.set_login_opacity(int(data["opacity"]))
|
self.controller.management.set_login_opacity(int(data["opacity"]))
|
||||||
|
@ -68,7 +68,7 @@ class ApiCraftyConfigServerDirHandler(BaseApiHandler):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
data = orjson.loads(self.request.body)
|
data = orjson.loads(self.request.body)
|
||||||
except orjson.decoder.JSONDecodeError as e:
|
except orjson.JSONDecodeError as e:
|
||||||
return self.finish_json(
|
return self.finish_json(
|
||||||
400, {"status": "error", "error": "INVALID_JSON", "error_data": str(e)}
|
400, {"status": "error", "error": "INVALID_JSON", "error_data": str(e)}
|
||||||
)
|
)
|
||||||
@ -109,7 +109,7 @@ class ApiCraftyConfigServerDirHandler(BaseApiHandler):
|
|||||||
self.controller.management.add_to_audit_log(
|
self.controller.management.add_to_audit_log(
|
||||||
auth_data[4]["user_id"],
|
auth_data[4]["user_id"],
|
||||||
f"updated master servers dir to {new_dir}/servers",
|
f"updated master servers dir to {new_dir}/servers",
|
||||||
server_id=0,
|
server_id=None,
|
||||||
source_ip=self.get_remote_ip(),
|
source_ip=self.get_remote_ip(),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -161,7 +161,7 @@ class ApiRolesIndexHandler(BaseApiHandler):
|
|||||||
self.controller.management.add_to_audit_log(
|
self.controller.management.add_to_audit_log(
|
||||||
user["user_id"],
|
user["user_id"],
|
||||||
f"created role {role_name} (RID:{role_id})",
|
f"created role {role_name} (RID:{role_id})",
|
||||||
server_id=0,
|
server_id=None,
|
||||||
source_ip=self.get_remote_ip(),
|
source_ip=self.get_remote_ip(),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ class ApiRolesRoleIndexHandler(BaseApiHandler):
|
|||||||
self.controller.management.add_to_audit_log(
|
self.controller.management.add_to_audit_log(
|
||||||
user["user_id"],
|
user["user_id"],
|
||||||
f"deleted role with ID {role_id}",
|
f"deleted role with ID {role_id}",
|
||||||
server_id=0,
|
server_id=None,
|
||||||
source_ip=self.get_remote_ip(),
|
source_ip=self.get_remote_ip(),
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -133,7 +133,7 @@ class ApiRolesRoleIndexHandler(BaseApiHandler):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
data = orjson.loads(self.request.body)
|
data = orjson.loads(self.request.body)
|
||||||
except orjson.decoder.JSONDecodeError as e:
|
except orjson.JSONDecodeError as e:
|
||||||
return self.finish_json(
|
return self.finish_json(
|
||||||
400, {"status": "error", "error": "INVALID_JSON", "error_data": str(e)}
|
400, {"status": "error", "error": "INVALID_JSON", "error_data": str(e)}
|
||||||
)
|
)
|
||||||
@ -172,7 +172,7 @@ class ApiRolesRoleIndexHandler(BaseApiHandler):
|
|||||||
self.controller.management.add_to_audit_log(
|
self.controller.management.add_to_audit_log(
|
||||||
user["user_id"],
|
user["user_id"],
|
||||||
f"modified role with ID {role_id}",
|
f"modified role with ID {role_id}",
|
||||||
server_id=0,
|
server_id=None,
|
||||||
source_ip=self.get_remote_ip(),
|
source_ip=self.get_remote_ip(),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -18,13 +18,14 @@ class ApiServersServerActionHandler(BaseApiHandler):
|
|||||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||||
# if the user doesn't have access to the server, return an error
|
# if the user doesn't have access to the server, return an error
|
||||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||||
|
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||||
if (
|
self.controller.server_perms.get_user_permissions_mask(
|
||||||
EnumPermissionsServer.COMMANDS
|
|
||||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
|
||||||
auth_data[4]["user_id"], server_id
|
auth_data[4]["user_id"], server_id
|
||||||
)
|
),
|
||||||
):
|
auth_data[5],
|
||||||
|
)
|
||||||
|
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||||
|
if EnumPermissionsServer.COMMANDS not in server_permissions:
|
||||||
# if the user doesn't have Commands permission, return an error
|
# if the user doesn't have Commands permission, return an error
|
||||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||||
|
|
||||||
@ -33,6 +34,17 @@ class ApiServersServerActionHandler(BaseApiHandler):
|
|||||||
self.controller.crafty_perms.can_create_server(auth_data[4]["user_id"])
|
self.controller.crafty_perms.can_create_server(auth_data[4]["user_id"])
|
||||||
or auth_data[4]["superuser"]
|
or auth_data[4]["superuser"]
|
||||||
):
|
):
|
||||||
|
srv_object = self.controller.servers.get_server_instance_by_id(
|
||||||
|
server_id
|
||||||
|
)
|
||||||
|
if srv_object.check_running():
|
||||||
|
return self.finish_json(
|
||||||
|
409,
|
||||||
|
{
|
||||||
|
"status": "error",
|
||||||
|
"error": "Server Running!",
|
||||||
|
},
|
||||||
|
)
|
||||||
self._clone_server(server_id, auth_data[4]["user_id"])
|
self._clone_server(server_id, auth_data[4]["user_id"])
|
||||||
return self.finish_json(200, {"status": "ok"})
|
return self.finish_json(200, {"status": "ok"})
|
||||||
return self.finish_json(
|
return self.finish_json(
|
||||||
@ -67,20 +79,29 @@ class ApiServersServerActionHandler(BaseApiHandler):
|
|||||||
name_counter += 1
|
name_counter += 1
|
||||||
new_server_name = server_data.get("server_name") + f" (Copy {name_counter})"
|
new_server_name = server_data.get("server_name") + f" (Copy {name_counter})"
|
||||||
|
|
||||||
new_server_id = self.controller.servers.create_server(
|
new_server_id = self.helper.create_uuid()
|
||||||
new_server_name,
|
new_server_path = os.path.join(self.helper.servers_dir, new_server_id)
|
||||||
None,
|
new_backup_path = os.path.join(self.helper.backup_path, new_server_id)
|
||||||
"",
|
new_server_command = str(server_data.get("execution_command")).replace(
|
||||||
None,
|
server_id, new_server_id
|
||||||
server_data.get("executable"),
|
)
|
||||||
None,
|
new_server_log_path = server_data.get("log_path").replace(
|
||||||
server_data.get("stop_command"),
|
server_id, new_server_id
|
||||||
server_data.get("type"),
|
|
||||||
user_id,
|
|
||||||
server_data.get("server_port"),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
new_server_path = os.path.join(self.helper.servers_dir, new_server_id)
|
self.controller.register_server(
|
||||||
|
new_server_name,
|
||||||
|
new_server_id,
|
||||||
|
new_server_path,
|
||||||
|
new_backup_path,
|
||||||
|
new_server_command,
|
||||||
|
server_data.get("executable"),
|
||||||
|
new_server_log_path,
|
||||||
|
server_data.get("stop_command"),
|
||||||
|
server_data.get("server_port"),
|
||||||
|
user_id,
|
||||||
|
server_data.get("type"),
|
||||||
|
)
|
||||||
|
|
||||||
self.controller.management.add_to_audit_log(
|
self.controller.management.add_to_audit_log(
|
||||||
user_id,
|
user_id,
|
||||||
@ -92,18 +113,6 @@ class ApiServersServerActionHandler(BaseApiHandler):
|
|||||||
# copy the old server
|
# copy the old server
|
||||||
FileHelpers.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
|
|
||||||
new_server_command = str(server_data.get("execution_command"))
|
|
||||||
new_server_log_file = str(
|
|
||||||
self.helper.get_os_understandable_path(server_data.get("log_path"))
|
|
||||||
)
|
|
||||||
|
|
||||||
server: Servers = self.controller.servers.get_server_obj(new_server_id)
|
|
||||||
server.path = new_server_path
|
|
||||||
server.log_path = new_server_log_file
|
|
||||||
server.execution_command = new_server_command
|
|
||||||
self.controller.servers.update_server(server)
|
|
||||||
|
|
||||||
for role in self.controller.server_perms.get_server_roles(server_id):
|
for role in self.controller.server_perms.get_server_roles(server_id):
|
||||||
mask = self.controller.server_perms.get_permissions_mask(
|
mask = self.controller.server_perms.get_permissions_mask(
|
||||||
role.role_id, server_id
|
role.role_id, server_id
|
||||||
|
@ -26,12 +26,14 @@ class ApiServersServerBackupsBackupIndexHandler(BaseApiHandler):
|
|||||||
auth_data = self.authenticate_user()
|
auth_data = self.authenticate_user()
|
||||||
if not auth_data:
|
if not auth_data:
|
||||||
return
|
return
|
||||||
if (
|
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||||
EnumPermissionsServer.BACKUP
|
self.controller.server_perms.get_user_permissions_mask(
|
||||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
|
||||||
auth_data[4]["user_id"], server_id
|
auth_data[4]["user_id"], server_id
|
||||||
)
|
),
|
||||||
):
|
auth_data[5],
|
||||||
|
)
|
||||||
|
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||||
|
if EnumPermissionsServer.BACKUP not in server_permissions:
|
||||||
# if the user doesn't have Schedule permission, return an error
|
# if the user doesn't have Schedule permission, return an error
|
||||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||||
self.finish_json(200, self.controller.management.get_backup_config(server_id))
|
self.finish_json(200, self.controller.management.get_backup_config(server_id))
|
||||||
@ -41,12 +43,14 @@ class ApiServersServerBackupsBackupIndexHandler(BaseApiHandler):
|
|||||||
backup_conf = self.controller.management.get_backup_config(server_id)
|
backup_conf = self.controller.management.get_backup_config(server_id)
|
||||||
if not auth_data:
|
if not auth_data:
|
||||||
return
|
return
|
||||||
if (
|
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||||
EnumPermissionsServer.BACKUP
|
self.controller.server_perms.get_user_permissions_mask(
|
||||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
|
||||||
auth_data[4]["user_id"], server_id
|
auth_data[4]["user_id"], server_id
|
||||||
)
|
),
|
||||||
):
|
auth_data[5],
|
||||||
|
)
|
||||||
|
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||||
|
if EnumPermissionsServer.BACKUP not in server_permissions:
|
||||||
# if the user doesn't have Schedule permission, return an error
|
# if the user doesn't have Schedule permission, return an error
|
||||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||||
|
|
||||||
@ -89,12 +93,14 @@ class ApiServersServerBackupsBackupIndexHandler(BaseApiHandler):
|
|||||||
auth_data = self.authenticate_user()
|
auth_data = self.authenticate_user()
|
||||||
if not auth_data:
|
if not auth_data:
|
||||||
return
|
return
|
||||||
if (
|
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||||
EnumPermissionsServer.BACKUP
|
self.controller.server_perms.get_user_permissions_mask(
|
||||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
|
||||||
auth_data[4]["user_id"], server_id
|
auth_data[4]["user_id"], server_id
|
||||||
)
|
),
|
||||||
):
|
auth_data[5],
|
||||||
|
)
|
||||||
|
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||||
|
if EnumPermissionsServer.BACKUP not in server_permissions:
|
||||||
# if the user doesn't have Schedule permission, return an error
|
# if the user doesn't have Schedule permission, return an error
|
||||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||||
|
|
||||||
@ -203,7 +209,7 @@ class ApiServersServerBackupsBackupIndexHandler(BaseApiHandler):
|
|||||||
except JobLookupError as e:
|
except JobLookupError as e:
|
||||||
logger.info("No active tasks found for server: {e}")
|
logger.info("No active tasks found for server: {e}")
|
||||||
self.controller.remove_server(server_id, True)
|
self.controller.remove_server(server_id, True)
|
||||||
except Exception as e:
|
except (FileNotFoundError, NotADirectoryError) as e:
|
||||||
return self.finish_json(
|
return self.finish_json(
|
||||||
400, {"status": "error", "error": f"NO BACKUP FOUND {e}"}
|
400, {"status": "error", "error": f"NO BACKUP FOUND {e}"}
|
||||||
)
|
)
|
||||||
|
@ -42,12 +42,14 @@ class ApiServersServerBackupsIndexHandler(BaseApiHandler):
|
|||||||
auth_data = self.authenticate_user()
|
auth_data = self.authenticate_user()
|
||||||
if not auth_data:
|
if not auth_data:
|
||||||
return
|
return
|
||||||
if (
|
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||||
EnumPermissionsServer.BACKUP
|
self.controller.server_perms.get_user_permissions_mask(
|
||||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
|
||||||
auth_data[4]["user_id"], server_id
|
auth_data[4]["user_id"], server_id
|
||||||
)
|
),
|
||||||
):
|
auth_data[5],
|
||||||
|
)
|
||||||
|
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||||
|
if EnumPermissionsServer.BACKUP not in server_permissions:
|
||||||
# if the user doesn't have Schedule permission, return an error
|
# if the user doesn't have Schedule permission, return an error
|
||||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||||
self.finish_json(200, self.controller.management.get_backup_config(server_id))
|
self.finish_json(200, self.controller.management.get_backup_config(server_id))
|
||||||
@ -82,13 +84,14 @@ class ApiServersServerBackupsIndexHandler(BaseApiHandler):
|
|||||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||||
# if the user doesn't have access to the server, return an error
|
# if the user doesn't have access to the server, return an error
|
||||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||||
|
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||||
if (
|
self.controller.server_perms.get_user_permissions_mask(
|
||||||
EnumPermissionsServer.BACKUP
|
|
||||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
|
||||||
auth_data[4]["user_id"], server_id
|
auth_data[4]["user_id"], server_id
|
||||||
)
|
),
|
||||||
):
|
auth_data[5],
|
||||||
|
)
|
||||||
|
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||||
|
if EnumPermissionsServer.BACKUP not in server_permissions:
|
||||||
# if the user doesn't have Schedule permission, return an error
|
# if the user doesn't have Schedule permission, return an error
|
||||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||||
|
|
||||||
|
@ -80,16 +80,16 @@ class ApiServersServerFilesIndexHandler(BaseApiHandler):
|
|||||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||||
# if the user doesn't have access to the server, return an error
|
# if the user doesn't have access to the server, return an error
|
||||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||||
|
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||||
|
self.controller.server_perms.get_user_permissions_mask(
|
||||||
|
auth_data[4]["user_id"], server_id
|
||||||
|
),
|
||||||
|
auth_data[5],
|
||||||
|
)
|
||||||
|
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||||
if (
|
if (
|
||||||
EnumPermissionsServer.FILES
|
EnumPermissionsServer.FILES not in server_permissions
|
||||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
and EnumPermissionsServer.BACKUP not in server_permissions
|
||||||
auth_data[4]["user_id"], server_id
|
|
||||||
)
|
|
||||||
and EnumPermissionsServer.BACKUP
|
|
||||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
|
||||||
auth_data[4]["user_id"], server_id
|
|
||||||
)
|
|
||||||
):
|
):
|
||||||
# if the user doesn't have Files or Backup permission, return an error
|
# if the user doesn't have Files or Backup permission, return an error
|
||||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||||
@ -197,13 +197,14 @@ class ApiServersServerFilesIndexHandler(BaseApiHandler):
|
|||||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||||
# if the user doesn't have access to the server, return an error
|
# if the user doesn't have access to the server, return an error
|
||||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||||
|
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||||
if (
|
self.controller.server_perms.get_user_permissions_mask(
|
||||||
EnumPermissionsServer.FILES
|
|
||||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
|
||||||
auth_data[4]["user_id"], server_id
|
auth_data[4]["user_id"], server_id
|
||||||
)
|
),
|
||||||
):
|
auth_data[5],
|
||||||
|
)
|
||||||
|
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||||
|
if EnumPermissionsServer.FILES not in server_permissions:
|
||||||
# if the user doesn't have Files permission, return an error
|
# if the user doesn't have Files permission, return an error
|
||||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||||
try:
|
try:
|
||||||
@ -254,13 +255,14 @@ class ApiServersServerFilesIndexHandler(BaseApiHandler):
|
|||||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||||
# if the user doesn't have access to the server, return an error
|
# if the user doesn't have access to the server, return an error
|
||||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||||
|
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||||
if (
|
self.controller.server_perms.get_user_permissions_mask(
|
||||||
EnumPermissionsServer.FILES
|
|
||||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
|
||||||
auth_data[4]["user_id"], server_id
|
auth_data[4]["user_id"], server_id
|
||||||
)
|
),
|
||||||
):
|
auth_data[5],
|
||||||
|
)
|
||||||
|
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||||
|
if EnumPermissionsServer.FILES not in server_permissions:
|
||||||
# if the user doesn't have Files permission, return an error
|
# if the user doesn't have Files permission, return an error
|
||||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||||
try:
|
try:
|
||||||
@ -307,13 +309,14 @@ class ApiServersServerFilesIndexHandler(BaseApiHandler):
|
|||||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||||
# if the user doesn't have access to the server, return an error
|
# if the user doesn't have access to the server, return an error
|
||||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||||
|
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||||
if (
|
self.controller.server_perms.get_user_permissions_mask(
|
||||||
EnumPermissionsServer.FILES
|
|
||||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
|
||||||
auth_data[4]["user_id"], server_id
|
auth_data[4]["user_id"], server_id
|
||||||
)
|
),
|
||||||
):
|
auth_data[5],
|
||||||
|
)
|
||||||
|
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||||
|
if EnumPermissionsServer.FILES not in server_permissions:
|
||||||
# if the user doesn't have Files permission, return an error
|
# if the user doesn't have Files permission, return an error
|
||||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||||
try:
|
try:
|
||||||
@ -373,13 +376,14 @@ class ApiServersServerFilesCreateHandler(BaseApiHandler):
|
|||||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||||
# if the user doesn't have access to the server, return an error
|
# if the user doesn't have access to the server, return an error
|
||||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||||
|
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||||
if (
|
self.controller.server_perms.get_user_permissions_mask(
|
||||||
EnumPermissionsServer.FILES
|
|
||||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
|
||||||
auth_data[4]["user_id"], server_id
|
auth_data[4]["user_id"], server_id
|
||||||
)
|
),
|
||||||
):
|
auth_data[5],
|
||||||
|
)
|
||||||
|
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||||
|
if EnumPermissionsServer.FILES not in server_permissions:
|
||||||
# if the user doesn't have Files permission, return an error
|
# if the user doesn't have Files permission, return an error
|
||||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||||
try:
|
try:
|
||||||
@ -438,13 +442,14 @@ class ApiServersServerFilesCreateHandler(BaseApiHandler):
|
|||||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||||
# if the user doesn't have access to the server, return an error
|
# if the user doesn't have access to the server, return an error
|
||||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||||
|
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||||
if (
|
self.controller.server_perms.get_user_permissions_mask(
|
||||||
EnumPermissionsServer.FILES
|
|
||||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
|
||||||
auth_data[4]["user_id"], server_id
|
auth_data[4]["user_id"], server_id
|
||||||
)
|
),
|
||||||
):
|
auth_data[5],
|
||||||
|
)
|
||||||
|
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||||
|
if EnumPermissionsServer.FILES not in server_permissions:
|
||||||
# if the user doesn't have Files permission, return an error
|
# if the user doesn't have Files permission, return an error
|
||||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||||
try:
|
try:
|
||||||
@ -504,13 +509,14 @@ class ApiServersServerFilesZipHandler(BaseApiHandler):
|
|||||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||||
# if the user doesn't have access to the server, return an error
|
# if the user doesn't have access to the server, return an error
|
||||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||||
|
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||||
if (
|
self.controller.server_perms.get_user_permissions_mask(
|
||||||
EnumPermissionsServer.FILES
|
|
||||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
|
||||||
auth_data[4]["user_id"], server_id
|
auth_data[4]["user_id"], server_id
|
||||||
)
|
),
|
||||||
):
|
auth_data[5],
|
||||||
|
)
|
||||||
|
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||||
|
if EnumPermissionsServer.FILES not in server_permissions:
|
||||||
# if the user doesn't have Files permission, return an error
|
# if the user doesn't have Files permission, return an error
|
||||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||||
try:
|
try:
|
||||||
|
@ -102,13 +102,14 @@ class ApiServersServerIndexHandler(BaseApiHandler):
|
|||||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||||
# if the user doesn't have access to the server, return an error
|
# if the user doesn't have access to the server, return an error
|
||||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||||
|
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||||
if (
|
self.controller.server_perms.get_user_permissions_mask(
|
||||||
EnumPermissionsServer.CONFIG
|
|
||||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
|
||||||
auth_data[4]["user_id"], server_id
|
auth_data[4]["user_id"], server_id
|
||||||
)
|
),
|
||||||
):
|
auth_data[5],
|
||||||
|
)
|
||||||
|
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||||
|
if EnumPermissionsServer.CONFIG not in server_permissions:
|
||||||
# if the user doesn't have Config permission, return an error
|
# if the user doesn't have Config permission, return an error
|
||||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||||
|
|
||||||
@ -154,13 +155,14 @@ class ApiServersServerIndexHandler(BaseApiHandler):
|
|||||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||||
# if the user doesn't have access to the server, return an error
|
# if the user doesn't have access to the server, return an error
|
||||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||||
|
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||||
if (
|
self.controller.server_perms.get_user_permissions_mask(
|
||||||
EnumPermissionsServer.CONFIG
|
|
||||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
|
||||||
auth_data[4]["user_id"], server_id
|
auth_data[4]["user_id"], server_id
|
||||||
)
|
),
|
||||||
):
|
auth_data[5],
|
||||||
|
)
|
||||||
|
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||||
|
if EnumPermissionsServer.CONFIG not in server_permissions:
|
||||||
# if the user doesn't have Config permission, return an error
|
# if the user doesn't have Config permission, return an error
|
||||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||||
|
|
||||||
|
@ -30,13 +30,14 @@ class ApiServersServerLogsHandler(BaseApiHandler):
|
|||||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||||
# if the user doesn't have access to the server, return an error
|
# if the user doesn't have access to the server, return an error
|
||||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||||
|
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||||
if (
|
self.controller.server_perms.get_user_permissions_mask(
|
||||||
EnumPermissionsServer.LOGS
|
|
||||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
|
||||||
auth_data[4]["user_id"], server_id
|
auth_data[4]["user_id"], server_id
|
||||||
)
|
),
|
||||||
):
|
auth_data[5],
|
||||||
|
)
|
||||||
|
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||||
|
if EnumPermissionsServer.LOGS not in server_permissions:
|
||||||
# if the user doesn't have Logs permission, return an error
|
# if the user doesn't have Logs permission, return an error
|
||||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||||
|
|
||||||
|
@ -16,13 +16,14 @@ class ApiServersServerStdinHandler(BaseApiHandler):
|
|||||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||||
# if the user doesn't have access to the server, return an error
|
# if the user doesn't have access to the server, return an error
|
||||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||||
|
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||||
if (
|
self.controller.server_perms.get_user_permissions_mask(
|
||||||
EnumPermissionsServer.COMMANDS
|
|
||||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
|
||||||
auth_data[4]["user_id"], server_id
|
auth_data[4]["user_id"], server_id
|
||||||
)
|
),
|
||||||
):
|
auth_data[5],
|
||||||
|
)
|
||||||
|
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||||
|
if EnumPermissionsServer.COMMANDS not in server_permissions:
|
||||||
# if the user doesn't have Commands permission, return an error
|
# if the user doesn't have Commands permission, return an error
|
||||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||||
|
|
||||||
|
@ -78,13 +78,14 @@ class ApiServersServerTasksIndexHandler(BaseApiHandler):
|
|||||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||||
# if the user doesn't have access to the server, return an error
|
# if the user doesn't have access to the server, return an error
|
||||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||||
|
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||||
if (
|
self.controller.server_perms.get_user_permissions_mask(
|
||||||
EnumPermissionsServer.SCHEDULE
|
|
||||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
|
||||||
auth_data[4]["user_id"], server_id
|
auth_data[4]["user_id"], server_id
|
||||||
)
|
),
|
||||||
):
|
auth_data[5],
|
||||||
|
)
|
||||||
|
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||||
|
if EnumPermissionsServer.SCHEDULE not in server_permissions:
|
||||||
# if the user doesn't have Schedule permission, return an error
|
# if the user doesn't have Schedule permission, return an error
|
||||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||||
data["server_id"] = server_id
|
data["server_id"] = server_id
|
||||||
|
@ -54,12 +54,14 @@ class ApiServersServerTasksTaskIndexHandler(BaseApiHandler):
|
|||||||
auth_data = self.authenticate_user()
|
auth_data = self.authenticate_user()
|
||||||
if not auth_data:
|
if not auth_data:
|
||||||
return
|
return
|
||||||
if (
|
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||||
EnumPermissionsServer.SCHEDULE
|
self.controller.server_perms.get_user_permissions_mask(
|
||||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
|
||||||
auth_data[4]["user_id"], server_id
|
auth_data[4]["user_id"], server_id
|
||||||
)
|
),
|
||||||
):
|
auth_data[5],
|
||||||
|
)
|
||||||
|
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||||
|
if EnumPermissionsServer.SCHEDULE not in server_permissions:
|
||||||
# if the user doesn't have Schedule permission, return an error
|
# if the user doesn't have Schedule permission, return an error
|
||||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||||
self.finish_json(200, self.controller.management.get_scheduled_task(task_id))
|
self.finish_json(200, self.controller.management.get_scheduled_task(task_id))
|
||||||
@ -68,12 +70,14 @@ class ApiServersServerTasksTaskIndexHandler(BaseApiHandler):
|
|||||||
auth_data = self.authenticate_user()
|
auth_data = self.authenticate_user()
|
||||||
if not auth_data:
|
if not auth_data:
|
||||||
return
|
return
|
||||||
if (
|
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||||
EnumPermissionsServer.SCHEDULE
|
self.controller.server_perms.get_user_permissions_mask(
|
||||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
|
||||||
auth_data[4]["user_id"], server_id
|
auth_data[4]["user_id"], server_id
|
||||||
)
|
),
|
||||||
):
|
auth_data[5],
|
||||||
|
)
|
||||||
|
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||||
|
if EnumPermissionsServer.SCHEDULE not in server_permissions:
|
||||||
# if the user doesn't have Schedule permission, return an error
|
# if the user doesn't have Schedule permission, return an error
|
||||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||||
|
|
||||||
@ -120,13 +124,14 @@ class ApiServersServerTasksTaskIndexHandler(BaseApiHandler):
|
|||||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||||
# if the user doesn't have access to the server, return an error
|
# if the user doesn't have access to the server, return an error
|
||||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||||
|
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||||
if (
|
self.controller.server_perms.get_user_permissions_mask(
|
||||||
EnumPermissionsServer.SCHEDULE
|
|
||||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
|
||||||
auth_data[4]["user_id"], server_id
|
auth_data[4]["user_id"], server_id
|
||||||
)
|
),
|
||||||
):
|
auth_data[5],
|
||||||
|
)
|
||||||
|
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||||
|
if EnumPermissionsServer.SCHEDULE not in server_permissions:
|
||||||
# if the user doesn't have Schedule permission, return an error
|
# if the user doesn't have Schedule permission, return an error
|
||||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||||
|
|
||||||
|
@ -38,12 +38,14 @@ class ApiServersServerWebhooksIndexHandler(BaseApiHandler):
|
|||||||
auth_data = self.authenticate_user()
|
auth_data = self.authenticate_user()
|
||||||
if not auth_data:
|
if not auth_data:
|
||||||
return
|
return
|
||||||
if (
|
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||||
EnumPermissionsServer.CONFIG
|
self.controller.server_perms.get_user_permissions_mask(
|
||||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
|
||||||
auth_data[4]["user_id"], server_id
|
auth_data[4]["user_id"], server_id
|
||||||
)
|
),
|
||||||
):
|
auth_data[5],
|
||||||
|
)
|
||||||
|
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||||
|
if EnumPermissionsServer.CONFIG not in server_permissions:
|
||||||
# if the user doesn't have Schedule permission, return an error
|
# if the user doesn't have Schedule permission, return an error
|
||||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||||
self.finish_json(
|
self.finish_json(
|
||||||
@ -81,13 +83,14 @@ class ApiServersServerWebhooksIndexHandler(BaseApiHandler):
|
|||||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||||
# if the user doesn't have access to the server, return an error
|
# if the user doesn't have access to the server, return an error
|
||||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||||
|
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||||
if (
|
self.controller.server_perms.get_user_permissions_mask(
|
||||||
EnumPermissionsServer.CONFIG
|
|
||||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
|
||||||
auth_data[4]["user_id"], server_id
|
auth_data[4]["user_id"], server_id
|
||||||
)
|
),
|
||||||
):
|
auth_data[5],
|
||||||
|
)
|
||||||
|
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||||
|
if EnumPermissionsServer.CONFIG not in server_permissions:
|
||||||
# if the user doesn't have Schedule permission, return an error
|
# if the user doesn't have Schedule permission, return an error
|
||||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||||
data["server_id"] = server_id
|
data["server_id"] = server_id
|
||||||
|
@ -39,12 +39,14 @@ class ApiServersServerWebhooksManagementIndexHandler(BaseApiHandler):
|
|||||||
auth_data = self.authenticate_user()
|
auth_data = self.authenticate_user()
|
||||||
if not auth_data:
|
if not auth_data:
|
||||||
return
|
return
|
||||||
if (
|
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||||
EnumPermissionsServer.CONFIG
|
self.controller.server_perms.get_user_permissions_mask(
|
||||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
|
||||||
auth_data[4]["user_id"], server_id
|
auth_data[4]["user_id"], server_id
|
||||||
)
|
),
|
||||||
):
|
auth_data[5],
|
||||||
|
)
|
||||||
|
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||||
|
if EnumPermissionsServer.CONFIG not in server_permissions:
|
||||||
# if the user doesn't have Schedule permission, return an error
|
# if the user doesn't have Schedule permission, return an error
|
||||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||||
if (
|
if (
|
||||||
@ -66,12 +68,14 @@ class ApiServersServerWebhooksManagementIndexHandler(BaseApiHandler):
|
|||||||
auth_data = self.authenticate_user()
|
auth_data = self.authenticate_user()
|
||||||
if not auth_data:
|
if not auth_data:
|
||||||
return
|
return
|
||||||
if (
|
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||||
EnumPermissionsServer.CONFIG
|
self.controller.server_perms.get_user_permissions_mask(
|
||||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
|
||||||
auth_data[4]["user_id"], server_id
|
auth_data[4]["user_id"], server_id
|
||||||
)
|
),
|
||||||
):
|
auth_data[5],
|
||||||
|
)
|
||||||
|
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||||
|
if EnumPermissionsServer.CONFIG not in server_permissions:
|
||||||
# if the user doesn't have Schedule permission, return an error
|
# if the user doesn't have Schedule permission, return an error
|
||||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||||
|
|
||||||
@ -117,13 +121,14 @@ class ApiServersServerWebhooksManagementIndexHandler(BaseApiHandler):
|
|||||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||||
# if the user doesn't have access to the server, return an error
|
# if the user doesn't have access to the server, return an error
|
||||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||||
|
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||||
if (
|
self.controller.server_perms.get_user_permissions_mask(
|
||||||
EnumPermissionsServer.CONFIG
|
|
||||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
|
||||||
auth_data[4]["user_id"], server_id
|
auth_data[4]["user_id"], server_id
|
||||||
)
|
),
|
||||||
):
|
auth_data[5],
|
||||||
|
)
|
||||||
|
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||||
|
if EnumPermissionsServer.CONFIG not in server_permissions:
|
||||||
# if the user doesn't have Schedule permission, return an error
|
# if the user doesn't have Schedule permission, return an error
|
||||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||||
|
|
||||||
@ -159,13 +164,14 @@ class ApiServersServerWebhooksManagementIndexHandler(BaseApiHandler):
|
|||||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||||
# if the user doesn't have access to the server, return an error
|
# if the user doesn't have access to the server, return an error
|
||||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||||
|
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||||
if (
|
self.controller.server_perms.get_user_permissions_mask(
|
||||||
EnumPermissionsServer.CONFIG
|
|
||||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
|
||||||
auth_data[4]["user_id"], server_id
|
auth_data[4]["user_id"], server_id
|
||||||
)
|
),
|
||||||
):
|
auth_data[5],
|
||||||
|
)
|
||||||
|
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||||
|
if EnumPermissionsServer.CONFIG not in server_permissions:
|
||||||
# if the user doesn't have Schedule permission, return an error
|
# if the user doesn't have Schedule permission, return an error
|
||||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||||
webhook = self.controller.management.get_webhook_by_id(webhook_id)
|
webhook = self.controller.management.get_webhook_by_id(webhook_id)
|
||||||
|
@ -177,7 +177,7 @@ class ApiUsersIndexHandler(BaseApiHandler):
|
|||||||
self.controller.management.add_to_audit_log(
|
self.controller.management.add_to_audit_log(
|
||||||
user["user_id"],
|
user["user_id"],
|
||||||
f"added user {username} (UID:{user_id}) with roles {roles}",
|
f"added user {username} (UID:{user_id}) with roles {roles}",
|
||||||
server_id=0,
|
server_id=None,
|
||||||
source_ip=self.get_remote_ip(),
|
source_ip=self.get_remote_ip(),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ class ApiUsersUserKeyHandler(BaseApiHandler):
|
|||||||
auth_data[4]["user_id"],
|
auth_data[4]["user_id"],
|
||||||
f"Generated a new API token for the key {key.name} "
|
f"Generated a new API token for the key {key.name} "
|
||||||
f"from user with UID: {key.user_id}",
|
f"from user with UID: {key.user_id}",
|
||||||
server_id=0,
|
server_id=None,
|
||||||
source_ip=self.get_remote_ip(),
|
source_ip=self.get_remote_ip(),
|
||||||
)
|
)
|
||||||
data_key = self.controller.authentication.generate(
|
data_key = self.controller.authentication.generate(
|
||||||
@ -75,7 +75,7 @@ class ApiUsersUserKeyHandler(BaseApiHandler):
|
|||||||
"name": key.name,
|
"name": key.name,
|
||||||
"server_permissions": key.server_permissions,
|
"server_permissions": key.server_permissions,
|
||||||
"crafty_permissions": key.crafty_permissions,
|
"crafty_permissions": key.crafty_permissions,
|
||||||
"superuser": key.superuser,
|
"full_access": key.full_access,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
self.finish_json(
|
self.finish_json(
|
||||||
@ -99,7 +99,7 @@ class ApiUsersUserKeyHandler(BaseApiHandler):
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"pattern": "^[01]{3}$", # 8 bits, see EnumPermissionsCrafty
|
"pattern": "^[01]{3}$", # 8 bits, see EnumPermissionsCrafty
|
||||||
},
|
},
|
||||||
"superuser": {"type": "boolean"},
|
"full_access": {"type": "boolean"},
|
||||||
},
|
},
|
||||||
"additionalProperties": False,
|
"additionalProperties": False,
|
||||||
"minProperties": 1,
|
"minProperties": 1,
|
||||||
@ -163,7 +163,7 @@ class ApiUsersUserKeyHandler(BaseApiHandler):
|
|||||||
key_id = self.controller.users.add_user_api_key(
|
key_id = self.controller.users.add_user_api_key(
|
||||||
data["name"],
|
data["name"],
|
||||||
user_id,
|
user_id,
|
||||||
data["superuser"],
|
data["full_access"],
|
||||||
data["server_permissions_mask"],
|
data["server_permissions_mask"],
|
||||||
data["crafty_permissions_mask"],
|
data["crafty_permissions_mask"],
|
||||||
)
|
)
|
||||||
@ -173,7 +173,7 @@ class ApiUsersUserKeyHandler(BaseApiHandler):
|
|||||||
f"Added API key {data['name']} with crafty permissions "
|
f"Added API key {data['name']} with crafty permissions "
|
||||||
f"{data['crafty_permissions_mask']}"
|
f"{data['crafty_permissions_mask']}"
|
||||||
f" and {data['server_permissions_mask']} for user with UID: {user_id}",
|
f" and {data['server_permissions_mask']} for user with UID: {user_id}",
|
||||||
server_id=0,
|
server_id=None,
|
||||||
source_ip=self.get_remote_ip(),
|
source_ip=self.get_remote_ip(),
|
||||||
)
|
)
|
||||||
self.finish_json(200, {"status": "ok", "data": {"id": key_id}})
|
self.finish_json(200, {"status": "ok", "data": {"id": key_id}})
|
||||||
@ -233,7 +233,7 @@ class ApiUsersUserKeyHandler(BaseApiHandler):
|
|||||||
auth_data[4]["user_id"],
|
auth_data[4]["user_id"],
|
||||||
f"Removed API key {target_key} "
|
f"Removed API key {target_key} "
|
||||||
f"(ID: {key_id}) from user {auth_data[4]['user_id']}",
|
f"(ID: {key_id}) from user {auth_data[4]['user_id']}",
|
||||||
server_id=0,
|
server_id=None,
|
||||||
source_ip=self.get_remote_ip(),
|
source_ip=self.get_remote_ip(),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ class ApiUsersUserIndexHandler(BaseApiHandler):
|
|||||||
self.controller.management.add_to_audit_log(
|
self.controller.management.add_to_audit_log(
|
||||||
user["user_id"],
|
user["user_id"],
|
||||||
f"deleted the user {user_id}",
|
f"deleted the user {user_id}",
|
||||||
server_id=0,
|
server_id=None,
|
||||||
source_ip=self.get_remote_ip(),
|
source_ip=self.get_remote_ip(),
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -283,7 +283,7 @@ class ApiUsersUserIndexHandler(BaseApiHandler):
|
|||||||
f"edited user {user_obj.username} (UID: {user_id})"
|
f"edited user {user_obj.username} (UID: {user_id})"
|
||||||
f"with roles {user_obj.roles}"
|
f"with roles {user_obj.roles}"
|
||||||
),
|
),
|
||||||
server_id=0,
|
server_id=None,
|
||||||
source_ip=self.get_remote_ip(),
|
source_ip=self.get_remote_ip(),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -52,6 +52,8 @@ class ApiUsersUserPermissionsHandler(BaseApiHandler):
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
counter_data = PermissionsCrafty.get_created_quantity_list(user_id)
|
||||||
|
|
||||||
self.finish_json(
|
self.finish_json(
|
||||||
200,
|
200,
|
||||||
{
|
{
|
||||||
@ -59,9 +61,9 @@ class ApiUsersUserPermissionsHandler(BaseApiHandler):
|
|||||||
"data": {
|
"data": {
|
||||||
"permissions": res_data.permissions,
|
"permissions": res_data.permissions,
|
||||||
"counters": {
|
"counters": {
|
||||||
SERVER_CREATION: res_data.created_server,
|
SERVER_CREATION: counter_data["SERVER_CREATION"],
|
||||||
USER_CONFIG: res_data.created_user,
|
USER_CONFIG: counter_data["USER_CONFIG"],
|
||||||
ROLES_CONFIG: res_data.created_role,
|
ROLES_CONFIG: counter_data["ROLES_CONFIG"],
|
||||||
},
|
},
|
||||||
"limits": {
|
"limits": {
|
||||||
SERVER_CREATION: res_data.limit_server_creation,
|
SERVER_CREATION: res_data.limit_server_creation,
|
||||||
|
@ -30,7 +30,7 @@ class ServerHandler(BaseHandler):
|
|||||||
) = self.current_user
|
) = self.current_user
|
||||||
superuser = exec_user["superuser"]
|
superuser = exec_user["superuser"]
|
||||||
if api_key is not None:
|
if api_key is not None:
|
||||||
superuser = superuser and api_key.superuser
|
superuser = superuser and api_key.full_access
|
||||||
|
|
||||||
if superuser:
|
if superuser:
|
||||||
defined_servers = self.controller.servers.list_defined_servers()
|
defined_servers = self.controller.servers.list_defined_servers()
|
||||||
@ -124,7 +124,7 @@ class ServerHandler(BaseHandler):
|
|||||||
"created": api_key.created,
|
"created": api_key.created,
|
||||||
"server_permissions": api_key.server_permissions,
|
"server_permissions": api_key.server_permissions,
|
||||||
"crafty_permissions": api_key.crafty_permissions,
|
"crafty_permissions": api_key.crafty_permissions,
|
||||||
"superuser": api_key.superuser,
|
"full_access": api_key.full_access,
|
||||||
}
|
}
|
||||||
if api_key is not None
|
if api_key is not None
|
||||||
else None
|
else None
|
||||||
@ -147,7 +147,7 @@ class ServerHandler(BaseHandler):
|
|||||||
page_data["server_api"] = False
|
page_data["server_api"] = False
|
||||||
if page_data["online"]:
|
if page_data["online"]:
|
||||||
page_data["server_api"] = self.helper.check_address_status(
|
page_data["server_api"] = self.helper.check_address_status(
|
||||||
"https://serverjars.com/api/fetchTypes"
|
"https://api.serverjars.com"
|
||||||
)
|
)
|
||||||
page_data["server_types"] = self.controller.server_jars.get_serverjar_data()
|
page_data["server_types"] = self.controller.server_jars.get_serverjar_data()
|
||||||
page_data["js_server_types"] = json.dumps(
|
page_data["js_server_types"] = json.dumps(
|
||||||
|
@ -98,7 +98,6 @@ class Webserver:
|
|||||||
# let's verify we have an SSL cert
|
# let's verify we have an SSL cert
|
||||||
self.helper.create_self_signed_cert()
|
self.helper.create_self_signed_cert()
|
||||||
|
|
||||||
http_port = self.helper.get_setting("http_port")
|
|
||||||
https_port = self.helper.get_setting("https_port")
|
https_port = self.helper.get_setting("https_port")
|
||||||
|
|
||||||
debug_errors = self.helper.get_setting("show_errors")
|
debug_errors = self.helper.get_setting("show_errors")
|
||||||
@ -110,9 +109,6 @@ class Webserver:
|
|||||||
cookie_secret = self.helper.random_string_generator(32)
|
cookie_secret = self.helper.random_string_generator(32)
|
||||||
HelpersManagement.set_cookie_secret(cookie_secret)
|
HelpersManagement.set_cookie_secret(cookie_secret)
|
||||||
|
|
||||||
if not http_port and http_port != 0:
|
|
||||||
http_port = 8000
|
|
||||||
|
|
||||||
if not https_port:
|
if not https_port:
|
||||||
https_port = 8443
|
https_port = 8443
|
||||||
|
|
||||||
@ -125,7 +121,7 @@ class Webserver:
|
|||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info(f"Starting Web Server on ports http:{http_port} https:{https_port}")
|
logger.info(f"Starting Web Server on ports https:{https_port}")
|
||||||
|
|
||||||
asyncio.set_event_loop(asyncio.new_event_loop())
|
asyncio.set_event_loop(asyncio.new_event_loop())
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ class UploadHandler(BaseHandler):
|
|||||||
if self.upload_type == "server_import":
|
if self.upload_type == "server_import":
|
||||||
superuser = exec_user["superuser"]
|
superuser = exec_user["superuser"]
|
||||||
if api_key is not None:
|
if api_key is not None:
|
||||||
superuser = superuser and api_key.superuser
|
superuser = superuser and api_key.full_access
|
||||||
user_id = exec_user["user_id"]
|
user_id = exec_user["user_id"]
|
||||||
stream_size_value = self.helper.get_setting("stream_size_GB")
|
stream_size_value = self.helper.get_setting("stream_size_GB")
|
||||||
|
|
||||||
@ -133,7 +133,7 @@ class UploadHandler(BaseHandler):
|
|||||||
elif self.upload_type == "background":
|
elif self.upload_type == "background":
|
||||||
superuser = exec_user["superuser"]
|
superuser = exec_user["superuser"]
|
||||||
if api_key is not None:
|
if api_key is not None:
|
||||||
superuser = superuser and api_key.superuser
|
superuser = superuser and api_key.full_access
|
||||||
user_id = exec_user["user_id"]
|
user_id = exec_user["user_id"]
|
||||||
stream_size_value = self.helper.get_setting("stream_size_GB")
|
stream_size_value = self.helper.get_setting("stream_size_GB")
|
||||||
|
|
||||||
@ -212,7 +212,7 @@ class UploadHandler(BaseHandler):
|
|||||||
server_id = self.get_argument("server_id", None)
|
server_id = self.get_argument("server_id", None)
|
||||||
superuser = exec_user["superuser"]
|
superuser = exec_user["superuser"]
|
||||||
if api_key is not None:
|
if api_key is not None:
|
||||||
superuser = superuser and api_key.superuser
|
superuser = superuser and api_key.full_access
|
||||||
user_id = exec_user["user_id"]
|
user_id = exec_user["user_id"]
|
||||||
stream_size_value = self.helper.get_setting("stream_size_GB")
|
stream_size_value = self.helper.get_setting("stream_size_GB")
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ class WebSocketHandler(tornado.websocket.WebSocketHandler):
|
|||||||
self.controller.management.add_to_audit_log_raw(
|
self.controller.management.add_to_audit_log_raw(
|
||||||
"unknown",
|
"unknown",
|
||||||
0,
|
0,
|
||||||
0,
|
None,
|
||||||
"Someone tried to connect via WebSocket without proper authentication",
|
"Someone tried to connect via WebSocket without proper authentication",
|
||||||
self.get_remote_ip(),
|
self.get_remote_ip(),
|
||||||
)
|
)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"major": 4,
|
"major": 4,
|
||||||
"minor": 3,
|
"minor": 3,
|
||||||
"sub": 2
|
"sub": 3
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,7 @@
|
|||||||
<!--<th>ID</th>-->
|
<!--<th>ID</th>-->
|
||||||
<th>{{ translate('apiKeys', 'name', data['lang']) }}</th>
|
<th>{{ translate('apiKeys', 'name', data['lang']) }}</th>
|
||||||
<th>{{ translate('apiKeys', 'created', data['lang']) }}</th>
|
<th>{{ translate('apiKeys', 'created', data['lang']) }}</th>
|
||||||
<th>{{ translate('apiKeys', 'superUser', data['lang']) }}</th>
|
<th>{{ translate('apiKeys', 'fullAccess', data['lang']) }}</th>
|
||||||
<th>{{ translate('apiKeys', 'perms', data['lang']) }}</th>
|
<th>{{ translate('apiKeys', 'perms', data['lang']) }}</th>
|
||||||
<th>{{ translate('apiKeys', 'buttons', data['lang']) }}</th>
|
<th>{{ translate('apiKeys', 'buttons', data['lang']) }}</th>
|
||||||
</tr>
|
</tr>
|
||||||
@ -70,7 +70,7 @@
|
|||||||
<td>{{ apikey.name }}</td>
|
<td>{{ apikey.name }}</td>
|
||||||
<td>{{ apikey.created.strftime('%d/%m/%Y %H:%M:%S') }}</td>
|
<td>{{ apikey.created.strftime('%d/%m/%Y %H:%M:%S') }}</td>
|
||||||
<td>
|
<td>
|
||||||
{% if apikey.superuser %}
|
{% if apikey.full_access %}
|
||||||
<span class="text-success">
|
<span class="text-success">
|
||||||
<i class="fas fa-check-square"></i> {{
|
<i class="fas fa-check-square"></i> {{
|
||||||
translate('apiKeys', 'yes', data['lang']) }}
|
translate('apiKeys', 'yes', data['lang']) }}
|
||||||
@ -148,9 +148,15 @@
|
|||||||
}}</label>
|
}}</label>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
|
{% if permission in data['user_crafty_permissions'] %}
|
||||||
<input type="checkbox" class="crafty_perm"
|
<input type="checkbox" class="crafty_perm"
|
||||||
id="permission_{{ permission.name }}"
|
id="permission_{{ permission.name }}"
|
||||||
name="permission_{{ permission.name }}" value="1">
|
name="permission_{{ permission.name }}" value="1">
|
||||||
|
{% else %}
|
||||||
|
<input type="checkbox" class="crafty_perm"
|
||||||
|
id="permission_{{ permission.name }}"
|
||||||
|
name="permission_{{ permission.name }}" value="1" disabled>
|
||||||
|
{% end %}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% end %}
|
{% end %}
|
||||||
@ -158,8 +164,8 @@
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<label for="superuser">Superuser</label>
|
<label for="full_access">{{translate('apiKeys', 'fullAccess', data['lang'])}}</label>
|
||||||
<input type="checkbox" class="" id="superuser" name="superuser" value="1">
|
<input type="checkbox" class="" id="full_access" name="full_access" value="1">
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
@ -240,7 +246,7 @@
|
|||||||
"name": formDataObject.name,
|
"name": formDataObject.name,
|
||||||
"server_permissions_mask": server_permissions,
|
"server_permissions_mask": server_permissions,
|
||||||
"crafty_permissions_mask": crafty_permissions,
|
"crafty_permissions_mask": crafty_permissions,
|
||||||
"superuser": $("#superuser").prop('checked'),
|
"full_access": $("#full_access").prop('checked'),
|
||||||
});
|
});
|
||||||
console.log(formDataJsonString);
|
console.log(formDataJsonString);
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="{{ data.get('lang_page', 'en') }}" class="{{data['user_data'].get('theme', 'default')}}"
|
||||||
|
data-username="{{data['user_data'].get('username', None)}}">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<!-- Required meta tags -->
|
<!-- Required meta tags -->
|
||||||
@ -60,6 +61,11 @@
|
|||||||
<b>{{ translate('error', 'hereIsTheError', data['lang']) }}: {{data['error']}}</b><br /><br />
|
<b>{{ translate('error', 'hereIsTheError', data['lang']) }}: {{data['error']}}</b><br /><br />
|
||||||
That's all the help I can give you - Godspeed
|
That's all the help I can give you - Godspeed
|
||||||
<br /><br />
|
<br /><br />
|
||||||
|
<a class="d-inline font-weight-medium" href="/panel/dashboard"><button class="btn btn-info">{{
|
||||||
|
translate('error', 'return',
|
||||||
|
data['lang'])}}</button></a>
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
<a class="d-inline font-weight-medium" href="https://discord.gg/9VJPhCE"> {{ translate('error',
|
<a class="d-inline font-weight-medium" href="https://discord.gg/9VJPhCE"> {{ translate('error',
|
||||||
'contact', data['lang']) }}</a>
|
'contact', data['lang']) }}</a>
|
||||||
</p>
|
</p>
|
||||||
|
@ -111,8 +111,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="text-block text-center my-3">
|
<div class="text-block text-center my-3">
|
||||||
<span class="text-small font-weight-semibold"><a href="https://craftycontrol.com/">Crafty Control
|
<span class="text-small font-weight-semibold"><a href="https://craftycontrol.com/">Crafty Control</a> </span>
|
||||||
{{data['version'] }}</a> </span>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="text-block text-center my-3">
|
<div class="text-block text-center my-3">
|
||||||
|
@ -54,9 +54,6 @@ def migrate(migrator: Migrator, database, **kwargs):
|
|||||||
database = db
|
database = db
|
||||||
|
|
||||||
try:
|
try:
|
||||||
logger.info("Migrating Data from Int to UUID (Type Change)")
|
|
||||||
Console.info("Migrating Data from Int to UUID (Type Change)")
|
|
||||||
|
|
||||||
# Changes on Server Table
|
# Changes on Server Table
|
||||||
migrator.alter_column_type(
|
migrator.alter_column_type(
|
||||||
Servers,
|
Servers,
|
||||||
@ -87,11 +84,6 @@ def migrate(migrator: Migrator, database, **kwargs):
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
migrator.run()
|
|
||||||
|
|
||||||
logger.info("Migrating Data from Int to UUID (Type Change) : SUCCESS")
|
|
||||||
Console.info("Migrating Data from Int to UUID (Type Change) : SUCCESS")
|
|
||||||
|
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
logger.error("Error while migrating Data from Int to UUID (Type Change)")
|
logger.error("Error while migrating Data from Int to UUID (Type Change)")
|
||||||
logger.error(ex)
|
logger.error(ex)
|
||||||
@ -101,118 +93,6 @@ def migrate(migrator: Migrator, database, **kwargs):
|
|||||||
last_migration.delete()
|
last_migration.delete()
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
|
||||||
logger.info("Migrating Data from Int to UUID (Foreign Keys)")
|
|
||||||
Console.info("Migrating Data from Int to UUID (Foreign Keys)")
|
|
||||||
# Changes on Audit Log Table
|
|
||||||
for audit_log in AuditLog.select():
|
|
||||||
old_server_id = audit_log.server_id_id
|
|
||||||
if old_server_id == "0" or old_server_id is None:
|
|
||||||
server_uuid = None
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
server = Servers.get_by_id(old_server_id)
|
|
||||||
server_uuid = server.server_uuid
|
|
||||||
except:
|
|
||||||
server_uuid = old_server_id
|
|
||||||
AuditLog.update(server_id=server_uuid).where(
|
|
||||||
AuditLog.audit_id == audit_log.audit_id
|
|
||||||
).execute()
|
|
||||||
|
|
||||||
# Changes on Webhooks Log Table
|
|
||||||
for webhook in Webhooks.select():
|
|
||||||
old_server_id = webhook.server_id_id
|
|
||||||
try:
|
|
||||||
server = Servers.get_by_id(old_server_id)
|
|
||||||
server_uuid = server.server_uuid
|
|
||||||
except:
|
|
||||||
server_uuid = old_server_id
|
|
||||||
Webhooks.update(server_id=server_uuid).where(
|
|
||||||
Webhooks.id == webhook.id
|
|
||||||
).execute()
|
|
||||||
|
|
||||||
# Changes on Schedules Log Table
|
|
||||||
for schedule in Schedules.select():
|
|
||||||
old_server_id = schedule.server_id_id
|
|
||||||
try:
|
|
||||||
server = Servers.get_by_id(old_server_id)
|
|
||||||
server_uuid = server.server_uuid
|
|
||||||
except:
|
|
||||||
server_uuid = old_server_id
|
|
||||||
Schedules.update(server_id=server_uuid).where(
|
|
||||||
Schedules.schedule_id == schedule.schedule_id
|
|
||||||
).execute()
|
|
||||||
|
|
||||||
# Changes on Backups Log Table
|
|
||||||
for backup in Backups.select():
|
|
||||||
old_server_id = backup.server_id_id
|
|
||||||
try:
|
|
||||||
server = Servers.get_by_id(old_server_id)
|
|
||||||
server_uuid = server.server_uuid
|
|
||||||
except:
|
|
||||||
server_uuid = old_server_id
|
|
||||||
Backups.update(server_id=server_uuid).where(
|
|
||||||
Backups.server_id == old_server_id
|
|
||||||
).execute()
|
|
||||||
|
|
||||||
# Changes on RoleServers Log Table
|
|
||||||
for role_servers in RoleServers.select():
|
|
||||||
old_server_id = role_servers.server_id_id
|
|
||||||
try:
|
|
||||||
server = Servers.get_by_id(old_server_id)
|
|
||||||
server_uuid = server.server_uuid
|
|
||||||
except:
|
|
||||||
server_uuid = old_server_id
|
|
||||||
RoleServers.update(server_id=server_uuid).where(
|
|
||||||
RoleServers.role_id == role_servers.id
|
|
||||||
and RoleServers.server_id == old_server_id
|
|
||||||
).execute()
|
|
||||||
|
|
||||||
logger.info("Migrating Data from Int to UUID (Foreign Keys) : SUCCESS")
|
|
||||||
Console.info("Migrating Data from Int to UUID (Foreign Keys) : SUCCESS")
|
|
||||||
|
|
||||||
except Exception as ex:
|
|
||||||
logger.error("Error while migrating Data from Int to UUID (Foreign Keys)")
|
|
||||||
logger.error(ex)
|
|
||||||
Console.error("Error while migrating Data from Int to UUID (Foreign Keys)")
|
|
||||||
Console.error(ex)
|
|
||||||
last_migration = MigrateHistory.get_by_id(MigrateHistory.select().count())
|
|
||||||
last_migration.delete()
|
|
||||||
return
|
|
||||||
|
|
||||||
try:
|
|
||||||
logger.info("Migrating Data from Int to UUID (Primary Keys)")
|
|
||||||
Console.info("Migrating Data from Int to UUID (Primary Keys)")
|
|
||||||
# Migrating servers from the old id type to the new one
|
|
||||||
for server in Servers.select():
|
|
||||||
Servers.update(server_id=server.server_uuid).where(
|
|
||||||
Servers.server_id == server.server_id
|
|
||||||
).execute()
|
|
||||||
|
|
||||||
logger.info("Migrating Data from Int to UUID (Primary Keys) : SUCCESS")
|
|
||||||
Console.info("Migrating Data from Int to UUID (Primary Keys) : SUCCESS")
|
|
||||||
|
|
||||||
except Exception as ex:
|
|
||||||
logger.error("Error while migrating Data from Int to UUID (Primary Keys)")
|
|
||||||
logger.error(ex)
|
|
||||||
Console.error("Error while migrating Data from Int to UUID (Primary Keys)")
|
|
||||||
Console.error(ex)
|
|
||||||
last_migration = MigrateHistory.get_by_id(MigrateHistory.select().count())
|
|
||||||
last_migration.delete()
|
|
||||||
return
|
|
||||||
|
|
||||||
# Changes on Server Table
|
|
||||||
logger.info("Migrating Data from Int to UUID (Removing UUID Field from Servers)")
|
|
||||||
Console.info("Migrating Data from Int to UUID (Removing UUID Field from Servers)")
|
|
||||||
migrator.drop_columns("servers", ["server_uuid"])
|
|
||||||
migrator.run()
|
|
||||||
logger.info(
|
|
||||||
"Migrating Data from Int to UUID (Removing UUID Field from Servers) : SUCCESS"
|
|
||||||
)
|
|
||||||
Console.info(
|
|
||||||
"Migrating Data from Int to UUID (Removing UUID Field from Servers) : SUCCESS"
|
|
||||||
)
|
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
326
app/migrations/20240217_rework_servers_uuid_part2.py
Normal file
326
app/migrations/20240217_rework_servers_uuid_part2.py
Normal file
@ -0,0 +1,326 @@
|
|||||||
|
import datetime
|
||||||
|
import uuid
|
||||||
|
import peewee
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from app.classes.shared.console import Console
|
||||||
|
from app.classes.shared.migration import Migrator, MigrateHistory
|
||||||
|
from app.classes.models.management import (
|
||||||
|
AuditLog,
|
||||||
|
Webhooks,
|
||||||
|
Schedules,
|
||||||
|
Backups,
|
||||||
|
)
|
||||||
|
from app.classes.models.server_permissions import RoleServers
|
||||||
|
from app.classes.models.base_model import BaseModel
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def migrate(migrator: Migrator, database, **kwargs):
|
||||||
|
"""
|
||||||
|
Write your migrations here.
|
||||||
|
"""
|
||||||
|
db = database
|
||||||
|
|
||||||
|
# **********************************************************************************
|
||||||
|
# Servers New Model from Old (easier to migrate without dunmping Database)
|
||||||
|
# **********************************************************************************
|
||||||
|
class Servers(peewee.Model):
|
||||||
|
server_id = peewee.CharField(primary_key=True, default=str(uuid.uuid4()))
|
||||||
|
created = peewee.DateTimeField(default=datetime.datetime.now)
|
||||||
|
server_uuid = peewee.CharField(default="", index=True)
|
||||||
|
server_name = peewee.CharField(default="Server", index=True)
|
||||||
|
path = peewee.CharField(default="")
|
||||||
|
backup_path = peewee.CharField(default="")
|
||||||
|
executable = peewee.CharField(default="")
|
||||||
|
log_path = peewee.CharField(default="")
|
||||||
|
execution_command = peewee.CharField(default="")
|
||||||
|
auto_start = peewee.BooleanField(default=0)
|
||||||
|
auto_start_delay = peewee.IntegerField(default=10)
|
||||||
|
crash_detection = peewee.BooleanField(default=0)
|
||||||
|
stop_command = peewee.CharField(default="stop")
|
||||||
|
executable_update_url = peewee.CharField(default="")
|
||||||
|
server_ip = peewee.CharField(default="127.0.0.1")
|
||||||
|
server_port = peewee.IntegerField(default=25565)
|
||||||
|
logs_delete_after = peewee.IntegerField(default=0)
|
||||||
|
type = peewee.CharField(default="minecraft-java")
|
||||||
|
show_status = peewee.BooleanField(default=1)
|
||||||
|
created_by = peewee.IntegerField(default=-100)
|
||||||
|
shutdown_timeout = peewee.IntegerField(default=60)
|
||||||
|
ignored_exits = peewee.CharField(default="0")
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
table_name = "servers"
|
||||||
|
database = db
|
||||||
|
|
||||||
|
this_migration = MigrateHistory.get_or_none(
|
||||||
|
MigrateHistory.name == "20240217_rework_servers_uuid_part2"
|
||||||
|
)
|
||||||
|
if this_migration is not None:
|
||||||
|
Console.debug("Update database already done, skipping this part")
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
servers_columns = db.get_columns("servers")
|
||||||
|
if not any(
|
||||||
|
column_data.name == "server_uuid" for column_data in servers_columns
|
||||||
|
):
|
||||||
|
Console.debug(
|
||||||
|
"Servers.server_uuid already deleted in Crafty version 4.3.0, skipping this part"
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
logger.info("Migrating Data from Int to UUID (Foreign Keys)")
|
||||||
|
Console.info("Migrating Data from Int to UUID (Foreign Keys)")
|
||||||
|
# Changes on Audit Log Table
|
||||||
|
for audit_log in AuditLog.select():
|
||||||
|
old_server_id = audit_log.server_id_id
|
||||||
|
if old_server_id == "0" or old_server_id is None:
|
||||||
|
server_uuid = None
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
server = Servers.get_by_id(old_server_id)
|
||||||
|
server_uuid = server.server_uuid
|
||||||
|
except:
|
||||||
|
server_uuid = old_server_id
|
||||||
|
AuditLog.update(server_id=server_uuid).where(
|
||||||
|
AuditLog.audit_id == audit_log.audit_id
|
||||||
|
).execute()
|
||||||
|
|
||||||
|
# Changes on Webhooks Log Table
|
||||||
|
for webhook in Webhooks.select():
|
||||||
|
old_server_id = webhook.server_id_id
|
||||||
|
try:
|
||||||
|
server = Servers.get_by_id(old_server_id)
|
||||||
|
server_uuid = server.server_uuid
|
||||||
|
except:
|
||||||
|
server_uuid = old_server_id
|
||||||
|
Webhooks.update(server_id=server_uuid).where(
|
||||||
|
Webhooks.id == webhook.id
|
||||||
|
).execute()
|
||||||
|
|
||||||
|
# Changes on Schedules Log Table
|
||||||
|
for schedule in Schedules.select():
|
||||||
|
old_server_id = schedule.server_id_id
|
||||||
|
try:
|
||||||
|
server = Servers.get_by_id(old_server_id)
|
||||||
|
server_uuid = server.server_uuid
|
||||||
|
except:
|
||||||
|
server_uuid = old_server_id
|
||||||
|
Schedules.update(server_id=server_uuid).where(
|
||||||
|
Schedules.schedule_id == schedule.schedule_id
|
||||||
|
).execute()
|
||||||
|
|
||||||
|
# Changes on Backups Log Table
|
||||||
|
for backup in Backups.select():
|
||||||
|
old_server_id = backup.server_id_id
|
||||||
|
try:
|
||||||
|
server = Servers.get_by_id(old_server_id)
|
||||||
|
server_uuid = server.server_uuid
|
||||||
|
except:
|
||||||
|
server_uuid = old_server_id
|
||||||
|
Backups.update(server_id=server_uuid).where(
|
||||||
|
Backups.server_id == old_server_id
|
||||||
|
).execute()
|
||||||
|
|
||||||
|
# Changes on RoleServers Log Table
|
||||||
|
for role_servers in RoleServers.select():
|
||||||
|
old_server_id = role_servers.server_id_id
|
||||||
|
try:
|
||||||
|
server = Servers.get_by_id(old_server_id)
|
||||||
|
server_uuid = server.server_uuid
|
||||||
|
except:
|
||||||
|
server_uuid = old_server_id
|
||||||
|
RoleServers.update(server_id=server_uuid).where(
|
||||||
|
RoleServers.role_id == role_servers.id
|
||||||
|
and RoleServers.server_id == old_server_id
|
||||||
|
).execute()
|
||||||
|
|
||||||
|
logger.info("Migrating Data from Int to UUID (Foreign Keys) : SUCCESS")
|
||||||
|
Console.info("Migrating Data from Int to UUID (Foreign Keys) : SUCCESS")
|
||||||
|
|
||||||
|
except Exception as ex:
|
||||||
|
logger.error("Error while migrating Data from Int to UUID (Foreign Keys)")
|
||||||
|
logger.error(ex)
|
||||||
|
Console.error("Error while migrating Data from Int to UUID (Foreign Keys)")
|
||||||
|
Console.error(ex)
|
||||||
|
last_migration = MigrateHistory.get_by_id(MigrateHistory.select().count())
|
||||||
|
last_migration.delete()
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
logger.info("Migrating Data from Int to UUID (Primary Keys)")
|
||||||
|
Console.info("Migrating Data from Int to UUID (Primary Keys)")
|
||||||
|
# Migrating servers from the old id type to the new one
|
||||||
|
for server in Servers.select():
|
||||||
|
Servers.update(server_id=server.server_uuid).where(
|
||||||
|
Servers.server_id == server.server_id
|
||||||
|
).execute()
|
||||||
|
|
||||||
|
logger.info("Migrating Data from Int to UUID (Primary Keys) : SUCCESS")
|
||||||
|
Console.info("Migrating Data from Int to UUID (Primary Keys) : SUCCESS")
|
||||||
|
|
||||||
|
except Exception as ex:
|
||||||
|
logger.error("Error while migrating Data from Int to UUID (Primary Keys)")
|
||||||
|
logger.error(ex)
|
||||||
|
Console.error("Error while migrating Data from Int to UUID (Primary Keys)")
|
||||||
|
Console.error(ex)
|
||||||
|
last_migration = MigrateHistory.get_by_id(MigrateHistory.select().count())
|
||||||
|
last_migration.delete()
|
||||||
|
return
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def rollback(migrator: Migrator, database, **kwargs):
|
||||||
|
"""
|
||||||
|
Write your rollback migrations here.
|
||||||
|
"""
|
||||||
|
db = database
|
||||||
|
|
||||||
|
# Condition to prevent running rollback each time we've got a rollback to do
|
||||||
|
this_migration = MigrateHistory.get_or_none(
|
||||||
|
MigrateHistory.name == "20240217_rework_servers_uuid_part2"
|
||||||
|
)
|
||||||
|
if this_migration is None:
|
||||||
|
Console.debug("Update database already done, skipping this part")
|
||||||
|
return
|
||||||
|
|
||||||
|
# **********************************************************************************
|
||||||
|
# Servers New Model from Old (easier to migrate without dunmping Database)
|
||||||
|
# **********************************************************************************
|
||||||
|
class Servers(peewee.Model):
|
||||||
|
server_id = peewee.CharField(primary_key=True, default=str(uuid.uuid4()))
|
||||||
|
created = peewee.DateTimeField(default=datetime.datetime.now)
|
||||||
|
server_uuid = peewee.CharField(default="", index=True)
|
||||||
|
server_name = peewee.CharField(default="Server", index=True)
|
||||||
|
path = peewee.CharField(default="")
|
||||||
|
backup_path = peewee.CharField(default="")
|
||||||
|
executable = peewee.CharField(default="")
|
||||||
|
log_path = peewee.CharField(default="")
|
||||||
|
execution_command = peewee.CharField(default="")
|
||||||
|
auto_start = peewee.BooleanField(default=0)
|
||||||
|
auto_start_delay = peewee.IntegerField(default=10)
|
||||||
|
crash_detection = peewee.BooleanField(default=0)
|
||||||
|
stop_command = peewee.CharField(default="stop")
|
||||||
|
executable_update_url = peewee.CharField(default="")
|
||||||
|
server_ip = peewee.CharField(default="127.0.0.1")
|
||||||
|
server_port = peewee.IntegerField(default=25565)
|
||||||
|
logs_delete_after = peewee.IntegerField(default=0)
|
||||||
|
type = peewee.CharField(default="minecraft-java")
|
||||||
|
show_status = peewee.BooleanField(default=1)
|
||||||
|
created_by = peewee.IntegerField(default=-100)
|
||||||
|
shutdown_timeout = peewee.IntegerField(default=60)
|
||||||
|
ignored_exits = peewee.CharField(default="0")
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
table_name = "servers"
|
||||||
|
database = db
|
||||||
|
|
||||||
|
try:
|
||||||
|
logger.info("Migrating Data from UUID to Int (Primary Keys)")
|
||||||
|
Console.info("Migrating Data from UUID to Int (Primary Keys)")
|
||||||
|
# Migrating servers from the old id type to the new one
|
||||||
|
new_id = 0
|
||||||
|
for server in Servers.select():
|
||||||
|
new_id += 1
|
||||||
|
Servers.update(server_uuid=server.server_id).where(
|
||||||
|
Servers.server_id == server.server_id
|
||||||
|
).execute()
|
||||||
|
Servers.update(server_id=new_id).where(
|
||||||
|
Servers.server_id == server.server_id
|
||||||
|
).execute()
|
||||||
|
|
||||||
|
logger.info("Migrating Data from UUID to Int (Primary Keys) : SUCCESS")
|
||||||
|
Console.info("Migrating Data from UUID to Int (Primary Keys) : SUCCESS")
|
||||||
|
|
||||||
|
except Exception as ex:
|
||||||
|
logger.error("Error while migrating Data from UUID to Int (Primary Keys)")
|
||||||
|
logger.error(ex)
|
||||||
|
Console.error("Error while migrating Data from UUID to Int (Primary Keys)")
|
||||||
|
Console.error(ex)
|
||||||
|
last_migration = MigrateHistory.get_by_id(MigrateHistory.select().count())
|
||||||
|
last_migration.delete()
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
logger.info("Migrating Data from UUID to Int (Foreign Keys)")
|
||||||
|
Console.info("Migrating Data from UUID to Int (Foreign Keys)")
|
||||||
|
# Changes on Audit Log Table
|
||||||
|
for audit_log in AuditLog.select():
|
||||||
|
old_server_id = audit_log.server_id_id
|
||||||
|
if old_server_id is None:
|
||||||
|
new_server_id = 0
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
server = Servers.get_or_none(Servers.server_uuid == old_server_id)
|
||||||
|
new_server_id = server.server_id
|
||||||
|
except:
|
||||||
|
new_server_id = old_server_id
|
||||||
|
AuditLog.update(server_id=new_server_id).where(
|
||||||
|
AuditLog.audit_id == audit_log.audit_id
|
||||||
|
).execute()
|
||||||
|
|
||||||
|
# Changes on Webhooks Log Table
|
||||||
|
for webhook in Webhooks.select():
|
||||||
|
old_server_id = webhook.server_id_id
|
||||||
|
try:
|
||||||
|
server = Servers.get_or_none(Servers.server_uuid == old_server_id)
|
||||||
|
new_server_id = server.server_id
|
||||||
|
except:
|
||||||
|
new_server_id = old_server_id
|
||||||
|
Webhooks.update(server_id=new_server_id).where(
|
||||||
|
Webhooks.id == webhook.id
|
||||||
|
).execute()
|
||||||
|
|
||||||
|
# Changes on Schedules Log Table
|
||||||
|
for schedule in Schedules.select():
|
||||||
|
old_server_id = schedule.server_id_id
|
||||||
|
try:
|
||||||
|
server = Servers.get_or_none(Servers.server_uuid == old_server_id)
|
||||||
|
new_server_id = server.server_id
|
||||||
|
except:
|
||||||
|
new_server_id = old_server_id
|
||||||
|
Schedules.update(server_id=new_server_id).where(
|
||||||
|
Schedules.schedule_id == schedule.schedule_id
|
||||||
|
).execute()
|
||||||
|
|
||||||
|
# Changes on Backups Log Table
|
||||||
|
for backup in Backups.select():
|
||||||
|
old_server_id = backup.server_id_id
|
||||||
|
try:
|
||||||
|
server = Servers.get_or_none(Servers.server_uuid == old_server_id)
|
||||||
|
new_server_id = server.server_id
|
||||||
|
except:
|
||||||
|
new_server_id = old_server_id
|
||||||
|
Backups.update(server_id=new_server_id).where(
|
||||||
|
Backups.server_id == old_server_id
|
||||||
|
).execute()
|
||||||
|
|
||||||
|
# Changes on RoleServers Log Table
|
||||||
|
for role_servers in RoleServers.select():
|
||||||
|
old_server_id = role_servers.server_id_id
|
||||||
|
try:
|
||||||
|
server = Servers.get_or_none(Servers.server_uuid == old_server_id)
|
||||||
|
new_server_id = server.server_id
|
||||||
|
except:
|
||||||
|
new_server_id = old_server_id
|
||||||
|
RoleServers.update(server_id=new_server_id).where(
|
||||||
|
RoleServers.role_id == role_servers.id
|
||||||
|
and RoleServers.server_id == old_server_id
|
||||||
|
).execute()
|
||||||
|
|
||||||
|
logger.info("Migrating Data from UUID to Int (Foreign Keys) : SUCCESS")
|
||||||
|
Console.info("Migrating Data from UUID to Int (Foreign Keys) : SUCCESS")
|
||||||
|
|
||||||
|
except Exception as ex:
|
||||||
|
logger.error("Error while migrating Data from UUID to Int (Foreign Keys)")
|
||||||
|
logger.error(ex)
|
||||||
|
Console.error("Error while migrating Data from UUID to Int (Foreign Keys)")
|
||||||
|
Console.error(ex)
|
||||||
|
last_migration = MigrateHistory.get_by_id(MigrateHistory.select().count())
|
||||||
|
last_migration.delete()
|
||||||
|
return
|
||||||
|
|
||||||
|
return
|
@ -7,6 +7,7 @@ from app.classes.shared.console import Console
|
|||||||
from app.classes.shared.migration import Migrator, MigrateHistory
|
from app.classes.shared.migration import Migrator, MigrateHistory
|
||||||
from app.classes.models.management import Schedules, Backups
|
from app.classes.models.management import Schedules, Backups
|
||||||
from app.classes.models.server_permissions import RoleServers
|
from app.classes.models.server_permissions import RoleServers
|
||||||
|
from app.classes.models.servers import Servers
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -17,40 +18,7 @@ def migrate(migrator: Migrator, database, **kwargs):
|
|||||||
"""
|
"""
|
||||||
db = database
|
db = database
|
||||||
|
|
||||||
# **********************************************************************************
|
|
||||||
# Servers New Model from Old (easier to migrate without dunmping Database)
|
|
||||||
# **********************************************************************************
|
|
||||||
class Servers(peewee.Model):
|
|
||||||
server_id = peewee.CharField(primary_key=True, default=str(uuid.uuid4()))
|
|
||||||
created = peewee.DateTimeField(default=datetime.datetime.now)
|
|
||||||
server_name = peewee.CharField(default="Server", index=True)
|
|
||||||
path = peewee.CharField(default="")
|
|
||||||
backup_path = peewee.CharField(default="")
|
|
||||||
executable = peewee.CharField(default="")
|
|
||||||
log_path = peewee.CharField(default="")
|
|
||||||
execution_command = peewee.CharField(default="")
|
|
||||||
auto_start = peewee.BooleanField(default=0)
|
|
||||||
auto_start_delay = peewee.IntegerField(default=10)
|
|
||||||
crash_detection = peewee.BooleanField(default=0)
|
|
||||||
stop_command = peewee.CharField(default="stop")
|
|
||||||
executable_update_url = peewee.CharField(default="")
|
|
||||||
server_ip = peewee.CharField(default="127.0.0.1")
|
|
||||||
server_port = peewee.IntegerField(default=25565)
|
|
||||||
logs_delete_after = peewee.IntegerField(default=0)
|
|
||||||
type = peewee.CharField(default="minecraft-java")
|
|
||||||
show_status = peewee.BooleanField(default=1)
|
|
||||||
created_by = peewee.IntegerField(default=-100)
|
|
||||||
shutdown_timeout = peewee.IntegerField(default=60)
|
|
||||||
ignored_exits = peewee.CharField(default="0")
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
table_name = "servers"
|
|
||||||
database = db
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
logger.info("Migrating Data from Int to UUID (Fixing Issue)")
|
|
||||||
Console.info("Migrating Data from Int to UUID (Fixing Issue)")
|
|
||||||
|
|
||||||
# Changes on Servers Roles Table
|
# Changes on Servers Roles Table
|
||||||
migrator.alter_column_type(
|
migrator.alter_column_type(
|
||||||
RoleServers,
|
RoleServers,
|
||||||
@ -87,10 +55,13 @@ def migrate(migrator: Migrator, database, **kwargs):
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
migrator.run()
|
# Drop Column after migration
|
||||||
|
servers_columns = db.get_columns("servers")
|
||||||
logger.info("Migrating Data from Int to UUID (Fixing Issue) : SUCCESS")
|
if any(column_data.name == "server_uuid" for column_data in servers_columns):
|
||||||
Console.info("Migrating Data from Int to UUID (Fixing Issue) : SUCCESS")
|
Console.debug(
|
||||||
|
"Servers.server_uuid not deleted before Crafty version 4.3.2, skipping this part"
|
||||||
|
)
|
||||||
|
migrator.drop_columns("servers", ["server_uuid"])
|
||||||
|
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
logger.error("Error while migrating Data from Int to UUID (Fixing Issue)")
|
logger.error("Error while migrating Data from Int to UUID (Fixing Issue)")
|
||||||
@ -130,3 +101,7 @@ def rollback(migrator: Migrator, database, **kwargs):
|
|||||||
"server_id",
|
"server_id",
|
||||||
peewee.IntegerField(null=True),
|
peewee.IntegerField(null=True),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
migrator.add_columns(
|
||||||
|
"servers", server_uuid=peewee.CharField(default="", index=True)
|
||||||
|
) # Recreating the column for roll back
|
||||||
|
17
app/migrations/20240317_apikey_full_access.py
Normal file
17
app/migrations/20240317_apikey_full_access.py
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
# Generated by database migrator
|
||||||
|
import peewee
|
||||||
|
|
||||||
|
|
||||||
|
def migrate(migrator, database, **kwargs):
|
||||||
|
migrator.rename_column("api_keys", "superuser", "full_access")
|
||||||
|
|
||||||
|
"""
|
||||||
|
Write your migrations here.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def rollback(migrator, database, **kwargs):
|
||||||
|
migrator.rename_column("api_keys", "full_access", "superuser")
|
||||||
|
"""
|
||||||
|
Write your rollback migrations here.
|
||||||
|
"""
|
@ -20,6 +20,7 @@
|
|||||||
"created": "Vytvořen",
|
"created": "Vytvořen",
|
||||||
"deleteKeyConfirmation": "Chcete tento API klíč odstranit? Tuto akci nelze vrátit zpět.",
|
"deleteKeyConfirmation": "Chcete tento API klíč odstranit? Tuto akci nelze vrátit zpět.",
|
||||||
"deleteKeyConfirmationTitle": "Odstranit klíč API ${keyId}?",
|
"deleteKeyConfirmationTitle": "Odstranit klíč API ${keyId}?",
|
||||||
|
"fullAccess": "všechno",
|
||||||
"getToken": "Získat token",
|
"getToken": "Získat token",
|
||||||
"name": "Jméno",
|
"name": "Jméno",
|
||||||
"nameDesc": "Jak chcete nazvat tento token API? ",
|
"nameDesc": "Jak chcete nazvat tento token API? ",
|
||||||
@ -218,6 +219,7 @@
|
|||||||
"not-downloaded": "Zdá se, že nemůžeme najít váš spustitelný soubor. Bylo jeho stahování dokončeno? Jsou oprávnění nastavena na spustitelný soubor?",
|
"not-downloaded": "Zdá se, že nemůžeme najít váš spustitelný soubor. Bylo jeho stahování dokončeno? Jsou oprávnění nastavena na spustitelný soubor?",
|
||||||
"portReminder": "Zjistili jsme, že server {} byl spuštěn poprvé. Ujistěte se, že jste přesměrovali port {} přes váš směrovač/firewall, aby byl tento port vzdáleně přístupný z internetu.",
|
"portReminder": "Zjistili jsme, že server {} byl spuštěn poprvé. Ujistěte se, že jste přesměrovali port {} přes váš směrovač/firewall, aby byl tento port vzdáleně přístupný z internetu.",
|
||||||
"privMsg": "a ",
|
"privMsg": "a ",
|
||||||
|
"return": "vrátit se na hlavní stránku",
|
||||||
"serverJars1": "Server JAR api je nepřístupná. Prosím zkontrolujte",
|
"serverJars1": "Server JAR api je nepřístupná. Prosím zkontrolujte",
|
||||||
"serverJars2": "pro aktualní informace.",
|
"serverJars2": "pro aktualní informace.",
|
||||||
"start-error": "Server {} se nepodařilo spustit s kódem chyby: {}",
|
"start-error": "Server {} se nepodařilo spustit s kódem chyby: {}",
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
"created": "Erstellt",
|
"created": "Erstellt",
|
||||||
"deleteKeyConfirmation": "Möchten Sie diesen API Schlüssel löschen? Diese Aktion kann nicht rückgängig gemacht werden.",
|
"deleteKeyConfirmation": "Möchten Sie diesen API Schlüssel löschen? Diese Aktion kann nicht rückgängig gemacht werden.",
|
||||||
"deleteKeyConfirmationTitle": "Folgenden API Schlüssel löschen: ${keyId}?",
|
"deleteKeyConfirmationTitle": "Folgenden API Schlüssel löschen: ${keyId}?",
|
||||||
|
"fullAccess": "Vollzugriff",
|
||||||
"getToken": "Schlüssel erhalten",
|
"getToken": "Schlüssel erhalten",
|
||||||
"name": "Name",
|
"name": "Name",
|
||||||
"nameDesc": "Wie soll der API Schlüssel genannt werden? ",
|
"nameDesc": "Wie soll der API Schlüssel genannt werden? ",
|
||||||
@ -203,6 +204,7 @@
|
|||||||
"not-downloaded": "Crafty kann die auszuführende Datei nicht finden. Ist der Download abgeschlossen? Sind die Berechtigungen für Crafty korrekt?",
|
"not-downloaded": "Crafty kann die auszuführende Datei nicht finden. Ist der Download abgeschlossen? Sind die Berechtigungen für Crafty korrekt?",
|
||||||
"portReminder": "Wir haben festgestellt, dass dies das erste Mal ist, dass {} ausgeführt wurde. Stellen Sie sicher, dass Sie Port {} durch Ihren Router/Firewall weiterleiten, um den Fernzugriff aus dem Internet zu ermöglichen.",
|
"portReminder": "Wir haben festgestellt, dass dies das erste Mal ist, dass {} ausgeführt wurde. Stellen Sie sicher, dass Sie Port {} durch Ihren Router/Firewall weiterleiten, um den Fernzugriff aus dem Internet zu ermöglichen.",
|
||||||
"privMsg": "und der/die/das ",
|
"privMsg": "und der/die/das ",
|
||||||
|
"return": "Zurück zum Dashboard",
|
||||||
"serverJars1": "Server-JAR-API nicht erreichbar. Bitte überprüfen Sie ",
|
"serverJars1": "Server-JAR-API nicht erreichbar. Bitte überprüfen Sie ",
|
||||||
"serverJars2": "um die aktuellsten Informationen zu erhalten.",
|
"serverJars2": "um die aktuellsten Informationen zu erhalten.",
|
||||||
"start-error": "Der Server {} konnte wegen dem Fehlercode: {} nicht gestartet werden",
|
"start-error": "Der Server {} konnte wegen dem Fehlercode: {} nicht gestartet werden",
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
"created": "Created",
|
"created": "Created",
|
||||||
"deleteKeyConfirmation": "Do you want to delete this API key? This cannot be undone.",
|
"deleteKeyConfirmation": "Do you want to delete this API key? This cannot be undone.",
|
||||||
"deleteKeyConfirmationTitle": "Remove API key ${keyId}?",
|
"deleteKeyConfirmationTitle": "Remove API key ${keyId}?",
|
||||||
|
"fullAccess": "Full Access",
|
||||||
"getToken": "Get A Token",
|
"getToken": "Get A Token",
|
||||||
"name": "Name",
|
"name": "Name",
|
||||||
"nameDesc": "What would you like to call this API token? ",
|
"nameDesc": "What would you like to call this API token? ",
|
||||||
@ -28,7 +29,6 @@
|
|||||||
"permName": "Permission Name",
|
"permName": "Permission Name",
|
||||||
"perms": "Permissions",
|
"perms": "Permissions",
|
||||||
"server": "Server: ",
|
"server": "Server: ",
|
||||||
"superUser": "Super User",
|
|
||||||
"yes": "Yes"
|
"yes": "Yes"
|
||||||
},
|
},
|
||||||
"base": {
|
"base": {
|
||||||
@ -203,6 +203,7 @@
|
|||||||
"not-downloaded": "We can't seem to find your executable file. Has it finished downloading? Are the permissions set to executable?",
|
"not-downloaded": "We can't seem to find your executable file. Has it finished downloading? Are the permissions set to executable?",
|
||||||
"portReminder": "We have detected this is the first time {} has been run. Make sure to forward port {} through your router/firewall to make this remotely accessible from the internet.",
|
"portReminder": "We have detected this is the first time {} has been run. Make sure to forward port {} through your router/firewall to make this remotely accessible from the internet.",
|
||||||
"privMsg": "and the ",
|
"privMsg": "and the ",
|
||||||
|
"return": "Return to Dashboard",
|
||||||
"serverJars1": "Server JARs API unreachable. Please check",
|
"serverJars1": "Server JARs API unreachable. Please check",
|
||||||
"serverJars2": "for the most up to date information.",
|
"serverJars2": "for the most up to date information.",
|
||||||
"start-error": "Server {} failed to start with error code: {}",
|
"start-error": "Server {} failed to start with error code: {}",
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
"created": "Creado",
|
"created": "Creado",
|
||||||
"deleteKeyConfirmation": "¿Quieres eliminar esta clave de API? Esto no se puede deshacer.",
|
"deleteKeyConfirmation": "¿Quieres eliminar esta clave de API? Esto no se puede deshacer.",
|
||||||
"deleteKeyConfirmationTitle": "¿Eliminar la clave API ${keyId}?",
|
"deleteKeyConfirmationTitle": "¿Eliminar la clave API ${keyId}?",
|
||||||
|
"fullAccess": "Acceso completo",
|
||||||
"getToken": "Conseguir un Token",
|
"getToken": "Conseguir un Token",
|
||||||
"name": "Nombre",
|
"name": "Nombre",
|
||||||
"nameDesc": "¿Como te gustaría llamar a este Token de API? ",
|
"nameDesc": "¿Como te gustaría llamar a este Token de API? ",
|
||||||
@ -203,6 +204,7 @@
|
|||||||
"not-downloaded": "No podemos encontrar el archivo ejecutable. ¿Ha terminado de descargarse? ¿Están los permisos puestos como ejecutable?",
|
"not-downloaded": "No podemos encontrar el archivo ejecutable. ¿Ha terminado de descargarse? ¿Están los permisos puestos como ejecutable?",
|
||||||
"portReminder": "Detectamos que es la primera vez que se inicia {}. Asegúrese de configurar el puerto {} a través de su router/firewall para hacer el servidor accesible por Internet.",
|
"portReminder": "Detectamos que es la primera vez que se inicia {}. Asegúrese de configurar el puerto {} a través de su router/firewall para hacer el servidor accesible por Internet.",
|
||||||
"privMsg": "y el ",
|
"privMsg": "y el ",
|
||||||
|
"return": "Volver al panel de control",
|
||||||
"serverJars1": "API de Servidor JAR no disponible. por favor, compruebe",
|
"serverJars1": "API de Servidor JAR no disponible. por favor, compruebe",
|
||||||
"serverJars2": "para la información más actualizada.",
|
"serverJars2": "para la información más actualizada.",
|
||||||
"start-error": "Servidor {} fallo al iniciar con código de error: {}",
|
"start-error": "Servidor {} fallo al iniciar con código de error: {}",
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
"created": "Crée",
|
"created": "Crée",
|
||||||
"deleteKeyConfirmation": "Es-tu sûr de vouloir supprimer cette clé API? Tu ne pourras plus revenir en arrière.",
|
"deleteKeyConfirmation": "Es-tu sûr de vouloir supprimer cette clé API? Tu ne pourras plus revenir en arrière.",
|
||||||
"deleteKeyConfirmationTitle": "Supprimer la clé API ${keyId}?",
|
"deleteKeyConfirmationTitle": "Supprimer la clé API ${keyId}?",
|
||||||
|
"fullAccess": "Accès Complet",
|
||||||
"getToken": "Obtenir un Jeton",
|
"getToken": "Obtenir un Jeton",
|
||||||
"name": "Nom",
|
"name": "Nom",
|
||||||
"nameDesc": "Comment appeler ce Jeton d'API ? ",
|
"nameDesc": "Comment appeler ce Jeton d'API ? ",
|
||||||
@ -203,6 +204,7 @@
|
|||||||
"not-downloaded": "Nous ne parvenons pas à trouver le fichier exécutable. A-t-il fini de Télécharger ? Les permissions permettent elles l'exécution ?",
|
"not-downloaded": "Nous ne parvenons pas à trouver le fichier exécutable. A-t-il fini de Télécharger ? Les permissions permettent elles l'exécution ?",
|
||||||
"portReminder": "Nous avons détecté que c'est la première fois que {} est exécuté. Assurez-vous de transférer le port {} via votre routeur/pare-feu pour le rendre accessible à distance depuis Internet.",
|
"portReminder": "Nous avons détecté que c'est la première fois que {} est exécuté. Assurez-vous de transférer le port {} via votre routeur/pare-feu pour le rendre accessible à distance depuis Internet.",
|
||||||
"privMsg": "et le ",
|
"privMsg": "et le ",
|
||||||
|
"return": "Revenir au Tableau de Bord",
|
||||||
"serverJars1": "l'API Server JARs est inaccessible. Merci de vérifier",
|
"serverJars1": "l'API Server JARs est inaccessible. Merci de vérifier",
|
||||||
"serverJars2": "pour les informations les plus à jour.",
|
"serverJars2": "pour les informations les plus à jour.",
|
||||||
"start-error": "Le serveur {} n'a pas pu démarrer avec le code d'erreur : {}",
|
"start-error": "Le serveur {} n'a pas pu démarrer avec le code d'erreur : {}",
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
"created": "נוצר",
|
"created": "נוצר",
|
||||||
"deleteKeyConfirmation": "האם ברצונך למחוק מפתח API זה? אי אפשר לבטל את זה.",
|
"deleteKeyConfirmation": "האם ברצונך למחוק מפתח API זה? אי אפשר לבטל את זה.",
|
||||||
"deleteKeyConfirmationTitle": "? ${keyId} API-להסיר את מפתח ה",
|
"deleteKeyConfirmationTitle": "? ${keyId} API-להסיר את מפתח ה",
|
||||||
|
"fullAccess": "גישה מלאה להכל",
|
||||||
"getToken": "קבלת אסימון",
|
"getToken": "קבלת אסימון",
|
||||||
"name": "שם",
|
"name": "שם",
|
||||||
"nameDesc": "הזה API-איך תרצו לקרוא לאסימון ה",
|
"nameDesc": "הזה API-איך תרצו לקרוא לאסימון ה",
|
||||||
@ -203,6 +204,7 @@
|
|||||||
"not-downloaded": "לא הצלחנו למצוא את קובץ ההפעלה שלך. האם זה סיים להוריד? האם ההרשאות מוגדרות בשביל הפעלה?",
|
"not-downloaded": "לא הצלחנו למצוא את קובץ ההפעלה שלך. האם זה סיים להוריד? האם ההרשאות מוגדרות בשביל הפעלה?",
|
||||||
"portReminder": "זיהינו שזו הפעם הראשונה ש-{} מופעל. הקפידו להעביר את היציאה {} דרך הנתב/חומת האש שלכם כדי להפוך אותה לנגישה מרחוק מהאינטרנט.",
|
"portReminder": "זיהינו שזו הפעם הראשונה ש-{} מופעל. הקפידו להעביר את היציאה {} דרך הנתב/חומת האש שלכם כדי להפוך אותה לנגישה מרחוק מהאינטרנט.",
|
||||||
"privMsg": "וה",
|
"privMsg": "וה",
|
||||||
|
"return": "חזרה לפאנל",
|
||||||
"serverJars1": "API של צנצנות השרת אינו נגיש. אנא בדוק",
|
"serverJars1": "API של צנצנות השרת אינו נגיש. אנא בדוק",
|
||||||
"serverJars2": "למידע מעודכן ביותר.",
|
"serverJars2": "למידע מעודכן ביותר.",
|
||||||
"start-error": "השרת {} לא הצליח להתחיל עם קוד שגיאה: {}",
|
"start-error": "השרת {} לא הצליח להתחיל עם קוד שגיאה: {}",
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
"created": "Creato",
|
"created": "Creato",
|
||||||
"deleteKeyConfirmation": "Vuoi cancellare questa chiave API? Non puoi tornare indietro.",
|
"deleteKeyConfirmation": "Vuoi cancellare questa chiave API? Non puoi tornare indietro.",
|
||||||
"deleteKeyConfirmationTitle": "Rimuovere la chiave API ${keyId}?",
|
"deleteKeyConfirmationTitle": "Rimuovere la chiave API ${keyId}?",
|
||||||
|
"fullAccess": " Accesso completo",
|
||||||
"getToken": "Prendi un Token",
|
"getToken": "Prendi un Token",
|
||||||
"name": "Nome",
|
"name": "Nome",
|
||||||
"nameDesc": "Come desideri chiamare questo Token API? ",
|
"nameDesc": "Come desideri chiamare questo Token API? ",
|
||||||
@ -53,6 +54,20 @@
|
|||||||
"translationTitle": "Traduttore in lingua",
|
"translationTitle": "Traduttore in lingua",
|
||||||
"translator": "Traduttori"
|
"translator": "Traduttori"
|
||||||
},
|
},
|
||||||
|
"customLogin": {
|
||||||
|
"apply": "Applica",
|
||||||
|
"backgroundUpload": "Carica sfondo",
|
||||||
|
"customLoginPage": "Personalizza la pagina di accesso",
|
||||||
|
"delete": "Cancella",
|
||||||
|
"labelLoginImage": "Scegli lo sfondo della finestra di accesso",
|
||||||
|
"loginBackground": "Immagini di sfondo della finestra di accesso",
|
||||||
|
"loginImage": "Carica un'immagine di sfondo per la schermata di accesso.",
|
||||||
|
"loginOpacity": "Seleziona l'opacità della finestra di accesso",
|
||||||
|
"pageTitle": "Pagina di accesso personalizzata",
|
||||||
|
"preview": "Anteprima",
|
||||||
|
"select": "Seleziona",
|
||||||
|
"selectImage": "Seleziona un'immagine"
|
||||||
|
},
|
||||||
"dashboard": {
|
"dashboard": {
|
||||||
"actions": "Azioni",
|
"actions": "Azioni",
|
||||||
"allServers": "Tutti i Server",
|
"allServers": "Tutti i Server",
|
||||||
@ -75,6 +90,7 @@
|
|||||||
"dashboard": "Pannello di Controllo",
|
"dashboard": "Pannello di Controllo",
|
||||||
"delay-explained": "Il servizio/agente è stato avviato di recente e sta ritardando l'avvio del server di Minecraft",
|
"delay-explained": "Il servizio/agente è stato avviato di recente e sta ritardando l'avvio del server di Minecraft",
|
||||||
"host": "Host",
|
"host": "Host",
|
||||||
|
"installing": "Installazione...",
|
||||||
"kill": "Termina il Processo",
|
"kill": "Termina il Processo",
|
||||||
"killing": "Terminando il processo...",
|
"killing": "Terminando il processo...",
|
||||||
"lastBackup": "Ultimo:",
|
"lastBackup": "Ultimo:",
|
||||||
@ -96,6 +112,7 @@
|
|||||||
"starting": "Avvio ritardato",
|
"starting": "Avvio ritardato",
|
||||||
"status": "Stato",
|
"status": "Stato",
|
||||||
"stop": "Stop",
|
"stop": "Stop",
|
||||||
|
"storage": "Archiviazione",
|
||||||
"version": "Versione",
|
"version": "Versione",
|
||||||
"welcome": "Benvenuto su Crafty Controller"
|
"welcome": "Benvenuto su Crafty Controller"
|
||||||
},
|
},
|
||||||
@ -164,20 +181,34 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"error": {
|
"error": {
|
||||||
|
"agree": "Conferma",
|
||||||
|
"bedrockError": "I download di Bedrock non sono disponibili. Si prega di controllare",
|
||||||
|
"cancel": "Annulla",
|
||||||
"contact": "Contact Crafty Control Support via Discord",
|
"contact": "Contact Crafty Control Support via Discord",
|
||||||
|
"craftyStatus": "Stato di Crafty",
|
||||||
|
"cronFormat": "Rilevato formato Cron non valido",
|
||||||
"embarassing": "Oh my, well, this is embarrassing.",
|
"embarassing": "Oh my, well, this is embarrassing.",
|
||||||
"error": "Error!",
|
"error": "Error!",
|
||||||
"eulaAgree": "Do you agree?",
|
"eulaAgree": "Do you agree?",
|
||||||
"eulaMsg": "You must agree to the EULA. A copy of the Minecraft EULA is linked under this message.",
|
"eulaMsg": "You must agree to the EULA. A copy of the Minecraft EULA is linked under this message.",
|
||||||
"eulaTitle": "Agree To EULA",
|
"eulaTitle": "Agree To EULA",
|
||||||
|
"fileError": "Il tipo di file deve essere un'immagine.",
|
||||||
"fileTooLarge": "Caricamento fallito. File da caricare troppo grande. Contatta un amministratore di sistema per assistenza.",
|
"fileTooLarge": "Caricamento fallito. File da caricare troppo grande. Contatta un amministratore di sistema per assistenza.",
|
||||||
"hereIsTheError": "Here is the error",
|
"hereIsTheError": "Here is the error",
|
||||||
|
"installerJava": "Installazione fallita {} : L'installazione di server Forge richiede Java. Abbiamo rilevato che Java non è installato. Installa Java e riprova.",
|
||||||
"internet": "We have detected the machine running Crafty has no connection to the internet. Client connections to the server may be limited.",
|
"internet": "We have detected the machine running Crafty has no connection to the internet. Client connections to the server may be limited.",
|
||||||
|
"migration": "Lo spazio di archiviazione del server principale di Crafty verrà migrato in una nuova posizione. Durante questo periodo tutti gli avvii dei server sono stati sospesi. Aspetta mentre completiamo la migrazione",
|
||||||
"no-file": "We can't seem to locate the requested file. Double check the path. Does Crafty have proper permissions?",
|
"no-file": "We can't seem to locate the requested file. Double check the path. Does Crafty have proper permissions?",
|
||||||
|
"noInternet": "Crafty ha problemi ad accedere a internet. La creazione di server è stata disabilitata. Controlla la tua connessione a internet e aggiorna la pagina.",
|
||||||
"noJava": "Server {} failed to start with error code: We have detected Java is not installed. Please install java then start the server.",
|
"noJava": "Server {} failed to start with error code: We have detected Java is not installed. Please install java then start the server.",
|
||||||
"not-downloaded": "We can't seem to find your executable file. Has it finished downloading? Are the permissions set to executable?",
|
"not-downloaded": "We can't seem to find your executable file. Has it finished downloading? Are the permissions set to executable?",
|
||||||
"portReminder": "We have detected this is the first time {} has been run. Make sure to forward port {} through your router/firewall to make this remotely accessible from the internet.",
|
"portReminder": "We have detected this is the first time {} has been run. Make sure to forward port {} through your router/firewall to make this remotely accessible from the internet.",
|
||||||
|
"privMsg": "e il ",
|
||||||
|
"return": "Torna alla pagina iniziale",
|
||||||
|
"serverJars1": "API JAR del server non raggiungibile. Si prega di controllare",
|
||||||
|
"serverJars2": "per informazioni più aggiornate.",
|
||||||
"start-error": "Server {} failed to start with error code: {}",
|
"start-error": "Server {} failed to start with error code: {}",
|
||||||
|
"superError": "Devi essere un super utente per eseguire questa azione.",
|
||||||
"terribleFailure": "What a Terrible Failure!"
|
"terribleFailure": "What a Terrible Failure!"
|
||||||
},
|
},
|
||||||
"footer": {
|
"footer": {
|
||||||
@ -186,10 +217,14 @@
|
|||||||
"version": "Versione"
|
"version": "Versione"
|
||||||
},
|
},
|
||||||
"login": {
|
"login": {
|
||||||
|
"defaultPath": "La password immessa è il percorso delle credenziali predefinite, non la password. Trova la password predefinita in quella posizione.",
|
||||||
|
"disabled": "Account utente disabilitato. Per ulteriori informazioni, contatta l'amministratore di sistema.",
|
||||||
"forgotPassword": "Password dimenticata",
|
"forgotPassword": "Password dimenticata",
|
||||||
|
"incorrect": "nome utente o password errati",
|
||||||
"login": "Accedi",
|
"login": "Accedi",
|
||||||
"password": "Password",
|
"password": "Password",
|
||||||
"username": "Nome utente"
|
"username": "Nome utente",
|
||||||
|
"viewStatus": "Visualizza la pagina di stato pubblica"
|
||||||
},
|
},
|
||||||
"notify": {
|
"notify": {
|
||||||
"activityLog": "Registri di Attività",
|
"activityLog": "Registri di Attività",
|
||||||
@ -201,24 +236,38 @@
|
|||||||
"preparingLogs": "Per favore aspetta mentre prepariamo i tuoi registri... Ti invieremo una notifica quando saranno pronti. Potrebbe volerci un po' per installazioni grosse.",
|
"preparingLogs": "Per favore aspetta mentre prepariamo i tuoi registri... Ti invieremo una notifica quando saranno pronti. Potrebbe volerci un po' per installazioni grosse.",
|
||||||
"supportLogs": "Registri di supporto"
|
"supportLogs": "Registri di supporto"
|
||||||
},
|
},
|
||||||
|
"offline": {
|
||||||
|
"offline": "Disconnesso",
|
||||||
|
"pleaseConnect": "Connettiti a internet per usare Crafty."
|
||||||
|
},
|
||||||
"panelConfig": {
|
"panelConfig": {
|
||||||
"adminControls": "Controllo admin",
|
"adminControls": "Controllo admin",
|
||||||
"allowedServers": "Server permessi",
|
"allowedServers": "Server permessi",
|
||||||
|
"apply": "Applica",
|
||||||
"assignedRoles": "Ruoli assegnati",
|
"assignedRoles": "Ruoli assegnati",
|
||||||
"cancel": "Cancella",
|
"cancel": "Cancella",
|
||||||
"clearComms": "Pulisci i comandi non eseguiti",
|
"clearComms": "Pulisci i comandi non eseguiti",
|
||||||
|
"custom": "Personalizza Crafty",
|
||||||
"delete": "Elimina",
|
"delete": "Elimina",
|
||||||
"edit": "Modifica",
|
"edit": "Modifica",
|
||||||
|
"enableLang": "Abilita tutte le lingue",
|
||||||
"enabled": "Abilitato",
|
"enabled": "Abilitato",
|
||||||
|
"globalExplain": "Dove Crafty memorizza tutti i file del tuo server. (Aggiungeremo il percorso con /servers/[uuid of server])",
|
||||||
|
"globalServer": "Directory dei server globali",
|
||||||
|
"json": "Config.json",
|
||||||
|
"match": "Le password devono corrispondere",
|
||||||
"newRole": "Aggiungi nuovo ruolo",
|
"newRole": "Aggiungi nuovo ruolo",
|
||||||
"newUser": "Aggiungi nuovo utente",
|
"newUser": "Aggiungi nuovo utente",
|
||||||
|
"noMounts": "Non mostrare supporti su Dash",
|
||||||
"pageTitle": "Configurazioni del pannello",
|
"pageTitle": "Configurazioni del pannello",
|
||||||
"role": "Ruolo",
|
"role": "Ruolo",
|
||||||
"roleUsers": "Utenti del ruolo",
|
"roleUsers": "Utenti del ruolo",
|
||||||
"roles": "Ruoli",
|
"roles": "Ruoli",
|
||||||
"save": "Salva",
|
"save": "Salva",
|
||||||
|
"select": "Seleziona",
|
||||||
"superConfirm": "Procedi solo se vuoi che questo utente abbia accesso a TUTTO (tutti gli utenti, server, impostazioni del pannello, ecc...). Può anche revocare i tuoi poteri da superuser.",
|
"superConfirm": "Procedi solo se vuoi che questo utente abbia accesso a TUTTO (tutti gli utenti, server, impostazioni del pannello, ecc...). Può anche revocare i tuoi poteri da superuser.",
|
||||||
"superConfirmTitle": "Abilitare lo superuser? Sei sicuro?",
|
"superConfirmTitle": "Abilitare lo superuser? Sei sicuro?",
|
||||||
|
"title": "Configurazione di Crafty",
|
||||||
"user": "Utente",
|
"user": "Utente",
|
||||||
"users": "Utenti"
|
"users": "Utenti"
|
||||||
},
|
},
|
||||||
@ -242,14 +291,17 @@
|
|||||||
"roleTitle": "Impostazioni del ruolo",
|
"roleTitle": "Impostazioni del ruolo",
|
||||||
"roleUserName": "Nome Utente",
|
"roleUserName": "Nome Utente",
|
||||||
"roleUsers": "Utenti con il ruolo: ",
|
"roleUsers": "Utenti con il ruolo: ",
|
||||||
|
"selectManager": "Seleziona un gestore per questo ruolo",
|
||||||
"serverAccess": "Abilitato?",
|
"serverAccess": "Abilitato?",
|
||||||
"serverName": "Nome del Server",
|
"serverName": "Nome del Server",
|
||||||
"serversDesc": "Server a cui questo ruolo è consentito l'accesso"
|
"serversDesc": "Server a cui questo ruolo è consentito l'accesso"
|
||||||
},
|
},
|
||||||
"serverBackups": {
|
"serverBackups": {
|
||||||
|
"after": "Esegui il comando prima del backup",
|
||||||
"backupAtMidnight": "Auto-backup a mezzanotte?",
|
"backupAtMidnight": "Auto-backup a mezzanotte?",
|
||||||
"backupNow": "Effettua il Backup Ora!",
|
"backupNow": "Effettua il Backup Ora!",
|
||||||
"backupTask": "Un'azione di backup è cominciata.",
|
"backupTask": "Un'azione di backup è cominciata.",
|
||||||
|
"before": "Esegui il comando dopo il backup",
|
||||||
"cancel": "Cancella",
|
"cancel": "Cancella",
|
||||||
"clickExclude": "Clicca per selezionare le esclusioni",
|
"clickExclude": "Clicca per selezionare le esclusioni",
|
||||||
"compress": "Comprimi backup",
|
"compress": "Comprimi backup",
|
||||||
@ -280,6 +332,7 @@
|
|||||||
"bePatientDeleteFiles": "Per favore sii paziente mentre rimuoviamo il tuo server dal pannello di Crafty e cancelliamo tutti i files. Questa schermata si chiuderà in pochi istanti.",
|
"bePatientDeleteFiles": "Per favore sii paziente mentre rimuoviamo il tuo server dal pannello di Crafty e cancelliamo tutti i files. Questa schermata si chiuderà in pochi istanti.",
|
||||||
"bePatientUpdate": "Per favore sii paziente mentre aggiorniamo il server. I tempi di download possono variare dalla tua velocità di internet.<br /> Questa schermata si aggiornerà a breve",
|
"bePatientUpdate": "Per favore sii paziente mentre aggiorniamo il server. I tempi di download possono variare dalla tua velocità di internet.<br /> Questa schermata si aggiornerà a breve",
|
||||||
"cancel": "Cancella",
|
"cancel": "Cancella",
|
||||||
|
"countPlayers": "Includi il server nel conteggio totale dei giocatori",
|
||||||
"crashTime": "Crash Timeout",
|
"crashTime": "Crash Timeout",
|
||||||
"crashTimeDesc": "Quanto dobbiamo aspettare per considerare il tuo server crashato per colpa di un timeout?",
|
"crashTimeDesc": "Quanto dobbiamo aspettare per considerare il tuo server crashato per colpa di un timeout?",
|
||||||
"deleteFilesQuestion": "Eliminare i file del server dalla macchina?",
|
"deleteFilesQuestion": "Eliminare i file del server dalla macchina?",
|
||||||
@ -289,6 +342,8 @@
|
|||||||
"deleteServerQuestionMessage": "Sei sicuro di voler eliminare questo server? Dopo la conferma non puoi tornare indietro...",
|
"deleteServerQuestionMessage": "Sei sicuro di voler eliminare questo server? Dopo la conferma non puoi tornare indietro...",
|
||||||
"exeUpdateURL": "URL di aggiornamento dell'eseguibile del server",
|
"exeUpdateURL": "URL di aggiornamento dell'eseguibile del server",
|
||||||
"exeUpdateURLDesc": "URL di download diretto per gli aggiornamenti del server.",
|
"exeUpdateURLDesc": "URL di download diretto per gli aggiornamenti del server.",
|
||||||
|
"ignoredExits": "Codici di arresto anomalo ignorati",
|
||||||
|
"ignoredExitsExplain": "I codici di arresto anomalo per il rilevamento degli incidenti di Crafty dovrebbero essere ignorati come un normale 'stop' (separato da virgole)",
|
||||||
"javaNoChange": "Non cambiare la versione di Java",
|
"javaNoChange": "Non cambiare la versione di Java",
|
||||||
"javaVersion": "Cambia la versione di Java attualmente in uso",
|
"javaVersion": "Cambia la versione di Java attualmente in uso",
|
||||||
"javaVersionDesc": "Se vuoi cambiare versione di Java, assicurati che la path dell'eseguibile di Java sia immessa tra 'apostrofi' ('java' di default è esclusa)",
|
"javaVersionDesc": "Se vuoi cambiare versione di Java, assicurati che la path dell'eseguibile di Java sia immessa tra 'apostrofi' ('java' di default è esclusa)",
|
||||||
@ -319,7 +374,13 @@
|
|||||||
"serverPortDesc": "La Porta a cui Crafty si dovrà collegare per le statistiche",
|
"serverPortDesc": "La Porta a cui Crafty si dovrà collegare per le statistiche",
|
||||||
"serverStopCommand": "Comando d'arresto del server",
|
"serverStopCommand": "Comando d'arresto del server",
|
||||||
"serverStopCommandDesc": "Comando inviato al server per l'arresto",
|
"serverStopCommandDesc": "Comando inviato al server per l'arresto",
|
||||||
|
"showStatus": "Mostra nella pagina di stato pubblica",
|
||||||
|
"shutdownTimeout": "Tempo di attesa dello spegnimento",
|
||||||
|
"statsHint1": "la porta che sta usando il server dovrebbe essere qui. Questo è il modo in cui Crafty apre una connessione al tuo server per le statistiche.",
|
||||||
|
"statsHint2": "Ciò non modifica la porta del tuo server. È comunque necessario modificare la porta nel file di configurazione del server.",
|
||||||
"stopBeforeDeleting": "Per favore arresta il server prima di eliminarlo",
|
"stopBeforeDeleting": "Per favore arresta il server prima di eliminarlo",
|
||||||
|
"timeoutExplain1": "Per quanto tempo Crafty attenderà lo spegnimento del tuo server dopo averlo eseguito",
|
||||||
|
"timeoutExplain2": "comando prima di forzare l'arresto del processo.",
|
||||||
"update": "Aggiorna l'eseguibile",
|
"update": "Aggiorna l'eseguibile",
|
||||||
"yesDelete": "Sì, elimina",
|
"yesDelete": "Sì, elimina",
|
||||||
"yesDeleteFiles": "Sì, elimina i files"
|
"yesDeleteFiles": "Sì, elimina i files"
|
||||||
@ -345,8 +406,12 @@
|
|||||||
"backup": "Backup",
|
"backup": "Backup",
|
||||||
"config": "Configura",
|
"config": "Configura",
|
||||||
"files": "Files",
|
"files": "Files",
|
||||||
|
"filter": "Filtra registri",
|
||||||
|
"filterList": "Parole filtrate",
|
||||||
"logs": "Registri",
|
"logs": "Registri",
|
||||||
|
"metrics": "Metrica",
|
||||||
"playerControls": "Gestisci i giocatori",
|
"playerControls": "Gestisci i giocatori",
|
||||||
|
"reset": "Ripristina scorrimento",
|
||||||
"schedule": "Programma",
|
"schedule": "Programma",
|
||||||
"serverDetails": "Dettagli del Server",
|
"serverDetails": "Dettagli del Server",
|
||||||
"terminal": "Terminale"
|
"terminal": "Terminale"
|
||||||
@ -383,6 +448,11 @@
|
|||||||
"waitUpload": "Per favore aspetta mentre carichiamo i tuoi files... Potrebbe volerci un momento.",
|
"waitUpload": "Per favore aspetta mentre carichiamo i tuoi files... Potrebbe volerci un momento.",
|
||||||
"yesDelete": "Sì, conosco le conseguenze"
|
"yesDelete": "Sì, conosco le conseguenze"
|
||||||
},
|
},
|
||||||
|
"serverMetrics": {
|
||||||
|
"resetZoom": "Ripristina ingrandimento",
|
||||||
|
"zoomHint1": "Per ingrandire il grafico, tieni premuto il tasto Maiusc, quindi usa la rotella di scorrimento.",
|
||||||
|
"zoomHint2": "In alternativa, tieni premuto il tasto Maiusc, quindi fai clic e trascina l'area su cui desideri ingrandire."
|
||||||
|
},
|
||||||
"serverPlayerManagement": {
|
"serverPlayerManagement": {
|
||||||
"bannedPlayers": "Giocatori Banditi",
|
"bannedPlayers": "Giocatori Banditi",
|
||||||
"loadingBannedPlayers": "Carico i giocatori banditi",
|
"loadingBannedPlayers": "Carico i giocatori banditi",
|
||||||
@ -410,23 +480,44 @@
|
|||||||
"parent-explain": "Quale azione dovrebbe far eseguire questa?",
|
"parent-explain": "Quale azione dovrebbe far eseguire questa?",
|
||||||
"reaction": "Reazione",
|
"reaction": "Reazione",
|
||||||
"restart": "Riavvia il Server",
|
"restart": "Riavvia il Server",
|
||||||
|
"select": "Seleziona Base / Cron / Reazione a catena",
|
||||||
"start": "Avvia il server",
|
"start": "Avvia il server",
|
||||||
"stop": "Arresta il Server",
|
"stop": "Arresta il Server",
|
||||||
"time": "Orario",
|
"time": "Orario",
|
||||||
"time-explain": "A che ora vuoi eseguire la tua azione programmata?"
|
"time-explain": "A che ora vuoi eseguire la tua azione programmata?"
|
||||||
},
|
},
|
||||||
"serverSchedules": {
|
"serverSchedules": {
|
||||||
|
"action": "Azione",
|
||||||
"areYouSure": "Eliminare l'azione programmata?",
|
"areYouSure": "Eliminare l'azione programmata?",
|
||||||
"cancel": "Cancella",
|
"cancel": "Cancella",
|
||||||
"cannotSee": "Non vedi tutto?",
|
"cannotSee": "Non vedi tutto?",
|
||||||
"cannotSeeOnMobile": "Prova a cliccare su un'azione programmata per tutti i dettagli.",
|
"cannotSeeOnMobile": "Prova a cliccare su un'azione programmata per tutti i dettagli.",
|
||||||
|
"child": "Schedario secondario con ID ",
|
||||||
|
"close": "Chiudi",
|
||||||
|
"command": "Comando",
|
||||||
"confirm": "Conferma",
|
"confirm": "Conferma",
|
||||||
"confirmDelete": "Vuoi eliminare l'azione programmata? Non puoi tornare indietro."
|
"confirmDelete": "Vuoi eliminare l'azione programmata? Non puoi tornare indietro.",
|
||||||
|
"create": "Crea nuovo schedario",
|
||||||
|
"cron": "Stringa Cron",
|
||||||
|
"delete": "Cancella",
|
||||||
|
"details": "Dettagli dello schedario",
|
||||||
|
"edit": "Modifica",
|
||||||
|
"enabled": "Abilitato",
|
||||||
|
"every": "Tutto",
|
||||||
|
"interval": "Intervallo",
|
||||||
|
"name": "Nome",
|
||||||
|
"newSchedule": "Nuovo schedario",
|
||||||
|
"nextRun": "Prossima operazione",
|
||||||
|
"no": "No",
|
||||||
|
"no-schedule": "Non sono attualmente presenti schedari per questo server. Per iniziare, clicca",
|
||||||
|
"scheduledTasks": "Attività schedate",
|
||||||
|
"yes": "Sì"
|
||||||
},
|
},
|
||||||
"serverStats": {
|
"serverStats": {
|
||||||
"cpuUsage": "Utilizzo del Processore",
|
"cpuUsage": "Utilizzo del Processore",
|
||||||
"description": "Descrizione",
|
"description": "Descrizione",
|
||||||
"errorCalculatingUptime": "Errore nel calcolo dei tempi di operazione",
|
"errorCalculatingUptime": "Errore nel calcolo dei tempi di operazione",
|
||||||
|
"loadingMotd": "Caricamento MOTD",
|
||||||
"memUsage": "Utilizzo della memoria",
|
"memUsage": "Utilizzo della memoria",
|
||||||
"offline": "Offline",
|
"offline": "Offline",
|
||||||
"online": "Online",
|
"online": "Online",
|
||||||
@ -444,6 +535,8 @@
|
|||||||
"commandInput": "Inserisci il comando",
|
"commandInput": "Inserisci il comando",
|
||||||
"delay-explained": "Il servizio/agente è stato avviato di recente e sta ritardando l'avvio del server di Minecraft",
|
"delay-explained": "Il servizio/agente è stato avviato di recente e sta ritardando l'avvio del server di Minecraft",
|
||||||
"downloading": "Scaricando...",
|
"downloading": "Scaricando...",
|
||||||
|
"importing": "Importazione...",
|
||||||
|
"installing": "Installazione...",
|
||||||
"restart": "Riavvia",
|
"restart": "Riavvia",
|
||||||
"sendCommand": "Invia il comando",
|
"sendCommand": "Invia il comando",
|
||||||
"start": "Avvia",
|
"start": "Avvia",
|
||||||
@ -468,6 +561,7 @@
|
|||||||
"importServerButton": "Importa Server!",
|
"importServerButton": "Importa Server!",
|
||||||
"importZip": "Importa da un File Zip",
|
"importZip": "Importa da un File Zip",
|
||||||
"importing": "Importando il Server...",
|
"importing": "Importando il Server...",
|
||||||
|
"labelZipFile": "Scegli il tuo file zip",
|
||||||
"maxMem": "Memoria Massima",
|
"maxMem": "Memoria Massima",
|
||||||
"minMem": "Memoria minima",
|
"minMem": "Memoria minima",
|
||||||
"myNewServer": "Il mio nuovo Server",
|
"myNewServer": "Il mio nuovo Server",
|
||||||
@ -478,6 +572,7 @@
|
|||||||
"save": "Salva",
|
"save": "Salva",
|
||||||
"selectRole": "Seleziona i Ruoli",
|
"selectRole": "Seleziona i Ruoli",
|
||||||
"selectRoot": "Seleziona la directory radice dell'archivio",
|
"selectRoot": "Seleziona la directory radice dell'archivio",
|
||||||
|
"selectServer": "Seleziona un server",
|
||||||
"selectType": "Seleziona un Tipo",
|
"selectType": "Seleziona un Tipo",
|
||||||
"selectVersion": "Seleziona una versione",
|
"selectVersion": "Seleziona una versione",
|
||||||
"selectZipDir": "Seleziona il percorso in memoria in cui scompatteremo i file",
|
"selectZipDir": "Seleziona il percorso in memoria in cui scompatteremo i file",
|
||||||
@ -485,9 +580,14 @@
|
|||||||
"serverName": "Nome Server",
|
"serverName": "Nome Server",
|
||||||
"serverPath": "Percorso del Server",
|
"serverPath": "Percorso del Server",
|
||||||
"serverPort": "Porta del Server",
|
"serverPort": "Porta del Server",
|
||||||
|
"serverSelect": "Server selezionato",
|
||||||
"serverType": "Tipo di Server",
|
"serverType": "Tipo di Server",
|
||||||
|
"serverUpload": "Carica server zippato",
|
||||||
"serverVersion": "Versione del Server",
|
"serverVersion": "Versione del Server",
|
||||||
"sizeInGB": "Dimensione in GB",
|
"sizeInGB": "Dimensione in GB",
|
||||||
|
"unsupported": "Le versioni di Minecraft inferiori alla 1.8 non sono supportate da Crafty. Puoi comunque installarlo. I risultati varieranno.",
|
||||||
|
"uploadButton": "Carica",
|
||||||
|
"uploadZip": "Carica file zip per l'importazione del server",
|
||||||
"zipPath": "Percorso del Server"
|
"zipPath": "Percorso del Server"
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
@ -495,10 +595,20 @@
|
|||||||
"credits": "Crediti",
|
"credits": "Crediti",
|
||||||
"dashboard": "Pannello di controllo",
|
"dashboard": "Pannello di controllo",
|
||||||
"documentation": "Documentazione",
|
"documentation": "Documentazione",
|
||||||
|
"inApp": "Documenti in app",
|
||||||
"navigation": "Navigazione",
|
"navigation": "Navigazione",
|
||||||
"newServer": "Crea un Nuovo Server",
|
"newServer": "Crea un Nuovo Server",
|
||||||
"servers": "Servers"
|
"servers": "Servers"
|
||||||
},
|
},
|
||||||
|
"startup": {
|
||||||
|
"almost": "Finalizzazione. Tieniti forte...",
|
||||||
|
"internals": "Configurazione e avvio dei componenti interni di Crafty",
|
||||||
|
"internet": "Controllo connessione a internet",
|
||||||
|
"server": "Inizializzazione ",
|
||||||
|
"serverInit": "Inizializzazione server",
|
||||||
|
"starting": "Avvio di Crafty...",
|
||||||
|
"tasks": "Avvio attività schedate"
|
||||||
|
},
|
||||||
"userConfig": {
|
"userConfig": {
|
||||||
"apiKey": "Chiavi API",
|
"apiKey": "Chiavi API",
|
||||||
"auth": "Autorizzato? ",
|
"auth": "Autorizzato? ",
|
||||||
@ -519,6 +629,7 @@
|
|||||||
"lastLogin": "Ultimo accesso: ",
|
"lastLogin": "Ultimo accesso: ",
|
||||||
"lastUpdate": "Ultimo aggiornamento: ",
|
"lastUpdate": "Ultimo aggiornamento: ",
|
||||||
"leaveBlank": "Per modificare l'utente senza cambiare la passowrd, lascia il campo in bianco.",
|
"leaveBlank": "Per modificare l'utente senza cambiare la passowrd, lascia il campo in bianco.",
|
||||||
|
"manager": "Gestore",
|
||||||
"member": "È membro?",
|
"member": "È membro?",
|
||||||
"notExist": "Non puoi eliminare qualcosa che non esiste!",
|
"notExist": "Non puoi eliminare qualcosa che non esiste!",
|
||||||
"pageTitle": "Modifica Utente",
|
"pageTitle": "Modifica Utente",
|
||||||
@ -527,6 +638,7 @@
|
|||||||
"permName": "Nome del Permesso",
|
"permName": "Nome del Permesso",
|
||||||
"repeat": "Ripeti la Password",
|
"repeat": "Ripeti la Password",
|
||||||
"roleName": "Nome del ruolo",
|
"roleName": "Nome del ruolo",
|
||||||
|
"selectManager": "Seleziona un gestore per l'utente",
|
||||||
"super": "Super User",
|
"super": "Super User",
|
||||||
"userLang": "Linguaggio dell'utente",
|
"userLang": "Linguaggio dell'utente",
|
||||||
"userName": "Nome utente",
|
"userName": "Nome utente",
|
||||||
@ -534,6 +646,32 @@
|
|||||||
"userRoles": "Ruoli dell'utente",
|
"userRoles": "Ruoli dell'utente",
|
||||||
"userRolesDesc": "Ruoli di cui l'utente fa parte.",
|
"userRolesDesc": "Ruoli di cui l'utente fa parte.",
|
||||||
"userSettings": "Impostazioni Utente",
|
"userSettings": "Impostazioni Utente",
|
||||||
|
"userTheme": "Tema IU",
|
||||||
"uses": "Numero di usi permessi (-1==Nessun limite)"
|
"uses": "Numero di usi permessi (-1==Nessun limite)"
|
||||||
|
},
|
||||||
|
"webhooks": {
|
||||||
|
"areYouSureDel": "Sei sicuro di voler eliminare questo webhook?",
|
||||||
|
"areYouSureRun": "Sei sicuro di voler testare questo webhook?",
|
||||||
|
"backup_server": "Backup del server completato",
|
||||||
|
"bot_name": "Nome del bot",
|
||||||
|
"color": "Seleziona l'accentuazione del colore",
|
||||||
|
"crash_detected": "Il server si è arrestato in modo anomalo",
|
||||||
|
"edit": "Modifica",
|
||||||
|
"enabled": "Abilitato",
|
||||||
|
"jar_update": "Eseguibile del server aggiornato",
|
||||||
|
"kill": "Server arrestato",
|
||||||
|
"name": "Nome",
|
||||||
|
"new": "Nuovo webhook",
|
||||||
|
"newWebhook": "Nuovo webhook",
|
||||||
|
"no-webhook": "Attualmente non ci sono webhook in questo server. Per iniziare, clicca",
|
||||||
|
"run": "Testa il webhook",
|
||||||
|
"send_command": "Comando del server ricevuto",
|
||||||
|
"start_server": "Server avviato",
|
||||||
|
"stop_server": "Server spento",
|
||||||
|
"trigger": "Attivazione a",
|
||||||
|
"type": "Tipo di Webhook",
|
||||||
|
"url": "URL del Webhook",
|
||||||
|
"webhook_body": "Corpo del Webhook",
|
||||||
|
"webhooks": "Webhook"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -20,6 +20,7 @@
|
|||||||
"created": "CREATED",
|
"created": "CREATED",
|
||||||
"deleteKeyConfirmation": "U SURE U WANTZ TO DELETE DIS? CAN'T UNDO!",
|
"deleteKeyConfirmation": "U SURE U WANTZ TO DELETE DIS? CAN'T UNDO!",
|
||||||
"deleteKeyConfirmationTitle": "I CAN EATZ IT??? : ${keyId}?",
|
"deleteKeyConfirmationTitle": "I CAN EATZ IT??? : ${keyId}?",
|
||||||
|
"fullAccess": "All da Doors Open",
|
||||||
"getToken": "GIT TOKEN",
|
"getToken": "GIT TOKEN",
|
||||||
"name": "NAME",
|
"name": "NAME",
|
||||||
"nameDesc": "WUT WUD U LIEK 2 CALL DIS API TOKEN? ",
|
"nameDesc": "WUT WUD U LIEK 2 CALL DIS API TOKEN? ",
|
||||||
@ -203,6 +204,7 @@
|
|||||||
"not-downloaded": "SOZ BUT I FAILDZ CAN'T SEEM TO FINDZ YOUR FISH. PLZ GIB MEZ IT. I HUNGRY.",
|
"not-downloaded": "SOZ BUT I FAILDZ CAN'T SEEM TO FINDZ YOUR FISH. PLZ GIB MEZ IT. I HUNGRY.",
|
||||||
"portReminder": "WE HAS DETECTD DIS AR TEH FURST TIEM {} IZ BEAN RUN. IF U WANTS IT ACESIBLE TO NEIGHBORHOOD CATS PLZ UNLOCK CAT_FLAP, {}, THRU UR ROUTR IF U HAS NOT DUN SO.",
|
"portReminder": "WE HAS DETECTD DIS AR TEH FURST TIEM {} IZ BEAN RUN. IF U WANTS IT ACESIBLE TO NEIGHBORHOOD CATS PLZ UNLOCK CAT_FLAP, {}, THRU UR ROUTR IF U HAS NOT DUN SO.",
|
||||||
"privMsg": "AND THEEZ ",
|
"privMsg": "AND THEEZ ",
|
||||||
|
"return": "Go Bak to Dashbored",
|
||||||
"serverJars1": "CAN'T TALK TO SERVER JARS API. CHECKZ",
|
"serverJars1": "CAN'T TALK TO SERVER JARS API. CHECKZ",
|
||||||
"serverJars2": "TO SEE NEWZ STUFFZ.",
|
"serverJars2": "TO SEE NEWZ STUFFZ.",
|
||||||
"start-error": "CHAIR {} FAILD 2 START WIF OOF CODE: {}",
|
"start-error": "CHAIR {} FAILD 2 START WIF OOF CODE: {}",
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
"created": "Izveidots",
|
"created": "Izveidots",
|
||||||
"deleteKeyConfirmation": "Vai vēlies dzēst šo API atslēgu? Šo nevar atdarīt.",
|
"deleteKeyConfirmation": "Vai vēlies dzēst šo API atslēgu? Šo nevar atdarīt.",
|
||||||
"deleteKeyConfirmationTitle": "Noņemt API atslēgu ${keyId}?",
|
"deleteKeyConfirmationTitle": "Noņemt API atslēgu ${keyId}?",
|
||||||
|
"fullAccess": "Pilna piekļuve",
|
||||||
"getToken": "Saņemt Pilnvaru (Token)",
|
"getToken": "Saņemt Pilnvaru (Token)",
|
||||||
"name": "Nosaukums",
|
"name": "Nosaukums",
|
||||||
"nameDesc": "Kā jūs vēlaties nosaukt šo Pilnvaru (Token)? ",
|
"nameDesc": "Kā jūs vēlaties nosaukt šo Pilnvaru (Token)? ",
|
||||||
@ -204,6 +205,7 @@
|
|||||||
"not-downloaded": "Mēs nevaram atrast jūsu izpildāmo failu. Vai tas ir beidzis lejupielādēties? Vai tā peikļuves ir uzstādītas kā palaižamas?",
|
"not-downloaded": "Mēs nevaram atrast jūsu izpildāmo failu. Vai tas ir beidzis lejupielādēties? Vai tā peikļuves ir uzstādītas kā palaižamas?",
|
||||||
"portReminder": "Mēs noteicām ka šī ir pirmā reize, kad {} ir ticis palaists. Pārliecinies izlaist portu {} cauri savam rūterim/ugunsmūrim lai padarītu šo attāli pieejamu no interneta.",
|
"portReminder": "Mēs noteicām ka šī ir pirmā reize, kad {} ir ticis palaists. Pārliecinies izlaist portu {} cauri savam rūterim/ugunsmūrim lai padarītu šo attāli pieejamu no interneta.",
|
||||||
"privMsg": "un ",
|
"privMsg": "un ",
|
||||||
|
"return": "Atgriezties uz pārskatu",
|
||||||
"serverJars1": "Serveru JAR API nav sasniedzams. Lūdzu pārbaudiet",
|
"serverJars1": "Serveru JAR API nav sasniedzams. Lūdzu pārbaudiet",
|
||||||
"serverJars2": "priekš jaunākās informācijas.",
|
"serverJars2": "priekš jaunākās informācijas.",
|
||||||
"start-error": "Serveris {} neveiskmīgi startējās ar kļūdas kodu: {}",
|
"start-error": "Serveris {} neveiskmīgi startējās ar kļūdas kodu: {}",
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
"created": "Gecreëerd",
|
"created": "Gecreëerd",
|
||||||
"deleteKeyConfirmation": "Wilt u deze API sleutel verwijderen? Dit kan niet ongedaan gemaakt worden.",
|
"deleteKeyConfirmation": "Wilt u deze API sleutel verwijderen? Dit kan niet ongedaan gemaakt worden.",
|
||||||
"deleteKeyConfirmationTitle": "API sleutel verwijderen ${keyId}?",
|
"deleteKeyConfirmationTitle": "API sleutel verwijderen ${keyId}?",
|
||||||
|
"fullAccess": "Volledige toegang",
|
||||||
"getToken": "Verkrijg een Token",
|
"getToken": "Verkrijg een Token",
|
||||||
"name": "Naam",
|
"name": "Naam",
|
||||||
"nameDesc": "Hoe wilt u dit API token noemen? ",
|
"nameDesc": "Hoe wilt u dit API token noemen? ",
|
||||||
@ -203,6 +204,7 @@
|
|||||||
"not-downloaded": "We kunnen uw uitvoerbare bestand niet vinden. Is het klaar met downloaden? Zijn de rechten ingesteld op uitvoerbaar?",
|
"not-downloaded": "We kunnen uw uitvoerbare bestand niet vinden. Is het klaar met downloaden? Zijn de rechten ingesteld op uitvoerbaar?",
|
||||||
"portReminder": "We hebben ontdekt dat dit de eerste keer is dat {} wordt uitgevoerd. Zorg ervoor dat u poort {} doorstuurt via uw router/firewall om deze op afstand toegankelijk te maken vanaf het internet.",
|
"portReminder": "We hebben ontdekt dat dit de eerste keer is dat {} wordt uitgevoerd. Zorg ervoor dat u poort {} doorstuurt via uw router/firewall om deze op afstand toegankelijk te maken vanaf het internet.",
|
||||||
"privMsg": "en de ",
|
"privMsg": "en de ",
|
||||||
|
"return": "Terug naar Dashboard",
|
||||||
"serverJars1": "Server JARs API niet bereikbaar. Controleer alstublieft",
|
"serverJars1": "Server JARs API niet bereikbaar. Controleer alstublieft",
|
||||||
"serverJars2": "voor de meest recente informatie.",
|
"serverJars2": "voor de meest recente informatie.",
|
||||||
"start-error": "Server {} kan niet starten met foutcode: {}",
|
"start-error": "Server {} kan niet starten met foutcode: {}",
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
"created": "Stworzono",
|
"created": "Stworzono",
|
||||||
"deleteKeyConfirmation": "Czy chcesz usunąć ten klucz API? Nie można tego cofnąć.",
|
"deleteKeyConfirmation": "Czy chcesz usunąć ten klucz API? Nie można tego cofnąć.",
|
||||||
"deleteKeyConfirmationTitle": "Usunąć Klucz API ${keyId}?",
|
"deleteKeyConfirmationTitle": "Usunąć Klucz API ${keyId}?",
|
||||||
|
"fullAccess": "Pełny dostęp",
|
||||||
"getToken": "Zdobądź token",
|
"getToken": "Zdobądź token",
|
||||||
"name": "Nazwa",
|
"name": "Nazwa",
|
||||||
"nameDesc": "Jak chcesz nazwać ten klucz API? ",
|
"nameDesc": "Jak chcesz nazwać ten klucz API? ",
|
||||||
@ -203,6 +204,7 @@
|
|||||||
"not-downloaded": "Nie możemy znaleść twojego pliku serwera. Czy skończył się pobierać? Czy permisje są ustawione na wykonywanle?",
|
"not-downloaded": "Nie możemy znaleść twojego pliku serwera. Czy skończył się pobierać? Czy permisje są ustawione na wykonywanle?",
|
||||||
"portReminder": "Zauważyliśmy że to jest pierwszy raz {} kiedy był włączony. Upewnij się że otworzyłeś port {} na swoim routerze/firewallu aby korzystać z tego poza domem.",
|
"portReminder": "Zauważyliśmy że to jest pierwszy raz {} kiedy był włączony. Upewnij się że otworzyłeś port {} na swoim routerze/firewallu aby korzystać z tego poza domem.",
|
||||||
"privMsg": "i także ",
|
"privMsg": "i także ",
|
||||||
|
"return": "Powrót do panelu",
|
||||||
"serverJars1": "API Server Jars jest niedostępne. Proszę sprawdź",
|
"serverJars1": "API Server Jars jest niedostępne. Proszę sprawdź",
|
||||||
"serverJars2": "dla najnowzsych informacji.",
|
"serverJars2": "dla najnowzsych informacji.",
|
||||||
"start-error": "Serwer {} nie mógł się odpalić z powodu: {}",
|
"start-error": "Serwer {} nie mógł się odpalić z powodu: {}",
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
"created": "สร้างเมื่อ",
|
"created": "สร้างเมื่อ",
|
||||||
"deleteKeyConfirmation": "คุณต้องการลบคีย์ API นี้หรือไม่ สิ่งนี้ไม่สามารถยกเลิกได้",
|
"deleteKeyConfirmation": "คุณต้องการลบคีย์ API นี้หรือไม่ สิ่งนี้ไม่สามารถยกเลิกได้",
|
||||||
"deleteKeyConfirmationTitle": "ลบคีย์ API นี้ ${keyId} หรือไม่?",
|
"deleteKeyConfirmationTitle": "ลบคีย์ API นี้ ${keyId} หรือไม่?",
|
||||||
|
"fullAccess": "เข้าถึงได้ทั้งหมด",
|
||||||
"getToken": "แสดงโทเค็น",
|
"getToken": "แสดงโทเค็น",
|
||||||
"name": "ชื่อ",
|
"name": "ชื่อ",
|
||||||
"nameDesc": "คุณต้องการเรียกโทเค็น API นี้ว่าอะไร ? ",
|
"nameDesc": "คุณต้องการเรียกโทเค็น API นี้ว่าอะไร ? ",
|
||||||
@ -203,6 +204,7 @@
|
|||||||
"not-downloaded": "ดูเหมือนว่าเราจะไม่พบแฟ้มกระทำการของคุณ (.jar) ตรวจสอบให้แน่ใจว่าการดาวโหลดน์เสร็จสิ้นแล้ว, การอนุญาตถูกตั้งไปยังแฟ้มกระทำการหรือไม่?",
|
"not-downloaded": "ดูเหมือนว่าเราจะไม่พบแฟ้มกระทำการของคุณ (.jar) ตรวจสอบให้แน่ใจว่าการดาวโหลดน์เสร็จสิ้นแล้ว, การอนุญาตถูกตั้งไปยังแฟ้มกระทำการหรือไม่?",
|
||||||
"portReminder": "เราตรวจพบว่านี่เป็นครั้งแรกที่มีการเรียกใช้ {} ตรวจสอบให้แน่ใจว่าได้ Forward port {} ผ่านเราเตอร์/ไฟร์วอลล์ของคุณเพื่อให้สามารถเข้าถึงได้จากอินเทอร์เน็ตจากระยะไกล",
|
"portReminder": "เราตรวจพบว่านี่เป็นครั้งแรกที่มีการเรียกใช้ {} ตรวจสอบให้แน่ใจว่าได้ Forward port {} ผ่านเราเตอร์/ไฟร์วอลล์ของคุณเพื่อให้สามารถเข้าถึงได้จากอินเทอร์เน็ตจากระยะไกล",
|
||||||
"privMsg": "และ ",
|
"privMsg": "และ ",
|
||||||
|
"return": "ย้อนกลับไปยังแผงควบคุม",
|
||||||
"serverJars1": "ไม่สามารถเข้าถึงเซิร์ฟเวอร์ JARs API กรุณาตรวจสอบ",
|
"serverJars1": "ไม่สามารถเข้าถึงเซิร์ฟเวอร์ JARs API กรุณาตรวจสอบ",
|
||||||
"serverJars2": "เพื่อข้อมูลที่ทันสมัยที่สุด",
|
"serverJars2": "เพื่อข้อมูลที่ทันสมัยที่สุด",
|
||||||
"start-error": "เซิร์ฟเวอร์ {} ไม่สามารถเริ่มต้นได้เนื่องจากรหัสข้อผิดพลาด: {}",
|
"start-error": "เซิร์ฟเวอร์ {} ไม่สามารถเริ่มต้นได้เนื่องจากรหัสข้อผิดพลาด: {}",
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
"created": "Oluşturuldu",
|
"created": "Oluşturuldu",
|
||||||
"deleteKeyConfirmation": "Bu API anahtarını silmek istediğine emin misin? Bu geri alınamaz.",
|
"deleteKeyConfirmation": "Bu API anahtarını silmek istediğine emin misin? Bu geri alınamaz.",
|
||||||
"deleteKeyConfirmationTitle": "${keyId} API anahtarını kaldırma işlemi.",
|
"deleteKeyConfirmationTitle": "${keyId} API anahtarını kaldırma işlemi.",
|
||||||
|
"fullAccess": "Tam Erişim",
|
||||||
"getToken": "Bir Token Al",
|
"getToken": "Bir Token Al",
|
||||||
"name": "Ad",
|
"name": "Ad",
|
||||||
"nameDesc": "Bu API tokeninin adı ne olsun?",
|
"nameDesc": "Bu API tokeninin adı ne olsun?",
|
||||||
@ -203,6 +204,7 @@
|
|||||||
"not-downloaded": "Çalıştırılabilir dosyanızı bulamıyoruz. İndirme işlemi tamamlandı mı? İzinler çalıştırılabilir olarak ayarlandı mı?",
|
"not-downloaded": "Çalıştırılabilir dosyanızı bulamıyoruz. İndirme işlemi tamamlandı mı? İzinler çalıştırılabilir olarak ayarlandı mı?",
|
||||||
"portReminder": "{} ilk kez çalıştırılıyor olduğunu tespit ettik. Bunu internetten uzaktan erişilebilir kılmak için {} bağlantı noktasını yönlendiriciniz/güvenlik duvarınız üzerinden ilettiğinizden emin olun.",
|
"portReminder": "{} ilk kez çalıştırılıyor olduğunu tespit ettik. Bunu internetten uzaktan erişilebilir kılmak için {} bağlantı noktasını yönlendiriciniz/güvenlik duvarınız üzerinden ilettiğinizden emin olun.",
|
||||||
"privMsg": "ve ",
|
"privMsg": "ve ",
|
||||||
|
"return": "Arayüze Geri Dön",
|
||||||
"serverJars1": "Sunucu JARs API'ına erişilemiyor.",
|
"serverJars1": "Sunucu JARs API'ına erişilemiyor.",
|
||||||
"serverJars2": "en güncel bilgilere sahiptir",
|
"serverJars2": "en güncel bilgilere sahiptir",
|
||||||
"start-error": "{} sunucusu başlamatılamadı. Hata kodu: {}",
|
"start-error": "{} sunucusu başlamatılamadı. Hata kodu: {}",
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
"created": "Створений",
|
"created": "Створений",
|
||||||
"deleteKeyConfirmation": "Ви дійсно бажаєте видалити API ключ? Це незворотня дія.",
|
"deleteKeyConfirmation": "Ви дійсно бажаєте видалити API ключ? Це незворотня дія.",
|
||||||
"deleteKeyConfirmationTitle": "Видалення API ключ ${keyId}?",
|
"deleteKeyConfirmationTitle": "Видалення API ключ ${keyId}?",
|
||||||
|
"fullAccess": "Повний доступ",
|
||||||
"getToken": "Отримати Токен",
|
"getToken": "Отримати Токен",
|
||||||
"name": "Ім'я",
|
"name": "Ім'я",
|
||||||
"nameDesc": "Як ви хочете назвати даний API токен?",
|
"nameDesc": "Як ви хочете назвати даний API токен?",
|
||||||
@ -203,6 +204,7 @@
|
|||||||
"not-downloaded": "Здається, ми не можемо знайти ваш виконуваний файл. Чи завершилось завантаження? Чи встановлено дозволи на виконуваний файл?",
|
"not-downloaded": "Здається, ми не можемо знайти ваш виконуваний файл. Чи завершилось завантаження? Чи встановлено дозволи на виконуваний файл?",
|
||||||
"portReminder": "Ми виявили це вперше {} був запущений. Обов’язково перенаправте порт {} через ваш маршрутизатор/брандмауер, щоб зробити це доступним з Інтернету.",
|
"portReminder": "Ми виявили це вперше {} був запущений. Обов’язково перенаправте порт {} через ваш маршрутизатор/брандмауер, щоб зробити це доступним з Інтернету.",
|
||||||
"privMsg": "і ",
|
"privMsg": "і ",
|
||||||
|
"return": "Повернутись до панелі",
|
||||||
"serverJars1": "API сервера JAR недоступний. Будь ласка, перевірте",
|
"serverJars1": "API сервера JAR недоступний. Будь ласка, перевірте",
|
||||||
"serverJars2": "для найактуальнішої інформації.",
|
"serverJars2": "для найактуальнішої інформації.",
|
||||||
"start-error": "Сервер {} не запустився через помилку: {}",
|
"start-error": "Сервер {} не запустився через помилку: {}",
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
"created": "创建时间",
|
"created": "创建时间",
|
||||||
"deleteKeyConfirmation": "您想要删除这个 API 密钥吗?此操作不能撤销。",
|
"deleteKeyConfirmation": "您想要删除这个 API 密钥吗?此操作不能撤销。",
|
||||||
"deleteKeyConfirmationTitle": "删除 API 密钥 ${keyId}?",
|
"deleteKeyConfirmationTitle": "删除 API 密钥 ${keyId}?",
|
||||||
|
"fullAccess": "完全访问",
|
||||||
"getToken": "获得一个令牌",
|
"getToken": "获得一个令牌",
|
||||||
"name": "名称",
|
"name": "名称",
|
||||||
"nameDesc": "你想把这个 API 令牌叫做什么?",
|
"nameDesc": "你想把这个 API 令牌叫做什么?",
|
||||||
@ -203,6 +204,7 @@
|
|||||||
"not-downloaded": "我们似乎找不到您的可执行文件。它下载完成了吗?可执行文件的权限设置正确了吗?",
|
"not-downloaded": "我们似乎找不到您的可执行文件。它下载完成了吗?可执行文件的权限设置正确了吗?",
|
||||||
"portReminder": "我们检测到这是你首次运行 {}。请确保从您的路由器/防火墙转发 {} 端口,以使程序可以从公网远程访问。",
|
"portReminder": "我们检测到这是你首次运行 {}。请确保从您的路由器/防火墙转发 {} 端口,以使程序可以从公网远程访问。",
|
||||||
"privMsg": "以及",
|
"privMsg": "以及",
|
||||||
|
"return": "返回仪表板",
|
||||||
"serverJars1": "无法访问服务器 JAR API。请检查",
|
"serverJars1": "无法访问服务器 JAR API。请检查",
|
||||||
"serverJars2": "以获取最新信息。",
|
"serverJars2": "以获取最新信息。",
|
||||||
"start-error": "服务器 {} 启动失败,错误代码为:{}",
|
"start-error": "服务器 {} 启动失败,错误代码为:{}",
|
||||||
|
@ -18,5 +18,5 @@ termcolor==1.1
|
|||||||
tornado==6.3.3
|
tornado==6.3.3
|
||||||
tzlocal==5.1
|
tzlocal==5.1
|
||||||
jsonschema==4.19.1
|
jsonschema==4.19.1
|
||||||
orjson==3.9.7
|
orjson==3.9.15
|
||||||
prometheus-client==0.17.1
|
prometheus-client==0.17.1
|
||||||
|
@ -3,7 +3,7 @@ sonar.organization=crafty-controller
|
|||||||
|
|
||||||
# This is the name and version displayed in the SonarCloud UI.
|
# This is the name and version displayed in the SonarCloud UI.
|
||||||
sonar.projectName=Crafty 4
|
sonar.projectName=Crafty 4
|
||||||
sonar.projectVersion=4.3.2
|
sonar.projectVersion=4.3.3
|
||||||
sonar.python.version=3.9, 3.10, 3.11
|
sonar.python.version=3.9, 3.10, 3.11
|
||||||
sonar.exclusions=app/migrations/**, app/frontend/static/assets/vendors/**
|
sonar.exclusions=app/migrations/**, app/frontend/static/assets/vendors/**
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user