Till Tomczak 2d33753b94 feat: Major updates to backend structure and security enhancements
- Removed `COMMON_ERRORS.md` file to streamline documentation.
- Added `Flask-Limiter` for rate limiting and `redis` for session management in `requirements.txt`.
- Expanded `ROADMAP.md` to include completed security features and planned enhancements for version 2.2.
- Enhanced `setup_myp.sh` for ultra-secure kiosk installation, including system hardening and security configurations.
- Updated `app.py` to integrate CSRF protection and improved logging setup.
- Refactored user model to include username and active status for better user management.
- Improved job scheduler with uptime tracking and task management features.
- Updated various templates for a more cohesive user interface and experience.
2025-05-25 20:33:38 +02:00

88 lines
3.7 KiB
Python

from flask import Blueprint, render_template, request, redirect, url_for, flash, jsonify
from flask_login import login_user, logout_user, current_user, login_required
from datetime import datetime
from models import User
from utils.logging_config import get_logger
from models import get_db_session
# Logger für Authentifizierung
auth_logger = get_logger("auth")
# Blueprint erstellen
auth_bp = Blueprint('auth', __name__, url_prefix='/auth')
@auth_bp.route("/login", methods=["GET", "POST"])
def login():
if current_user.is_authenticated:
return redirect(url_for("index"))
error = None
if request.method == "POST":
# Unterscheiden zwischen JSON-Anfragen und normalen Formular-Anfragen
is_json_request = request.is_json or request.headers.get('Content-Type') == 'application/json'
# Daten je nach Anfrageart auslesen
if is_json_request:
data = request.get_json()
username = data.get("username")
password = data.get("password")
remember_me = data.get("remember_me", False)
else:
username = request.form.get("username")
password = request.form.get("password")
remember_me = request.form.get("remember-me") == "on"
if not username or not password:
error = "Benutzername und Passwort müssen angegeben werden."
if is_json_request:
return jsonify({"error": error}), 400
else:
try:
db_session = get_db_session()
# Suche nach Benutzer mit übereinstimmendem Benutzernamen oder E-Mail
user = db_session.query(User).filter(
(User.username == username) | (User.email == username)
).first()
if user and user.check_password(password):
login_user(user, remember=remember_me)
auth_logger.info(f"Benutzer {username} hat sich angemeldet")
next_page = request.args.get("next")
db_session.close()
if is_json_request:
return jsonify({"success": True, "redirect_url": next_page or url_for("index")})
else:
if next_page:
return redirect(next_page)
return redirect(url_for("index"))
else:
error = "Ungültiger Benutzername oder Passwort."
auth_logger.warning(f"Fehlgeschlagener Login-Versuch für Benutzer {username}")
db_session.close()
if is_json_request:
return jsonify({"error": error}), 401
except Exception as e:
# Fehlerbehandlung für Datenbankprobleme
error = "Anmeldefehler. Bitte versuchen Sie es später erneut."
auth_logger.error(f"Fehler bei der Anmeldung: {str(e)}")
if is_json_request:
return jsonify({"error": error}), 500
return render_template("login.html", error=error)
@auth_bp.route("/logout", methods=["GET", "POST"])
@login_required
def logout():
username = current_user.username if hasattr(current_user, "username") else "Unbekannt"
logout_user()
auth_logger.info(f"Benutzer {username} hat sich abgemeldet")
# Unterscheiden zwischen JSON-Anfragen und normalen Anfragen
if request.is_json or request.headers.get('Content-Type') == 'application/json':
return jsonify({"success": True, "redirect_url": url_for("auth.login")})
else:
return redirect(url_for("auth.login"))