Merge branch 'pretzels-fixes' into 'dev'

Pretzels fixes

See merge request crafty-controller/crafty-commander!110
This commit is contained in:
Andrew 2021-12-09 22:39:40 +00:00
commit 49893ea5a6
5 changed files with 268 additions and 197 deletions

View File

@ -12,12 +12,14 @@ import os
import shutil
import html
import re
from app.classes.models.users import helper_users
from app.classes.shared.console import console
from app.classes.shared.main_models import Users, installer
from app.classes.web.base_handler import BaseHandler
from app.classes.shared.helpers import helper
from app.classes.shared.server import ServerOutBuf
from app.classes.models.server_permissions import Enum_Permissions_Server
logger = logging.getLogger(__name__)
@ -133,6 +135,20 @@ class AjaxHandler(BaseHandler):
@tornado.web.authenticated
def post(self, page):
user_data = json.loads(self.get_secure_cookie("user_data"))
server_id = self.get_argument('id', None)
exec_user_id = user_data['user_id']
exec_user = helper_users.get_user(exec_user_id)
permissions = {
'Commands': Enum_Permissions_Server.Commands,
'Terminal': Enum_Permissions_Server.Terminal,
'Logs': Enum_Permissions_Server.Logs,
'Schedule': Enum_Permissions_Server.Schedule,
'Backup': Enum_Permissions_Server.Backup,
'Files': Enum_Permissions_Server.Files,
'Config': Enum_Permissions_Server.Config,
'Players': Enum_Permissions_Server.Players,
}
user_perms = self.controller.server_perms.get_server_permissions_foruser(exec_user_id, server_id)
error = bleach.clean(self.get_argument('error', "WTF Error!"))
page_data = {
@ -157,6 +173,10 @@ class AjaxHandler(BaseHandler):
self.controller.management.add_to_audit_log(user_data['user_id'], "Sent command to {} terminal: {}".format(self.controller.servers.get_server_friendly_name(server_id), command), server_id, self.get_remote_ip())
elif page == "create_file":
if not permissions['Files'] in user_perms:
if not exec_user['superuser']:
self.redirect("/panel/error?error=Unauthorized access to Files")
return
file_parent = helper.get_os_understandable_path(self.get_body_argument('file_parent', default=None, strip=True))
file_name = self.get_body_argument('file_name', default=None, strip=True)
file_path = os.path.join(file_parent, file_name)
@ -176,6 +196,10 @@ class AjaxHandler(BaseHandler):
file_object.close()
elif page == "create_dir":
if not permissions['Files'] in user_perms:
if not exec_user['superuser']:
self.redirect("/panel/error?error=Unauthorized access to Files")
return
dir_parent = helper.get_os_understandable_path(self.get_body_argument('dir_parent', default=None, strip=True))
dir_name = self.get_body_argument('dir_name', default=None, strip=True)
dir_path = os.path.join(dir_parent, dir_name)
@ -193,6 +217,10 @@ class AjaxHandler(BaseHandler):
os.mkdir(dir_path)
elif page == "unzip_file":
if not permissions['Files'] in user_perms:
if not exec_user['superuser']:
self.redirect("/panel/error?error=Unauthorized access to Files")
return
server_id = self.get_argument('id', None)
path = helper.get_os_understandable_path(self.get_argument('path', None))
helper.unzipFile(path)
@ -200,6 +228,10 @@ class AjaxHandler(BaseHandler):
return
elif page == "kill":
if not permissions['Commands'] in user_perms:
if not exec_user['superuser']:
self.redirect("/panel/error?error=Unauthorized access to Commands")
return
server_id = self.get_argument('id', None)
svr = self.controller.get_server_obj(server_id)
try:
@ -213,6 +245,10 @@ class AjaxHandler(BaseHandler):
svr.agree_eula(user_data['user_id'])
elif page == "restore_backup":
if not permissions['Backup'] in user_perms:
if not exec_user['superuser']:
self.redirect("/panel/error?error=Unauthorized access to Backups")
return
server_id = bleach.clean(self.get_argument('id', None))
zip_name = bleach.clean(self.get_argument('zip_file', None))
svr_obj = self.controller.servers.get_server_obj(server_id)
@ -229,7 +265,51 @@ class AjaxHandler(BaseHandler):
@tornado.web.authenticated
def delete(self, page):
user_data = json.loads(self.get_secure_cookie("user_data"))
server_id = self.get_argument('id', None)
exec_user_id = user_data['user_id']
exec_user = helper_users.get_user(exec_user_id)
permissions = {
'Commands': Enum_Permissions_Server.Commands,
'Terminal': Enum_Permissions_Server.Terminal,
'Logs': Enum_Permissions_Server.Logs,
'Schedule': Enum_Permissions_Server.Schedule,
'Backup': Enum_Permissions_Server.Backup,
'Files': Enum_Permissions_Server.Files,
'Config': Enum_Permissions_Server.Config,
'Players': Enum_Permissions_Server.Players,
}
user_perms = self.controller.server_perms.get_server_permissions_foruser(exec_user_id, server_id)
if page == "del_file":
if not permissions['Files'] in user_perms:
if not exec_user['superuser']:
self.redirect("/panel/error?error=Unauthorized access to Files")
return
file_path = helper.get_os_understandable_path(self.get_body_argument('file_path', default=None, strip=True))
server_id = self.get_argument('id', None)
console.warning("delete {} for server {}".format(file_path, server_id))
if not self.check_server_id(server_id, 'del_file'):
return
else: server_id = bleach.clean(server_id)
server_info = self.controller.servers.get_server_data_by_id(server_id)
if not (helper.in_path(helper.get_os_understandable_path(server_info['path']), file_path) \
or helper.in_path(helper.get_os_understandable_path(server_info['backup_path']), file_path)) \
or not helper.check_file_exists(os.path.abspath(file_path)):
logger.warning("Invalid path in del_file ajax call ({})".format(file_path))
console.warning("Invalid path in del_file ajax call ({})".format(file_path))
return
# Delete the file
os.remove(file_path)
if page == "del_backup":
if not permissions['Backup'] in user_perms:
if not exec_user['superuser']:
self.redirect("/panel/error?error=Unauthorized access to Backups")
return
file_path = helper.get_os_understandable_path(self.get_body_argument('file_path', default=None, strip=True))
server_id = self.get_argument('id', None)
@ -251,6 +331,10 @@ class AjaxHandler(BaseHandler):
os.remove(file_path)
elif page == "del_dir":
if not permissions['Files'] in user_perms:
if not exec_user['superuser']:
self.redirect("/panel/error?error=Unauthorized access to Files")
return
dir_path = helper.get_os_understandable_path(self.get_body_argument('dir_path', default=None, strip=True))
server_id = self.get_argument('id', None)
@ -271,12 +355,20 @@ class AjaxHandler(BaseHandler):
shutil.rmtree(dir_path) # Removes also when there are contents
elif page == "delete_server":
if not permissions['Config'] in user_perms:
if not exec_user['superuser']:
self.redirect("/panel/error?error=Unauthorized access to Config")
return
server_id = self.get_argument('id', None)
logger.info(
"Removing server from panel for server: {}".format(self.controller.servers.get_server_friendly_name(server_id)))
self.controller.remove_server(server_id, False)
elif page == "delete_server_files":
if not permissions['Config'] in user_perms:
if not exec_user['superuser']:
self.redirect("/panel/error?error=Unauthorized access to Config")
return
server_id = self.get_argument('id', None)
logger.info(
"Removing server and all associated files for server: {}".format(self.controller.servers.get_server_friendly_name(server_id)))
@ -284,7 +376,26 @@ class AjaxHandler(BaseHandler):
@tornado.web.authenticated
def put(self, page):
user_data = json.loads(self.get_secure_cookie("user_data"))
server_id = self.get_argument('id', None)
exec_user_id = user_data['user_id']
exec_user = helper_users.get_user(exec_user_id)
permissions = {
'Commands': Enum_Permissions_Server.Commands,
'Terminal': Enum_Permissions_Server.Terminal,
'Logs': Enum_Permissions_Server.Logs,
'Schedule': Enum_Permissions_Server.Schedule,
'Backup': Enum_Permissions_Server.Backup,
'Files': Enum_Permissions_Server.Files,
'Config': Enum_Permissions_Server.Config,
'Players': Enum_Permissions_Server.Players,
}
user_perms = self.controller.server_perms.get_server_permissions_foruser(exec_user_id, server_id)
if page == "save_file":
if not permissions['Files'] in user_perms:
if not exec_user['superuser']:
self.redirect("/panel/error?error=Unauthorized access to Files")
return
file_contents = self.get_body_argument('file_contents', default=None, strip=True)
file_path = helper.get_os_understandable_path(self.get_body_argument('file_path', default=None, strip=True))
server_id = self.get_argument('id', None)
@ -303,6 +414,10 @@ class AjaxHandler(BaseHandler):
file_object.write(file_contents)
elif page == "rename_item":
if not permissions['Files'] in user_perms:
if not exec_user['superuser']:
self.redirect("/panel/error?error=Unauthorized access to Files")
return
item_path = helper.get_os_understandable_path(self.get_body_argument('item_path', default=None, strip=True))
new_item_name = self.get_body_argument('new_item_name', default=None, strip=True)
server_id = self.get_argument('id', None)

View File

@ -18,6 +18,7 @@ from app.classes.web.base_handler import BaseHandler
from app.classes.models.servers import Servers
from app.classes.models.server_permissions import Enum_Permissions_Server
from app.classes.models.crafty_permissions import Enum_Permissions_Crafty
from app.classes.models.management import management_helper
from app.classes.shared.helpers import helper
@ -185,7 +186,7 @@ class PanelHandler(BaseHandler):
self.redirect("/panel/error?error=Invalid Server ID")
return False
valid_subpages = ['term', 'logs', 'backup', 'config', 'files', 'admin_controls']
valid_subpages = ['term', 'logs', 'backup', 'config', 'files', 'admin_controls', 'tasks']
if subpage not in valid_subpages:
logger.debug('not a valid subpage')
@ -213,39 +214,45 @@ class PanelHandler(BaseHandler):
'Players': Enum_Permissions_Server.Players,
}
page_data['user_permissions'] = self.controller.server_perms.get_server_permissions_foruser(exec_user_id, server_id)
user_perms = self.controller.server_perms.get_server_permissions_foruser(exec_user_id, server_id)
if subpage == 'term':
if not page_data['permissions']['Terminal'] in page_data['user_permissions']:
if not exec_user['superuser']:
self.redirect("/panel/error?error=Unauthorized access to Terminal")
return
if subpage == 'logs':
if not page_data['permissions']['Logs'] in page_data['user_permissions']:
if not exec_user['superuser']:
self.redirect("/panel/error?error=Unauthorized access to Logs")
self.redirect("/panel/error?error=Unauthorized access to Logs")
return
if subpage == 'tasks':
if not page_data['permissions']['Schedule'] in page_data['user_permissions']:
if not exec_user['superuser']:
self.redirect("/panel/error?error=Unauthorized access To Scheduled Tasks")
return
page_data['schedules'] = management_helper.get_schedules_by_server(server_id)
if subpage == 'config':
if not page_data['permissions']['Config'] in page_data['user_permissions']:
if not exec_user['superuser']:
self.redirect("/panel/error?error=Unauthorized access Server Config")
return
if subpage == 'files':
if not page_data['permissions']['Files'] in page_data['user_permissions']:
if not exec_user['superuser']:
self.redirect("/panel/error?error=Unauthorized access Files")
return
if subpage == "backup":
if not page_data['permissions']['Backup'] in page_data['user_permissions']:
if not exec_user['superuser']:
self.redirect("/panel/error?error=Unauthorized access to Backups")
return
server_info = self.controller.servers.get_server_data_by_id(server_id)
page_data['backup_config'] = self.controller.management.get_backup_config(server_id)
self.controller.refresh_server_settings(server_id)
@ -647,7 +654,18 @@ class PanelHandler(BaseHandler):
exec_user_data = json.loads(self.get_secure_cookie("user_data"))
exec_user_id = exec_user_data['user_id']
exec_user = self.controller.users.get_user_by_id(exec_user_id)
server_id = self.get_argument('id', None)
permissions = {
'Commands': Enum_Permissions_Server.Commands,
'Terminal': Enum_Permissions_Server.Terminal,
'Logs': Enum_Permissions_Server.Logs,
'Schedule': Enum_Permissions_Server.Schedule,
'Backup': Enum_Permissions_Server.Backup,
'Files': Enum_Permissions_Server.Files,
'Config': Enum_Permissions_Server.Config,
'Players': Enum_Permissions_Server.Players,
}
user_perms = self.controller.server_perms.get_server_permissions_foruser(exec_user_id, server_id)
exec_user_role = set()
if exec_user['superuser'] == 1:
defined_servers = self.controller.list_defined_servers()
@ -661,17 +679,26 @@ class PanelHandler(BaseHandler):
exec_user_role.add(role['role_name'])
if page == 'server_detail':
if not permissions['Config'] in user_perms:
if not exec_user['superuser']:
self.redirect("/panel/error?error=Unauthorized access to Config")
return
server_id = self.get_argument('id', None)
server_name = self.get_argument('server_name', None)
server_path = self.get_argument('server_path', None)
log_path = self.get_argument('log_path', None)
executable = self.get_argument('executable', None)
execution_command = self.get_argument('execution_command', None)
server_obj = self.controller.servers.get_server_obj(server_id)
if exec_user['superuser']:
server_path = self.get_argument('server_path', None)
log_path = self.get_argument('log_path', None)
executable = self.get_argument('executable', None)
execution_command = self.get_argument('execution_command', None)
server_ip = self.get_argument('server_ip', None)
server_port = self.get_argument('server_port', None)
executable_update_url = self.get_argument('executable_update_url', None)
else:
execution_command = server_obj.execution_command
executable = server_obj.executable
stop_command = self.get_argument('stop_command', None)
auto_start_delay = self.get_argument('auto_start_delay', '10')
server_ip = self.get_argument('server_ip', None)
server_port = self.get_argument('server_port', None)
executable_update_url = self.get_argument('executable_update_url', None)
auto_start = int(float(self.get_argument('auto_start', '0')))
crash_detection = int(float(self.get_argument('crash_detection', '0')))
logs_delete_after = int(float(self.get_argument('logs_delete_after', '0')))
@ -705,10 +732,19 @@ class PanelHandler(BaseHandler):
if helper.validate_traversal(helper.get_servers_root_dir(), executable):
server_obj.executable = executable
server_obj.execution_command = execution_command
server_obj.stop_command = stop_command
server_obj.server_ip = server_ip
server_obj.server_port = server_port
server_obj.executable_update_url = executable_update_url
else:
server_obj.path = server_obj.path
server_obj.log_path = server_obj.log_path
server_obj.executable = server_obj.executable
print(server_obj.execution_command)
server_obj.execution_command = server_obj.execution_command
server_obj.server_ip = server_obj.server_ip
server_obj.server_port = server_obj.server_port
server_obj.executable_update_url = server_obj.executable_update_url
server_obj.stop_command = stop_command
server_obj.auto_start_delay = auto_start_delay
server_obj.auto_start = auto_start
server_obj.crash_detection = crash_detection
@ -727,15 +763,20 @@ class PanelHandler(BaseHandler):
if page == "server_backup":
logger.debug(self.request.arguments)
server_id = self.get_argument('id', None)
backup_path = bleach.clean(self.get_argument('backup_path', None))
server_obj = self.controller.servers.get_server_obj(server_id)
if exec_user['superuser']:
backup_path = bleach.clean(self.get_argument('backup_path', None))
else:
backup_path = server_obj.backup_path
max_backups = bleach.clean(self.get_argument('max_backups', None))
try:
enabled = int(float(bleach.clean(self.get_argument('auto_enabled'), '0')))
except Exception as e:
enabled = '0'
if not exec_user['superuser']:
self.redirect("/panel/error?error=Unauthorized access: not superuser")
if not permissions['Backup'] in user_perms:
if not exec_user['superuser']:
self.redirect("/panel/error?error=Unauthorized access: User not authorized")
return
elif server_id is None:
self.redirect("/panel/error?error=Invalid Server ID")

View File

@ -157,7 +157,7 @@
$.ajax({
type: "DELETE",
headers: {'X-XSRFToken': token},
url: '/ajax/del_file?server_id='+id,
url: '/ajax/del_backup?server_id='+id,
data: {
file_path: filename,
id: id

View File

@ -4,7 +4,7 @@
<!-- <meta http-equiv="refresh" content="60">-->
{% end %}
{% block title %}Crafty Controller - Schedule{% end %}
{% block title %}Crafty Controller - {{ translate('serverDetails', 'serverDetails', data['lang']) }}{% end %}
{% block content %}
@ -14,221 +14,128 @@
<div class="row page-title-header">
<div class="col-12">
<div class="page-header">
{% if data['new_user'] %}
<h4 class="page-title">
New User
<br />
<small>UID: N/A</small>
</h4>
{% else %}
<h4 class="page-title">
Edit User - {{ data['user']['user_id'] }}
<br />
<small>UID: {{ data['user']['user_id'] }}</small>
</h4>
{% end %}
<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">
<ul class="nav nav-tabs col-md-12 tab-simple-styled " role="tablist">
<li class="nav-item">
<a class="nav-link active" href="/panel/{{ 'add_user' if data['new_user'] else 'edit_user' }}?id={{ data['user']['user_id'] }}&subpage=config" role="tab" aria-selected="true">
<i class="fas fa-cogs"></i>Config</a>
</li>
{% if not data['new_user'] %}
<li class="nav-item">
<a class="nav-link" href="/panel/add_user?id={{ data['user']['user_id'] }}&subpage=other" role="tab" aria-selected="false">
<i class="fas fa-folder-tree"></i>Other</a>
</li>
{% end %}
</ul>
{% include "parts/server_controls_list.html %}
<div class="row">
<div class="col-md-6 col-sm-12">
{% if data['new_user'] %}
<form id="user_form" class="forms-sample" method="post" action="/panel/add_user">
{% else %}
<form id="user_form" class="forms-sample" method="post" action="/panel/edit_user">
{% end %}
<div class="col-md-4 col-sm-12">
<form class="forms-sample" method="post" action="/panel/server_detail">
{% raw xsrf_form_html() %}
<input type="hidden" name="id" value="{{ data['user']['user_id'] }}">
<input type="hidden" name="id" value="{{ data['server_stats']['server_id']['server_id'] }}">
<input type="hidden" name="subpage" value="config">
<div class="card">
<div class="card-header header-sm d-flex justify-content-between align-items-center">
<h4 class="card-title"><i class="fas fa-user"></i> User Settings</h4>
</div>
<div class="card-body">
<div class="form-group">
<label class="form-label" for="username">User Name <small class="text-muted ml-1"> - What you wish to call this user</small> </label>
<input type="text" class="form-control" name="username" id="username" value="{{ data['user']['username'] }}" placeholder="User Name" >
</div>
<div class="form-group">
<label class="form-label" for="password0">Password <small class="text-muted ml-1"> - leave blank to don't change</small> </label>
<input type="password" class="form-control" name="password0" id="password0" value="" placeholder="Password" >
</div>
<div class="form-group">
<label class="form-label" for="password1">Repeat Password <small class="text-muted ml-1"> - leave blank to don't change</small> </label>
<input type="password" class="form-control" name="password1" id="password1" value="" placeholder="Repeat Password" >
</div>
<div class="form-group">
<label class="form-label" for="language">User Language:</label>
<select class="form-select" id="language" name="language" form="user_form">
{% for lang in data['languages'] %}
<option value="{{lang}}">{{lang}}</option>
{% end %}
</select>
</div>
</div>
<div class="form-group">
<label for="server_name">Action<small class="text-muted ml-1"></small> </label><br>
<select id="action" name="action" onchange="yesnoCheck(this);" class="form-control form-control-lg select-css">
<option value="start">Start Server</option>
<option value="restart">Restart Server</option>
<option value="shutdown">Shutdown Server</option>
<option value="command">Custon Command</option>
</select>
</div>
<div class="card">
<div class="card-header header-sm d-flex justify-content-between align-items-center">
<h4 class="card-title"><i class="fas fa-user-tag"></i> Roles <small class="text-muted ml-1"> - the roles this user is a member of</small></h4>
</div>
<div class="card-body">
<div class="form-group">
<div class="table-responsive">
<table class="table table-hover">
<thead>
<tr class="rounded">
<th>Role Name</th>
<th>Member?</th>
</tr>
</thead>
<tbody>
{% for role in data['roles_all'] %}
<tr>
<td>{{ role.role_name }}</td>
<td>
{% if role.role_id in data['user']['roles'] %}
<input type="checkbox" class="form-check-input" id="role_{{ role.role_id }}_membership" name="role_{{ role.role_id }}_membership" checked="" value="1">
{% else %}
<input type="checkbox" class="form-check-input" id="role_{{ role.role_id }}_membership" name="role_{{ role.role_id }}_membership" value="1">
{% end %}
</td>
</tr>
{% end %}
</tbody>
</table>
</div>
</div>
</div>
<div class="form-group">
<label for="server_path">Interval <small class="text-muted ml-1"> - How often you want this task to execute</small> </label>
<input type="number" class="form-control" name="server_path" id="server_path" value="{{ data['server_stats']['server_id']['path'] }}" placeholder="Interval" required>
<br>
<br>
<select id="interval_type" name="interval_type" class="form-control form-control-lg select-css">
<option value="days">Days</option>
<option value="hours">Hours</option>
<option value="minutes">Minutes</option>
<option value="weeks">Weeks</option>
</select>
</div>
<!-- Put Permissions Crafty part here -->
<div class="card">
<div class="card-header header-sm d-flex justify-content-between align-items-center">
<h4 class="card-title"><i class="fas fa-user-lock"></i> Crafty Permissions <small class="text-muted ml-1"> - permissions this user has on Crafty Controller </small></h4>
</div>
<div class="card-body">
<div class="form-group">
<div class="table-responsive">
<table class="table table-hover">
<thead>
<tr class="rounded">
<th>Permission Name</th>
<th>Authorized ?</th>
<th>Number of Uses Allowed (-1=No Limit)</th>
</tr>
</thead>
<tbody>
{% for permission in data['permissions_all'] %}
<tr>
<td>{{ permission.name }}</td>
<td>
{% if permission in data['permissions_list'] %}
<input type="checkbox" class="form-check-input" id="permission_{{ permission.name }}" name="permission_{{ permission.name }}" checked="" value="1">
{% else %}
<input type="checkbox" class="form-check-input" id="permission_{{ permission.name }}" name="permission_{{ permission.name }}" value="1">
{% end %}
</td>
<td><input type="text" class="form-control" name="quantity_{{ permission.name }}" id="quantity_{{ permission.name }}" value="{{ data['quantity_server'][permission.name] }}"></td>
</tr>
{% end %}
</tbody>
</table>
</div>
</div>
</div>
<div class="form-group">
<label for="time">Time <small class="text-muted ml-1"> - What time do you want your task to execute?</small> </label>
<input type="time" class="form-control" name="time" id="time" value="{{ data['server_stats']['server_id']['log_path'] }}" placeholder="Time" required>
</div>
<div id="ifYes" style="display: none;">
<div class="form-group">
<label for="command">Command <small class="text-muted ml-1"> - What command do you want us to execute? Do not include the '/'</small> </label>
<input type="input" class="form-control" name="command" id="command" value="" placeholder="Command" required>
</div>
</div>
<div class="form-check-flat">
<label for="enabled" class="form-check-label ml-4 mb-4">
{% if data['user']['enabled'] %}
<input type="checkbox" class="form-check-input" id="enabled" name="enabled" checked="" value="1">Enabled
{% else %}
<input type="checkbox" class="form-check-input" id="enabled" name="enabled" value="1">Enabled
{% end %}
<input type="checkbox" class="form-check-input" id="enabled" name="enabled" checked="" value="1">Enabled
</label>
<label for="regen_api" class="form-check-label ml-4 mb-4">
{% if data['new_user'] %}
<input type="checkbox" class="form-check-input" id="regen_api" name="regen_api" checked="" value="1" disabled >Regenerate API Key
{% else %}
<input type="checkbox" class="form-check-input" id="regen_api" name="regen_api" value="1">Regenerate API Key
{% end %}
</label>
<label for="superuser" class="form-check-label ml-4 mb-4">
{% if data['user']['superuser'] %}
<input type="checkbox" class="form-check-input" id="superuser" name="superuser" checked="" value="1" disabled >Super User
{% else %}
<input type="checkbox" class="form-check-input" id="superuser" name="superuser" value="1" disabled >Super User
{% end %}
</div>
<div class="form-check-flat">
<label for="one_time" class="form-check-label ml-4 mb-4">
<input type="checkbox" class="form-check-input" id="one_time" name="one_time" value="1">Delete After Execution
</label>
</div>
<button type="submit" class="btn btn-success mr-2"><i class="fas fa-save"></i> {{ translate('panelConfig', 'save', data['lang']) }}</button>
<button type="reset" onclick="location.href='/panel/panel_config'" class="btn btn-light"><i class="fas fa-undo-alt"></i> {{ translate('panelConfig', 'cancel', data['lang']) }}</button>
<button type="submit" class="btn btn-success mr-2"><i class="fas fa-save"></i> {{ translate('serverConfig', 'save', data['lang']) }}</button>
<button type="reset" class="btn btn-light"><i class="fas fa-times"></i> {{ translate('serverConfig', 'cancel', data['lang']) }}</button>
</form>
</div>
<div class="col-md-6 col-sm-12">
<div class="col-md-8 col-sm-12">
<div class="card">
<div class="card-body">
<h4 class="card-title"><i class="fas fa-user-cog"></i> User Config Area</h4>
<p class="card-description"> Here is where you can change the configuration of your user</p>
<blockquote class="blockquote">
<p class="mb-0">
Created: {{ str(data['user']['created']) }}
<br />
Last login: {{ str(data['user']['last_login']) }}
<br />
Last update: {{ str(data['user']['last_update']) }}
<br />
Last IP: {{ data['user']['last_ip'] }}
<br />
API Key: {{ data['user']['api_token'] }}
<br />
</p>
</blockquote>
<h4 class="card-title">Scheduled Tasks</h4>
<table class="table table-hover" width="100%">
<tr class="rounded">
<th>Action</th>
<th>Interval</th>
<th>Start Time</th>
<th>Enabled</th>
<th>Edit</th>
</tr>
{% for schedule in data['schedules'] %}
<td id="{{schedule.action}}" class="action">
<p>{{schedule.action}}</p>
</td>
<td id="{{schedule.interval}}" class="action">
<p>Every</p>
<p>{{schedule.interval}} {{schedule.interval_type}}</p>
</td>
<td id="{{schedule.start_time}}" class="action">
<p>{{schedule.start_time}}</p>
</td>
<td id="{{schedule.enabled}}" class="action">
{% if schedule.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>
</td>
<td id="{{schedule.action}}" class="action">
<a href="/panel/edit_schedule?id={{schedule.schedule_id}}"><i class="fas fa-pencil-alt"></i></a>
</td>
{% end %}
{% end %}
</table>
</div>
</div>
<div class="text-center">
{% if data['new_user'] %}
<a class="btn btn-sm btn-danger disabled"><i class="fas fa-trash"></i> Delete User</a><br />
<small>You cannot delete something that does not yet exist</small>
{% elif data['user']['superuser'] %}
<a class="btn btn-sm btn-danger disabled"><i class="fas fa-trash"></i> Delete User</a><br />
<small>You cannot delete a superuser</small>
{% else %}
<a href="/panel/remove_user?id={{ data['user']['user_id'] }}" class="btn btn-sm btn-danger"><i class="fas fa-trash"></i> Delete User</a>
{% end %}
</div>
</div>
</div>
@ -259,6 +166,13 @@
});
function yesnoCheck(that) {
if (that.value == "command") {
document.getElementById("ifYes").style.display = "block";
} else {
document.getElementById("ifYes").style.display = "none";
}
}
</script>

View File

@ -141,9 +141,10 @@ if __name__ == '__main__':
console.info("Checking Internet/Port Service. This may take a minute.")
if not helper.check_internet():
console.error("We have detected the machine running Crafty has no connection to the internet. Client connections to the server may be limited.")
console.warning("We have detected the machine running Crafty has no connection to the internet. Client connections to the server may be limited.")
elif not helper.check_port(helper.get_setting('https_port')):
console.error("We have detected Crafty's port, {} may not be open on the host network or a firewall is blocking it. Remote client connections to Crafty may be limited.".format(helper.get_setting('https_port')))
console.warning("We have detected Crafty's port, {} may not be open on the host network or a firewall is blocking it. Remote client connections to Crafty may be limited.".format(helper.get_setting('https_port')))
console.help("If you are not forwarding ports from your public IP or your router does not support hairpin NAT you can safely disregard the previous message.")
Crafty = MainPrompt(tasks_manager, migration_manager)