-
Notifications
You must be signed in to change notification settings - Fork 316
Description
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)