from flask import Flask, render_template, request, session, redirect, url_for
import time
import sqlite3
import os
from collections import defaultdict
from datetime import datetime

# Resolve DB path relative to this file, not the CWD — fixes PyCharm working directory issues
DB_PATH = os.path.join(os.path.dirname(__file__), "app.db")


SECURE_LOGIN = False
login_attempts = defaultdict(list)  # username: [timestamps]
MAX_ATTEMPTS = 5
LOCKOUT_TIME = 120

app = Flask(__name__)
app.secret_key = "dummy_secret_key"

team = [
    {
        "first_name": "Alice",
        "last_name": "Johnson",
        "email": "alice@cybercorp.com",
        "department": "Penetration Testing",
        "bio": "Alice specializes in web application vulnerabilities and has 8+ years of experience in ethical hacking.",
        "photo": "../static/images/alice.png"
    },
    {
        "first_name": "Bob",
        "last_name": "Smith",
        "email": "bob@cybercorp.com",
        "department": "Incident Response",
        "bio": "Bob is an expert in forensic analysis and coordinates rapid response for major breaches.",
        "photo": "../static/images/bob.png"
    },
    {
        "first_name": "Eve",
        "last_name": "Mallory",
        "email": "eve@cybercorp.com",
        "department": "Security Research",
        "bio": "Eve focuses on threat intelligence and reverse engineering of malware samples.",
        "photo": "../static/images/eve.png"
    },
    {
        "first_name": "Mark",
        "last_name": "Anthony",
        "email": "mark@cybercorp.com",
        "department": "Website Programmer",
        "bio": "Mark is responsible for the creation of the awesome and super-secure website you are browsing now.",
        "photo": "../static/images/mark.png"
    }
]

@app.context_processor
def inject_year():
    return {'year': datetime.now().year}

@app.route("/")
def home():
    return render_template("home.html")

@app.route("/people")
def people():
    return render_template("people.html", team=team)

@app.route("/about")
def about():
    return render_template("about.html")

@app.route("/apply")
def apply():
    return render_template("apply.html")

@app.route("/hosting")
def hosting():
    return render_template("hosting.html")

@app.route("/admin", methods=["GET", "POST"])
def admin():
    if 'user' not in session:  # Controlla se l'utente è autenticato
        return redirect(url_for("login"))  # Reindirizza alla pagina di login
    return render_template("admin.html", message=f"Welcome back, Admin {session['user']}!")

@app.route('/logout')
def logout():
    session.clear()
    return redirect(url_for('login'))


@app.route("/smartworking", methods=["GET", "POST"])
def login():
    #-------------------------------------------------------------------
    # INSECURE LOGIN: ALLOWING INFINITE ATTEMPTS
    #-------------------------------------------------------------------
    if not SECURE_LOGIN:
        error = None
        if request.method == "POST":
            username = request.form["username"]
            password = request.form["password"]

            # VULNERABLE SQL QUERY (deliberate for demo)
            conn = sqlite3.connect("app.db")
            cursor = conn.cursor()
            query = f"SELECT * FROM users WHERE username = '{username}' AND password = '{password}'"
            print(f"[DEBUG] Executing: {query}")  # optional for terminal visibility
            cursor.execute(query)
            result = cursor.fetchone()
            conn.close()

            if result:
                session['user'] = username
                #message = f"Welcome back, Admin {username}!\nYou are now logged to CyberCorp private pages."
                return redirect(url_for("admin"))
            else:
                error = "Invalid credentials."

        return render_template("smartworking.html", error=error)
    else:

        #-------------------------------------------------------------------
        # SECURE LOGIN: BLOCKING LOGINS AFTER N FAILED ATTEMPTS
        #-------------------------------------------------------------------
        error = None

        if request.method == 'POST':
            username = request.form['username']
            password = request.form['password']
            now = time.time()

            # Clean up old attempts
            login_attempts[username] = [t for t in login_attempts[username] if now - t < LOCKOUT_TIME]

            if len(login_attempts[username]) >= MAX_ATTEMPTS:
                error = f"Too many failed attempts. Try again in {int(LOCKOUT_TIME - (now - login_attempts[username][0]))}s."
            else:
                # VULNERABLE SQL QUERY (deliberate for demo)
                conn = sqlite3.connect(DB_PATH)
                cursor = conn.cursor()
                query = f"SELECT * FROM users WHERE username = '{username}' AND password = '{password}'"
                cursor.execute(query)
                result = cursor.fetchone()
                conn.close()

                if result:
                    session['user'] = username
                    login_attempts[username] = []  # reset on successful login
                    return f"<h2>Welcome, {username}!</h2><p>You are now logged in.</p>"
                else:
                    login_attempts[username].append(now)
                    error = "Invalid credentials."

        return render_template('smartworking.html', error=error)


@app.route('/products', methods=['GET', 'POST'])
def products():
    results = []

    if request.method == 'POST':
        search = request.form['search']
        conn = sqlite3.connect(DB_PATH)
        cursor = conn.cursor()

        # Intentionally vulnerable query (for demo)
        query = f"SELECT * FROM products WHERE name LIKE '%{search}%'"
        print(f"[DEBUG] Executing: {query}")  # optional for terminal visibility
        try:
            cursor.execute(query)
            results = cursor.fetchall()
        except Exception as e:
            results = [('ERROR', str(e))]

        conn.close()

    return render_template('products.html', results=results)


if __name__ == "__main__":
    app.run(debug=False, port=5001)