Zabezpieczenie API
This commit is contained in:
parent
dfb6f5f370
commit
3b689196a0
4 changed files with 155 additions and 51 deletions
46
app/api.py
46
app/api.py
|
@ -17,6 +17,7 @@ client = docker.from_env()
|
|||
|
||||
# Server Deployment
|
||||
@api.route('/setup', methods=['POST'])
|
||||
@oidc.require_login
|
||||
def setup_server():
|
||||
data = request.get_json()
|
||||
username = oidc.user_getfield('preferred_username')
|
||||
|
@ -31,9 +32,9 @@ def setup_server():
|
|||
|
||||
|
||||
@api.route('/delete', methods=['POST'])
|
||||
@oidc.require_login
|
||||
def delete():
|
||||
data = request.get_json()
|
||||
username = data.get("username")
|
||||
username = oidc.user_getfield('preferred_username')
|
||||
|
||||
if not username:
|
||||
return jsonify({"error": "Brak nazwy użytkownika"}), 400
|
||||
|
@ -44,8 +45,9 @@ def delete():
|
|||
|
||||
# Server Controls
|
||||
@api.route('/start', methods=['POST'])
|
||||
@oidc.require_login
|
||||
def start():
|
||||
username = request.json['username']
|
||||
username = oidc.user_getfield('preferred_username')
|
||||
setup_file_path = f"./servers/mc-{username}/server_info.json"
|
||||
|
||||
if not os.path.exists(setup_file_path):
|
||||
|
@ -66,22 +68,25 @@ def start():
|
|||
|
||||
|
||||
@api.route('/stop', methods=['POST'])
|
||||
@oidc.require_login
|
||||
def stop():
|
||||
username = request.json['username']
|
||||
username = oidc.user_getfield('preferred_username')
|
||||
stop_server(username)
|
||||
return jsonify({"status": "stopped"})
|
||||
|
||||
|
||||
@api.route('/restart', methods=['POST'])
|
||||
@oidc.require_login
|
||||
def restart():
|
||||
username = request.json['username']
|
||||
username = oidc.user_getfield('preferred_username')
|
||||
restart_server(username)
|
||||
return jsonify({"status": "restarted"})
|
||||
|
||||
|
||||
@api.route('/logs', methods=['GET'])
|
||||
@oidc.require_login
|
||||
def logs():
|
||||
username = request.args.get('username')
|
||||
username = oidc.user_getfield('preferred_username')
|
||||
return jsonify({"logs": get_logs(username)})
|
||||
|
||||
|
||||
|
@ -92,6 +97,9 @@ def send_command():
|
|||
username = data['username']
|
||||
command = data['command']
|
||||
|
||||
if username != oidc.user_getfield('preferred_username'):
|
||||
return jsonify({"error": "Unauthorized request."}), 403
|
||||
|
||||
container_name = f"mc-{username}"
|
||||
|
||||
try:
|
||||
|
@ -107,8 +115,9 @@ def send_command():
|
|||
|
||||
# Files APIs (Upload, download, delete)
|
||||
@api.route('/files', methods=['GET'])
|
||||
@oidc.require_login
|
||||
def list_files():
|
||||
username = request.args.get('username')
|
||||
username = oidc.user_getfield('preferred_username')
|
||||
path = request.args.get('path', '')
|
||||
|
||||
base_path = os.path.abspath(f'./servers/mc-{username}')
|
||||
|
@ -134,8 +143,9 @@ def list_files():
|
|||
|
||||
|
||||
@api.route('/files/download', methods=['GET'])
|
||||
@oidc.require_login
|
||||
def download_file():
|
||||
username = request.args.get('username')
|
||||
username = oidc.user_getfield('preferred_username')
|
||||
path = request.args.get('path')
|
||||
|
||||
base_path = os.path.abspath(f'./servers/mc-{username}')
|
||||
|
@ -150,8 +160,9 @@ def download_file():
|
|||
|
||||
|
||||
@api.route('/files/upload', methods=['POST'])
|
||||
@oidc.require_login
|
||||
def upload_file():
|
||||
username = request.form.get('username')
|
||||
username = oidc.user_getfield('preferred_username')
|
||||
path = request.form.get('path', '')
|
||||
file = request.files['files']
|
||||
base_path = os.path.abspath(f'./servers/mc-{username}')
|
||||
|
@ -167,12 +178,17 @@ def upload_file():
|
|||
|
||||
|
||||
@api.route('/files/delete', methods=['POST'])
|
||||
@oidc.require_login
|
||||
def delete_file_or_folder():
|
||||
data = request.get_json()
|
||||
username = data.get('username')
|
||||
if username != oidc.user_getfield('preferred_username'):
|
||||
return jsonify({"error": "Unauthorized request."}), 403
|
||||
|
||||
path = data.get('path')
|
||||
base_path = os.path.abspath(f'./servers/mc-{username}')
|
||||
target_path = os.path.abspath(os.path.join(base_path, path))
|
||||
|
||||
if not target_path.startswith(base_path):
|
||||
return abort(403)
|
||||
if not os.path.exists(target_path):
|
||||
|
@ -189,8 +205,9 @@ def delete_file_or_folder():
|
|||
|
||||
# Server config
|
||||
@api.route('/config')
|
||||
@oidc.require_login
|
||||
def get_config():
|
||||
username = request.args.get('username')
|
||||
username = oidc.user_getfield('preferred_username')
|
||||
server_info_path = f'./servers/mc-{username}/server_info.json'
|
||||
if not os.path.exists(server_info_path):
|
||||
return jsonify({"success": False, "message": "Server config not found"})
|
||||
|
@ -201,9 +218,13 @@ def get_config():
|
|||
|
||||
|
||||
@api.route('/config', methods=['POST'])
|
||||
@oidc.require_login
|
||||
def update_config():
|
||||
data = request.json
|
||||
username = data.get('username')
|
||||
if username != oidc.user_getfield('preferred_username'):
|
||||
return jsonify({"error": "Unauthorized request."}), 403
|
||||
|
||||
incoming_config = data.get('config', {})
|
||||
server_info_path = f'./servers/mc-{username}/server_info.json'
|
||||
if os.path.exists(server_info_path):
|
||||
|
@ -211,9 +232,11 @@ def update_config():
|
|||
server_info = json.load(f)
|
||||
else:
|
||||
server_info = DEFAULT_CONFIG.copy()
|
||||
|
||||
for key in ["type", "version"]:
|
||||
if key in incoming_config:
|
||||
server_info[key] = incoming_config.pop(key)
|
||||
|
||||
formatted_config = {key.replace('_', '-'): value for key, value in incoming_config.items()}
|
||||
server_info["config"] = formatted_config
|
||||
with open(server_info_path, 'w') as f:
|
||||
|
@ -235,8 +258,9 @@ def status():
|
|||
|
||||
|
||||
@api.route('/stats', methods=['GET'])
|
||||
@oidc.require_login
|
||||
def stats():
|
||||
username = request.args.get("username")
|
||||
username = oidc.user_getfield("preferred_username")
|
||||
container_name = f"mc-{username}"
|
||||
|
||||
try:
|
||||
|
|
|
@ -528,26 +528,6 @@ a.non-link:hover {
|
|||
justify-content: center;
|
||||
}
|
||||
|
||||
/* Mobile Tweaks */
|
||||
@media (max-width: 600px) {
|
||||
body {
|
||||
padding: 24px 12px;
|
||||
}
|
||||
|
||||
.dashboard-card {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
width: 100%;
|
||||
margin: 8px 0;
|
||||
}
|
||||
|
||||
.console-output {
|
||||
height: 180px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 404 Error */
|
||||
.error-container {
|
||||
max-width: 800px;
|
||||
|
@ -580,25 +560,6 @@ a.non-link:hover {
|
|||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.references-list {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0 auto 3rem;
|
||||
max-width: 600px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.references-list li {
|
||||
margin: 1rem 0;
|
||||
font-size: 1.1rem;
|
||||
line-height: 1.5;
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
|
||||
.references-list li:hover {
|
||||
transform: translateX(10px);
|
||||
}
|
||||
|
||||
.back-button {
|
||||
display: inline-block;
|
||||
padding: 0.75rem 1.5rem;
|
||||
|
@ -615,3 +576,118 @@ a.non-link:hover {
|
|||
background-color: #fff;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
/* Mobile Tweaks */
|
||||
@media (max-width: 480px) {
|
||||
html {
|
||||
font-size: clamp(14px, 2.5vw, 16px);
|
||||
}
|
||||
|
||||
/* Heading adjustment */
|
||||
h2 {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
/* Dashboard Card */
|
||||
.dashboard-card {
|
||||
padding: 16px;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
/* Tab buttons */
|
||||
.tab-button {
|
||||
padding: 10px;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
/* Square button adjustments */
|
||||
.square-button {
|
||||
width: 100%;
|
||||
aspect-ratio: unset;
|
||||
flex-direction: row;
|
||||
justify-content: flex-start;
|
||||
gap: 12px;
|
||||
padding: 10px;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.square-button img {
|
||||
width: 32px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* Navigation Bar */
|
||||
.top-nav {
|
||||
padding: 12px;
|
||||
font-size: 0.9rem;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.nav-links a {
|
||||
margin-left: 10px;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
/* Console Output */
|
||||
.console-output {
|
||||
font-size: 0.8rem;
|
||||
height: 160px;
|
||||
}
|
||||
|
||||
/* Chart container */
|
||||
.chart-container {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
/* Buttons */
|
||||
.btn {
|
||||
font-size: 0.9rem;
|
||||
padding: 12px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* Form layout */
|
||||
form {
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
/* Tab content spacing */
|
||||
.tab-content {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
/* Particle background on small screens */
|
||||
#particle-background {
|
||||
display: none; /* Improves performance */
|
||||
}
|
||||
|
||||
/* Charts Row - Allow horizontal scroll */
|
||||
.charts-row {
|
||||
overflow-x: auto;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
/* Input Fields */
|
||||
input[type="text"], input[type="number"], select {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* Adjust drop zone */
|
||||
#drop-zone {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
/* Adjust text area height */
|
||||
.console-output {
|
||||
height: 160px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Additional general fixes for small screens */
|
||||
* {
|
||||
max-width: 100%;
|
||||
word-wrap: break-word;
|
||||
}
|
|
@ -9,6 +9,10 @@
|
|||
<button class="tab-button" onclick="showTab('files')">Pliki 📁</button>
|
||||
<button class="tab-button" onclick="showTab('config')">Konfiguracja 🛠️</button>
|
||||
<button class="tab-button" onclick="showTab('statistics')">Statystyki 📈</button>
|
||||
|
||||
</div>
|
||||
<div class="tabs">
|
||||
<button class="tab-button" onclick="showTab('mods')">Mody/Pluginy 🧩</button>
|
||||
</div>
|
||||
|
||||
<div class="tab-content">
|
||||
|
|
|
@ -12,6 +12,6 @@
|
|||
<li><b>Motywacja</b> do dalszego rozwijania panelu</li>
|
||||
<li><b>Wsparcie</b> w opłacaniu serwera na backupy</li>
|
||||
</ul>
|
||||
Donate możesz wysłać <a href="https://ko-fi.com/andusdev">tutaj</a>
|
||||
<p>Donate możesz wysłać <a href="https://ko-fi.com/andusdev">tutaj</a></p>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
Loading…
Add table
Reference in a new issue