"""
vulnerable-webapp.py.txt
========================
INTENTIONALLY VULNERABLE Flask web application for CTF / code-auditing practice.
DO NOT deploy or run in production. All vulnerabilities are educational.
"""

import os
import pickle
import base64
import sqlite3
from flask import Flask, request, render_template_string, send_file, redirect, session

app = Flask(__name__)
app.secret_key = "supersecret123"  # TODO: fix this later

# ---------- Database Setup ----------

DATABASE = "app.db"

def get_db():
    conn = sqlite3.connect(DATABASE)
    conn.row_factory = sqlite3.Row
    return conn

def init_db():
    db = get_db()
    db.execute("""
        CREATE TABLE IF NOT EXISTS users (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            username TEXT UNIQUE,
            password TEXT,
            role TEXT DEFAULT 'user'
        )
    """)
    db.execute("""
        CREATE TABLE IF NOT EXISTS posts (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            author TEXT,
            title TEXT,
            body TEXT
        )
    """)
    # Hardcoded admin credentials -- TODO: fix this later
    db.execute(
        "INSERT OR IGNORE INTO users (username, password, role) VALUES (?, ?, ?)",
        ("admin", "admin123", "admin")
    )
    db.commit()

init_db()

# ---------- Hardcoded Credentials ----------

API_KEY = "sk-live-4f3c2b1a0d9e8f7c6b5a4d3e2f1a0b9c"  # TODO: move to env
ADMIN_PASSWORD = "Passw0rd!"  # TODO: fix this later
DB_CONNECTION_STRING = "postgresql://appuser:s3cretDBpass@10.0.0.5:5432/production"

# ---------- Routes ----------

# VULNERABILITY: SQL Injection (string concatenation)
@app.route("/login", methods=["GET", "POST"])
def login():
    if request.method == "POST":
        username = request.form.get("username", "")
        password = request.form.get("password", "")
        db = get_db()
        # Vulnerable: string formatting in SQL query
        query = f"SELECT * FROM users WHERE username = '{username}' AND password = '{password}'"
        user = db.execute(query).fetchone()  # TODO: fix this later
        if user:
            session["user"] = username
            session["role"] = user["role"]
            return redirect("/dashboard")
        return "Invalid credentials", 401
    return '''
        <form method="POST">
            <input name="username" placeholder="Username">
            <input name="password" type="password" placeholder="Password">
            <button type="submit">Login</button>
        </form>
    '''

# VULNERABILITY: XSS (unescaped user input in template)
@app.route("/search")
def search():
    query = request.args.get("q", "")
    db = get_db()
    results = db.execute(
        "SELECT * FROM posts WHERE title LIKE ?", (f"%{query}%",)
    ).fetchall()
    # Vulnerable: user input rendered directly into HTML without escaping
    html = f"""
    <h1>Search Results for: {query}</h1>
    <ul>
    {"".join(f"<li>{r['title']}</li>" for r in results)}
    </ul>
    """
    return render_template_string(html)  # TODO: fix this later

# VULNERABILITY: Command Injection (os.system with user input)
@app.route("/ping")
def ping():
    host = request.args.get("host", "127.0.0.1")
    # Vulnerable: user input passed directly to shell
    os.system(f"ping -c 3 {host}")  # TODO: fix this later
    return f"Pinged {host}"

# VULNERABILITY: Path Traversal (no path sanitization)
@app.route("/download")
def download():
    filename = request.args.get("file", "")
    # Vulnerable: no sanitization of filename, allows ../../../etc/passwd
    filepath = os.path.join("/var/www/uploads", filename)
    return send_file(filepath)

# VULNERABILITY: Insecure Deserialization (pickle.loads on user data)
@app.route("/load-session", methods=["POST"])
def load_session():
    data = request.form.get("session_data", "")
    try:
        decoded = base64.b64decode(data)
        # Vulnerable: deserializing untrusted user input with pickle
        session_obj = pickle.loads(decoded)  # TODO: fix this later
        return f"Session loaded: {session_obj}"
    except Exception as e:
        return f"Error: {e}", 400

# VULNERABILITY: Broken Access Control (no auth check)
@app.route("/admin/users")
def admin_users():
    # No authentication or authorization check
    db = get_db()
    users = db.execute("SELECT id, username, role FROM users").fetchall()
    return "<br>".join(f"{u['id']}: {u['username']} ({u['role']})" for u in users)

# VULNERABILITY: Information Disclosure (verbose error + debug mode)
@app.route("/debug")
def debug_info():
    return {
        "secret_key": app.secret_key,
        "api_key": API_KEY,
        "db_string": DB_CONNECTION_STRING,
        "environment": dict(os.environ),
    }

# VULNERABILITY: Open Redirect
@app.route("/redirect")
def open_redirect():
    url = request.args.get("url", "/")
    # Vulnerable: no validation of redirect target
    return redirect(url)

if __name__ == "__main__":
    app.run(debug=True, host="0.0.0.0", port=5000)  # debug=True in production!
