from flask import Blueprint, render_template, request, redirect, url_for, flash, session from functools import wraps from ldap3 import Server, Connection, ALL from ldap3.core.exceptions import LDAPException class LoginAuth: def __init__(self): # Create Blueprint self.bp = Blueprint("auth", __name__) # ------------------------------- # LDAP CONFIGURATION # ------------------------------- self.LDAP_SERVER = "ldap://localhost:389" self.BASE_DN = "ou=users,dc=lcepl,dc=org" # LDAP Users DN # ------------------------------- # LOGIN ROUTE # ------------------------------- @self.bp.route('/login', methods=['GET', 'POST']) def login(): if request.method == 'POST': username = request.form.get("username") password = request.form.get("password") if not username or not password: flash("Username and password are required!", "danger") return render_template("login.html") user_dn = f"uid={username},{self.BASE_DN}" server = Server(self.LDAP_SERVER, get_info=ALL) try: # Attempt LDAP bind conn = Connection(server, user=user_dn, password=password, auto_bind=True) if conn.bound: session['user'] = username flash(f"Login successful! Welcome {username}", "success") return redirect(url_for('welcome')) else: flash("Invalid username or password!", "danger") except LDAPException as e: flash(f"LDAP login failed: {str(e)}", "danger") finally: if 'conn' in locals(): conn.unbind() # GET request: show login form return render_template("login.html") # ------------------------------- # LOGOUT ROUTE # ------------------------------- @self.bp.route('/logout') def logout(): session.clear() flash("Logged out successfully!", "success") return redirect(url_for('auth.login')) # =================================================== # LOGIN REQUIRED DECORATOR INSIDE CLASS # =================================================== def login_required(self, f): """ Protect routes: redirect to login if user not authenticated. """ @wraps(f) def wrapper(*args, **kwargs): if "user" not in session: flash("Please login first!", "danger") return redirect(url_for("auth.login")) return f(*args, **kwargs) return wrapper