# core/student_auth.py import os import sqlite3 import hashlib from typing import Optional from db import DB_PATH def _ensure_auth_table() -> None: os.makedirs(os.path.dirname(DB_PATH), exist_ok=True) with sqlite3.connect(DB_PATH) as conn: c = conn.cursor() c.execute( """ CREATE TABLE IF NOT EXISTS student_auth ( student_email TEXT PRIMARY KEY, password_hash TEXT NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) """ ) conn.commit() def _hash_password(plain: str) -> str: salt = os.urandom(16).hex() h = hashlib.sha256((salt + plain).encode("utf-8")).hexdigest() return f"{salt}${h}" def _verify_password(stored: str, plain: str) -> bool: try: salt, h = stored.split("$", 1) calc = hashlib.sha256((salt + plain).encode("utf-8")).hexdigest() return h == calc except Exception: return False def set_student_password(email: str, plain: str) -> None: if not email or not plain: raise ValueError("E-mail e senha são obrigatórios.") _ensure_auth_table() hp = _hash_password(plain) with sqlite3.connect(DB_PATH) as conn: c = conn.cursor() c.execute( """ INSERT INTO student_auth (student_email, password_hash) VALUES (?, ?) ON CONFLICT(student_email) DO UPDATE SET password_hash=excluded.password_hash, created_at=CURRENT_TIMESTAMP """, (email.strip().lower(), hp), ) conn.commit() def has_student_password(email: str) -> bool: if not email: return False _ensure_auth_table() with sqlite3.connect(DB_PATH) as conn: c = conn.cursor() c.execute("SELECT 1 FROM student_auth WHERE student_email=?", (email.strip().lower(),)) return c.fetchone() is not None def check_student_password(email: str, plain: str) -> bool: if not email or not plain: return False _ensure_auth_table() with sqlite3.connect(DB_PATH) as conn: c = conn.cursor() c.execute("SELECT password_hash FROM student_auth WHERE student_email=?", (email.strip().lower(),)) row = c.fetchone() if not row: return False return _verify_password(row[0], plain)