|
|
|
|
|
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) |