From 6ae75e9b84df9fec55ae2f10dd281b6041697713 Mon Sep 17 00:00:00 2001 From: AIIrondev Date: Mon, 7 Sep 2026 22:27:29 +0200 Subject: [PATCH] changes to the Trialver5sion processing to just use the functioning add and modul configuration --- Website/launch.sh | 65 ++++++++++++++++++++++++++++++++++++++++------- Website/main.py | 50 +++++++++++++----------------------- 2 files changed, 73 insertions(+), 42 deletions(-) diff --git a/Website/launch.sh b/Website/launch.sh index 65f937d..936f8fb 100755 --- a/Website/launch.sh +++ b/Website/launch.sh @@ -179,6 +179,8 @@ build_website_image() { # ============================================================================ TARGET_SYSTEM_DIR="/opt/Inventarsystem" TARGET_SCRIPT="$TARGET_SYSTEM_DIR/manage-tenant.sh" +TRIAL_EXPIRATION_DIR="$TARGET_SYSTEM_DIR/trial-expirations" +TRIAL_MODULES_OFF="library=off inventory=off student_cards=off terminplan=off" get_free_port() { local requested_port="${1:-10002}" @@ -201,15 +203,62 @@ get_free_port() { echo "$check_port" } +register_trial_expiration() { + local slug="$1" + local expires_at="$2" + local expires_epoch + + expires_epoch=$(date -d "$expires_at" +%s 2>/dev/null || true) + if [ -z "$expires_epoch" ]; then + echo "[ERROR] Ungültiges Trial-Ablaufdatum für $slug: $expires_at" >&2 + return 1 + fi + + mkdir -p "$TRIAL_EXPIRATION_DIR" + printf '%s\n' "$expires_epoch" > "$TRIAL_EXPIRATION_DIR/$slug.expiry" +} + +deactivate_expired_trials() { + local now_epoch + now_epoch=$(date +%s) + + for expiry_file in "$TRIAL_EXPIRATION_DIR"/*.expiry; do + [ -f "$expiry_file" ] || continue + + local slug expires_epoch + slug="${expiry_file##*/}" + slug="${slug%.expiry}" + expires_epoch=$(cat "$expiry_file" 2>/dev/null || true) + if ! [[ "$expires_epoch" =~ ^[0-9]+$ ]]; then + echo "[ERROR] Ungültige Ablaufdatei: $expiry_file" >&2 + continue + fi + if [ "$expires_epoch" -gt "$now_epoch" ]; then + continue + fi + + echo "[INFO] Deaktiviere abgelaufene Testversion: $slug" + if (cd "$TARGET_SYSTEM_DIR" && "$TARGET_SCRIPT" module "$slug" $TRIAL_MODULES_OFF); then + rm -f "$expiry_file" + echo "[SUCCESS] Testversion deaktiviert: $slug" + else + echo "[ERROR] Testversion konnte nicht deaktiviert werden: $slug" >&2 + fi + done +} + watcher_loop() { local trigger_dir="$1" echo "[INFO] Tenant Watcher gestartet. Lausche in $trigger_dir..." + mkdir -p "$TRIAL_EXPIRATION_DIR" while true; do + deactivate_expired_trials for file in "$trigger_dir"/*.json; do [ -f "$file" ] || continue echo "[INFO] Verarbeite Trigger: $file" + EXPIRES_AT="" if command -v jq >/dev/null 2>&1; then ACTION=$(jq -r '.action // "add"' "$file" 2>/dev/null || echo "add") @@ -217,6 +266,7 @@ watcher_loop() { PORT=$(jq -r '.port // empty' "$file" 2>/dev/null || true) PASS=$(jq -r '.password // empty' "$file" 2>/dev/null || true) MODULES=$(jq -r '.module_config // empty' "$file" 2>/dev/null || true) + EXPIRES_AT=$(jq -r '.expires_at // empty' "$file" 2>/dev/null || true) else ACTION=$(grep -o '"action": *"[^"]*"' "$file" | cut -d'"' -f4 || echo "add") [ -z "$ACTION" ] && ACTION="add" @@ -224,6 +274,7 @@ watcher_loop() { PORT=$(grep -o '"port": *[0-9]*' "$file" | cut -d':' -f2 | tr -d ' ' || true) PASS=$(grep -o '"password": *"[^"]*"' "$file" | cut -d'"' -f4 || true) MODULES=$(grep -o '"module_config": *"[^"]*"' "$file" | cut -d'"' -f4 || true) + EXPIRES_AT=$(grep -o '"expires_at": *"[^"]*"' "$file" | cut -d'"' -f4 || true) fi if [ -z "$SLUG" ]; then @@ -262,6 +313,10 @@ watcher_loop() { sleep 8 fi + if [ -n "${EXPIRES_AT:-}" ]; then + register_trial_expiration "$SLUG" "$EXPIRES_AT" || true + fi + # Um sicherzugehen, löschen wir verwaiste Container, bevor das Skript greift echo "[INFO] Bereinige verwaiste App-Container..." sudo docker rm -f inventarsystem-app-1 2>/dev/null || true @@ -295,15 +350,7 @@ watcher_loop() { fi ;; "trial") - DAYS=$(jq -r '.days // 14' "$file" 2>/dev/null || echo "14") - ACTUAL_PORT=$(get_free_port "$PORT") - - echo "[INFO] Erstelle Testversion für $SLUG (Port: $ACTUAL_PORT, Laufzeit: $DAYS Tage)..." - if (cd "$TARGET_SYSTEM_DIR" && "$TARGET_SCRIPT" trial "$SLUG" "$ACTUAL_PORT" "$DAYS"); then - echo "[SUCCESS] Testversion erfolgreich eingerichtet: $SLUG" - else - echo "[ERROR] Fehler beim Erstellen der Testversion für $SLUG" >&2 - fi + echo "[ERROR] Veralteter trial-Trigger für $SLUG: Testversionen müssen über add erstellt werden." >&2 ;; *) echo "[ERROR] Unbekannte Aktion ($ACTION) in $file" >&2 diff --git a/Website/main.py b/Website/main.py index 3cefeec..fbcf118 100644 --- a/Website/main.py +++ b/Website/main.py @@ -2180,7 +2180,7 @@ def book_option_package(): return redirect(url_for("booking_payment", packages=packages_raw, flow=booking_flow)) -ALL_MODULE_KEYS = ["library", "inventory", "student_cards", "terminplan", "testversion"] +ALL_MODULE_KEYS = ["library", "inventory", "student_cards", "terminplan"] PACKAGE_MODULE_MAP = { "buecherei": ["library"], "inventarsystem": ["inventory"], @@ -2189,7 +2189,6 @@ PACKAGE_MODULE_MAP = { "startpaket": ["library", "inventory", "student_cards"], "advanced": ["library", "inventory", "student_cards", "terminplan"], "komplettpaket": ["library", "inventory", "student_cards", "terminplan"], - "testversion": ["testversion", "Testversion", "trial", "Testversionen", "Testversionen"], } @@ -2229,22 +2228,18 @@ def background_booking_provisioning( address, price, software_name="Invario Inventarsystem", - is_trial=False, # Neu: Flag für Testversion - trial_days=14, # Neu: Laufzeit der Testversion in Tagen - trial_prefix="testversion-" # Neu: Präfix für Testversionen + is_trial=False, + trial_days=14, ): """ Hintergrund-Worker, der die Tenant-Bereitstellung über das Host-Watcher-Triggersystem auslöst. - Unterstützt reguläre Buchungen sowie Testversionen (mit 'testversion-' Präfix & Trial-Laufzeit). + Unterstützt reguläre Buchungen sowie Testversionen mit zeitlich begrenzter Modulfreischaltung. """ with app_instance.app_context(): req_client, req_col = _get_collection("instance_requests") try: # 1. Präfix für Testversionen verarbeiten effective_subdomain = subdomain - if is_trial: - if not effective_subdomain.startswith(trial_prefix): - effective_subdomain = f"{trial_prefix}{effective_subdomain}" # 2. Status auf "in_progress" setzen req_col.update_one( @@ -2272,7 +2267,8 @@ def background_booking_provisioning( admin_password = generate_secure_password() # Generiere den korrekten Modul-String - module_config_str = build_module_config_string(package_list) + # Trial tenants use the regular instance path, with every module enabled. + module_config_str = " ".join(f"{module}=on" for module in ALL_MODULE_KEYS) if is_trial else build_module_config_string(package_list) # 4. Ablaufdatum berechnen (bei Testversion) now = datetime.now(timezone.utc) @@ -2282,25 +2278,16 @@ def background_booking_provisioning( os.makedirs(TRIGGER_DIR, exist_ok=True) trigger_file = os.path.join(TRIGGER_DIR, f"{effective_subdomain}.json") + trigger_payload = { + "action": "add", + "request_id": str(prov_id), + "slug": effective_subdomain, + "port": next_port, + "password": admin_password, + "module_config": module_config_str, + } if is_trial: - trigger_payload = { - "action": "trial", - "request_id": str(prov_id), - "slug": effective_subdomain, - "port": next_port, - "days": trial_days, - "password": admin_password, - "module_config": module_config_str - } - else: - trigger_payload = { - "action": "add", - "request_id": str(prov_id), - "slug": effective_subdomain, - "port": next_port, - "password": admin_password, - "module_config": module_config_str - } + trigger_payload["expires_at"] = expires_at with open(trigger_file, "w") as f: json.dump(trigger_payload, f) @@ -2328,9 +2315,6 @@ def background_booking_provisioning( instance_doc["trial_days"] = trial_days instance_doc["expires_at"] = expires_at - if is_trial: - instance_doc["admin_password"] = "admin123" - inst_client, inst_col = _get_collection("instances") try: created_inst_id = str(inst_col.insert_one(instance_doc).inserted_id) @@ -2458,7 +2442,7 @@ def booking_payment(): packages_str = _sanitize_text(request.values.get("packages") or request.values.get("package") or "", 200).lower() booking_flow = _sanitize_text(request.values.get("flow") or "payment", 24).lower() - is_trial = (booking_flow == "testversion") or request.values.get("testversion", "").strip().lower() in {"1", "on", "true", "yes"} + is_trial = booking_flow in {"trial", "testversion"} or request.values.get("testversion", "").strip().lower() in {"1", "on", "true", "yes"} trial_days = int(request.values.get("trial_days") or 14) if booking_flow not in BOOKING_FLOW_MAP and booking_flow != "trial": @@ -2594,7 +2578,7 @@ def booking_payment(): flash(f"Gesprächstermin für {selected_package} wurde an das Team gesendet.", "success") return redirect(url_for("user_chat")) - if booking_flow in ["payment", "testversion"]: + if booking_flow in ["payment", "testversion", "trial"]: # CORRECTED: Syntax error in the f-string is fixed below (uses single quotes inside double quotes) booking_number = f"{'TRIAL' if is_trial else 'BOOK'}-{datetime.utcnow().strftime('%Y%m%d%H%M%S')}"