Skip to content

3MFA #4629

@Baptistar108

Description

@Baptistar108

import re
import random
import smtplib
import bcrypt
import pyotp
import sqlite3
import requests
import time
import platform
import win32com.client # Windows Hello API (Fingerprint)
from flask import Flask, render_template, request, redirect, session, jsonify
from flask_login import LoginManager, UserMixin, login_user, logout_user, login_required, current_user
from datetime import datetime

Initialize Flask App

app = Flask(name)
app.secret_key = "supersecretkey" # Change this for security

Setup Flask-Login

login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = "login_page"

------------------ DATABASE SETUP ------------------

def setup_database():
"""Creates users and login_history tables with role support."""
conn = sqlite3.connect("users.db")
c = conn.cursor()

# Users Table with Fingerprint Support
c.execute(
    """CREATE TABLE IF NOT EXISTS users (
        email TEXT PRIMARY KEY, 
        phone TEXT, 
        password_hash TEXT, 
        fingerprint_hash TEXT, 
        otp_secret TEXT,
        role TEXT DEFAULT 'user')"""
)

# Login History Table
c.execute(
    """CREATE TABLE IF NOT EXISTS login_history (
        email TEXT, 
        device TEXT, 
        ip_address TEXT, 
        city TEXT,
        country TEXT,
        timestamp TEXT,
        last_activity TEXT,
        session_active INTEGER DEFAULT 1,
        FOREIGN KEY(email) REFERENCES users(email))"""
)

conn.commit()
conn.close()

------------------ USER MODEL FOR FLASK-LOGIN ------------------

class User(UserMixin):
def init(self, email, role):
self.id = email
self.role = role

@login_manager.user_loader
def load_user(email):
"""Loads the user from the database."""
conn = sqlite3.connect("users.db")
c = conn.cursor()
c.execute("SELECT role FROM users WHERE email=?", (email,))
user_data = c.fetchone()
conn.close()

if user_data:
    return User(email, user_data[0])
return None

------------------ WINDOWS HELLO FINGERPRINT AUTHENTICATION ------------------

def authenticate_fingerprint():
"""Authenticates user via Windows Hello fingerprint scanner."""
try:
bio = win32com.client.Dispatch("WinBioCredentialProvider.WinBioCredentialProvider")
result = bio.Validate()
return result # True if authentication succeeds
except Exception as e:
print("Fingerprint authentication failed:", str(e))
return False

@app.route("/fingerprint-login", methods=["POST"])
def fingerprint_login():
"""Logs in a user using Windows Hello fingerprint authentication."""
email = request.form["email"]

conn = sqlite3.connect("users.db")
c = conn.cursor()
c.execute("SELECT role FROM users WHERE email=?", (email,))
user_data = c.fetchone()
conn.close()

if user_data:
    role = user_data[0]
    if authenticate_fingerprint():
        user = User(email, role)
        login_user(user)
        return redirect("/dashboard")
    else:
        return "Fingerprint authentication failed", 401
return "User not found", 404

------------------ LOGIN FUNCTION WITH PASSWORD AUTH ------------------

@app.route("/login", methods=["GET", "POST"])
def login_page():
if request.method == "POST":
email = request.form["email"]
password = request.form["password"]

    conn = sqlite3.connect("users.db")
    c = conn.cursor()
    c.execute("SELECT password_hash, role FROM users WHERE email=?", (email,))
    user_data = c.fetchone()
    conn.close()

    if user_data:
        stored_password_hash, role = user_data
        if bcrypt.checkpw(password.encode(), stored_password_hash.encode()):
            user = User(email, role)
            login_user(user)
            return redirect("/dashboard")
    
    return "Invalid email or password", 401

return render_template("login.html")

------------------ DASHBOARD FOR USERS ------------------

@app.route("/dashboard")
@login_required
def user_dashboard():
"""User dashboard - shows login history for normal users."""
conn = sqlite3.connect("users.db")
c = conn.cursor()
c.execute("SELECT * FROM login_history WHERE email=?", (current_user.id,))
login_history = c.fetchall()
conn.close()

return render_template("dashboard.html", logins=login_history, user=current_user)

------------------ ADMIN PANEL ------------------

@app.route("/admin")
@login_required
def admin_dashboard():
"""Admin panel - only accessible to admins."""
conn = sqlite3.connect("users.db")
c = conn.cursor()
c.execute("SELECT * FROM login_history ORDER BY timestamp DESC")
login_data = c.fetchall()
conn.close()

return render_template("admin.html", logins=login_data, user=current_user)

------------------ LOGOUT ------------------

@app.route("/logout")
@login_required
def logout():
logout_user()
return redirect("/login")

if name == "main":
setup_database()
app.run(debug=True)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions