central config

This commit is contained in:
lelo 2025-05-04 17:24:04 +00:00
parent 80e3b1abb5
commit fceeabe652
8 changed files with 67 additions and 55 deletions

12
app.py
View File

@ -9,7 +9,6 @@ import mimetypes
from datetime import datetime, date, timedelta from datetime import datetime, date, timedelta
import diskcache import diskcache
import threading import threading
import json
import time import time
from flask_socketio import SocketIO, emit from flask_socketio import SocketIO, emit
import geoip2.database import geoip2.database
@ -24,11 +23,7 @@ import auth
import analytics as a import analytics as a
import folder_secret_config_editor as fsce import folder_secret_config_editor as fsce
with open("app_config.json", 'r') as file: app_config = auth.return_app_config()
app_config = json.load(file)
with open('folder_secret_config.json') as file:
folder_config = json.load(file)
cache_audio = diskcache.Cache('./filecache_audio', size_limit= app_config['filecache_size_limit_audio'] * 1024**3) cache_audio = diskcache.Cache('./filecache_audio', size_limit= app_config['filecache_size_limit_audio'] * 1024**3)
cache_image = diskcache.Cache('./filecache_image', size_limit= app_config['filecache_size_limit_image'] * 1024**3) cache_image = diskcache.Cache('./filecache_image', size_limit= app_config['filecache_size_limit_image'] * 1024**3)
@ -55,7 +50,7 @@ app.add_url_rule('/searchcommand', view_func=search.searchcommand, methods=['POS
app.add_url_rule('/songs_dashboard', view_func=a.songs_dashboard) app.add_url_rule('/songs_dashboard', view_func=a.songs_dashboard)
app.add_url_rule('/admin/folder_secret_config_editor', view_func=auth.require_admin(fsce.folder_secret_config_editor), methods=['GET', 'POST']) app.add_url_rule('/admin/folder_secret_config_editor', view_func=auth.require_admin(fsce.folder_secret_config_editor), methods=['GET', 'POST'])
app.add_url_rule('/admin/folder_secret_config_editor/data', view_func=auth.require_admin(fsce.folder_secret_config_data)) app.add_url_rule('/admin/folder_secret_config_editor/data', view_func=auth.require_admin(auth.load_folder_config))
app.add_url_rule('/admin/folder_secret_config_editor/action', view_func=auth.require_admin(fsce.folder_secret_config_action), methods=['POST']) app.add_url_rule('/admin/folder_secret_config_editor/action', view_func=auth.require_admin(fsce.folder_secret_config_action), methods=['POST'])
# Grab the HOST_RULE environment variable # Grab the HOST_RULE environment variable
@ -104,6 +99,7 @@ def list_directory_contents(directory, subpath):
""" """
directories = [] directories = []
files = [] files = []
folder_config = auth.return_folder_config()
transcription_dir = os.path.join(directory, "Transkription") transcription_dir = os.path.join(directory, "Transkription")
transcription_exists = os.path.isdir(transcription_dir) transcription_exists = os.path.isdir(transcription_dir)
@ -441,6 +437,7 @@ def create_share(subpath):
if 'admin' not in session and not session.get('admin'): if 'admin' not in session and not session.get('admin'):
return "Unauthorized", 403 return "Unauthorized", 403
folder_config = auth.return_folder_config()
paths = {} paths = {}
for item in folder_config: for item in folder_config:
for folder in item['folders']: for folder in item['folders']:
@ -550,6 +547,7 @@ def handle_request_initial_data():
@app.route('/<path:path>') @app.route('/<path:path>')
@auth.require_secret @auth.require_secret
def index(path): def index(path):
app_config = auth.return_app_config()
title_short = app_config.get('TITLE_SHORT', 'Default Title') title_short = app_config.get('TITLE_SHORT', 'Default Title')
title_long = app_config.get('TITLE_LONG' , 'Default Title') title_long = app_config.get('TITLE_LONG' , 'Default Title')

55
auth.py
View File

@ -12,29 +12,42 @@ import zlib
import hmac import hmac
import hashlib import hashlib
FOLDER_CONFIG_FILENAME = 'folder_secret_config.json'
APP_CONFIG_FILENAME = 'app_config.json'
# initial read of the config files
with open("app_config.json", 'r') as file: with open(APP_CONFIG_FILENAME, 'r') as file:
app_config = json.load(file) app_config = json.load(file)
with open('folder_secret_config.json') as file: with open(FOLDER_CONFIG_FILENAME) as file:
folder_config = json.load(file) folder_config = json.load(file)
# functions to be used by other modules
def load_folder_config():
global folder_config
with open(FOLDER_CONFIG_FILENAME) as file:
folder_config = json.load(file)
return folder_config
def load_app_config():
global app_config
with open(APP_CONFIG_FILENAME, 'r') as file:
app_config = json.load(file)
return app_config
def return_folder_config():
return folder_config
def return_app_config():
return app_config
def is_admin(): def is_admin():
""" """
Check if the user is an admin based on the session. Check if the user is an admin based on the session.
""" """
return session.get('admin', False) return session.get('admin', False)
def require_admin(f):
@wraps(f)
@require_secret
def decorated_function(*args, **kwargs):
if is_admin():
return f(*args, **kwargs)
else:
return "You don't have admin permission", 403
return decorated_function
def require_secret(f): def require_secret(f):
@wraps(f) @wraps(f)
@ -150,6 +163,24 @@ def require_secret(f):
) )
return decorated_function return decorated_function
def require_admin(f):
@wraps(f)
@require_secret
def decorated_function(*args, **kwargs):
if is_admin():
return f(*args, **kwargs)
else:
return "You don't have admin permission", 403
return decorated_function
@require_admin
def save_folder_config(data):
global folder_config
folder_config = data
with open(FOLDER_CONFIG_FILENAME, 'w') as file:
json.dump(folder_config, file, indent=4)
return folder_config
@require_secret @require_secret
def mylinks(): def mylinks():
scheme = request.scheme # current scheme (http or https) scheme = request.scheme # current scheme (http or https)

View File

@ -7,39 +7,18 @@ import string
import auth import auth
DATA_FILE = 'folder_secret_config.json'
# Secret alphabet # Secret alphabet
ALPHABET = string.ascii_letters + string.digits ALPHABET = string.ascii_letters + string.digits
@auth.require_admin
def load_data():
with open(DATA_FILE) as f:
try:
data = json.load(f)
print(f"Loaded {len(data)} records from {DATA_FILE}.")
return data
except:
print(f"Error loading {DATA_FILE}. File may be empty or corrupted.")
return []
@auth.require_admin
def save_data(data):
with open(DATA_FILE, 'w') as f:
json.dump(data, f, indent=4)
@auth.require_admin @auth.require_admin
def folder_secret_config_editor(): def folder_secret_config_editor():
return render_template('folder_secret_config_editor.html', alphabet=ALPHABET, admin_enabled=auth.is_admin()) return render_template('folder_secret_config_editor.html', alphabet=ALPHABET, admin_enabled=auth.is_admin())
@auth.require_admin
def folder_secret_config_data():
return jsonify(load_data())
@auth.require_admin @auth.require_admin
def folder_secret_config_action(): def folder_secret_config_action():
p = request.get_json() p = request.get_json()
data = load_data() data = auth.return_folder_config()
action = p.get('action') action = p.get('action')
if action == 'delete': if action == 'delete':
data = [r for r in data if r['secret'] != p['secret']] data = [r for r in data if r['secret'] != p['secret']]
@ -58,6 +37,6 @@ def folder_secret_config_action():
'validity': datetime.strptime(p['validity'], '%Y-%m-%d').strftime('%d.%m.%Y'), 'validity': datetime.strptime(p['validity'], '%Y-%m-%d').strftime('%d.%m.%Y'),
'folders': p['folders'] 'folders': p['folders']
}) })
save_data(data) auth.save_folder_config(data)
return jsonify(success=True) return jsonify(success=True)

View File

@ -45,12 +45,16 @@
<div class="wrapper"> <div class="wrapper">
<div class="container"> <div class="container">
{% if admin_enabled %} {% if admin_enabled %}
<div style="margin: 20px;"> <div style="color: #ccc; margin: 20px; border: 1px solid #ccc; padding: 10px; background-color: #979797;">
<a href="{{ url_for('index') }}" style="color: #ccc; text-decoration: none;">App</a><span style="color: #ccc;"> · </span> <a href="{{ url_for('index') }}" style="color: #ccc; text-decoration: none;">App</a>
<a href="{{ url_for('mylinks') }}" style="color: #ccc; text-decoration: none;">Meine Links</a><span style="color: #ccc;"> · </span> <span> | </span>
<a href="{{ url_for('connections') }}" style="color: #ccc; text-decoration: none;">Verbindungen</a><span style="color: #ccc;"> · </span> <a href="{{ url_for('mylinks') }}" style="color: #ccc; text-decoration: none;">Meine Links</a>
<a href="{{ url_for('dashboard') }}" style="color: #ccc; text-decoration: none;">Auswertung</a><span style="color: #ccc;"> · </span> <span> | </span>
<a href="{{ url_for('folder_secret_config_editor') }}" id="edit-folder-config" style="color: #ccc; text-decoration: none;">Folder Config Editor</a> <a href="{{ url_for('connections') }}" style="color: #ccc; text-decoration: none;">Verbindungen</a>
<span> | </span>
<a href="{{ url_for('dashboard') }}" style="color: #ccc; text-decoration: none;">Auswertung</a>
<span> | </span>
<a href="{{ url_for('folder_secret_config_editor') }}" style="color: #ccc; text-decoration: none;" id="edit-folder-config" >Ordnerkonfiguration</a>
</div> </div>
{% endif %} {% endif %}
<div id="breadcrumbs" class="breadcrumb"></div> <div id="breadcrumbs" class="breadcrumb"></div>

View File

@ -51,7 +51,7 @@
<li class="nav-item"><a href="{{ url_for('dashboard') }}" class="nav-link">Auswertung-Downloads</a></li> <li class="nav-item"><a href="{{ url_for('dashboard') }}" class="nav-link">Auswertung-Downloads</a></li>
<li class="nav-item"><a href="{{ url_for('songs_dashboard') }}" class="nav-link">Auswertung-Wiederholungen</a></li> <li class="nav-item"><a href="{{ url_for('songs_dashboard') }}" class="nav-link">Auswertung-Wiederholungen</a></li>
{% if admin_enabled %} {% if admin_enabled %}
<li class="nav-item"><a href="{{ url_for('folder_secret_config_editor') }}" class="nav-link">Edit Folder Config</a></li> <li class="nav-item"><a href="{{ url_for('folder_secret_config_editor') }}" class="nav-link">Ordnerkonfiguration</a></li>
{% endif %} {% endif %}
</ul> </ul>
</div> </div>

View File

@ -2,10 +2,10 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{# page title #} {# page title #}
{% block title %}Edit Folder Config{% endblock %} {% block title %}Ordnerkonfiguration{% endblock %}
{# override navbar text: #} {# override navbar text: #}
{% block nav_brand %}Folder Config Editor{% endblock %} {% block nav_brand %}Ordnerkonfiguration{% endblock %}
{# page content #} {# page content #}
{% block content %} {% block content %}

View File

@ -27,7 +27,7 @@
<p class="card-text"> <p class="card-text">
<small class="text-muted">Gültig bis: {{ secret_valid_to[secret] }}</small> <small class="text-muted">Gültig bis: {{ secret_valid_to[secret] }}</small>
</p> </p>
<a href="{{ secret_url[secret] }}" class="btn btn-secondary btn-sm">Link öffnen</a> <a href="{{ secret_url[secret] }}" class="btn btn-secondary btn-sm" style="text-decoration: none;">Link öffnen</a>
<button class="btn btn-secondary btn-sm" <button class="btn btn-secondary btn-sm"
onclick="toClipboard('{{ secret_url[secret] }}')"> onclick="toClipboard('{{ secret_url[secret] }}')">
Link kopieren Link kopieren

View File

@ -33,8 +33,8 @@
<div class="card-body"> <div class="card-body">
<div class="card-text mt-2"> <div class="card-text mt-2">
<h2 class="card-title">Token-Link:</h2> <h2 class="card-title">Token-Link:</h2>
<a href="{{ token_url }}" class="copy-btn" id="tokenLink">Direct Link</a> <a href="{{ token_url }}" class="copy-btn" style="text-decoration: none;" id="tokenLink">Link öffnen</a>
<button class="copy-btn" onclick="toClipboard('{{ token_url }}')">Copy Link</button> <button class="copy-btn" onclick="toClipboard('{{ token_url }}')">Link kopieren</button>
</div> </div>
<div class="card-text mt-2"> <div class="card-text mt-2">
<h2 class="mt-3">Gültig bis:</h2> <h2 class="mt-3">Gültig bis:</h2>