from functools import wraps from flask import Blueprint, flash, redirect, render_template, request, session, url_for from app.db import get_db from app.auth.utils import create_device_directories, slugify_device_name bp = Blueprint("main", __name__) def portal_session_required(view_func): @wraps(view_func) def wrapped(*args, **kwargs): if "otb_user_id" not in session or "otb_tenant_id" not in session: return redirect(url_for("auth.login_required_notice")) return view_func(*args, **kwargs) return wrapped @bp.route("/") def index(): if "otb_user_id" in session: return redirect(url_for("main.dashboard")) return redirect(url_for("auth.login_required_notice")) @bp.route("/dashboard") @portal_session_required def dashboard(): db = get_db() with db.cursor() as cur: cur.execute( """ SELECT id, device_name, device_type, relative_path, is_active, created_at FROM devices WHERE tenant_id = %s ORDER BY id """, (session["otb_tenant_id"],), ) devices = cur.fetchall() return render_template( "cloud/dashboard.html", user_email=session.get("otb_email"), tenant_slug=session.get("otb_tenant_slug"), devices=devices, ) @bp.route("/devices/new", methods=["GET", "POST"]) @portal_session_required def add_device(): if request.method == "GET": return render_template( "cloud/device_new.html", user_email=session.get("otb_email"), tenant_slug=session.get("otb_tenant_slug"), ) device_name = (request.form.get("device_name") or "").strip() device_type = (request.form.get("device_type") or "").strip() if not device_name: flash("Device name is required.", "warning") return render_template( "cloud/device_new.html", user_email=session.get("otb_email"), tenant_slug=session.get("otb_tenant_slug"), device_name=device_name, device_type=device_type, ) if not device_type: flash("Device type is required.", "warning") return render_template( "cloud/device_new.html", user_email=session.get("otb_email"), tenant_slug=session.get("otb_tenant_slug"), device_name=device_name, device_type=device_type, ) slug = slugify_device_name(device_name) relative_path = f"devices/{slug}" db = get_db() with db.cursor() as cur: cur.execute( """ SELECT id FROM devices WHERE tenant_id = %s AND device_name = %s """, (session["otb_tenant_id"], device_name), ) existing = cur.fetchone() if existing: flash("A device with that name already exists.", "warning") return render_template( "cloud/device_new.html", user_email=session.get("otb_email"), tenant_slug=session.get("otb_tenant_slug"), device_name=device_name, device_type=device_type, ) cur.execute( """ INSERT INTO devices (tenant_id, device_name, device_type, relative_path, is_active) VALUES (%s, %s, %s, %s, 1) """, (session["otb_tenant_id"], device_name, device_type, relative_path), ) cur.execute( """ INSERT INTO audit_logs ( tenant_id, user_id, actor_type, event_type, ip_address, user_agent, event_detail ) VALUES (%s, %s, 'user', 'device_created', %s, %s, %s) """, ( session["otb_tenant_id"], session["otb_user_id"], request.headers.get("X-Forwarded-For", request.remote_addr), request.headers.get("User-Agent", ""), f"Created device '{device_name}' ({device_type}) at {relative_path}", ), ) db.commit() create_device_directories(session["otb_tenant_slug"], relative_path) flash("Device added successfully.", "success") return redirect(url_for("main.dashboard"))