from flask import Blueprint, render_template, request, redirect, url_for, session, flash from web.config import Config from web.auth import admin_required from web.database import query_db import os bp = Blueprint('admin', __name__, url_prefix='/admin') @bp.route('/login', methods=['GET', 'POST']) def login(): if request.method == 'POST': token = request.form.get('token') if token == Config.ADMIN_TOKEN: session['is_admin'] = True return redirect(url_for('admin.dashboard')) else: flash('Invalid Token', 'error') return render_template('admin/login.html') @bp.route('/logout') def logout(): session.pop('is_admin', None) return redirect(url_for('main.index')) @bp.route('/') @admin_required def dashboard(): return render_template('admin/dashboard.html') from web.services.etl_service import EtlService @bp.route('/trigger_etl', methods=['POST']) @admin_required def trigger_etl(): script_name = request.form.get('script') allowed = ['L1A.py', 'L2_Builder.py', 'L3_Builder.py'] if script_name not in allowed: return "Invalid script", 400 success, message = EtlService.run_script(script_name) status_code = 200 if success else 500 return message, status_code @bp.route('/sql', methods=['GET', 'POST']) @admin_required def sql_runner(): result = None error = None query = "" db_name = "l2" if request.method == 'POST': query = request.form.get('query') db_name = request.form.get('db_name', 'l2') # Safety check forbidden = ['DELETE', 'DROP', 'UPDATE', 'INSERT', 'ALTER', 'GRANT', 'REVOKE'] if any(x in query.upper() for x in forbidden): error = "Only SELECT queries allowed in Web Runner." else: try: # Enforce limit if not present if 'LIMIT' not in query.upper(): query += " LIMIT 50" rows = query_db(db_name, query) if rows: columns = rows[0].keys() result = {'columns': columns, 'rows': rows} else: result = {'columns': [], 'rows': []} except Exception as e: error = str(e) return render_template('admin/sql.html', result=result, error=error, query=query, db_name=db_name)