From 5b71a1d60dd9e20b0991c9f2b657d28bee13b41a Mon Sep 17 00:00:00 2001 From: UserIsMH Date: Sun, 22 Jun 2025 23:58:39 +0200 Subject: [PATCH] Namenskonsistenz + Ablauf der Lizenzen --- v2_adminpanel/app.py | 29 ++-------- v2_adminpanel/routes/admin_routes.py | 22 ++++++++ v2_adminpanel/scheduler.py | 73 +++++++++++++++++++++++++- v2_adminpanel/templates/resources.html | 2 +- 4 files changed, 100 insertions(+), 26 deletions(-) diff --git a/v2_adminpanel/app.py b/v2_adminpanel/app.py index 51772eb..e84b8d0 100644 --- a/v2_adminpanel/app.py +++ b/v2_adminpanel/app.py @@ -53,13 +53,13 @@ init_error_handlers(app) init_monitoring(app) ErrorHandlingMiddleware(app) -# Scheduler für automatische Backups -scheduler = BackgroundScheduler() -scheduler.start() - # Logging konfigurieren logging.basicConfig(level=logging.INFO) +# Initialize scheduler from scheduler module +from scheduler import init_scheduler +scheduler = init_scheduler() + # Import and register blueprints try: from routes.auth_routes import auth_bp @@ -119,26 +119,7 @@ def debug_routes(): routes.append(f"{rule.endpoint}: {rule.rule}") return "
".join(sorted(routes)) -# Scheduled Backup Job -def scheduled_backup(): - """Erstellt ein automatisches Backup""" - try: - backup_file = create_backup() - logging.info(f"Scheduled backup created: {backup_file}") - except Exception as e: - logging.error(f"Scheduled backup failed: {str(e)}") - - -# Schedule daily backup at 3 AM -scheduler.add_job( - func=scheduled_backup, - trigger="cron", - hour=3, - minute=0, - id='daily_backup', - name='Daily backup', - replace_existing=True -) +# Scheduled backup job is now handled by scheduler module # Error handlers are now managed by the error handling system in core/error_handlers.py diff --git a/v2_adminpanel/routes/admin_routes.py b/v2_adminpanel/routes/admin_routes.py index edfb682..067726d 100644 --- a/v2_adminpanel/routes/admin_routes.py +++ b/v2_adminpanel/routes/admin_routes.py @@ -1417,3 +1417,25 @@ def test_license_types(): cur.close() if 'conn' in locals(): conn.close() + + +@admin_bp.route("/admin/licenses/check-expiration", methods=["POST"]) +@login_required +def check_license_expiration(): + """Manually trigger license expiration check""" + if session.get('username') not in ['rac00n', 'w@rh@mm3r']: + return jsonify({'error': 'Zugriff verweigert'}), 403 + + try: + from scheduler import deactivate_expired_licenses + deactivate_expired_licenses() + + flash('License expiration check completed successfully', 'success') + log_audit('MANUAL_LICENSE_EXPIRATION_CHECK', 'system', + additional_info="Manual license expiration check triggered") + + return jsonify({'success': True, 'message': 'License expiration check completed'}) + + except Exception as e: + current_app.logger.error(f"Error in manual license expiration check: {str(e)}") + return jsonify({'error': str(e)}), 500 diff --git a/v2_adminpanel/scheduler.py b/v2_adminpanel/scheduler.py index 8ff046c..9626ed4 100644 --- a/v2_adminpanel/scheduler.py +++ b/v2_adminpanel/scheduler.py @@ -5,7 +5,7 @@ import logging from apscheduler.schedulers.background import BackgroundScheduler import config from utils.backup import create_backup -from utils.db_utils import get_connection +from db import get_connection def scheduled_backup(): @@ -64,6 +64,66 @@ def cleanup_expired_sessions(): conn.rollback() +def deactivate_expired_licenses(): + """Deactivate licenses that have expired""" + try: + conn = get_connection() + cur = conn.cursor() + + # Find active licenses that have expired + # Check valid_until < today (at midnight) + cur.execute(""" + SELECT id, license_key, customer_id, valid_until + FROM licenses + WHERE is_active = true + AND valid_until IS NOT NULL + AND valid_until < CURRENT_DATE + AND is_fake = false + """) + + expired_licenses = cur.fetchall() + + if expired_licenses: + logging.info(f"Found {len(expired_licenses)} expired licenses to deactivate") + + for license in expired_licenses: + license_id, license_key, customer_id, valid_until = license + + # Deactivate the license + cur.execute(""" + UPDATE licenses + SET is_active = false, + updated_at = CURRENT_TIMESTAMP + WHERE id = %s + """, (license_id,)) + + # Log to audit trail + cur.execute(""" + INSERT INTO audit_log + (timestamp, username, action, entity_type, entity_id, + old_values, new_values, additional_info) + VALUES (CURRENT_TIMESTAMP, 'system', 'DEACTIVATE', 'license', %s, + jsonb_build_object('is_active', true), + jsonb_build_object('is_active', false), + %s) + """, (license_id, f"License automatically deactivated due to expiration. Valid until: {valid_until}")) + + logging.info(f"Deactivated expired license: {license_key} (ID: {license_id})") + + conn.commit() + logging.info(f"Successfully deactivated {len(expired_licenses)} expired licenses") + else: + logging.debug("No expired licenses found to deactivate") + + cur.close() + conn.close() + + except Exception as e: + logging.error(f"Error deactivating expired licenses: {str(e)}") + if 'conn' in locals(): + conn.rollback() + + def init_scheduler(): """Initialize and configure the scheduler""" scheduler = BackgroundScheduler() @@ -87,8 +147,19 @@ def init_scheduler(): replace_existing=True ) + # Configure license expiration job - runs daily at midnight + scheduler.add_job( + deactivate_expired_licenses, + 'cron', + hour=0, + minute=0, + id='license_expiration_check', + replace_existing=True + ) + scheduler.start() logging.info(f"Scheduler started. Daily backup scheduled at {config.SCHEDULER_CONFIG['backup_hour']:02d}:{config.SCHEDULER_CONFIG['backup_minute']:02d}") logging.info("Session cleanup job scheduled to run every 60 seconds") + logging.info("License expiration check scheduled to run daily at midnight") return scheduler \ No newline at end of file diff --git a/v2_adminpanel/templates/resources.html b/v2_adminpanel/templates/resources.html index 6d7411d..8253652 100644 --- a/v2_adminpanel/templates/resources.html +++ b/v2_adminpanel/templates/resources.html @@ -228,7 +228,7 @@ {% if show_fake %}checked{% endif %} onchange="toggleTestResources()">