CoolFace
Apppublic

mansi14883md/AI-Keystroke-Security-System

sourceHugging Faceupdated 4mo agoView on Hugging Face
1likes
admin_dashboard.py161 linesDownload Raw Back to root
1import os2import tkinter as tk3from tkinter import messagebox, ttk4 5from backend_utils import (6    delete_user_profile,7    export_attempt_history,8    get_attempt_history,9    get_dashboard_stats,10    get_user_overview,11    set_setting,12)13 14 15EXPORT_FILE = os.path.join("data", "exported_attempt_history.csv")16 17 18class AdminDashboard:19    def __init__(self, root: tk.Tk) -> None:20        self.root = root21        self.root.title("Admin Dashboard")22        self.root.geometry("920x620")23        self.root.configure(bg="#081420")24 25        self.threshold_var = tk.StringVar()26        self.failed_attempts_var = tk.StringVar()27        self.cooldown_var = tk.StringVar()28 29        self.build_gui()30        self.refresh_all()31 32    def build_gui(self) -> None:33        tk.Label(34            self.root,35            text="Admin Dashboard",36            font=("Arial", 24, "bold"),37            fg="#f1faee",38            bg="#081420",39            pady=14,40        ).pack()41 42        summary_frame = tk.Frame(self.root, bg="#102235")43        summary_frame.pack(fill="x", padx=18, pady=10)44        self.summary_label = tk.Label(summary_frame, text="", font=("Arial", 12), fg="#caf0f8", bg="#102235", justify="left", pady=12)45        self.summary_label.pack(anchor="w", padx=16)46 47        settings_frame = tk.Frame(self.root, bg="#102235")48        settings_frame.pack(fill="x", padx=18, pady=6)49        tk.Label(settings_frame, text="Decision Threshold", fg="#f1faee", bg="#102235", font=("Arial", 11, "bold")).grid(row=0, column=0, padx=10, pady=10, sticky="w")50        tk.Entry(settings_frame, textvariable=self.threshold_var, width=8).grid(row=0, column=1, padx=6)51        tk.Label(settings_frame, text="Max Failed Attempts", fg="#f1faee", bg="#102235", font=("Arial", 11, "bold")).grid(row=0, column=2, padx=10, pady=10, sticky="w")52        tk.Entry(settings_frame, textvariable=self.failed_attempts_var, width=8).grid(row=0, column=3, padx=6)53        tk.Label(settings_frame, text="Cooldown Seconds", fg="#f1faee", bg="#102235", font=("Arial", 11, "bold")).grid(row=0, column=4, padx=10, pady=10, sticky="w")54        tk.Entry(settings_frame, textvariable=self.cooldown_var, width=8).grid(row=0, column=5, padx=6)55        tk.Button(settings_frame, text="Save Security Settings", command=self.save_settings, bg="#00b4d8", fg="white", relief="flat", padx=12).grid(row=0, column=6, padx=12)56        tk.Button(settings_frame, text="Export Attempt Report", command=self.export_report, bg="#1f8a70", fg="white", relief="flat", padx=12).grid(row=0, column=7, padx=12)57 58        content = tk.Frame(self.root, bg="#081420")59        content.pack(fill="both", expand=True, padx=18, pady=10)60 61        users_frame = tk.Frame(content, bg="#102235")62        users_frame.pack(side="left", fill="both", expand=True, padx=(0, 8))63        tk.Label(users_frame, text="Registered Users", font=("Arial", 14, "bold"), fg="#f1faee", bg="#102235").pack(pady=10)64        self.users_tree = ttk.Treeview(users_frame, columns=("samples", "threshold", "updated"), show="headings", height=16)65        self.users_tree.heading("samples", text="Samples")66        self.users_tree.heading("threshold", text="Threshold")67        self.users_tree.heading("updated", text="Updated")68        self.users_tree.column("samples", width=80, anchor="center")69        self.users_tree.column("threshold", width=90, anchor="center")70        self.users_tree.column("updated", width=180, anchor="center")71        self.users_tree.pack(fill="both", expand=True, padx=12, pady=8)72        tk.Button(users_frame, text="Delete Selected User", command=self.delete_selected_user, bg="#c1121f", fg="white", relief="flat", padx=12).pack(pady=(0, 12))73 74        attempts_frame = tk.Frame(content, bg="#102235")75        attempts_frame.pack(side="right", fill="both", expand=True, padx=(8, 0))76        tk.Label(attempts_frame, text="Attempt History", font=("Arial", 14, "bold"), fg="#f1faee", bg="#102235").pack(pady=10)77        self.attempts_tree = ttk.Treeview(attempts_frame, columns=("time", "user", "result", "confidence"), show="headings", height=16)78        self.attempts_tree.heading("time", text="Timestamp")79        self.attempts_tree.heading("user", text="User")80        self.attempts_tree.heading("result", text="Result")81        self.attempts_tree.heading("confidence", text="Confidence")82        self.attempts_tree.column("time", width=170)83        self.attempts_tree.column("user", width=90, anchor="center")84        self.attempts_tree.column("result", width=110, anchor="center")85        self.attempts_tree.column("confidence", width=90, anchor="center")86        self.attempts_tree.pack(fill="both", expand=True, padx=12, pady=8)87 88    def refresh_all(self) -> None:89        stats = get_dashboard_stats()90        self.summary_label.config(91            text=(92                f"Total Users: {stats['total_users']}    "93                f"Total Attempts: {stats['total_attempts']}    "94                f"Granted: {stats['granted_attempts']}    "95                f"Denied: {stats['denied_attempts']}    "96                f"Avg Confidence: {stats['average_confidence'] * 100:.2f}%"97            )98        )99        self.threshold_var.set(str(stats["decision_threshold"]))100        self.failed_attempts_var.set(str(stats["max_failed_attempts"]))101        self.cooldown_var.set(str(stats["cooldown_seconds"]))102 103        for item in self.users_tree.get_children():104            self.users_tree.delete(item)105        for user in get_user_overview():106            self.users_tree.insert("", "end", iid=user["username"], values=(user["sample_count"], f"{user['threshold']:.2f}", user["updated_at"] or "-"))107 108        for item in self.attempts_tree.get_children():109            self.attempts_tree.delete(item)110        for attempt in get_attempt_history(limit=20):111            self.attempts_tree.insert(112                "",113                "end",114                values=(115                    attempt["timestamp"],116                    attempt["username"],117                    attempt["result"],118                    f"{float(attempt['confidence']) * 100:.2f}%",119                ),120            )121 122    def save_settings(self) -> None:123        try:124            threshold = float(self.threshold_var.get())125            max_attempts = int(self.failed_attempts_var.get())126            cooldown = int(self.cooldown_var.get())127        except ValueError:128            messagebox.showwarning("Invalid Values", "Please enter valid numeric security settings.")129            return130 131        set_setting("decision_threshold", threshold)132        set_setting("max_failed_attempts", max_attempts)133        set_setting("cooldown_seconds", cooldown)134        self.refresh_all()135        messagebox.showinfo("Saved", "Security settings updated successfully.")136 137    def export_report(self) -> None:138        path = export_attempt_history(EXPORT_FILE)139        messagebox.showinfo("Exported", f"Attempt history exported to:\n{os.path.abspath(path)}")140 141    def delete_selected_user(self) -> None:142        selected = self.users_tree.selection()143        if not selected:144            messagebox.showwarning("No Selection", "Please select a user first.")145            return146        username = selected[0]147        if not messagebox.askyesno("Confirm Delete", f"Delete user '{username}' and all typing samples?"):148            return149        delete_user_profile(username)150        self.refresh_all()151 152 153def main() -> None:154    root = tk.Tk()155    AdminDashboard(root)156    root.mainloop()157 158 159if __name__ == "__main__":160    main()161