"""Authentication routes - Login, Logout, Register""" from flask import Blueprint, render_template, request, redirect, url_for, session, jsonify, flash from functools import wraps from database import db from database.models import User from datetime import datetime import logging auth_bp = Blueprint('auth', __name__) logger = logging.getLogger(__name__) def login_required(f): """Decorator to require login""" @wraps(f) def decorated_function(*args, **kwargs): if 'user_id' not in session: return redirect(url_for('auth.login', next=request.url)) return f(*args, **kwargs) return decorated_function def admin_required(f): """Decorator to require admin role""" @wraps(f) def decorated_function(*args, **kwargs): if 'user_id' not in session: return redirect(url_for('auth.login')) user = User.query.get(session['user_id']) if not user or not user.is_admin: flash('Admin access required', 'danger') return redirect(url_for('main.index')) return f(*args, **kwargs) return decorated_function @auth_bp.route('/login', methods=['GET', 'POST']) def login(): """Login page""" if request.method == 'POST': username = request.form.get('username') password = request.form.get('password') if not username or not password: flash('Username and password required', 'warning') return redirect(url_for('auth.login')) user = User.query.filter_by(username=username).first() if user and user.check_password(password): session['user_id'] = user.id session['username'] = user.username session['is_admin'] = user.is_admin session.permanent = True user.last_login = datetime.utcnow() db.session.commit() logger.info(f"[AUTH] User '{username}' logged in", flush=True) next_page = request.args.get('next') if next_page and next_page.startswith('/'): return redirect(next_page) return redirect(url_for('main.index')) logger.warning(f"[AUTH] Failed login attempt for '{username}'", flush=True) flash('Invalid username or password', 'danger') return render_template('login.html') @auth_bp.route('/logout') def logout(): """Logout""" username = session.get('username', 'Unknown') session.clear() logger.info(f"[AUTH] User '{username}' logged out", flush=True) flash('You have been logged out', 'info') return redirect(url_for('auth.login')) @auth_bp.route('/api/current-user') def api_current_user(): """Get current user info (API)""" if 'user_id' not in session: return jsonify({'error': 'Not authenticated'}), 401 user = User.query.get(session['user_id']) if not user: session.clear() return jsonify({'error': 'User not found'}), 404 return jsonify({ 'id': user.id, 'username': user.username, 'is_admin': user.is_admin, 'created_at': user.created_at.isoformat() if user.created_at else None, 'last_login': user.last_login.isoformat() if user.last_login else None })