mirror of
https://gitlab.com/crafty-controller/crafty-4.git
synced 2024-08-30 18:23:09 +00:00
Merge branch 'dev' into tweak/support-logs-zip-comment
This commit is contained in:
commit
51d123e9eb
11
CHANGELOG.md
11
CHANGELOG.md
@ -1,11 +1,16 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
## --- [4.0.11] - 2022/TBD
|
## --- [4.0.11] - 2022/TBD
|
||||||
### New features
|
### New features
|
||||||
TBD
|
- Add server import status indicators ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/433))
|
||||||
|
- Users can now be assigned as manager of other users/roles ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/434))
|
||||||
|
- Add variable shutdown timeouts ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/435))
|
||||||
|
- Add server metrics graph ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/436))
|
||||||
### Bug fixes
|
### Bug fixes
|
||||||
TBD
|
- Fix creation quota not refilling after server delete ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/434))
|
||||||
|
- Add missing bedrock dependency (libcurl.so.4) ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/437))
|
||||||
### Tweaks
|
### Tweaks
|
||||||
TBD
|
- Make imports threaded ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/433))
|
||||||
|
- Add 'Created By' Field to servers ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/434))
|
||||||
### Lang
|
### Lang
|
||||||
TBD
|
TBD
|
||||||
<br><br>
|
<br><br>
|
||||||
|
@ -15,6 +15,7 @@ RUN apt-get update \
|
|||||||
&& apt-get -y --no-install-recommends install \
|
&& apt-get -y --no-install-recommends install \
|
||||||
sudo \
|
sudo \
|
||||||
gcc \
|
gcc \
|
||||||
|
libcurl4 \
|
||||||
python3 \
|
python3 \
|
||||||
python3-dev \
|
python3-dev \
|
||||||
python3-pip \
|
python3-pip \
|
||||||
|
@ -60,26 +60,6 @@ class CraftyPermsController:
|
|||||||
permissions_list = PermissionsCrafty.get_permissions(permissions_mask)
|
permissions_list = PermissionsCrafty.get_permissions(permissions_mask)
|
||||||
return permissions_list
|
return permissions_list
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def add_server_creation(user_id):
|
|
||||||
"""Increase the "Server Creation" counter for this user
|
|
||||||
|
|
||||||
Args:
|
|
||||||
user_id (int): The modifiable user's ID
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
int: The new count of servers created by this user
|
|
||||||
"""
|
|
||||||
return PermissionsCrafty.add_server_creation(user_id)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def add_user_creation(user_id):
|
|
||||||
return PermissionsCrafty.add_user_creation(user_id)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def add_role_creation(user_id):
|
|
||||||
return PermissionsCrafty.add_role_creation(user_id)
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_api_key_permissions_list(key: ApiKeys):
|
def get_api_key_permissions_list(key: ApiKeys):
|
||||||
return PermissionsCrafty.get_api_key_permissions_list(key)
|
return PermissionsCrafty.get_api_key_permissions_list(key)
|
||||||
|
@ -64,8 +64,8 @@ class RolesController:
|
|||||||
HelperRoles.update_role(role_id, up_data)
|
HelperRoles.update_role(role_id, up_data)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def add_role(role_name):
|
def add_role(role_name, manager):
|
||||||
return HelperRoles.add_role(role_name)
|
return HelperRoles.add_role(role_name, manager)
|
||||||
|
|
||||||
class RoleServerJsonType(t.TypedDict):
|
class RoleServerJsonType(t.TypedDict):
|
||||||
server_id: t.Union[str, int]
|
server_id: t.Union[str, int]
|
||||||
@ -92,6 +92,7 @@ class RolesController:
|
|||||||
def add_role_advanced(
|
def add_role_advanced(
|
||||||
name: str,
|
name: str,
|
||||||
servers: t.Iterable[RoleServerJsonType],
|
servers: t.Iterable[RoleServerJsonType],
|
||||||
|
manager: int,
|
||||||
) -> int:
|
) -> int:
|
||||||
"""Add a role with a name and a list of servers
|
"""Add a role with a name and a list of servers
|
||||||
|
|
||||||
@ -102,7 +103,7 @@ class RolesController:
|
|||||||
Returns:
|
Returns:
|
||||||
int: The new role's ID
|
int: The new role's ID
|
||||||
"""
|
"""
|
||||||
role_id: t.Final[int] = HelperRoles.add_role(name)
|
role_id: t.Final[int] = HelperRoles.add_role(name, manager)
|
||||||
for server in servers:
|
for server in servers:
|
||||||
PermissionsServers.get_or_create(
|
PermissionsServers.get_or_create(
|
||||||
role_id, server["server_id"], server["permissions"]
|
role_id, server["server_id"], server["permissions"]
|
||||||
@ -114,6 +115,7 @@ class RolesController:
|
|||||||
role_id: t.Union[str, int],
|
role_id: t.Union[str, int],
|
||||||
role_name: t.Optional[str],
|
role_name: t.Optional[str],
|
||||||
servers: t.Optional[t.Iterable[RoleServerJsonType]],
|
servers: t.Optional[t.Iterable[RoleServerJsonType]],
|
||||||
|
manager: int,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Update a role with a name and a list of servers
|
"""Update a role with a name and a list of servers
|
||||||
|
|
||||||
@ -152,6 +154,7 @@ class RolesController:
|
|||||||
up_data = {
|
up_data = {
|
||||||
"role_name": role_name,
|
"role_name": role_name,
|
||||||
"last_update": Helpers.get_time_as_string(),
|
"last_update": Helpers.get_time_as_string(),
|
||||||
|
"manager": manager,
|
||||||
}
|
}
|
||||||
# TODO: do the last_update on the db side
|
# TODO: do the last_update on the db side
|
||||||
HelperRoles.update_role(role_id, up_data)
|
HelperRoles.update_role(role_id, up_data)
|
||||||
|
@ -4,6 +4,7 @@ import time
|
|||||||
import json
|
import json
|
||||||
import pathlib
|
import pathlib
|
||||||
import typing as t
|
import typing as t
|
||||||
|
import datetime
|
||||||
|
|
||||||
from app.classes.controllers.roles_controller import RolesController
|
from app.classes.controllers.roles_controller import RolesController
|
||||||
from app.classes.shared.file_helpers import FileHelpers
|
from app.classes.shared.file_helpers import FileHelpers
|
||||||
@ -51,6 +52,7 @@ class ServersController(metaclass=Singleton):
|
|||||||
server_log_file: str,
|
server_log_file: str,
|
||||||
server_stop: str,
|
server_stop: str,
|
||||||
server_type: str,
|
server_type: str,
|
||||||
|
created_by: int,
|
||||||
server_port: int = 25565,
|
server_port: int = 25565,
|
||||||
server_host: str = "127.0.0.1",
|
server_host: str = "127.0.0.1",
|
||||||
) -> int:
|
) -> int:
|
||||||
@ -85,6 +87,7 @@ class ServersController(metaclass=Singleton):
|
|||||||
server_log_file,
|
server_log_file,
|
||||||
server_stop,
|
server_stop,
|
||||||
server_type,
|
server_type,
|
||||||
|
created_by,
|
||||||
server_port,
|
server_port,
|
||||||
server_host,
|
server_host,
|
||||||
)
|
)
|
||||||
@ -102,25 +105,32 @@ class ServersController(metaclass=Singleton):
|
|||||||
server_instance.update_server_instance()
|
server_instance.update_server_instance()
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
def get_history_stats(self, server_id):
|
||||||
|
max_age = self.helper.get_setting("history_max_age")
|
||||||
|
now = datetime.datetime.now()
|
||||||
|
minimum_to_exist = now - datetime.timedelta(days=max_age)
|
||||||
|
srv = ServersController().get_server_instance_by_id(server_id)
|
||||||
|
return srv.stats_helper.get_history_stats(server_id, minimum_to_exist)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def update_unloaded_server(server_obj):
|
def update_unloaded_server(server_obj):
|
||||||
ret = HelperServers.update_server(server_obj)
|
ret = HelperServers.update_server(server_obj)
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def set_download(server_id):
|
def set_import(server_id):
|
||||||
srv = ServersController().get_server_instance_by_id(server_id)
|
srv = ServersController().get_server_instance_by_id(server_id)
|
||||||
return srv.stats_helper.set_download()
|
return srv.stats_helper.set_import()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def finish_download(server_id):
|
def finish_import(server_id):
|
||||||
srv = ServersController().get_server_instance_by_id(server_id)
|
srv = ServersController().get_server_instance_by_id(server_id)
|
||||||
return srv.stats_helper.finish_download()
|
return srv.stats_helper.finish_import()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_download_status(server_id):
|
def get_import_status(server_id):
|
||||||
server = ServersController().get_server_instance_by_id(server_id)
|
server = ServersController().get_server_instance_by_id(server_id)
|
||||||
return server.stats_helper.get_download_status()
|
return server.stats_helper.get_import_status()
|
||||||
|
|
||||||
def remove_server(self, server_id):
|
def remove_server(self, server_id):
|
||||||
roles_list = PermissionsServers.get_roles_from_server(server_id)
|
roles_list = PermissionsServers.get_roles_from_server(server_id)
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
import logging
|
import logging
|
||||||
import typing as t
|
import typing as t
|
||||||
|
from app.classes.models.servers import HelperServers
|
||||||
|
|
||||||
from app.classes.models.users import HelperUsers
|
from app.classes.models.users import HelperUsers
|
||||||
|
from app.classes.models.roles import HelperRoles
|
||||||
from app.classes.models.crafty_permissions import (
|
from app.classes.models.crafty_permissions import (
|
||||||
PermissionsCrafty,
|
PermissionsCrafty,
|
||||||
EnumPermissionsCrafty,
|
EnumPermissionsCrafty,
|
||||||
@ -132,6 +134,18 @@ class UsersController:
|
|||||||
def set_support_path(user_id, support_path):
|
def set_support_path(user_id, support_path):
|
||||||
HelperUsers.set_support_path(user_id, support_path)
|
HelperUsers.set_support_path(user_id, support_path)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_managed_users(exec_user_id):
|
||||||
|
return HelperUsers.get_managed_users(exec_user_id)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_managed_roles(exec_user_id):
|
||||||
|
return HelperUsers.get_managed_roles(exec_user_id)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_created_servers(exec_user_id):
|
||||||
|
return HelperServers.get_total_owned_servers(exec_user_id)
|
||||||
|
|
||||||
def update_user(self, user_id: str, user_data=None, user_crafty_data=None):
|
def update_user(self, user_id: str, user_data=None, user_crafty_data=None):
|
||||||
if user_crafty_data is None:
|
if user_crafty_data is None:
|
||||||
user_crafty_data = {}
|
user_crafty_data = {}
|
||||||
@ -206,6 +220,7 @@ class UsersController:
|
|||||||
def add_user(
|
def add_user(
|
||||||
self,
|
self,
|
||||||
username,
|
username,
|
||||||
|
manager,
|
||||||
password,
|
password,
|
||||||
email="default@example.com",
|
email="default@example.com",
|
||||||
enabled: bool = True,
|
enabled: bool = True,
|
||||||
@ -213,6 +228,7 @@ class UsersController:
|
|||||||
):
|
):
|
||||||
return self.users_helper.add_user(
|
return self.users_helper.add_user(
|
||||||
username,
|
username,
|
||||||
|
manager,
|
||||||
password=password,
|
password=password,
|
||||||
email=email,
|
email=email,
|
||||||
enabled=enabled,
|
enabled=enabled,
|
||||||
@ -236,6 +252,10 @@ class UsersController:
|
|||||||
)
|
)
|
||||||
|
|
||||||
def remove_user(self, user_id):
|
def remove_user(self, user_id):
|
||||||
|
for user in self.get_managed_users(user_id):
|
||||||
|
self.update_user(user.user_id, {"manager": None})
|
||||||
|
for role in HelperUsers.get_managed_roles(user_id):
|
||||||
|
HelperRoles.update_role(role.role_id, {"manager": None})
|
||||||
return self.users_helper.remove_user(user_id)
|
return self.users_helper.remove_user(user_id)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -175,7 +175,7 @@ class ServerJars:
|
|||||||
# we submit a db update for it's stats.
|
# we submit a db update for it's stats.
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
ServersController.set_download(server_id)
|
ServersController.set_import(server_id)
|
||||||
for user in server_users:
|
for user in server_users:
|
||||||
self.helper.websocket_helper.broadcast_user(
|
self.helper.websocket_helper.broadcast_user(
|
||||||
user, "send_start_reload", {}
|
user, "send_start_reload", {}
|
||||||
@ -190,7 +190,7 @@ class ServerJars:
|
|||||||
try:
|
try:
|
||||||
with open(path, "wb") as output:
|
with open(path, "wb") as output:
|
||||||
shutil.copyfileobj(r.raw, output)
|
shutil.copyfileobj(r.raw, output)
|
||||||
ServersController.finish_download(server_id)
|
ServersController.finish_import(server_id)
|
||||||
|
|
||||||
for user in server_users:
|
for user in server_users:
|
||||||
self.helper.websocket_helper.broadcast_user(
|
self.helper.websocket_helper.broadcast_user(
|
||||||
@ -203,7 +203,7 @@ class ServerJars:
|
|||||||
return True
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Unable to save jar to {path} due to error:{e}")
|
logger.error(f"Unable to save jar to {path} due to error:{e}")
|
||||||
ServersController.finish_download(server_id)
|
ServersController.finish_import(server_id)
|
||||||
server_users = PermissionsServers.get_server_user_list(server_id)
|
server_users = PermissionsServers.get_server_user_list(server_id)
|
||||||
for user in server_users:
|
for user in server_users:
|
||||||
self.helper.websocket_helper.broadcast_user(
|
self.helper.websocket_helper.broadcast_user(
|
||||||
|
@ -9,6 +9,7 @@ from peewee import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
from app.classes.models.base_model import BaseModel
|
from app.classes.models.base_model import BaseModel
|
||||||
|
from app.classes.models.servers import HelperServers
|
||||||
from app.classes.models.users import Users, ApiKeys, HelperUsers
|
from app.classes.models.users import Users, ApiKeys, HelperUsers
|
||||||
from app.classes.shared.permission_helper import PermissionHelper
|
from app.classes.shared.permission_helper import PermissionHelper
|
||||||
|
|
||||||
@ -23,9 +24,6 @@ class UserCrafty(BaseModel):
|
|||||||
limit_server_creation = IntegerField(default=-1)
|
limit_server_creation = IntegerField(default=-1)
|
||||||
limit_user_creation = IntegerField(default=0)
|
limit_user_creation = IntegerField(default=0)
|
||||||
limit_role_creation = IntegerField(default=0)
|
limit_role_creation = IntegerField(default=0)
|
||||||
created_server = IntegerField(default=0)
|
|
||||||
created_user = IntegerField(default=0)
|
|
||||||
created_role = IntegerField(default=0)
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
table_name = "user_crafty"
|
table_name = "user_crafty"
|
||||||
@ -107,9 +105,6 @@ class PermissionsCrafty:
|
|||||||
UserCrafty.limit_server_creation: 0,
|
UserCrafty.limit_server_creation: 0,
|
||||||
UserCrafty.limit_user_creation: 0,
|
UserCrafty.limit_user_creation: 0,
|
||||||
UserCrafty.limit_role_creation: 0,
|
UserCrafty.limit_role_creation: 0,
|
||||||
UserCrafty.created_server: 0,
|
|
||||||
UserCrafty.created_user: 0,
|
|
||||||
UserCrafty.created_role: 0,
|
|
||||||
}
|
}
|
||||||
).execute()
|
).execute()
|
||||||
user_crafty = PermissionsCrafty.get_user_crafty(user_id)
|
user_crafty = PermissionsCrafty.get_user_crafty(user_id)
|
||||||
@ -159,11 +154,16 @@ class PermissionsCrafty:
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_created_quantity_list(user_id):
|
def get_created_quantity_list(user_id):
|
||||||
user_crafty = PermissionsCrafty.get_user_crafty(user_id)
|
|
||||||
quantity_list = {
|
quantity_list = {
|
||||||
EnumPermissionsCrafty.SERVER_CREATION.name: user_crafty.created_server,
|
EnumPermissionsCrafty.SERVER_CREATION.name: HelperServers.get_total_owned_servers( # pylint: disable=line-too-long
|
||||||
EnumPermissionsCrafty.USER_CONFIG.name: user_crafty.created_user,
|
user_id
|
||||||
EnumPermissionsCrafty.ROLES_CONFIG.name: user_crafty.created_role,
|
),
|
||||||
|
EnumPermissionsCrafty.USER_CONFIG.name: HelperUsers.get_managed_users(
|
||||||
|
user_id
|
||||||
|
).count(),
|
||||||
|
EnumPermissionsCrafty.ROLES_CONFIG.name: HelperUsers.get_managed_roles(
|
||||||
|
user_id
|
||||||
|
).count(),
|
||||||
}
|
}
|
||||||
return quantity_list
|
return quantity_list
|
||||||
|
|
||||||
@ -183,31 +183,6 @@ class PermissionsCrafty:
|
|||||||
or limit_list[permission.name] == -1
|
or limit_list[permission.name] == -1
|
||||||
)
|
)
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def add_server_creation(user_id: int):
|
|
||||||
"""Increase the "Server Creation" counter for this user
|
|
||||||
|
|
||||||
Args:
|
|
||||||
user_id (int): The modifiable user's ID
|
|
||||||
"""
|
|
||||||
UserCrafty.update(created_server=UserCrafty.created_server + 1).where(
|
|
||||||
UserCrafty.user_id == user_id
|
|
||||||
).execute()
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def add_user_creation(user_id):
|
|
||||||
user_crafty = PermissionsCrafty.get_user_crafty(user_id)
|
|
||||||
user_crafty.created_user += 1
|
|
||||||
UserCrafty.save(user_crafty)
|
|
||||||
return user_crafty.created_user
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def add_role_creation(user_id):
|
|
||||||
user_crafty = PermissionsCrafty.get_user_crafty(user_id)
|
|
||||||
user_crafty.created_role += 1
|
|
||||||
UserCrafty.save(user_crafty)
|
|
||||||
return user_crafty.created_role
|
|
||||||
|
|
||||||
@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)
|
||||||
|
@ -6,6 +6,7 @@ from peewee import (
|
|||||||
DoesNotExist,
|
DoesNotExist,
|
||||||
AutoField,
|
AutoField,
|
||||||
DateTimeField,
|
DateTimeField,
|
||||||
|
IntegerField,
|
||||||
)
|
)
|
||||||
from playhouse.shortcuts import model_to_dict
|
from playhouse.shortcuts import model_to_dict
|
||||||
|
|
||||||
@ -22,6 +23,7 @@ class Roles(BaseModel):
|
|||||||
created = DateTimeField(default=datetime.datetime.now)
|
created = DateTimeField(default=datetime.datetime.now)
|
||||||
last_update = DateTimeField(default=datetime.datetime.now)
|
last_update = DateTimeField(default=datetime.datetime.now)
|
||||||
role_name = CharField(default="", unique=True, index=True)
|
role_name = CharField(default="", unique=True, index=True)
|
||||||
|
manager = IntegerField(null=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
table_name = "roles"
|
table_name = "roles"
|
||||||
@ -71,11 +73,12 @@ class HelperRoles:
|
|||||||
)
|
)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def add_role(role_name):
|
def add_role(role_name, manager):
|
||||||
role_id = Roles.insert(
|
role_id = Roles.insert(
|
||||||
{
|
{
|
||||||
Roles.role_name: role_name.lower(),
|
Roles.role_name: role_name.lower(),
|
||||||
Roles.created: Helpers.get_time_as_string(),
|
Roles.created: Helpers.get_time_as_string(),
|
||||||
|
Roles.manager: manager,
|
||||||
}
|
}
|
||||||
).execute()
|
).execute()
|
||||||
return role_id
|
return role_id
|
||||||
|
@ -53,7 +53,7 @@ class ServerStats(Model):
|
|||||||
waiting_start = BooleanField(default=False)
|
waiting_start = BooleanField(default=False)
|
||||||
first_run = BooleanField(default=True)
|
first_run = BooleanField(default=True)
|
||||||
crashed = BooleanField(default=False)
|
crashed = BooleanField(default=False)
|
||||||
downloading = BooleanField(default=False)
|
importing = BooleanField(default=False)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
table_name = "server_stats"
|
table_name = "server_stats"
|
||||||
@ -137,6 +137,14 @@ class HelperServerStats:
|
|||||||
)
|
)
|
||||||
return server_data
|
return server_data
|
||||||
|
|
||||||
|
def get_history_stats(self, server_id, max_age):
|
||||||
|
return (
|
||||||
|
ServerStats.select()
|
||||||
|
.where(ServerStats.created > max_age)
|
||||||
|
.where(ServerStats.server_id == server_id)
|
||||||
|
.execute(self.database)
|
||||||
|
)
|
||||||
|
|
||||||
def insert_server_stats(self, server_stats):
|
def insert_server_stats(self, server_stats):
|
||||||
server_id = server_stats.get("id", 0)
|
server_id = server_stats.get("id", 0)
|
||||||
|
|
||||||
@ -207,26 +215,26 @@ class HelperServerStats:
|
|||||||
ServerStats.server_id == self.server_id
|
ServerStats.server_id == self.server_id
|
||||||
).execute(self.database)
|
).execute(self.database)
|
||||||
|
|
||||||
def set_download(self):
|
def set_import(self):
|
||||||
# self.select_database(self.server_id)
|
# self.select_database(self.server_id)
|
||||||
ServerStats.update(downloading=True).where(
|
ServerStats.update(importing=True).where(
|
||||||
ServerStats.server_id == self.server_id
|
ServerStats.server_id == self.server_id
|
||||||
).execute(self.database)
|
).execute(self.database)
|
||||||
|
|
||||||
def finish_download(self):
|
def finish_import(self):
|
||||||
# self.select_database(self.server_id)
|
# self.select_database(self.server_id)
|
||||||
ServerStats.update(downloading=False).where(
|
ServerStats.update(importing=False).where(
|
||||||
ServerStats.server_id == self.server_id
|
ServerStats.server_id == self.server_id
|
||||||
).execute(self.database)
|
).execute(self.database)
|
||||||
|
|
||||||
def get_download_status(self):
|
def get_import_status(self):
|
||||||
# self.select_database(self.server_id)
|
# self.select_database(self.server_id)
|
||||||
download_status = (
|
import_status = (
|
||||||
ServerStats.select()
|
ServerStats.select()
|
||||||
.where(ServerStats.server_id == self.server_id)
|
.where(ServerStats.server_id == self.server_id)
|
||||||
.get(self.database)
|
.get(self.database)
|
||||||
)
|
)
|
||||||
return download_status.downloading
|
return import_status.importing
|
||||||
|
|
||||||
def server_crash_reset(self):
|
def server_crash_reset(self):
|
||||||
if self.server_id is None:
|
if self.server_id is None:
|
||||||
@ -249,7 +257,6 @@ class HelperServerStats:
|
|||||||
def set_update(self, value):
|
def set_update(self, value):
|
||||||
if self.server_id is None:
|
if self.server_id is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
# self.select_database(self.server_id)
|
# self.select_database(self.server_id)
|
||||||
try:
|
try:
|
||||||
# Checks if server even exists
|
# Checks if server even exists
|
||||||
|
@ -38,6 +38,8 @@ class Servers(BaseModel):
|
|||||||
logs_delete_after = IntegerField(default=0)
|
logs_delete_after = IntegerField(default=0)
|
||||||
type = CharField(default="minecraft-java")
|
type = CharField(default="minecraft-java")
|
||||||
show_status = BooleanField(default=1)
|
show_status = BooleanField(default=1)
|
||||||
|
created_by = IntegerField(default=-100)
|
||||||
|
shutdown_timeout = IntegerField(default=60)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
table_name = "servers"
|
table_name = "servers"
|
||||||
@ -64,6 +66,7 @@ class HelperServers:
|
|||||||
server_log_file: str,
|
server_log_file: str,
|
||||||
server_stop: str,
|
server_stop: str,
|
||||||
server_type: str,
|
server_type: str,
|
||||||
|
created_by: int,
|
||||||
server_port: int = 25565,
|
server_port: int = 25565,
|
||||||
server_host: str = "127.0.0.1",
|
server_host: str = "127.0.0.1",
|
||||||
) -> int:
|
) -> int:
|
||||||
@ -105,6 +108,7 @@ class HelperServers:
|
|||||||
Servers.stop_command: server_stop,
|
Servers.stop_command: server_stop,
|
||||||
Servers.backup_path: backup_path,
|
Servers.backup_path: backup_path,
|
||||||
Servers.type: server_type,
|
Servers.type: server_type,
|
||||||
|
Servers.created_by: created_by,
|
||||||
}
|
}
|
||||||
).execute()
|
).execute()
|
||||||
|
|
||||||
@ -112,6 +116,10 @@ class HelperServers:
|
|||||||
def get_server_obj(server_id):
|
def get_server_obj(server_id):
|
||||||
return Servers.get_by_id(server_id)
|
return Servers.get_by_id(server_id)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_total_owned_servers(user_id):
|
||||||
|
return Servers.select().where(Servers.created_by == user_id).count()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_server_type_by_id(server_id):
|
def get_server_type_by_id(server_id):
|
||||||
server_type = Servers.select().where(Servers.server_id == server_id).get()
|
server_type = Servers.select().where(Servers.server_id == server_id).get()
|
||||||
|
@ -6,6 +6,7 @@ from peewee import (
|
|||||||
ForeignKeyField,
|
ForeignKeyField,
|
||||||
CharField,
|
CharField,
|
||||||
AutoField,
|
AutoField,
|
||||||
|
IntegerField,
|
||||||
DateTimeField,
|
DateTimeField,
|
||||||
BooleanField,
|
BooleanField,
|
||||||
CompositeKey,
|
CompositeKey,
|
||||||
@ -40,6 +41,7 @@ class Users(BaseModel):
|
|||||||
server_order = CharField(default="")
|
server_order = CharField(default="")
|
||||||
preparing = BooleanField(default=False)
|
preparing = BooleanField(default=False)
|
||||||
hints = BooleanField(default=True)
|
hints = BooleanField(default=True)
|
||||||
|
manager = IntegerField(default=None, null=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
table_name = "users"
|
table_name = "users"
|
||||||
@ -138,6 +140,16 @@ class HelperUsers:
|
|||||||
user_query = Users.select().where(Users.user_id == user_id)
|
user_query = Users.select().where(Users.user_id == user_id)
|
||||||
return user_query
|
return user_query
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_managed_users(exec_user_id):
|
||||||
|
user_query = Users.select().where(Users.manager == exec_user_id)
|
||||||
|
return user_query
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_managed_roles(exec_user_id):
|
||||||
|
roles_query = Roles.select().where(Roles.manager == exec_user_id)
|
||||||
|
return roles_query
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_user(user_id):
|
def get_user(user_id):
|
||||||
if user_id == 0:
|
if user_id == 0:
|
||||||
@ -192,6 +204,7 @@ class HelperUsers:
|
|||||||
def add_user(
|
def add_user(
|
||||||
self,
|
self,
|
||||||
username: str,
|
username: str,
|
||||||
|
manager: str,
|
||||||
password: str = None,
|
password: str = None,
|
||||||
email: t.Optional[str] = None,
|
email: t.Optional[str] = None,
|
||||||
enabled: bool = True,
|
enabled: bool = True,
|
||||||
@ -209,6 +222,7 @@ class HelperUsers:
|
|||||||
Users.enabled: enabled,
|
Users.enabled: enabled,
|
||||||
Users.superuser: superuser,
|
Users.superuser: superuser,
|
||||||
Users.created: Helpers.get_time_as_string(),
|
Users.created: Helpers.get_time_as_string(),
|
||||||
|
Users.manager: manager,
|
||||||
}
|
}
|
||||||
).execute()
|
).execute()
|
||||||
return user_id
|
return user_id
|
||||||
@ -229,6 +243,7 @@ class HelperUsers:
|
|||||||
Users.enabled: enabled,
|
Users.enabled: enabled,
|
||||||
Users.superuser: superuser,
|
Users.superuser: superuser,
|
||||||
Users.created: Helpers.get_time_as_string(),
|
Users.created: Helpers.get_time_as_string(),
|
||||||
|
Users.manager: None,
|
||||||
}
|
}
|
||||||
).execute()
|
).execute()
|
||||||
return user_id
|
return user_id
|
||||||
|
@ -27,10 +27,15 @@ class FileHelpers:
|
|||||||
FileHelpers.del_dirs(sub)
|
FileHelpers.del_dirs(sub)
|
||||||
else:
|
else:
|
||||||
# Delete file if it is a file:
|
# Delete file if it is a file:
|
||||||
|
try:
|
||||||
sub.unlink()
|
sub.unlink()
|
||||||
|
except:
|
||||||
|
logger.error(f"Unable to delete file {sub}")
|
||||||
|
try:
|
||||||
# This removes the top-level folder:
|
# This removes the top-level folder:
|
||||||
path.rmdir()
|
path.rmdir()
|
||||||
|
except:
|
||||||
|
logger.error("Unable to remove top level")
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
216
app/classes/shared/import_helper.py
Normal file
216
app/classes/shared/import_helper.py
Normal file
@ -0,0 +1,216 @@
|
|||||||
|
import os
|
||||||
|
import time
|
||||||
|
import shutil
|
||||||
|
import logging
|
||||||
|
import threading
|
||||||
|
|
||||||
|
from app.classes.controllers.server_perms_controller import PermissionsServers
|
||||||
|
from app.classes.controllers.servers_controller import ServersController
|
||||||
|
from app.classes.shared.helpers import Helpers
|
||||||
|
from app.classes.shared.file_helpers import FileHelpers
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class ImportHelpers:
|
||||||
|
allowed_quotes = ['"', "'", "`"]
|
||||||
|
|
||||||
|
def __init__(self, helper, file_helper):
|
||||||
|
self.file_helper: FileHelpers = file_helper
|
||||||
|
self.helper: Helpers = helper
|
||||||
|
|
||||||
|
def import_jar_server(self, server_path, new_server_dir, port, new_id):
|
||||||
|
import_thread = threading.Thread(
|
||||||
|
target=self.import_threaded_jar_server,
|
||||||
|
daemon=True,
|
||||||
|
args=(server_path, new_server_dir, port, new_id),
|
||||||
|
name=f"{new_id}_import",
|
||||||
|
)
|
||||||
|
import_thread.start()
|
||||||
|
|
||||||
|
def import_threaded_jar_server(self, server_path, new_server_dir, port, new_id):
|
||||||
|
for item in os.listdir(server_path):
|
||||||
|
if not item == "db_stats":
|
||||||
|
try:
|
||||||
|
if os.path.isdir(os.path.join(server_path, item)):
|
||||||
|
FileHelpers.copy_dir(
|
||||||
|
os.path.join(server_path, item),
|
||||||
|
os.path.join(new_server_dir, item),
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
FileHelpers.copy_file(
|
||||||
|
os.path.join(server_path, item),
|
||||||
|
os.path.join(new_server_dir, item),
|
||||||
|
)
|
||||||
|
except shutil.Error as ex:
|
||||||
|
logger.error(f"Server import failed with error: {ex}")
|
||||||
|
|
||||||
|
has_properties = False
|
||||||
|
for item in os.listdir(new_server_dir):
|
||||||
|
if str(item) == "server.properties":
|
||||||
|
has_properties = True
|
||||||
|
if not has_properties:
|
||||||
|
logger.info(
|
||||||
|
f"No server.properties found on zip file import. "
|
||||||
|
f"Creating one with port selection of {str(port)}"
|
||||||
|
)
|
||||||
|
with open(
|
||||||
|
os.path.join(new_server_dir, "server.properties"), "w", encoding="utf-8"
|
||||||
|
) as file:
|
||||||
|
file.write(f"server-port={port}")
|
||||||
|
file.close()
|
||||||
|
time.sleep(5)
|
||||||
|
ServersController.finish_import(new_id)
|
||||||
|
server_users = PermissionsServers.get_server_user_list(new_id)
|
||||||
|
for user in server_users:
|
||||||
|
self.helper.websocket_helper.broadcast_user(user, "send_start_reload", {})
|
||||||
|
|
||||||
|
def import_java_zip_server(self, temp_dir, new_server_dir, port, new_id):
|
||||||
|
import_thread = threading.Thread(
|
||||||
|
target=self.import_threaded_java_zip_server,
|
||||||
|
daemon=True,
|
||||||
|
args=(temp_dir, new_server_dir, port, new_id),
|
||||||
|
name=f"{new_id}_java_zip_import",
|
||||||
|
)
|
||||||
|
import_thread.start()
|
||||||
|
|
||||||
|
def import_threaded_java_zip_server(self, temp_dir, new_server_dir, port, new_id):
|
||||||
|
has_properties = False
|
||||||
|
# extracts archive to temp directory
|
||||||
|
for item in os.listdir(temp_dir):
|
||||||
|
if str(item) == "server.properties":
|
||||||
|
has_properties = True
|
||||||
|
try:
|
||||||
|
if not os.path.isdir(os.path.join(temp_dir, item)):
|
||||||
|
FileHelpers.move_file(
|
||||||
|
os.path.join(temp_dir, item), os.path.join(new_server_dir, item)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
if item != "db_stats":
|
||||||
|
FileHelpers.move_dir(
|
||||||
|
os.path.join(temp_dir, item),
|
||||||
|
os.path.join(new_server_dir, item),
|
||||||
|
)
|
||||||
|
except Exception as ex:
|
||||||
|
logger.error(f"ERROR IN ZIP IMPORT: {ex}")
|
||||||
|
if not has_properties:
|
||||||
|
logger.info(
|
||||||
|
f"No server.properties found on zip file import. "
|
||||||
|
f"Creating one with port selection of {str(port)}"
|
||||||
|
)
|
||||||
|
with open(
|
||||||
|
os.path.join(new_server_dir, "server.properties"), "w", encoding="utf-8"
|
||||||
|
) as file:
|
||||||
|
file.write(f"server-port={port}")
|
||||||
|
file.close()
|
||||||
|
|
||||||
|
server_users = PermissionsServers.get_server_user_list(new_id)
|
||||||
|
ServersController.finish_import(new_id)
|
||||||
|
for user in server_users:
|
||||||
|
self.helper.websocket_helper.broadcast_user(user, "send_start_reload", {})
|
||||||
|
# deletes temp dir
|
||||||
|
FileHelpers.del_dirs(temp_dir)
|
||||||
|
|
||||||
|
def import_bedrock_server(
|
||||||
|
self, server_path, new_server_dir, port, full_jar_path, new_id
|
||||||
|
):
|
||||||
|
import_thread = threading.Thread(
|
||||||
|
target=self.import_threaded_bedrock_server,
|
||||||
|
daemon=True,
|
||||||
|
args=(server_path, new_server_dir, port, full_jar_path, new_id),
|
||||||
|
name=f"{new_id}_bedrock_import",
|
||||||
|
)
|
||||||
|
import_thread.start()
|
||||||
|
|
||||||
|
def import_threaded_bedrock_server(
|
||||||
|
self, server_path, new_server_dir, port, full_jar_path, new_id
|
||||||
|
):
|
||||||
|
for item in os.listdir(server_path):
|
||||||
|
if not item == "db_stats":
|
||||||
|
try:
|
||||||
|
if os.path.isdir(os.path.join(server_path, item)):
|
||||||
|
FileHelpers.copy_dir(
|
||||||
|
os.path.join(server_path, item),
|
||||||
|
os.path.join(new_server_dir, item),
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
FileHelpers.copy_file(
|
||||||
|
os.path.join(server_path, item),
|
||||||
|
os.path.join(new_server_dir, item),
|
||||||
|
)
|
||||||
|
except shutil.Error as ex:
|
||||||
|
logger.error(f"Server import failed with error: {ex}")
|
||||||
|
|
||||||
|
has_properties = False
|
||||||
|
for item in os.listdir(new_server_dir):
|
||||||
|
if str(item) == "server.properties":
|
||||||
|
has_properties = True
|
||||||
|
if not has_properties:
|
||||||
|
logger.info(
|
||||||
|
f"No server.properties found on zip file import. "
|
||||||
|
f"Creating one with port selection of {str(port)}"
|
||||||
|
)
|
||||||
|
with open(
|
||||||
|
os.path.join(new_server_dir, "server.properties"), "w", encoding="utf-8"
|
||||||
|
) as file:
|
||||||
|
file.write(f"server-port={port}")
|
||||||
|
file.close()
|
||||||
|
if os.name != "nt":
|
||||||
|
if Helpers.check_file_exists(full_jar_path):
|
||||||
|
os.chmod(full_jar_path, 0o2760)
|
||||||
|
ServersController.finish_import(new_id)
|
||||||
|
server_users = PermissionsServers.get_server_user_list(new_id)
|
||||||
|
for user in server_users:
|
||||||
|
self.helper.websocket_helper.broadcast_user(user, "send_start_reload", {})
|
||||||
|
|
||||||
|
def import_bedrock_zip_server(
|
||||||
|
self, temp_dir, new_server_dir, full_jar_path, port, new_id
|
||||||
|
):
|
||||||
|
import_thread = threading.Thread(
|
||||||
|
target=self.import_threaded_bedrock_zip_server,
|
||||||
|
daemon=True,
|
||||||
|
args=(temp_dir, new_server_dir, full_jar_path, port, new_id),
|
||||||
|
name=f"{new_id}_bedrock_import",
|
||||||
|
)
|
||||||
|
import_thread.start()
|
||||||
|
|
||||||
|
def import_threaded_bedrock_zip_server(
|
||||||
|
self, temp_dir, new_server_dir, full_jar_path, port, new_id
|
||||||
|
):
|
||||||
|
has_properties = False
|
||||||
|
# extracts archive to temp directory
|
||||||
|
for item in os.listdir(temp_dir):
|
||||||
|
if str(item) == "server.properties":
|
||||||
|
has_properties = True
|
||||||
|
try:
|
||||||
|
if not os.path.isdir(os.path.join(temp_dir, item)):
|
||||||
|
FileHelpers.move_file(
|
||||||
|
os.path.join(temp_dir, item), os.path.join(new_server_dir, item)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
if item != "db_stats":
|
||||||
|
FileHelpers.move_dir(
|
||||||
|
os.path.join(temp_dir, item),
|
||||||
|
os.path.join(new_server_dir, item),
|
||||||
|
)
|
||||||
|
except Exception as ex:
|
||||||
|
logger.error(f"ERROR IN ZIP IMPORT: {ex}")
|
||||||
|
if not has_properties:
|
||||||
|
logger.info(
|
||||||
|
f"No server.properties found on zip file import. "
|
||||||
|
f"Creating one with port selection of {str(port)}"
|
||||||
|
)
|
||||||
|
with open(
|
||||||
|
os.path.join(new_server_dir, "server.properties"), "w", encoding="utf-8"
|
||||||
|
) as file:
|
||||||
|
file.write(f"server-port={port}")
|
||||||
|
file.close()
|
||||||
|
ServersController.finish_import(new_id)
|
||||||
|
server_users = PermissionsServers.get_server_user_list(new_id)
|
||||||
|
for user in server_users:
|
||||||
|
self.helper.websocket_helper.broadcast_user(user, "send_start_reload", {})
|
||||||
|
if os.name != "nt":
|
||||||
|
if Helpers.check_file_exists(full_jar_path):
|
||||||
|
os.chmod(full_jar_path, 0o2760)
|
||||||
|
# deletes temp dir
|
||||||
|
FileHelpers.del_dirs(temp_dir)
|
@ -29,15 +29,17 @@ from app.classes.shared.authentication import Authentication
|
|||||||
from app.classes.shared.console import Console
|
from app.classes.shared.console import Console
|
||||||
from app.classes.shared.helpers import Helpers
|
from app.classes.shared.helpers import Helpers
|
||||||
from app.classes.shared.file_helpers import FileHelpers
|
from app.classes.shared.file_helpers import FileHelpers
|
||||||
|
from app.classes.shared.import_helper import ImportHelpers
|
||||||
from app.classes.minecraft.serverjars import ServerJars
|
from app.classes.minecraft.serverjars import ServerJars
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class Controller:
|
class Controller:
|
||||||
def __init__(self, database, helper, file_helper):
|
def __init__(self, database, helper, file_helper, import_helper):
|
||||||
self.helper: Helpers = helper
|
self.helper: Helpers = helper
|
||||||
self.file_helper: FileHelpers = file_helper
|
self.file_helper: FileHelpers = file_helper
|
||||||
|
self.import_helper: ImportHelpers = import_helper
|
||||||
self.server_jars: ServerJars = ServerJars(helper)
|
self.server_jars: ServerJars = ServerJars(helper)
|
||||||
self.users_helper: HelperUsers = HelperUsers(database, self.helper)
|
self.users_helper: HelperUsers = HelperUsers(database, self.helper)
|
||||||
self.roles_helper: HelperRoles = HelperRoles(database)
|
self.roles_helper: HelperRoles = HelperRoles(database)
|
||||||
@ -247,7 +249,7 @@ class Controller:
|
|||||||
except:
|
except:
|
||||||
return {"percent": 0, "total_files": 0}
|
return {"percent": 0, "total_files": 0}
|
||||||
|
|
||||||
def create_api_server(self, data: dict):
|
def create_api_server(self, data: dict, user_id):
|
||||||
server_fs_uuid = Helpers.create_uuid()
|
server_fs_uuid = Helpers.create_uuid()
|
||||||
new_server_path = os.path.join(self.helper.servers_dir, server_fs_uuid)
|
new_server_path = os.path.join(self.helper.servers_dir, server_fs_uuid)
|
||||||
backup_path = os.path.join(self.helper.backup_path, server_fs_uuid)
|
backup_path = os.path.join(self.helper.backup_path, server_fs_uuid)
|
||||||
@ -310,7 +312,9 @@ class Controller:
|
|||||||
# TODO: Copy files from the zip file to the new server directory
|
# TODO: Copy files from the zip file to the new server directory
|
||||||
server_file = create_data["jarfile"]
|
server_file = create_data["jarfile"]
|
||||||
raise Exception("Not yet implemented")
|
raise Exception("Not yet implemented")
|
||||||
_create_server_properties_if_needed(create_data["server_properties_port"])
|
_create_server_properties_if_needed(
|
||||||
|
create_data["server_properties_port"],
|
||||||
|
)
|
||||||
|
|
||||||
min_mem = create_data["mem_min"]
|
min_mem = create_data["mem_min"]
|
||||||
max_mem = create_data["mem_max"]
|
max_mem = create_data["mem_max"]
|
||||||
@ -406,6 +410,7 @@ class Controller:
|
|||||||
server_log_file=log_location,
|
server_log_file=log_location,
|
||||||
server_stop=stop_command,
|
server_stop=stop_command,
|
||||||
server_port=monitoring_port,
|
server_port=monitoring_port,
|
||||||
|
created_by=user_id,
|
||||||
server_host=monitoring_host,
|
server_host=monitoring_host,
|
||||||
server_type=monitoring_type,
|
server_type=monitoring_type,
|
||||||
)
|
)
|
||||||
@ -432,6 +437,7 @@ class Controller:
|
|||||||
min_mem: int,
|
min_mem: int,
|
||||||
max_mem: int,
|
max_mem: int,
|
||||||
port: int,
|
port: int,
|
||||||
|
user_id: int,
|
||||||
):
|
):
|
||||||
server_id = Helpers.create_uuid()
|
server_id = Helpers.create_uuid()
|
||||||
server_dir = os.path.join(self.helper.servers_dir, server_id)
|
server_dir = os.path.join(self.helper.servers_dir, server_id)
|
||||||
@ -492,6 +498,7 @@ class Controller:
|
|||||||
server_log_file,
|
server_log_file,
|
||||||
server_stop,
|
server_stop,
|
||||||
port,
|
port,
|
||||||
|
user_id,
|
||||||
server_type="minecraft-java",
|
server_type="minecraft-java",
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -527,6 +534,7 @@ class Controller:
|
|||||||
min_mem: int,
|
min_mem: int,
|
||||||
max_mem: int,
|
max_mem: int,
|
||||||
port: int,
|
port: int,
|
||||||
|
user_id: int,
|
||||||
):
|
):
|
||||||
server_id = Helpers.create_uuid()
|
server_id = Helpers.create_uuid()
|
||||||
new_server_dir = os.path.join(self.helper.servers_dir, server_id)
|
new_server_dir = os.path.join(self.helper.servers_dir, server_id)
|
||||||
@ -540,25 +548,6 @@ class Controller:
|
|||||||
Helpers.ensure_dir_exists(new_server_dir)
|
Helpers.ensure_dir_exists(new_server_dir)
|
||||||
Helpers.ensure_dir_exists(backup_path)
|
Helpers.ensure_dir_exists(backup_path)
|
||||||
server_path = Helpers.get_os_understandable_path(server_path)
|
server_path = Helpers.get_os_understandable_path(server_path)
|
||||||
try:
|
|
||||||
FileHelpers.copy_dir(server_path, new_server_dir, True)
|
|
||||||
except shutil.Error as ex:
|
|
||||||
logger.error(f"Server import failed with error: {ex}")
|
|
||||||
|
|
||||||
has_properties = False
|
|
||||||
for item in os.listdir(new_server_dir):
|
|
||||||
if str(item) == "server.properties":
|
|
||||||
has_properties = True
|
|
||||||
if not has_properties:
|
|
||||||
logger.info(
|
|
||||||
f"No server.properties found on zip file import. "
|
|
||||||
f"Creating one with port selection of {str(port)}"
|
|
||||||
)
|
|
||||||
with open(
|
|
||||||
os.path.join(new_server_dir, "server.properties"), "w", encoding="utf-8"
|
|
||||||
) as file:
|
|
||||||
file.write(f"server-port={port}")
|
|
||||||
file.close()
|
|
||||||
|
|
||||||
full_jar_path = os.path.join(new_server_dir, server_jar)
|
full_jar_path = os.path.join(new_server_dir, server_jar)
|
||||||
|
|
||||||
@ -587,8 +576,11 @@ class Controller:
|
|||||||
server_log_file,
|
server_log_file,
|
||||||
server_stop,
|
server_stop,
|
||||||
port,
|
port,
|
||||||
|
user_id,
|
||||||
server_type="minecraft-java",
|
server_type="minecraft-java",
|
||||||
)
|
)
|
||||||
|
ServersController.set_import(new_id)
|
||||||
|
self.import_helper.import_jar_server(server_path, new_server_dir, port, new_id)
|
||||||
return new_id
|
return new_id
|
||||||
|
|
||||||
def import_zip_server(
|
def import_zip_server(
|
||||||
@ -599,6 +591,7 @@ class Controller:
|
|||||||
min_mem: int,
|
min_mem: int,
|
||||||
max_mem: int,
|
max_mem: int,
|
||||||
port: int,
|
port: int,
|
||||||
|
user_id: int,
|
||||||
):
|
):
|
||||||
server_id = Helpers.create_uuid()
|
server_id = Helpers.create_uuid()
|
||||||
new_server_dir = os.path.join(self.helper.servers_dir, server_id)
|
new_server_dir = os.path.join(self.helper.servers_dir, server_id)
|
||||||
@ -612,32 +605,6 @@ class Controller:
|
|||||||
temp_dir = Helpers.get_os_understandable_path(zip_path)
|
temp_dir = Helpers.get_os_understandable_path(zip_path)
|
||||||
Helpers.ensure_dir_exists(new_server_dir)
|
Helpers.ensure_dir_exists(new_server_dir)
|
||||||
Helpers.ensure_dir_exists(backup_path)
|
Helpers.ensure_dir_exists(backup_path)
|
||||||
has_properties = False
|
|
||||||
# extracts archive to temp directory
|
|
||||||
for item in os.listdir(temp_dir):
|
|
||||||
if str(item) == "server.properties":
|
|
||||||
has_properties = True
|
|
||||||
try:
|
|
||||||
if not os.path.isdir(os.path.join(temp_dir, item)):
|
|
||||||
FileHelpers.move_file(
|
|
||||||
os.path.join(temp_dir, item), os.path.join(new_server_dir, item)
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
FileHelpers.move_dir(
|
|
||||||
os.path.join(temp_dir, item), os.path.join(new_server_dir, item)
|
|
||||||
)
|
|
||||||
except Exception as ex:
|
|
||||||
logger.error(f"ERROR IN ZIP IMPORT: {ex}")
|
|
||||||
if not has_properties:
|
|
||||||
logger.info(
|
|
||||||
f"No server.properties found on zip file import. "
|
|
||||||
f"Creating one with port selection of {str(port)}"
|
|
||||||
)
|
|
||||||
with open(
|
|
||||||
os.path.join(new_server_dir, "server.properties"), "w", encoding="utf-8"
|
|
||||||
) as file:
|
|
||||||
file.write(f"server-port={port}")
|
|
||||||
file.close()
|
|
||||||
|
|
||||||
full_jar_path = os.path.join(new_server_dir, server_jar)
|
full_jar_path = os.path.join(new_server_dir, server_jar)
|
||||||
|
|
||||||
@ -667,8 +634,13 @@ class Controller:
|
|||||||
server_log_file,
|
server_log_file,
|
||||||
server_stop,
|
server_stop,
|
||||||
port,
|
port,
|
||||||
|
user_id,
|
||||||
server_type="minecraft-java",
|
server_type="minecraft-java",
|
||||||
)
|
)
|
||||||
|
ServersController.set_import(new_id)
|
||||||
|
self.import_helper.import_java_zip_server(
|
||||||
|
temp_dir, new_server_dir, port, new_id
|
||||||
|
)
|
||||||
return new_id
|
return new_id
|
||||||
|
|
||||||
# **********************************************************************************
|
# **********************************************************************************
|
||||||
@ -676,7 +648,12 @@ class Controller:
|
|||||||
# **********************************************************************************
|
# **********************************************************************************
|
||||||
|
|
||||||
def import_bedrock_server(
|
def import_bedrock_server(
|
||||||
self, server_name: str, server_path: str, server_exe: str, port: int
|
self,
|
||||||
|
server_name: str,
|
||||||
|
server_path: str,
|
||||||
|
server_exe: str,
|
||||||
|
port: int,
|
||||||
|
user_id: int,
|
||||||
):
|
):
|
||||||
server_id = Helpers.create_uuid()
|
server_id = Helpers.create_uuid()
|
||||||
new_server_dir = os.path.join(self.helper.servers_dir, server_id)
|
new_server_dir = os.path.join(self.helper.servers_dir, server_id)
|
||||||
@ -690,25 +667,6 @@ class Controller:
|
|||||||
Helpers.ensure_dir_exists(new_server_dir)
|
Helpers.ensure_dir_exists(new_server_dir)
|
||||||
Helpers.ensure_dir_exists(backup_path)
|
Helpers.ensure_dir_exists(backup_path)
|
||||||
server_path = Helpers.get_os_understandable_path(server_path)
|
server_path = Helpers.get_os_understandable_path(server_path)
|
||||||
try:
|
|
||||||
FileHelpers.copy_dir(server_path, new_server_dir, True)
|
|
||||||
except shutil.Error as ex:
|
|
||||||
logger.error(f"Server import failed with error: {ex}")
|
|
||||||
|
|
||||||
has_properties = False
|
|
||||||
for item in os.listdir(new_server_dir):
|
|
||||||
if str(item) == "server.properties":
|
|
||||||
has_properties = True
|
|
||||||
if not has_properties:
|
|
||||||
logger.info(
|
|
||||||
f"No server.properties found on zip file import. "
|
|
||||||
f"Creating one with port selection of {str(port)}"
|
|
||||||
)
|
|
||||||
with open(
|
|
||||||
os.path.join(new_server_dir, "server.properties"), "w", encoding="utf-8"
|
|
||||||
) as file:
|
|
||||||
file.write(f"server-port={port}")
|
|
||||||
file.close()
|
|
||||||
|
|
||||||
full_jar_path = os.path.join(new_server_dir, server_exe)
|
full_jar_path = os.path.join(new_server_dir, server_exe)
|
||||||
|
|
||||||
@ -730,15 +688,22 @@ class Controller:
|
|||||||
server_log_file,
|
server_log_file,
|
||||||
server_stop,
|
server_stop,
|
||||||
port,
|
port,
|
||||||
|
user_id,
|
||||||
server_type="minecraft-bedrock",
|
server_type="minecraft-bedrock",
|
||||||
)
|
)
|
||||||
if os.name != "nt":
|
ServersController.set_import(new_id)
|
||||||
if Helpers.check_file_exists(full_jar_path):
|
self.import_helper.import_bedrock_server(
|
||||||
os.chmod(full_jar_path, 0o2760)
|
server_path, new_server_dir, port, full_jar_path, new_id
|
||||||
|
)
|
||||||
return new_id
|
return new_id
|
||||||
|
|
||||||
def import_bedrock_zip_server(
|
def import_bedrock_zip_server(
|
||||||
self, server_name: str, zip_path: str, server_exe: str, port: int
|
self,
|
||||||
|
server_name: str,
|
||||||
|
zip_path: str,
|
||||||
|
server_exe: str,
|
||||||
|
port: int,
|
||||||
|
user_id: int,
|
||||||
):
|
):
|
||||||
server_id = Helpers.create_uuid()
|
server_id = Helpers.create_uuid()
|
||||||
new_server_dir = os.path.join(self.helper.servers_dir, server_id)
|
new_server_dir = os.path.join(self.helper.servers_dir, server_id)
|
||||||
@ -752,32 +717,6 @@ class Controller:
|
|||||||
temp_dir = Helpers.get_os_understandable_path(zip_path)
|
temp_dir = Helpers.get_os_understandable_path(zip_path)
|
||||||
Helpers.ensure_dir_exists(new_server_dir)
|
Helpers.ensure_dir_exists(new_server_dir)
|
||||||
Helpers.ensure_dir_exists(backup_path)
|
Helpers.ensure_dir_exists(backup_path)
|
||||||
has_properties = False
|
|
||||||
# extracts archive to temp directory
|
|
||||||
for item in os.listdir(temp_dir):
|
|
||||||
if str(item) == "server.properties":
|
|
||||||
has_properties = True
|
|
||||||
try:
|
|
||||||
if not os.path.isdir(os.path.join(temp_dir, item)):
|
|
||||||
FileHelpers.move_file(
|
|
||||||
os.path.join(temp_dir, item), os.path.join(new_server_dir, item)
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
FileHelpers.move_dir(
|
|
||||||
os.path.join(temp_dir, item), os.path.join(new_server_dir, item)
|
|
||||||
)
|
|
||||||
except Exception as ex:
|
|
||||||
logger.error(f"ERROR IN ZIP IMPORT: {ex}")
|
|
||||||
if not has_properties:
|
|
||||||
logger.info(
|
|
||||||
f"No server.properties found on zip file import. "
|
|
||||||
f"Creating one with port selection of {str(port)}"
|
|
||||||
)
|
|
||||||
with open(
|
|
||||||
os.path.join(new_server_dir, "server.properties"), "w", encoding="utf-8"
|
|
||||||
) as file:
|
|
||||||
file.write(f"server-port={port}")
|
|
||||||
file.close()
|
|
||||||
|
|
||||||
full_jar_path = os.path.join(new_server_dir, server_exe)
|
full_jar_path = os.path.join(new_server_dir, server_exe)
|
||||||
|
|
||||||
@ -799,8 +738,12 @@ class Controller:
|
|||||||
server_log_file,
|
server_log_file,
|
||||||
server_stop,
|
server_stop,
|
||||||
port,
|
port,
|
||||||
|
user_id,
|
||||||
server_type="minecraft-bedrock",
|
server_type="minecraft-bedrock",
|
||||||
)
|
)
|
||||||
|
self.import_helper.import_bedrock_zip_server(
|
||||||
|
temp_dir, new_server_dir, full_jar_path, port, new_id
|
||||||
|
)
|
||||||
if os.name != "nt":
|
if os.name != "nt":
|
||||||
if Helpers.check_file_exists(full_jar_path):
|
if Helpers.check_file_exists(full_jar_path):
|
||||||
os.chmod(full_jar_path, 0o2760)
|
os.chmod(full_jar_path, 0o2760)
|
||||||
@ -841,6 +784,7 @@ class Controller:
|
|||||||
server_log_file: str,
|
server_log_file: str,
|
||||||
server_stop: str,
|
server_stop: str,
|
||||||
server_port: int,
|
server_port: int,
|
||||||
|
created_by: int,
|
||||||
server_type: str,
|
server_type: str,
|
||||||
server_host: str = "127.0.0.1",
|
server_host: str = "127.0.0.1",
|
||||||
):
|
):
|
||||||
@ -855,6 +799,7 @@ class Controller:
|
|||||||
server_log_file,
|
server_log_file,
|
||||||
server_stop,
|
server_stop,
|
||||||
server_type,
|
server_type,
|
||||||
|
created_by,
|
||||||
server_port,
|
server_port,
|
||||||
server_host,
|
server_host,
|
||||||
)
|
)
|
||||||
|
@ -26,6 +26,7 @@ class DatabaseBuilder:
|
|||||||
password=password,
|
password=password,
|
||||||
email="default@example.com",
|
email="default@example.com",
|
||||||
superuser=True,
|
superuser=True,
|
||||||
|
manager=None,
|
||||||
)
|
)
|
||||||
|
|
||||||
def is_fresh_install(self):
|
def is_fresh_install(self):
|
||||||
|
@ -293,7 +293,7 @@ class ServerInstance:
|
|||||||
else:
|
else:
|
||||||
user_lang = HelperUsers.get_user_lang_by_id(user_id)
|
user_lang = HelperUsers.get_user_lang_by_id(user_id)
|
||||||
|
|
||||||
if self.stats_helper.get_download_status():
|
if self.stats_helper.get_import_status():
|
||||||
if user_id:
|
if user_id:
|
||||||
self.helper.websocket_helper.broadcast_user(
|
self.helper.websocket_helper.broadcast_user(
|
||||||
user_id,
|
user_id,
|
||||||
@ -612,12 +612,16 @@ class ServerInstance:
|
|||||||
# caching the name and pid number
|
# caching the name and pid number
|
||||||
server_name = self.name
|
server_name = self.name
|
||||||
server_pid = self.process.pid
|
server_pid = self.process.pid
|
||||||
|
self.shutdown_timeout = self.settings["shutdown_timeout"]
|
||||||
|
|
||||||
while running:
|
while running:
|
||||||
i += 1
|
i += 1
|
||||||
|
ttk = int(self.shutdown_timeout - (i * 2))
|
||||||
|
if i <= self.shutdown_timeout / 2:
|
||||||
logstr = (
|
logstr = (
|
||||||
f"Server {server_name} is still running "
|
f"Server {server_name} is still running "
|
||||||
f"- waiting 2s to see if it stops ({int(60-(i*2))} "
|
"- waiting 2s to see if it stops"
|
||||||
|
f"({ttk} "
|
||||||
f"seconds until force close)"
|
f"seconds until force close)"
|
||||||
)
|
)
|
||||||
logger.info(logstr)
|
logger.info(logstr)
|
||||||
@ -626,7 +630,7 @@ class ServerInstance:
|
|||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
|
|
||||||
# if we haven't closed in 60 seconds, let's just slam down on the PID
|
# if we haven't closed in 60 seconds, let's just slam down on the PID
|
||||||
if i >= 30:
|
if i >= round(self.shutdown_timeout / 2, 0):
|
||||||
logger.info(
|
logger.info(
|
||||||
f"Server {server_name} is still running - Forcing the process down"
|
f"Server {server_name} is still running - Forcing the process down"
|
||||||
)
|
)
|
||||||
@ -1223,6 +1227,7 @@ class ServerInstance:
|
|||||||
"version": raw_ping_result.get("version"),
|
"version": raw_ping_result.get("version"),
|
||||||
"icon": raw_ping_result.get("icon"),
|
"icon": raw_ping_result.get("icon"),
|
||||||
"crashed": self.is_crashed,
|
"crashed": self.is_crashed,
|
||||||
|
"created": datetime.datetime.now().strftime("%Y/%m/%d, %H:%M:%S"),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
total_players += int(raw_ping_result.get("online"))
|
total_players += int(raw_ping_result.get("online"))
|
||||||
|
@ -394,6 +394,7 @@ class AjaxHandler(BaseHandler):
|
|||||||
"1",
|
"1",
|
||||||
"2",
|
"2",
|
||||||
server_data["server_port"],
|
server_data["server_port"],
|
||||||
|
server_data["created_by"],
|
||||||
)
|
)
|
||||||
new_server_id = new_server
|
new_server_id = new_server
|
||||||
new_server = self.controller.servers.get_server_data(new_server)
|
new_server = self.controller.servers.get_server_data(new_server)
|
||||||
@ -416,6 +417,7 @@ class AjaxHandler(BaseHandler):
|
|||||||
temp_dir,
|
temp_dir,
|
||||||
server_data["executable"],
|
server_data["executable"],
|
||||||
server_data["server_port"],
|
server_data["server_port"],
|
||||||
|
server_data["created_by"],
|
||||||
)
|
)
|
||||||
new_server_id = new_server
|
new_server_id = new_server
|
||||||
new_server = self.controller.servers.get_server_data(new_server)
|
new_server = self.controller.servers.get_server_data(new_server)
|
||||||
|
@ -340,10 +340,11 @@ class CreateUser(ApiHandler):
|
|||||||
|
|
||||||
new_username = self.get_argument("username").lower()
|
new_username = self.get_argument("username").lower()
|
||||||
new_pass = self.get_argument("password")
|
new_pass = self.get_argument("password")
|
||||||
|
manager = int(user_obj["user_id"])
|
||||||
|
|
||||||
if new_username:
|
if new_username:
|
||||||
self.controller.users.add_user(
|
self.controller.users.add_user(
|
||||||
new_username, new_pass, "default@example.com", True, False
|
new_username, manager, new_pass, "default@example.com", True, False
|
||||||
)
|
)
|
||||||
|
|
||||||
self.return_response(
|
self.return_response(
|
||||||
|
@ -453,8 +453,8 @@ class PanelHandler(BaseHandler):
|
|||||||
for server in un_used_servers[:]:
|
for server in un_used_servers[:]:
|
||||||
if flag == 0:
|
if flag == 0:
|
||||||
server["stats"][
|
server["stats"][
|
||||||
"downloading"
|
"importing"
|
||||||
] = self.controller.servers.get_download_status(
|
] = self.controller.servers.get_import_status(
|
||||||
str(server["stats"]["server_id"]["server_id"])
|
str(server["stats"]["server_id"]["server_id"])
|
||||||
)
|
)
|
||||||
server["stats"]["crashed"] = self.controller.servers.is_crashed(
|
server["stats"]["crashed"] = self.controller.servers.is_crashed(
|
||||||
@ -524,6 +524,7 @@ class PanelHandler(BaseHandler):
|
|||||||
"files",
|
"files",
|
||||||
"admin_controls",
|
"admin_controls",
|
||||||
"schedules",
|
"schedules",
|
||||||
|
"metrics",
|
||||||
]
|
]
|
||||||
if not self.failed_server:
|
if not self.failed_server:
|
||||||
server = self.controller.servers.get_server_instance_by_id(server_id)
|
server = self.controller.servers.get_server_instance_by_id(server_id)
|
||||||
@ -571,11 +572,11 @@ class PanelHandler(BaseHandler):
|
|||||||
"started": "False",
|
"started": "False",
|
||||||
}
|
}
|
||||||
if not self.failed_server:
|
if not self.failed_server:
|
||||||
page_data["downloading"] = self.controller.servers.get_download_status(
|
page_data["importing"] = self.controller.servers.get_import_status(
|
||||||
server_id
|
server_id
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
page_data["downloading"] = False
|
page_data["importing"] = False
|
||||||
page_data["server_id"] = server_id
|
page_data["server_id"] = server_id
|
||||||
try:
|
try:
|
||||||
page_data["waiting_start"] = self.controller.servers.get_waiting_start(
|
page_data["waiting_start"] = self.controller.servers.get_waiting_start(
|
||||||
@ -754,6 +755,11 @@ class PanelHandler(BaseHandler):
|
|||||||
page_data["backup_list"] = []
|
page_data["backup_list"] = []
|
||||||
page_data["backup_path"] = Helpers.wtol_path(server_info["backup_path"])
|
page_data["backup_path"] = Helpers.wtol_path(server_info["backup_path"])
|
||||||
|
|
||||||
|
if subpage == "metrics":
|
||||||
|
page_data["history_stats"] = self.controller.servers.get_history_stats(
|
||||||
|
server_id
|
||||||
|
)
|
||||||
|
|
||||||
def get_banned_players_html():
|
def get_banned_players_html():
|
||||||
banned_players = self.controller.servers.get_banned_players(server_id)
|
banned_players = self.controller.servers.get_banned_players(server_id)
|
||||||
if banned_players is None:
|
if banned_players is None:
|
||||||
@ -860,6 +866,18 @@ class PanelHandler(BaseHandler):
|
|||||||
page_data["users"] = self.controller.users.get_all_users()
|
page_data["users"] = self.controller.users.get_all_users()
|
||||||
page_data["roles"] = self.controller.roles.get_all_roles()
|
page_data["roles"] = self.controller.roles.get_all_roles()
|
||||||
page_data["auth-servers"][user.user_id] = super_auth_servers
|
page_data["auth-servers"][user.user_id] = super_auth_servers
|
||||||
|
page_data["managed_users"] = []
|
||||||
|
else:
|
||||||
|
page_data["managed_users"] = self.controller.users.get_managed_users(
|
||||||
|
exec_user["user_id"]
|
||||||
|
)
|
||||||
|
page_data["assigned_roles"] = []
|
||||||
|
for item in page_data["roles"]:
|
||||||
|
page_data["assigned_roles"].append(item.role_id)
|
||||||
|
|
||||||
|
page_data["managed_roles"] = self.controller.users.get_managed_roles(
|
||||||
|
exec_user["user_id"]
|
||||||
|
)
|
||||||
|
|
||||||
template = "panel/panel_config.html"
|
template = "panel/panel_config.html"
|
||||||
|
|
||||||
@ -885,7 +903,7 @@ class PanelHandler(BaseHandler):
|
|||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
page_data["roles_all"] = self.controller.roles.get_all_roles()
|
page_data["roles"] = self.controller.roles.get_all_roles()
|
||||||
page_data["servers"] = []
|
page_data["servers"] = []
|
||||||
page_data["servers_all"] = self.controller.servers.get_all_defined_servers()
|
page_data["servers_all"] = self.controller.servers.get_all_defined_servers()
|
||||||
page_data["role-servers"] = []
|
page_data["role-servers"] = []
|
||||||
@ -904,8 +922,16 @@ class PanelHandler(BaseHandler):
|
|||||||
)
|
)
|
||||||
if superuser:
|
if superuser:
|
||||||
page_data["super-disabled"] = ""
|
page_data["super-disabled"] = ""
|
||||||
|
page_data["users"] = self.controller.users.get_all_users()
|
||||||
else:
|
else:
|
||||||
page_data["super-disabled"] = "disabled"
|
page_data["super-disabled"] = "disabled"
|
||||||
|
|
||||||
|
page_data["exec_user"] = exec_user["user_id"]
|
||||||
|
|
||||||
|
page_data["manager"] = {
|
||||||
|
"user_id": -100,
|
||||||
|
"username": "None",
|
||||||
|
}
|
||||||
for file in sorted(
|
for file in sorted(
|
||||||
os.listdir(os.path.join(self.helper.root_dir, "app", "translations"))
|
os.listdir(os.path.join(self.helper.root_dir, "app", "translations"))
|
||||||
):
|
):
|
||||||
@ -1074,9 +1100,21 @@ class PanelHandler(BaseHandler):
|
|||||||
page_data["user"] = self.controller.users.get_user_by_id(user_id)
|
page_data["user"] = self.controller.users.get_user_by_id(user_id)
|
||||||
page_data["servers"] = set()
|
page_data["servers"] = set()
|
||||||
page_data["role-servers"] = page_role_servers
|
page_data["role-servers"] = page_role_servers
|
||||||
page_data["roles_all"] = self.controller.roles.get_all_roles()
|
page_data["roles"] = self.controller.roles.get_all_roles()
|
||||||
|
page_data["exec_user"] = exec_user["user_id"]
|
||||||
page_data["servers_all"] = self.controller.servers.get_all_defined_servers()
|
page_data["servers_all"] = self.controller.servers.get_all_defined_servers()
|
||||||
page_data["superuser"] = superuser
|
page_data["superuser"] = superuser
|
||||||
|
if page_data["user"]["manager"] is not None:
|
||||||
|
page_data["manager"] = self.controller.users.get_user_by_id(
|
||||||
|
page_data["user"]["manager"]
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
page_data["manager"] = {
|
||||||
|
"user_id": -100,
|
||||||
|
"username": "None",
|
||||||
|
}
|
||||||
|
if exec_user["superuser"]:
|
||||||
|
page_data["users"] = self.controller.users.get_all_users()
|
||||||
page_data[
|
page_data[
|
||||||
"permissions_all"
|
"permissions_all"
|
||||||
] = self.controller.crafty_perms.list_defined_crafty_permissions()
|
] = self.controller.crafty_perms.list_defined_crafty_permissions()
|
||||||
@ -1115,6 +1153,17 @@ class PanelHandler(BaseHandler):
|
|||||||
"/panel/error?error=Unauthorized access: not a user editor"
|
"/panel/error?error=Unauthorized access: not a user editor"
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
if (
|
||||||
|
(
|
||||||
|
self.controller.users.get_user_by_id(user_id)["manager"]
|
||||||
|
!= exec_user["user_id"]
|
||||||
|
)
|
||||||
|
and not exec_user["superuser"]
|
||||||
|
and str(exec_user["user_id"]) != str(user_id)
|
||||||
|
):
|
||||||
|
self.redirect(
|
||||||
|
"/panel/error?error=Unauthorized access: you cannot edit this user"
|
||||||
|
)
|
||||||
|
|
||||||
page_data["servers"] = []
|
page_data["servers"] = []
|
||||||
page_data["role-servers"] = []
|
page_data["role-servers"] = []
|
||||||
@ -1212,6 +1261,11 @@ class PanelHandler(BaseHandler):
|
|||||||
defined_servers = self.controller.servers.get_authorized_servers(
|
defined_servers = self.controller.servers.get_authorized_servers(
|
||||||
exec_user["user_id"]
|
exec_user["user_id"]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
page_data["role_manager"] = {
|
||||||
|
"user_id": -100,
|
||||||
|
"username": "None",
|
||||||
|
}
|
||||||
page_servers = []
|
page_servers = []
|
||||||
for server in defined_servers:
|
for server in defined_servers:
|
||||||
if server not in page_servers:
|
if server not in page_servers:
|
||||||
@ -1229,6 +1283,7 @@ class PanelHandler(BaseHandler):
|
|||||||
user_roles = self.get_user_roles()
|
user_roles = self.get_user_roles()
|
||||||
page_data["new_role"] = False
|
page_data["new_role"] = False
|
||||||
role_id = self.get_argument("id", None)
|
role_id = self.get_argument("id", None)
|
||||||
|
role = self.controller.roles.get_role(role_id)
|
||||||
page_data["role"] = self.controller.roles.get_role_with_servers(role_id)
|
page_data["role"] = self.controller.roles.get_role_with_servers(role_id)
|
||||||
if exec_user["superuser"]:
|
if exec_user["superuser"]:
|
||||||
defined_servers = self.controller.servers.list_defined_servers()
|
defined_servers = self.controller.servers.list_defined_servers()
|
||||||
@ -1252,7 +1307,21 @@ class PanelHandler(BaseHandler):
|
|||||||
page_data["user-roles"] = user_roles
|
page_data["user-roles"] = user_roles
|
||||||
page_data["users"] = self.controller.users.get_all_users()
|
page_data["users"] = self.controller.users.get_all_users()
|
||||||
|
|
||||||
if EnumPermissionsCrafty.ROLES_CONFIG not in exec_user_crafty_permissions:
|
if page_data["role"]["manager"] is not None:
|
||||||
|
page_data["role_manager"] = self.controller.users.get_user_by_id(
|
||||||
|
page_data["role"]["manager"]
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
page_data["role_manager"] = {
|
||||||
|
"user_id": -100,
|
||||||
|
"username": "None",
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
EnumPermissionsCrafty.ROLES_CONFIG not in exec_user_crafty_permissions
|
||||||
|
or exec_user["user_id"] != role["manager"]
|
||||||
|
and not exec_user["superuser"]
|
||||||
|
):
|
||||||
self.redirect(
|
self.redirect(
|
||||||
"/panel/error?error=Unauthorized access: not a role editor"
|
"/panel/error?error=Unauthorized access: not a role editor"
|
||||||
)
|
)
|
||||||
@ -1266,8 +1335,15 @@ class PanelHandler(BaseHandler):
|
|||||||
elif page == "remove_role":
|
elif page == "remove_role":
|
||||||
role_id = bleach.clean(self.get_argument("id", None))
|
role_id = bleach.clean(self.get_argument("id", None))
|
||||||
|
|
||||||
if not superuser:
|
if (
|
||||||
self.redirect("/panel/error?error=Unauthorized access: not superuser")
|
not superuser
|
||||||
|
and self.controller.roles.get_role(role_id)["manager"]
|
||||||
|
!= exec_user["user_id"]
|
||||||
|
):
|
||||||
|
self.redirect(
|
||||||
|
"/panel/error?error=Unauthorized access: not superuser not"
|
||||||
|
" role manager"
|
||||||
|
)
|
||||||
return
|
return
|
||||||
if role_id is None:
|
if role_id is None:
|
||||||
self.redirect("/panel/error?error=Invalid Role ID")
|
self.redirect("/panel/error?error=Invalid Role ID")
|
||||||
@ -1418,6 +1494,7 @@ class PanelHandler(BaseHandler):
|
|||||||
return
|
return
|
||||||
server_name = self.get_argument("server_name", None)
|
server_name = self.get_argument("server_name", None)
|
||||||
server_obj = self.controller.servers.get_server_obj(server_id)
|
server_obj = self.controller.servers.get_server_obj(server_id)
|
||||||
|
shutdown_timeout = self.get_argument("shutdown_timeout", 60)
|
||||||
if superuser:
|
if superuser:
|
||||||
server_path = self.get_argument("server_path", None)
|
server_path = self.get_argument("server_path", None)
|
||||||
if Helpers.is_os_windows():
|
if Helpers.is_os_windows():
|
||||||
@ -1498,6 +1575,7 @@ class PanelHandler(BaseHandler):
|
|||||||
)
|
)
|
||||||
|
|
||||||
server_obj.server_name = server_name
|
server_obj.server_name = server_name
|
||||||
|
server_obj.shutdown_timeout = shutdown_timeout
|
||||||
if superuser:
|
if superuser:
|
||||||
if Helpers.validate_traversal(
|
if Helpers.validate_traversal(
|
||||||
self.helper.get_servers_root_dir(), server_path
|
self.helper.get_servers_root_dir(), server_path
|
||||||
@ -1930,6 +2008,7 @@ class PanelHandler(BaseHandler):
|
|||||||
"system user is not editable"
|
"system user is not editable"
|
||||||
)
|
)
|
||||||
user_id = bleach.clean(self.get_argument("id", None))
|
user_id = bleach.clean(self.get_argument("id", None))
|
||||||
|
user = self.controller.users.get_user_by_id(user_id)
|
||||||
username = bleach.clean(self.get_argument("username", None).lower())
|
username = bleach.clean(self.get_argument("username", None).lower())
|
||||||
if (
|
if (
|
||||||
username != self.controller.users.get_user_by_id(user_id)["username"]
|
username != self.controller.users.get_user_by_id(user_id)["username"]
|
||||||
@ -1962,7 +2041,19 @@ class PanelHandler(BaseHandler):
|
|||||||
else:
|
else:
|
||||||
superuser = 0
|
superuser = 0
|
||||||
|
|
||||||
if not exec_user["superuser"]:
|
if exec_user["superuser"]:
|
||||||
|
manager = self.get_argument("manager")
|
||||||
|
if manager == "":
|
||||||
|
manager = None
|
||||||
|
else:
|
||||||
|
manager = int(manager)
|
||||||
|
else:
|
||||||
|
manager = user["manager"]
|
||||||
|
|
||||||
|
if (
|
||||||
|
not exec_user["superuser"]
|
||||||
|
and int(exec_user["user_id"]) != user["manager"]
|
||||||
|
):
|
||||||
if username is None or username == "":
|
if username is None or username == "":
|
||||||
self.redirect("/panel/error?error=Invalid username")
|
self.redirect("/panel/error?error=Invalid username")
|
||||||
return
|
return
|
||||||
@ -2013,6 +2104,7 @@ class PanelHandler(BaseHandler):
|
|||||||
|
|
||||||
user_data = {
|
user_data = {
|
||||||
"username": username,
|
"username": username,
|
||||||
|
"manager": manager,
|
||||||
"password": password0,
|
"password": password0,
|
||||||
"email": email,
|
"email": email,
|
||||||
"enabled": enabled,
|
"enabled": enabled,
|
||||||
@ -2158,6 +2250,15 @@ class PanelHandler(BaseHandler):
|
|||||||
if username is None or username == "":
|
if username is None or username == "":
|
||||||
self.redirect("/panel/error?error=Invalid username")
|
self.redirect("/panel/error?error=Invalid username")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if exec_user["superuser"]:
|
||||||
|
manager = self.get_argument("manager")
|
||||||
|
if manager == "":
|
||||||
|
manager = None
|
||||||
|
else:
|
||||||
|
manager = int(manager)
|
||||||
|
else:
|
||||||
|
manager = int(exec_user["user_id"])
|
||||||
# does this user id exist?
|
# does this user id exist?
|
||||||
if self.controller.users.get_id_by_name(username) is not None:
|
if self.controller.users.get_id_by_name(username) is not None:
|
||||||
self.redirect("/panel/error?error=User exists")
|
self.redirect("/panel/error?error=User exists")
|
||||||
@ -2172,6 +2273,7 @@ class PanelHandler(BaseHandler):
|
|||||||
|
|
||||||
user_id = self.controller.users.add_user(
|
user_id = self.controller.users.add_user(
|
||||||
username,
|
username,
|
||||||
|
manager=manager,
|
||||||
password=password0,
|
password=password0,
|
||||||
email=email,
|
email=email,
|
||||||
enabled=enabled,
|
enabled=enabled,
|
||||||
@ -2198,14 +2300,19 @@ class PanelHandler(BaseHandler):
|
|||||||
server_id=0,
|
server_id=0,
|
||||||
source_ip=self.get_remote_ip(),
|
source_ip=self.get_remote_ip(),
|
||||||
)
|
)
|
||||||
self.controller.crafty_perms.add_user_creation(exec_user["user_id"])
|
|
||||||
self.redirect("/panel/panel_config")
|
self.redirect("/panel/panel_config")
|
||||||
|
|
||||||
elif page == "edit_role":
|
elif page == "edit_role":
|
||||||
role_id = bleach.clean(self.get_argument("id", None))
|
role_id = bleach.clean(self.get_argument("id", None))
|
||||||
role_name = bleach.clean(self.get_argument("role_name", None))
|
role_name = bleach.clean(self.get_argument("role_name", None))
|
||||||
|
|
||||||
if EnumPermissionsCrafty.ROLES_CONFIG not in exec_user_crafty_permissions:
|
role = self.controller.roles.get_role(role_id)
|
||||||
|
|
||||||
|
if (
|
||||||
|
EnumPermissionsCrafty.ROLES_CONFIG not in exec_user_crafty_permissions
|
||||||
|
and exec_user["user_id"] != role["manager"]
|
||||||
|
and not exec_user["superuser"]
|
||||||
|
):
|
||||||
self.redirect(
|
self.redirect(
|
||||||
"/panel/error?error=Unauthorized access: not a role editor"
|
"/panel/error?error=Unauthorized access: not a role editor"
|
||||||
)
|
)
|
||||||
@ -2221,9 +2328,18 @@ class PanelHandler(BaseHandler):
|
|||||||
self.redirect("/panel/error?error=Invalid Role ID")
|
self.redirect("/panel/error?error=Invalid Role ID")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if exec_user["superuser"]:
|
||||||
|
manager = self.get_argument("manager", None)
|
||||||
|
if manager == "":
|
||||||
|
manager = None
|
||||||
|
else:
|
||||||
|
manager = role["manager"]
|
||||||
|
|
||||||
servers = self.get_role_servers()
|
servers = self.get_role_servers()
|
||||||
|
|
||||||
self.controller.roles.update_role_advanced(role_id, role_name, servers)
|
self.controller.roles.update_role_advanced(
|
||||||
|
role_id, role_name, servers, manager
|
||||||
|
)
|
||||||
|
|
||||||
self.controller.management.add_to_audit_log(
|
self.controller.management.add_to_audit_log(
|
||||||
exec_user["user_id"],
|
exec_user["user_id"],
|
||||||
@ -2235,6 +2351,12 @@ class PanelHandler(BaseHandler):
|
|||||||
|
|
||||||
elif page == "add_role":
|
elif page == "add_role":
|
||||||
role_name = bleach.clean(self.get_argument("role_name", None))
|
role_name = bleach.clean(self.get_argument("role_name", None))
|
||||||
|
if exec_user["superuser"]:
|
||||||
|
manager = self.get_argument("manager", None)
|
||||||
|
if manager == "":
|
||||||
|
manager = None
|
||||||
|
else:
|
||||||
|
manager = exec_user["user_id"]
|
||||||
|
|
||||||
if EnumPermissionsCrafty.ROLES_CONFIG not in exec_user_crafty_permissions:
|
if EnumPermissionsCrafty.ROLES_CONFIG not in exec_user_crafty_permissions:
|
||||||
self.redirect(
|
self.redirect(
|
||||||
@ -2259,7 +2381,9 @@ class PanelHandler(BaseHandler):
|
|||||||
|
|
||||||
servers = self.get_role_servers()
|
servers = self.get_role_servers()
|
||||||
|
|
||||||
role_id = self.controller.roles.add_role_advanced(role_name, servers)
|
role_id = self.controller.roles.add_role_advanced(
|
||||||
|
role_name, servers, manager
|
||||||
|
)
|
||||||
|
|
||||||
self.controller.management.add_to_audit_log(
|
self.controller.management.add_to_audit_log(
|
||||||
exec_user["user_id"],
|
exec_user["user_id"],
|
||||||
@ -2267,7 +2391,6 @@ class PanelHandler(BaseHandler):
|
|||||||
server_id=0,
|
server_id=0,
|
||||||
source_ip=self.get_remote_ip(),
|
source_ip=self.get_remote_ip(),
|
||||||
)
|
)
|
||||||
self.controller.crafty_perms.add_role_creation(exec_user["user_id"])
|
|
||||||
self.redirect("/panel/panel_config")
|
self.redirect("/panel/panel_config")
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
@ -116,7 +116,9 @@ class ApiRolesIndexHandler(BaseApiHandler):
|
|||||||
400, {"status": "error", "error": "ROLE_NAME_ALREADY_EXISTS"}
|
400, {"status": "error", "error": "ROLE_NAME_ALREADY_EXISTS"}
|
||||||
)
|
)
|
||||||
|
|
||||||
role_id = self.controller.roles.add_role_advanced(role_name, servers)
|
role_id = self.controller.roles.add_role_advanced(
|
||||||
|
role_name, servers, user["user_id"]
|
||||||
|
)
|
||||||
|
|
||||||
self.controller.management.add_to_audit_log(
|
self.controller.management.add_to_audit_log(
|
||||||
user["user_id"],
|
user["user_id"],
|
||||||
|
@ -665,10 +665,9 @@ class ApiServersIndexHandler(BaseApiHandler):
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
new_server_id, new_server_uuid = self.controller.create_api_server(data)
|
new_server_id, new_server_uuid = self.controller.create_api_server(
|
||||||
|
data, user["user_id"]
|
||||||
# Increase the server creation counter
|
)
|
||||||
self.controller.crafty_perms.add_server_creation(user["user_id"])
|
|
||||||
|
|
||||||
self.controller.servers.stats.record_stats()
|
self.controller.servers.stats.record_stats()
|
||||||
|
|
||||||
|
@ -84,6 +84,7 @@ class ApiServersServerActionHandler(BaseApiHandler):
|
|||||||
new_server_log_file,
|
new_server_log_file,
|
||||||
server_data.get("stop_command"),
|
server_data.get("stop_command"),
|
||||||
server_data.get("type"),
|
server_data.get("type"),
|
||||||
|
user_id,
|
||||||
server_data.get("server_port"),
|
server_data.get("server_port"),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -96,6 +96,7 @@ class ApiUsersIndexHandler(BaseApiHandler):
|
|||||||
|
|
||||||
username = data["username"]
|
username = data["username"]
|
||||||
username = str(username).lower()
|
username = str(username).lower()
|
||||||
|
manager = int(user["user_id"])
|
||||||
password = data["password"]
|
password = data["password"]
|
||||||
email = data.get("email", "default@example.com")
|
email = data.get("email", "default@example.com")
|
||||||
enabled = data.get("enabled", True)
|
enabled = data.get("enabled", True)
|
||||||
@ -149,6 +150,7 @@ class ApiUsersIndexHandler(BaseApiHandler):
|
|||||||
# TODO: do this in the most efficient way
|
# TODO: do this in the most efficient way
|
||||||
user_id = self.controller.users.add_user(
|
user_id = self.controller.users.add_user(
|
||||||
username,
|
username,
|
||||||
|
manager,
|
||||||
password,
|
password,
|
||||||
email,
|
email,
|
||||||
enabled,
|
enabled,
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
import time
|
||||||
import tornado.web
|
import tornado.web
|
||||||
import tornado.escape
|
import tornado.escape
|
||||||
import bleach
|
import bleach
|
||||||
@ -224,6 +225,23 @@ class ServerHandler(BaseHandler):
|
|||||||
|
|
||||||
if server_id is not None:
|
if server_id is not None:
|
||||||
if command == "clone_server":
|
if command == "clone_server":
|
||||||
|
if (
|
||||||
|
not superuser
|
||||||
|
and not self.controller.crafty_perms.can_create_server(
|
||||||
|
exec_user["user_id"]
|
||||||
|
)
|
||||||
|
):
|
||||||
|
time.sleep(3)
|
||||||
|
self.helper.websocket_helper.broadcast_user(
|
||||||
|
exec_user["user_id"],
|
||||||
|
"send_start_error",
|
||||||
|
{
|
||||||
|
"error": "<i class='fas fa-exclamation-triangle'"
|
||||||
|
" style='font-size:48px;color:red'>"
|
||||||
|
"</i> Not a server creator or server limit reached."
|
||||||
|
},
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
def is_name_used(name):
|
def is_name_used(name):
|
||||||
for server in self.controller.servers.get_all_defined_servers():
|
for server in self.controller.servers.get_all_defined_servers():
|
||||||
@ -231,6 +249,7 @@ class ServerHandler(BaseHandler):
|
|||||||
return True
|
return True
|
||||||
return
|
return
|
||||||
|
|
||||||
|
template = "/panel/dashboard"
|
||||||
server_data = self.controller.servers.get_server_data_by_id(
|
server_data = self.controller.servers.get_server_data_by_id(
|
||||||
server_id
|
server_id
|
||||||
)
|
)
|
||||||
@ -265,6 +284,7 @@ class ServerHandler(BaseHandler):
|
|||||||
backup_path = os.path.join(self.helper.backup_path, new_server_uuid)
|
backup_path = os.path.join(self.helper.backup_path, new_server_uuid)
|
||||||
server_port = server_data.get("server_port")
|
server_port = server_data.get("server_port")
|
||||||
server_type = server_data.get("type")
|
server_type = server_data.get("type")
|
||||||
|
created_by = exec_user["user_id"]
|
||||||
|
|
||||||
new_server_id = self.controller.servers.create_server(
|
new_server_id = self.controller.servers.create_server(
|
||||||
new_server_name,
|
new_server_name,
|
||||||
@ -276,6 +296,7 @@ class ServerHandler(BaseHandler):
|
|||||||
new_server_log_file,
|
new_server_log_file,
|
||||||
stop_command,
|
stop_command,
|
||||||
server_type,
|
server_type,
|
||||||
|
created_by,
|
||||||
server_port,
|
server_port,
|
||||||
)
|
)
|
||||||
if not exec_user["superuser"]:
|
if not exec_user["superuser"]:
|
||||||
@ -283,7 +304,8 @@ class ServerHandler(BaseHandler):
|
|||||||
new_server_id
|
new_server_id
|
||||||
).get("server_uuid")
|
).get("server_uuid")
|
||||||
role_id = self.controller.roles.add_role(
|
role_id = self.controller.roles.add_role(
|
||||||
f"Creator of Server with uuid={new_server_uuid}"
|
f"Creator of Server with uuid={new_server_uuid}",
|
||||||
|
exec_user["user_id"],
|
||||||
)
|
)
|
||||||
self.controller.server_perms.add_role_server(
|
self.controller.server_perms.add_role_server(
|
||||||
new_server_id, role_id, "11111111"
|
new_server_id, role_id, "11111111"
|
||||||
@ -291,9 +313,6 @@ class ServerHandler(BaseHandler):
|
|||||||
self.controller.users.add_role_to_user(
|
self.controller.users.add_role_to_user(
|
||||||
exec_user["user_id"], role_id
|
exec_user["user_id"], role_id
|
||||||
)
|
)
|
||||||
self.controller.crafty_perms.add_server_creation(
|
|
||||||
exec_user["user_id"]
|
|
||||||
)
|
|
||||||
|
|
||||||
self.controller.servers.init_all_servers()
|
self.controller.servers.init_all_servers()
|
||||||
|
|
||||||
@ -353,6 +372,7 @@ class ServerHandler(BaseHandler):
|
|||||||
min_mem,
|
min_mem,
|
||||||
max_mem,
|
max_mem,
|
||||||
port,
|
port,
|
||||||
|
exec_user["user_id"],
|
||||||
)
|
)
|
||||||
self.controller.management.add_to_audit_log(
|
self.controller.management.add_to_audit_log(
|
||||||
exec_user["user_id"],
|
exec_user["user_id"],
|
||||||
@ -369,7 +389,13 @@ class ServerHandler(BaseHandler):
|
|||||||
return
|
return
|
||||||
|
|
||||||
new_server_id = self.controller.import_zip_server(
|
new_server_id = self.controller.import_zip_server(
|
||||||
server_name, zip_path, import_server_jar, min_mem, max_mem, port
|
server_name,
|
||||||
|
zip_path,
|
||||||
|
import_server_jar,
|
||||||
|
min_mem,
|
||||||
|
max_mem,
|
||||||
|
port,
|
||||||
|
exec_user["user_id"],
|
||||||
)
|
)
|
||||||
if new_server_id == "false":
|
if new_server_id == "false":
|
||||||
self.redirect(
|
self.redirect(
|
||||||
@ -385,8 +411,6 @@ class ServerHandler(BaseHandler):
|
|||||||
new_server_id,
|
new_server_id,
|
||||||
self.get_remote_ip(),
|
self.get_remote_ip(),
|
||||||
)
|
)
|
||||||
# deletes temp dir
|
|
||||||
FileHelpers.del_dirs(zip_path)
|
|
||||||
else:
|
else:
|
||||||
if len(server_parts) != 3:
|
if len(server_parts) != 3:
|
||||||
self.redirect("/panel/error?error=Invalid server data")
|
self.redirect("/panel/error?error=Invalid server data")
|
||||||
@ -402,6 +426,7 @@ class ServerHandler(BaseHandler):
|
|||||||
min_mem,
|
min_mem,
|
||||||
max_mem,
|
max_mem,
|
||||||
port,
|
port,
|
||||||
|
exec_user["user_id"],
|
||||||
)
|
)
|
||||||
self.controller.management.add_to_audit_log(
|
self.controller.management.add_to_audit_log(
|
||||||
exec_user["user_id"],
|
exec_user["user_id"],
|
||||||
@ -420,7 +445,8 @@ class ServerHandler(BaseHandler):
|
|||||||
new_server_id
|
new_server_id
|
||||||
).get("server_uuid")
|
).get("server_uuid")
|
||||||
role_id = self.controller.roles.add_role(
|
role_id = self.controller.roles.add_role(
|
||||||
f"Creator of Server with uuid={new_server_uuid}"
|
f"Creator of Server with uuid={new_server_uuid}",
|
||||||
|
exec_user["user_id"],
|
||||||
)
|
)
|
||||||
self.controller.server_perms.add_role_server(
|
self.controller.server_perms.add_role_server(
|
||||||
new_server_id, role_id, "11111111"
|
new_server_id, role_id, "11111111"
|
||||||
@ -428,9 +454,6 @@ class ServerHandler(BaseHandler):
|
|||||||
self.controller.users.add_role_to_user(
|
self.controller.users.add_role_to_user(
|
||||||
exec_user["user_id"], role_id
|
exec_user["user_id"], role_id
|
||||||
)
|
)
|
||||||
self.controller.crafty_perms.add_server_creation(
|
|
||||||
exec_user["user_id"]
|
|
||||||
)
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
for role in captured_roles:
|
for role in captured_roles:
|
||||||
@ -483,7 +506,11 @@ class ServerHandler(BaseHandler):
|
|||||||
return
|
return
|
||||||
|
|
||||||
new_server_id = self.controller.import_bedrock_server(
|
new_server_id = self.controller.import_bedrock_server(
|
||||||
server_name, import_server_path, import_server_exe, port
|
server_name,
|
||||||
|
import_server_path,
|
||||||
|
import_server_exe,
|
||||||
|
port,
|
||||||
|
exec_user["user_id"],
|
||||||
)
|
)
|
||||||
self.controller.management.add_to_audit_log(
|
self.controller.management.add_to_audit_log(
|
||||||
exec_user["user_id"],
|
exec_user["user_id"],
|
||||||
@ -500,7 +527,11 @@ class ServerHandler(BaseHandler):
|
|||||||
return
|
return
|
||||||
|
|
||||||
new_server_id = self.controller.import_bedrock_zip_server(
|
new_server_id = self.controller.import_bedrock_zip_server(
|
||||||
server_name, zip_path, import_server_exe, port
|
server_name,
|
||||||
|
zip_path,
|
||||||
|
import_server_exe,
|
||||||
|
port,
|
||||||
|
exec_user["user_id"],
|
||||||
)
|
)
|
||||||
if new_server_id == "false":
|
if new_server_id == "false":
|
||||||
self.redirect(
|
self.redirect(
|
||||||
@ -516,8 +547,6 @@ class ServerHandler(BaseHandler):
|
|||||||
new_server_id,
|
new_server_id,
|
||||||
self.get_remote_ip(),
|
self.get_remote_ip(),
|
||||||
)
|
)
|
||||||
# deletes temp dir
|
|
||||||
FileHelpers.del_dirs(zip_path)
|
|
||||||
else:
|
else:
|
||||||
if len(server_parts) != 2:
|
if len(server_parts) != 2:
|
||||||
self.redirect("/panel/error?error=Invalid server data")
|
self.redirect("/panel/error?error=Invalid server data")
|
||||||
@ -526,7 +555,13 @@ class ServerHandler(BaseHandler):
|
|||||||
# TODO: add server type check here and call the correct server
|
# TODO: add server type check here and call the correct server
|
||||||
# add functions if not a jar
|
# add functions if not a jar
|
||||||
new_server_id = self.controller.create_jar_server(
|
new_server_id = self.controller.create_jar_server(
|
||||||
server_type, server_version, server_name, min_mem, max_mem, port
|
server_type,
|
||||||
|
server_version,
|
||||||
|
server_name,
|
||||||
|
min_mem,
|
||||||
|
max_mem,
|
||||||
|
port,
|
||||||
|
exec_user["user_id"],
|
||||||
)
|
)
|
||||||
self.controller.management.add_to_audit_log(
|
self.controller.management.add_to_audit_log(
|
||||||
exec_user["user_id"],
|
exec_user["user_id"],
|
||||||
@ -545,7 +580,8 @@ class ServerHandler(BaseHandler):
|
|||||||
new_server_id
|
new_server_id
|
||||||
).get("server_uuid")
|
).get("server_uuid")
|
||||||
role_id = self.controller.roles.add_role(
|
role_id = self.controller.roles.add_role(
|
||||||
f"Creator of Server with uuid={new_server_uuid}"
|
f"Creator of Server with uuid={new_server_uuid}",
|
||||||
|
exec_user["user_id"],
|
||||||
)
|
)
|
||||||
self.controller.server_perms.add_role_server(
|
self.controller.server_perms.add_role_server(
|
||||||
new_server_id, role_id, "11111111"
|
new_server_id, role_id, "11111111"
|
||||||
@ -553,9 +589,6 @@ class ServerHandler(BaseHandler):
|
|||||||
self.controller.users.add_role_to_user(
|
self.controller.users.add_role_to_user(
|
||||||
exec_user["user_id"], role_id
|
exec_user["user_id"], role_id
|
||||||
)
|
)
|
||||||
self.controller.crafty_perms.add_server_creation(
|
|
||||||
exec_user["user_id"]
|
|
||||||
)
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
for role in captured_roles:
|
for role in captured_roles:
|
||||||
|
@ -40,6 +40,16 @@
|
|||||||
<!-- Bootstrap Toggle -->
|
<!-- Bootstrap Toggle -->
|
||||||
<link href="https://gitcdn.github.io/bootstrap-toggle/2.2.2/css/bootstrap-toggle.min.css" rel="stylesheet">
|
<link href="https://gitcdn.github.io/bootstrap-toggle/2.2.2/css/bootstrap-toggle.min.css" rel="stylesheet">
|
||||||
<script defer src="https://gitcdn.github.io/bootstrap-toggle/2.2.2/js/bootstrap-toggle.min.js"></script>
|
<script defer src="https://gitcdn.github.io/bootstrap-toggle/2.2.2/js/bootstrap-toggle.min.js"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.9.1/chart.min.js"
|
||||||
|
integrity="sha512-ElRFoEQdI5Ht6kZvyzXhYG9NqjtkmlkfYk0wr6wHxU9JEHakS7UJZNeml5ALk+8IKlU6jDgMabC3vkumRokgJA=="
|
||||||
|
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js"
|
||||||
|
integrity="sha512-UXumZrZNiOwnTcZSHLOfcTs0aos2MzBWHXOHOuB0J/R44QB0dwY5JgfbvljXcklVf65Gc4El6RjZ+lnwd2az2g=="
|
||||||
|
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-zoom/1.2.1/chartjs-plugin-zoom.min.js"
|
||||||
|
integrity="sha512-klQv6lz2YR+MecyFYMFRuU2eAl8IPRo6zHnsc9n142TJuJHS8CG0ix4Oq9na9ceeg1u5EkBfZsFcV3U7J51iew=="
|
||||||
|
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||||
|
|
||||||
<!-- End Bootstrap Toggle -->
|
<!-- End Bootstrap Toggle -->
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
|
@ -193,9 +193,9 @@
|
|||||||
<a data-id="{{server['server_data']['server_id']}}" class="" title="{{
|
<a data-id="{{server['server_data']['server_id']}}" class="" title="{{
|
||||||
translate('dashboard', 'delay-explained' , data['lang'])}}">{{ translate('dashboard', 'starting',
|
translate('dashboard', 'delay-explained' , data['lang'])}}">{{ translate('dashboard', 'starting',
|
||||||
data['lang']) }}</i></a>
|
data['lang']) }}</i></a>
|
||||||
{% elif server['stats']['downloading']%}
|
{% elif server['stats']['importing']%}
|
||||||
<a data-id="{{server['server_data']['server_id']}}" class=""><i class="fa fa-spinner fa-spin"></i>
|
<a data-id="{{server['server_data']['server_id']}}" class=""><i class="fa fa-spinner fa-spin"></i>
|
||||||
{{ translate('serverTerm', 'downloading',
|
{{ translate('serverTerm', 'importing',
|
||||||
data['lang']) }}</a>
|
data['lang']) }}</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
<a data-id="{{server['server_data']['server_id']}}" class="play_button" data-toggle="tooltip"
|
<a data-id="{{server['server_data']['server_id']}}" class="play_button" data-toggle="tooltip"
|
||||||
@ -399,12 +399,12 @@
|
|||||||
data['lang']) }}</i></a>
|
data['lang']) }}</i></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% elif server['stats']['downloading']%}
|
{% elif server['stats']['importing']%}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-12 px-0">
|
<div class="col-12 px-0">
|
||||||
<a data-id="{{server['server_data']['server_id']}}" class="btn btn-link"><i
|
<a data-id="{{server['server_data']['server_id']}}" class="btn btn-link"><i
|
||||||
class="fa fa-spinner fa-spin"></i>
|
class="fa fa-spinner fa-spin"></i>
|
||||||
{{ translate('serverTerm', 'downloading', data['lang']) }}</a>
|
{{ translate('serverTerm', 'importing', data['lang']) }}</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
@ -893,9 +893,6 @@
|
|||||||
message: '<div align="center"><i class="fas fa-spin fa-spinner"></i> {% raw translate("dashboard", "bePatientClone", data["lang"]) %} </div>',
|
message: '<div align="center"><i class="fas fa-spin fa-spinner"></i> {% raw translate("dashboard", "bePatientClone", data["lang"]) %} </div>',
|
||||||
closeButton: false,
|
closeButton: false,
|
||||||
});
|
});
|
||||||
setTimeout(function () {
|
|
||||||
location.reload();
|
|
||||||
}, 5000)
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<script src="/static/assets/vendors/js/jquery-ui.js"></script>
|
<script src="/static/assets/vendors/js/jquery-ui.js"></script>
|
||||||
|
@ -87,6 +87,38 @@
|
|||||||
<td><a href="/panel/edit_user?id={{user.user_id}}"><i class="fas fa-pencil-alt"></i></a></td>
|
<td><a href="/panel/edit_user?id={{user.user_id}}"><i class="fas fa-pencil-alt"></i></a></td>
|
||||||
</tr>
|
</tr>
|
||||||
{% end %}
|
{% end %}
|
||||||
|
{% for user in data['managed_users'] %}
|
||||||
|
<tr>
|
||||||
|
<td><i class="fas fa-user"></i> {{ user.username }}</td>
|
||||||
|
<td>
|
||||||
|
{% if user.enabled %}
|
||||||
|
<span class="text-success">
|
||||||
|
<i class="fas fa-check-square"></i> Yes
|
||||||
|
</span>
|
||||||
|
{% else %}
|
||||||
|
<span class="text-danger">
|
||||||
|
<i class="far fa-times-square"></i> No
|
||||||
|
</span>
|
||||||
|
|
||||||
|
{% end %}
|
||||||
|
</td>
|
||||||
|
<td id="server_list_{{user.user_id}}">
|
||||||
|
<ul id="{{user.user_id}}">
|
||||||
|
{% for item in data['auth-servers'][user.user_id] %}
|
||||||
|
<li>{{item}}</li>
|
||||||
|
{% end %}
|
||||||
|
</ul>
|
||||||
|
</td>
|
||||||
|
<td id="role_list_{{user.user_id}}">
|
||||||
|
<ul>
|
||||||
|
{% for item in data['user-roles'][user.user_id] %}
|
||||||
|
<li data-toggle="tooltip" title="{{ item }}">{{item}}</li>
|
||||||
|
{% end %}
|
||||||
|
</ul>
|
||||||
|
</td>
|
||||||
|
<td><a href="/panel/edit_user?id={{user.user_id}}"><i class="fas fa-pencil-alt"></i></a></td>
|
||||||
|
</tr>
|
||||||
|
{% end %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
@ -146,6 +178,34 @@
|
|||||||
</tr>
|
</tr>
|
||||||
{% end %}
|
{% end %}
|
||||||
|
|
||||||
|
{% if not data['superuser'] %}
|
||||||
|
{% for role in data['managed_roles'] %}
|
||||||
|
{% if role.role_id not in data['assigned_roles'] %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ role.role_name }}</td>
|
||||||
|
<td id="role_list_{{role.role_id}}">
|
||||||
|
<ul id="{{role.role_id}}">
|
||||||
|
{% for item in data['role-servers'][role.role_id] %}
|
||||||
|
<li>{{item}}</li>
|
||||||
|
{% end %}
|
||||||
|
</ul>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<ul>
|
||||||
|
{% for user in data['users'] %}
|
||||||
|
{% for ruser in data['user-roles'][user.user_id] %}
|
||||||
|
{% if ruser == role.role_name %}
|
||||||
|
<li>{{ user.username }}</li>
|
||||||
|
{% end %}
|
||||||
|
{% end %}
|
||||||
|
{% end %}
|
||||||
|
</ul>
|
||||||
|
</td>
|
||||||
|
<td><a href="/panel/edit_role?id={{role.role_id}}"><i class="fas fa-pencil-alt"></i></a></td>
|
||||||
|
</tr>
|
||||||
|
{% end %}
|
||||||
|
{% end %}
|
||||||
|
{% end %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
@ -49,7 +49,7 @@
|
|||||||
</ul>
|
</ul>
|
||||||
<div class="">
|
<div class="">
|
||||||
<div class="">
|
<div class="">
|
||||||
<form class="forms-sample" method="post" action="{{ '/panel/add_role' if data['new_role'] else '/panel/edit_role' }}">
|
<form id="role_form" class="forms-sample" method="post" action="{{ '/panel/add_role' if data['new_role'] else '/panel/edit_role' }}">
|
||||||
{% raw xsrf_form_html() %}
|
{% raw xsrf_form_html() %}
|
||||||
<input type="hidden" name="id" value="{{ data['role']['role_id'] }}">
|
<input type="hidden" name="id" value="{{ data['role']['role_id'] }}">
|
||||||
<input type="hidden" name="subpage" value="config">
|
<input type="hidden" name="subpage" value="config">
|
||||||
@ -63,6 +63,29 @@
|
|||||||
<label for="role_name">{{ translate('rolesConfig', 'roleName', data['lang']) }} <small class="text-muted ml-1"> - {{ translate('rolesConfig', 'roleDesc', data['lang']) }}</small> </label>
|
<label for="role_name">{{ translate('rolesConfig', 'roleName', data['lang']) }} <small class="text-muted ml-1"> - {{ translate('rolesConfig', 'roleDesc', data['lang']) }}</small> </label>
|
||||||
<input type="text" class="form-control" name="role_name" id="role_name" value="{{ data['role']['role_name'] }}" placeholder="Role Name" >
|
<input type="text" class="form-control" name="role_name" id="role_name" value="{{ data['role']['role_name'] }}" placeholder="Role Name" >
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
{% if data['superuser'] %}
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label" for="manager">{{ translate('rolesConfig', 'selectManager',
|
||||||
|
data['lang']) }}
|
||||||
|
</label>
|
||||||
|
<select class="form-select form-control form-control-lg select-css" id="manager" name="manager"
|
||||||
|
form="role_form">
|
||||||
|
{% if data["role_manager"]["username"] != "None" %}
|
||||||
|
<option value='{{data["role_manager"]["user_id"]}}'>{{ data["role_manager"]["username"]
|
||||||
|
}}</option>
|
||||||
|
{% end %}
|
||||||
|
<option value="">None</option>
|
||||||
|
{% for user in data['users'] %}
|
||||||
|
{% if user.user_id != data['role_manager']['user_id']
|
||||||
|
%}
|
||||||
|
<option value="{{user.user_id}}">{{user.username}}</option>
|
||||||
|
{% end %}
|
||||||
|
{% end %}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
{% end %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -252,6 +275,8 @@
|
|||||||
<br />
|
<br />
|
||||||
{{ translate('rolesConfig', 'configUpdate', data['lang']) }} {{ str(data['role']['last_update']) }}
|
{{ translate('rolesConfig', 'configUpdate', data['lang']) }} {{ str(data['role']['last_update']) }}
|
||||||
<br />
|
<br />
|
||||||
|
{{ translate('userConfig', 'manager', data['lang']) }}: {{ data['role_manager']['username'] }}
|
||||||
|
<br />
|
||||||
</p>
|
</p>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
<div class="text-center">
|
<div class="text-center">
|
||||||
|
@ -121,6 +121,27 @@ data['lang']) }}{% end %}
|
|||||||
{% end %}
|
{% end %}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
{% if data['superuser'] %}
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label" for="manager">{{ translate('userConfig', 'selectManager',
|
||||||
|
data['lang']) }}
|
||||||
|
</label>
|
||||||
|
<select class="form-select form-control form-control-lg select-css" id="manager" name="manager"
|
||||||
|
form="user_form">
|
||||||
|
{% if data["manager"]["username"] != "None" %}
|
||||||
|
<option value='{{data["manager"]["user_id"]}}'>{{ data["manager"]["username"]
|
||||||
|
}}</option>
|
||||||
|
{% end %}
|
||||||
|
<option value="">None</option>
|
||||||
|
{% for user in data['users'] %}
|
||||||
|
{% if user.username != data['user']['username'] and user.user_id != data['manager']['user_id']
|
||||||
|
%}
|
||||||
|
<option value="{{user.user_id}}">{{user.username}}</option>
|
||||||
|
{% end %}
|
||||||
|
{% end %}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
{% end %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -141,21 +162,29 @@ data['lang']) }}{% end %}
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for role in data['roles_all'] %}
|
{% for role in data['roles'] %}
|
||||||
<tr>
|
<tr>
|
||||||
|
{% if data['superuser'] or role.role_id in data['user']['roles'] or role.manager == data['exec_user'] %}
|
||||||
<td>{{ role.role_name }}</td>
|
<td>{{ role.role_name }}</td>
|
||||||
<td>
|
<td>
|
||||||
{% if role.role_id in data['user']['roles'] %}
|
{% if role.role_id in data['user']['roles'] %}
|
||||||
|
{% if role.manager == data['exec_user'] or data['superuser'] %}
|
||||||
<input type="checkbox" class="form-check-input"
|
<input type="checkbox" class="form-check-input"
|
||||||
id="role_{{ role.role_id }}_membership" name="role_{{ role.role_id }}_membership"
|
id="role_{{ role.role_id }}_membership" name="role_{{ role.role_id }}_membership"
|
||||||
checked="" value="1">
|
checked="" value="1">
|
||||||
{% else %}
|
{% else %}
|
||||||
|
<input type="checkbox" class="form-check-input"
|
||||||
|
id="role_{{ role.role_id }}_membership" name="role_{{ role.role_id }}_membership"
|
||||||
|
checked="" value="1" disabled>
|
||||||
|
{% end %}
|
||||||
|
{% elif data['superuser'] or role.manager == data['exec_user'] %}
|
||||||
<input type="checkbox" class="form-check-input"
|
<input type="checkbox" class="form-check-input"
|
||||||
id="role_{{ role.role_id }}_membership" name="role_{{ role.role_id }}_membership"
|
id="role_{{ role.role_id }}_membership" name="role_{{ role.role_id }}_membership"
|
||||||
value="1">
|
value="1">
|
||||||
{% end %}
|
{% end %}
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
|
{% end %}
|
||||||
</tr>
|
</tr>
|
||||||
{% end %}
|
{% end %}
|
||||||
</tbody>
|
</tbody>
|
||||||
@ -268,6 +297,8 @@ data['lang']) }}{% end %}
|
|||||||
<br />
|
<br />
|
||||||
{{ translate('userConfig', 'lastIP', data['lang']) }} {{ data['user']['last_ip'] }}
|
{{ translate('userConfig', 'lastIP', data['lang']) }} {{ data['user']['last_ip'] }}
|
||||||
<br />
|
<br />
|
||||||
|
{{ translate('userConfig', 'manager', data['lang'])}}: {{data['manager']['username'] }}
|
||||||
|
<br />
|
||||||
</p>
|
</p>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
</div>
|
</div>
|
||||||
@ -284,7 +315,7 @@ data['lang']) }}{% end %}
|
|||||||
{% else %}
|
{% else %}
|
||||||
<button class="btn btn-sm btn-danger delete-user"><i class="fas fa-trash"></i> {{
|
<button class="btn btn-sm btn-danger delete-user"><i class="fas fa-trash"></i> {{
|
||||||
translate('userConfig', 'deleteUserB', data['lang']) }}</a>
|
translate('userConfig', 'deleteUserB', data['lang']) }}</a>
|
||||||
{% end %}
|
{% end %}</button>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
{% if data['permissions']['Players'] in data['user_permissions'] and data['server_data']['type'] != 'minecraft-bedrock' %}
|
{% if data['permissions']['Players'] in data['user_permissions'] and data['server_data']['type'] != 'minecraft-bedrock' %}
|
||||||
<a class="dropdown-item {% if data['active_link'] == 'admin_controls' %}active{% end %}" href="/panel/server_detail?id={{ data['server_stats']['server_id']['server_id'] }}&subpage=admin_controls" role="tab" aria-selected="true"><i class="fas fa-users"></i> {{ translate('serverDetails', 'playerControls', data['lang']) }}</a>
|
<a class="dropdown-item {% if data['active_link'] == 'admin_controls' %}active{% end %}" href="/panel/server_detail?id={{ data['server_stats']['server_id']['server_id'] }}&subpage=admin_controls" role="tab" aria-selected="true"><i class="fas fa-users"></i> {{ translate('serverDetails', 'playerControls', data['lang']) }}</a>
|
||||||
{% end %}
|
{% end %}
|
||||||
|
<a class="dropdown-item {% if data['active_link'] == 'metrics' %}active{% end %}" href="/panel/server_detail?id={{ data['server_stats']['server_id']['server_id'] }}&subpage=metrics" role="tab" aria-selected="true"><i class='fas fa-chart-area'></i>{{ translate('serverDetails', 'metrics', data['lang']) }}</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
@ -49,4 +49,8 @@
|
|||||||
<i class="fas fa-users"></i>{{ translate('serverDetails', 'playerControls', data['lang']) }}</a>
|
<i class="fas fa-users"></i>{{ translate('serverDetails', 'playerControls', data['lang']) }}</a>
|
||||||
</li>
|
</li>
|
||||||
{% end %}
|
{% end %}
|
||||||
|
<li class="nav-item term-nav-item">
|
||||||
|
<a class="nav-link {% if data['active_link'] == 'metrics' %}active{% end %}" href="/panel/server_detail?id={{ data['server_stats']['server_id']['server_id'] }}&subpage=metrics" role="tab" aria-selected="true">
|
||||||
|
<i class='fas fa-chart-area'></i>{{ translate('serverDetails', 'metrics', data['lang']) }}</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
@ -165,6 +165,18 @@
|
|||||||
</div>
|
</div>
|
||||||
{% end %}
|
{% end %}
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="shutdown_timeout">{{ translate('serverConfig', 'shutdownTimeout', data['lang']) }}
|
||||||
|
<small class="text-muted ml-1"> - {{ translate('serverConfig', 'timeoutExplain1', data['lang'])
|
||||||
|
}}
|
||||||
|
{{ data['server_stats']['server_id']['stop_command'] }} {{ translate('serverConfig',
|
||||||
|
'timeoutExplain2', data['lang']) }}
|
||||||
|
</small> </label>
|
||||||
|
<input type="number" class="form-control" name="shutdown_timeout" id="shutdown_timeout"
|
||||||
|
value="{{ data['server_stats']['server_id']['shutdown_timeout'] }}" step="2" max="300" min="60"
|
||||||
|
required>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="logs_delete_after">{{ translate('serverConfig', 'removeOldLogsAfter', data['lang']) }}
|
<label for="logs_delete_after">{{ translate('serverConfig', 'removeOldLogsAfter', data['lang']) }}
|
||||||
<small class="text-muted ml-1"> - {{ translate('serverConfig', 'removeOldLogsAfterDesc',
|
<small class="text-muted ml-1"> - {{ translate('serverConfig', 'removeOldLogsAfterDesc',
|
||||||
|
225
app/frontend/templates/panel/server_metrics.html
Normal file
225
app/frontend/templates/panel/server_metrics.html
Normal file
@ -0,0 +1,225 @@
|
|||||||
|
{% extends ../base.html %}
|
||||||
|
|
||||||
|
{% block meta %}
|
||||||
|
{% end %}
|
||||||
|
|
||||||
|
{% block title %}Crafty Controller - {{ translate('serverDetails', 'serverDetails', data['lang']) }}{% end %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
<div class="content-wrapper">
|
||||||
|
|
||||||
|
<!-- Page Title Header Starts-->
|
||||||
|
<div class="row page-title-header">
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="page-header">
|
||||||
|
<h4 class="page-title">
|
||||||
|
{{ translate('serverDetails', 'serverDetails', data['lang']) }} - {{
|
||||||
|
data['server_stats']['server_id']['server_name'] }}
|
||||||
|
<br />
|
||||||
|
<small>UUID: {{ data['server_stats']['server_id']['server_uuid'] }}</small>
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- Page Title Header Ends-->
|
||||||
|
|
||||||
|
{% include "parts/details_stats.html %}
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
<div class="col-sm-12 grid-margin">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body pt-0">
|
||||||
|
<span class="d-none d-sm-block">
|
||||||
|
{% include "parts/server_controls_list.html %}
|
||||||
|
</span>
|
||||||
|
<span class="d-block d-sm-none">
|
||||||
|
{% include "parts/m_server_controls_list.html %}
|
||||||
|
</span>
|
||||||
|
<button style="float: right; visibility: hidden;" class="btn btn-outline-success reset-button"
|
||||||
|
id="reset-button"><i class="fas fa-undo"></i> {{ translate('serverMetrics', 'resetZoom', data['lang'])
|
||||||
|
}}</button>
|
||||||
|
{% if data['user_data']['hints'] %}
|
||||||
|
<span data-html="true" class="hints text-center" title="<i class='fa fa-info-circle'></i> " ,
|
||||||
|
data-content="{{
|
||||||
|
translate('serverMetrics', 'zoomHint1' , data['lang'])}} <br> <br> {{ translate('serverMetrics', 'zoomHint2', data['lang'])}}" , data-placement="top"></span>
|
||||||
|
{% end %}
|
||||||
|
<div class="chart-wrapper">
|
||||||
|
<canvas id="lineChart"></canvas>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<style>
|
||||||
|
.chart-wrapper {
|
||||||
|
height: 65vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popover-body {
|
||||||
|
color: white !important;
|
||||||
|
;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script type="text/javascript">
|
||||||
|
var zoomed = false;
|
||||||
|
//line
|
||||||
|
var ctxL = document.getElementById("lineChart").getContext('2d');
|
||||||
|
const players = []
|
||||||
|
const dates = []
|
||||||
|
const ram = []
|
||||||
|
const cpu = []
|
||||||
|
{% for item in data['history_stats'] %}
|
||||||
|
{% if 'minecraft-java' in data['server_stats']['server_type'] %}
|
||||||
|
players.push("{{ item.online }}");
|
||||||
|
{% end %}
|
||||||
|
dates.push("{{ item.created.strftime('%Y/%m/%d, %H:%M:%S') }}");
|
||||||
|
ram.push("{{ item.mem_percent }}")
|
||||||
|
cpu.push("{{ item.cpu }}")
|
||||||
|
{% end %}
|
||||||
|
var hist_chart = new Chart(ctxL, {
|
||||||
|
type: 'line',
|
||||||
|
data: {
|
||||||
|
labels: dates,
|
||||||
|
datasets: [{
|
||||||
|
label: "Players",
|
||||||
|
data: players,
|
||||||
|
borderColor: [
|
||||||
|
'rgba(136, 98, 224, .5)',
|
||||||
|
],
|
||||||
|
borderWidth: 2,
|
||||||
|
lineTension: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "MEM",
|
||||||
|
data: ram,
|
||||||
|
borderColor: [
|
||||||
|
'rgba(33, 150, 243, .5)',
|
||||||
|
],
|
||||||
|
borderWidth: 2,
|
||||||
|
lineTension: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "CPU",
|
||||||
|
data: cpu,
|
||||||
|
borderColor: [
|
||||||
|
'rgba(255, 175, 0, .5)',
|
||||||
|
],
|
||||||
|
borderWidth: 2,
|
||||||
|
lineTension: 0,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
plugins: {
|
||||||
|
zoom: {
|
||||||
|
zoom: {
|
||||||
|
onZoom({ hist_chart }) {
|
||||||
|
console.log("zooming");
|
||||||
|
document.getElementById("reset-button").style.visibility = "visible";
|
||||||
|
zoomed = true;
|
||||||
|
},
|
||||||
|
wheel: {
|
||||||
|
enabled: true,
|
||||||
|
modifierKey: 'shift',
|
||||||
|
},
|
||||||
|
drag: {
|
||||||
|
enabled: true,
|
||||||
|
modifierKey: "shift"
|
||||||
|
},
|
||||||
|
pinch: {
|
||||||
|
enabled: true
|
||||||
|
},
|
||||||
|
mode: 'x',
|
||||||
|
},
|
||||||
|
pan: {
|
||||||
|
enabled: true,
|
||||||
|
mode: "x",
|
||||||
|
threshhold: 1,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
fill: false,
|
||||||
|
lineTension: 5,
|
||||||
|
responsive: true,
|
||||||
|
scales: {
|
||||||
|
y: {
|
||||||
|
min: 0,
|
||||||
|
},
|
||||||
|
x: {
|
||||||
|
position: 'right',
|
||||||
|
min: dates.length - 200,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$(window).ready(function () {
|
||||||
|
$('body').click(function () {
|
||||||
|
$('.hints').popover("hide");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
$(document).ready(function () {
|
||||||
|
if ($(window).width() > 1000) {
|
||||||
|
$('[data-toggle="popover"]').popover();
|
||||||
|
$('.hints').popover("show");
|
||||||
|
}
|
||||||
|
webSocket.on('update_server_details', function (data) {
|
||||||
|
dates.push(data.created);
|
||||||
|
players.push(data.online);
|
||||||
|
cpu.push(data.cpu)
|
||||||
|
ram.push(data.mem_percent)
|
||||||
|
data = {
|
||||||
|
labels: dates,
|
||||||
|
datasets: [{
|
||||||
|
label: "Players",
|
||||||
|
data: players,
|
||||||
|
borderColor: [
|
||||||
|
'rgba(136, 98, 224, .5)',
|
||||||
|
],
|
||||||
|
borderWidth: 2,
|
||||||
|
lineTension: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "MEM",
|
||||||
|
data: ram,
|
||||||
|
borderColor: [
|
||||||
|
'rgba(33, 150, 243, .5)',
|
||||||
|
],
|
||||||
|
borderWidth: 2,
|
||||||
|
lineTension: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "CPU",
|
||||||
|
data: cpu,
|
||||||
|
borderColor: [
|
||||||
|
'rgba(255, 175, 0, .5)',
|
||||||
|
],
|
||||||
|
borderWidth: 2,
|
||||||
|
lineTension: 0,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
if (!zoomed) {
|
||||||
|
hist_chart.options.scales.x.min = dates.length - 200;
|
||||||
|
}
|
||||||
|
hist_chart.update(data)
|
||||||
|
});
|
||||||
|
|
||||||
|
$(".reset-button").click(function () {
|
||||||
|
console.log("resetting zoom");
|
||||||
|
zoomed = false;
|
||||||
|
hist_chart.resetZoom();
|
||||||
|
document.getElementById("reset-button").style.visibility = "hidden";
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{% end %}
|
@ -65,9 +65,9 @@
|
|||||||
<button onclick="" id="restart-btn" style="max-width: 7rem;" class="btn btn-outline-primary m-1 flex-grow-1 disabled">{% raw translate('serverTerm', 'restart', data['lang']) %}</button>
|
<button onclick="" id="restart-btn" style="max-width: 7rem;" class="btn btn-outline-primary m-1 flex-grow-1 disabled">{% raw translate('serverTerm', 'restart', data['lang']) %}</button>
|
||||||
<button onclick="" id="stop-btn" style="max-width: 7rem;" class="btn btn-danger m-1 flex-grow-1 disabled">{{ translate('serverTerm', 'stop', data['lang']) }}</button>
|
<button onclick="" id="stop-btn" style="max-width: 7rem;" class="btn btn-danger m-1 flex-grow-1 disabled">{{ translate('serverTerm', 'stop', data['lang']) }}</button>
|
||||||
</div>
|
</div>
|
||||||
{% elif data['downloading'] %}
|
{% elif data['importing'] %}
|
||||||
<div id="control_buttons" class="mt-4 flex-wrap d-flex justify-content-between justify-content-md-center align-items-center px-5 px-md-0" style="visibility: visible">
|
<div id="control_buttons" class="mt-4 flex-wrap d-flex justify-content-between justify-content-md-center align-items-center px-5 px-md-0" style="visibility: visible">
|
||||||
<button onclick="" id="start-btn" style="max-width: 12rem; white-space: nowrap;" class="btn btn-secondary m-1 flex-grow-1 disabled"><i class="fa fa-spinner fa-spin"></i> {{ translate('serverTerm', 'downloading',
|
<button onclick="" id="start-btn" style="max-width: 12rem; white-space: nowrap;" class="btn btn-secondary m-1 flex-grow-1 disabled"><i class="fa fa-spinner fa-spin"></i> {{ translate('serverTerm', 'importing',
|
||||||
data['lang']) }}</button>
|
data['lang']) }}</button>
|
||||||
<button onclick="" id="restart-btn" style="max-width: 7rem;" class="btn btn-outline-primary m-1 flex-grow-1 disabled">{% raw translate('serverTerm', 'restart', data['lang']) %}</button>
|
<button onclick="" id="restart-btn" style="max-width: 7rem;" class="btn btn-outline-primary m-1 flex-grow-1 disabled">{% raw translate('serverTerm', 'restart', data['lang']) %}</button>
|
||||||
<button onclick="" id="stop-btn" style="max-width: 7rem;" class="btn btn-danger m-1 flex-grow-1 disabled">{{ translate('serverTerm', 'stop', data['lang']) }}</button>
|
<button onclick="" id="stop-btn" style="max-width: 7rem;" class="btn btn-danger m-1 flex-grow-1 disabled">{{ translate('serverTerm', 'stop', data['lang']) }}</button>
|
||||||
|
16
app/migrations/20220819_role_manager.py
Normal file
16
app/migrations/20220819_role_manager.py
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
# Generated by database migrator
|
||||||
|
import peewee
|
||||||
|
|
||||||
|
|
||||||
|
def migrate(migrator, database, **kwargs):
|
||||||
|
migrator.add_columns("roles", manager=peewee.IntegerField(null=True))
|
||||||
|
"""
|
||||||
|
Write your migrations here.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def rollback(migrator, database, **kwargs):
|
||||||
|
migrator.drop_columns("roles", ["manager"])
|
||||||
|
"""
|
||||||
|
Write your rollback migrations here.
|
||||||
|
"""
|
16
app/migrations/20220819_user_manager.py
Normal file
16
app/migrations/20220819_user_manager.py
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
# Generated by database migrator
|
||||||
|
import peewee
|
||||||
|
|
||||||
|
|
||||||
|
def migrate(migrator, database, **kwargs):
|
||||||
|
migrator.add_columns("users", manager=peewee.IntegerField(null=True))
|
||||||
|
"""
|
||||||
|
Write your migrations here.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def rollback(migrator, database, **kwargs):
|
||||||
|
migrator.drop_columns("users", ["manager"])
|
||||||
|
"""
|
||||||
|
Write your rollback migrations here.
|
||||||
|
"""
|
16
app/migrations/20220820_quota.py
Normal file
16
app/migrations/20220820_quota.py
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
# Generated by database migrator
|
||||||
|
import peewee
|
||||||
|
|
||||||
|
|
||||||
|
def migrate(migrator, database, **kwargs):
|
||||||
|
migrator.add_columns("servers", created_by=peewee.IntegerField(default=-100))
|
||||||
|
"""
|
||||||
|
Write your migrations here.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def rollback(migrator, database, **kwargs):
|
||||||
|
migrator.drop_columns("servers", ["created_by"])
|
||||||
|
"""
|
||||||
|
Write your rollback migrations here.
|
||||||
|
"""
|
20
app/migrations/20220820_user_crafty.py
Normal file
20
app/migrations/20220820_user_crafty.py
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# Generated by database migrator
|
||||||
|
import peewee
|
||||||
|
|
||||||
|
|
||||||
|
def migrate(migrator, database, **kwargs):
|
||||||
|
migrator.drop_columns("user_crafty", ["created_server"])
|
||||||
|
migrator.drop_columns("user_crafty", ["created_user"])
|
||||||
|
migrator.drop_columns("user_crafty", ["created_role"])
|
||||||
|
"""
|
||||||
|
Write your migrations here.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def rollback(migrator, database, **kwargs):
|
||||||
|
migrator.add_columns("user_crafty", created_server=peewee.IntegerField(default=0))
|
||||||
|
migrator.add_columns("user_crafty", created_user=peewee.IntegerField(default=0))
|
||||||
|
migrator.add_columns("user_crafty", created_role=peewee.IntegerField(default=0))
|
||||||
|
"""
|
||||||
|
Write your rollback migrations here.
|
||||||
|
"""
|
16
app/migrations/20220821_shutdown_timeout.py
Normal file
16
app/migrations/20220821_shutdown_timeout.py
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
# Generated by database migrator
|
||||||
|
import peewee
|
||||||
|
|
||||||
|
|
||||||
|
def migrate(migrator, database, **kwargs):
|
||||||
|
migrator.add_columns("servers", shutdown_timeout=peewee.IntegerField(default=60))
|
||||||
|
"""
|
||||||
|
Write your migrations here.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def rollback(migrator, database, **kwargs):
|
||||||
|
migrator.drop_columns("servers", ["shutdown_timeout"])
|
||||||
|
"""
|
||||||
|
Write your rollback migrations here.
|
||||||
|
"""
|
17
app/migrations/stats/20220817_schedule_rename_downloading.py
Normal file
17
app/migrations/stats/20220817_schedule_rename_downloading.py
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
# Generated by database migrator
|
||||||
|
import peewee
|
||||||
|
|
||||||
|
|
||||||
|
def migrate(migrator, database, **kwargs):
|
||||||
|
migrator.rename_column("server_stats", "downloading", "importing")
|
||||||
|
|
||||||
|
"""
|
||||||
|
Write your migrations here.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def rollback(migrator, database, **kwargs):
|
||||||
|
migrator.rename_column("server_stats", "importing", "downloading")
|
||||||
|
"""
|
||||||
|
Write your rollback migrations here.
|
||||||
|
"""
|
@ -245,7 +245,8 @@
|
|||||||
"roleUsers": "Role Users: ",
|
"roleUsers": "Role Users: ",
|
||||||
"serverAccess": "Access?",
|
"serverAccess": "Access?",
|
||||||
"serverName": "Server Name",
|
"serverName": "Server Name",
|
||||||
"serversDesc": "servers this role is allowed to access"
|
"serversDesc": "servers this role is allowed to access",
|
||||||
|
"selectManager": "Select a manager for this Role"
|
||||||
},
|
},
|
||||||
"serverBackups": {
|
"serverBackups": {
|
||||||
"backupAtMidnight": "Auto-backup at midnight?",
|
"backupAtMidnight": "Auto-backup at midnight?",
|
||||||
@ -324,7 +325,10 @@
|
|||||||
"stopBeforeDeleting": "Please stop the server before deleting it",
|
"stopBeforeDeleting": "Please stop the server before deleting it",
|
||||||
"update": "Update Executable",
|
"update": "Update Executable",
|
||||||
"yesDelete": "Yes, delete",
|
"yesDelete": "Yes, delete",
|
||||||
"yesDeleteFiles": "Yes, delete files"
|
"yesDeleteFiles": "Yes, delete files",
|
||||||
|
"shutdownTimeout": "Shutdown Timeout",
|
||||||
|
"timeoutExplain1": "How long Crafty will wait for your server to shutdown after executing the",
|
||||||
|
"timeoutExplain2": "command before it forces the process down."
|
||||||
},
|
},
|
||||||
"serverConfigHelp": {
|
"serverConfigHelp": {
|
||||||
"desc": "Here is where you can change the configuration of your server",
|
"desc": "Here is where you can change the configuration of your server",
|
||||||
@ -351,7 +355,8 @@
|
|||||||
"playerControls": "Player Management",
|
"playerControls": "Player Management",
|
||||||
"schedule": "Schedule",
|
"schedule": "Schedule",
|
||||||
"serverDetails": "Server Details",
|
"serverDetails": "Server Details",
|
||||||
"terminal": "Terminal"
|
"terminal": "Terminal",
|
||||||
|
"metrics": "Metrics"
|
||||||
},
|
},
|
||||||
"serverFiles": {
|
"serverFiles": {
|
||||||
"clickUpload": "Click here to select your files",
|
"clickUpload": "Click here to select your files",
|
||||||
@ -463,7 +468,7 @@
|
|||||||
"serverTerm": {
|
"serverTerm": {
|
||||||
"commandInput": "Enter your command",
|
"commandInput": "Enter your command",
|
||||||
"delay-explained": "The service/agent has recently started and is delaying the start of the minecraft server instance",
|
"delay-explained": "The service/agent has recently started and is delaying the start of the minecraft server instance",
|
||||||
"downloading": "Downloading...",
|
"importing": "Importing...",
|
||||||
"restart": "Restart",
|
"restart": "Restart",
|
||||||
"sendCommand": "Send command",
|
"sendCommand": "Send command",
|
||||||
"start": "Start",
|
"start": "Start",
|
||||||
@ -472,6 +477,11 @@
|
|||||||
"stopScroll": "Stop Auto Scrolling",
|
"stopScroll": "Stop Auto Scrolling",
|
||||||
"updating": "Updating..."
|
"updating": "Updating..."
|
||||||
},
|
},
|
||||||
|
"serverMetrics": {
|
||||||
|
"resetZoom": "Reset Zoom",
|
||||||
|
"zoomHint1": "To zoom on the graph hold your shift key then use your scroll wheel.",
|
||||||
|
"zoomHint2": "Alternatively hold the shift key then click and drag the area you'd like to zoom in on."
|
||||||
|
},
|
||||||
"serverWizard": {
|
"serverWizard": {
|
||||||
"absoluteServerPath": "Absolute path to your server",
|
"absoluteServerPath": "Absolute path to your server",
|
||||||
"absoluteZipPath": "Absolute path to your server",
|
"absoluteZipPath": "Absolute path to your server",
|
||||||
@ -556,6 +566,8 @@
|
|||||||
"userRoles": "User Roles",
|
"userRoles": "User Roles",
|
||||||
"userRolesDesc": "Roles this user is a member of.",
|
"userRolesDesc": "Roles this user is a member of.",
|
||||||
"userSettings": "User Settings",
|
"userSettings": "User Settings",
|
||||||
"uses": "Number of uses allowed (-1==No Limit)"
|
"uses": "Number of uses allowed (-1==No Limit)",
|
||||||
|
"manager": "Manager",
|
||||||
|
"selectManager": "Select Manager for User"
|
||||||
}
|
}
|
||||||
}
|
}
|
4
main.py
4
main.py
@ -14,6 +14,7 @@ from app.classes.shared.import3 import Import3
|
|||||||
from app.classes.shared.console import Console
|
from app.classes.shared.console import Console
|
||||||
from app.classes.shared.helpers import Helpers
|
from app.classes.shared.helpers import Helpers
|
||||||
from app.classes.models.users import HelperUsers
|
from app.classes.models.users import HelperUsers
|
||||||
|
from app.classes.shared.import_helper import ImportHelpers
|
||||||
|
|
||||||
console = Console()
|
console = Console()
|
||||||
helper = Helpers()
|
helper = Helpers()
|
||||||
@ -135,8 +136,9 @@ if __name__ == "__main__":
|
|||||||
else:
|
else:
|
||||||
Console.debug("Existing install detected")
|
Console.debug("Existing install detected")
|
||||||
file_helper = FileHelpers(helper)
|
file_helper = FileHelpers(helper)
|
||||||
|
import_helper = ImportHelpers(helper, file_helper)
|
||||||
# now the tables are created, we can load the tasks_manager and server controller
|
# now the tables are created, we can load the tasks_manager and server controller
|
||||||
controller = Controller(database, helper, file_helper)
|
controller = Controller(database, helper, file_helper, import_helper)
|
||||||
import3 = Import3(helper, controller)
|
import3 = Import3(helper, controller)
|
||||||
tasks_manager = TasksManager(helper, controller)
|
tasks_manager = TasksManager(helper, controller)
|
||||||
tasks_manager.start_webserver()
|
tasks_manager.start_webserver()
|
||||||
|
Loading…
Reference in New Issue
Block a user