src/auth/db.py : schéma SQLite et connexion (#73)

This commit is contained in:
Colin Maudry
2026-04-20 17:15:26 +02:00
parent 9ffa9c39f8
commit 5c6e75e3d3
5 changed files with 109 additions and 0 deletions
View File
+66
View File
@@ -0,0 +1,66 @@
import os
import sqlite3
from pathlib import Path
from threading import Lock
_conn: sqlite3.Connection | None = None
_conn_lock = Lock()
USERS_SCHEMA = """
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
email TEXT NOT NULL UNIQUE,
password_hash TEXT NOT NULL,
email_verified INTEGER NOT NULL DEFAULT 0,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
);
CREATE UNIQUE INDEX IF NOT EXISTS idx_users_email ON users(email);
CREATE TABLE IF NOT EXISTS email_verification_tokens (
token_hash TEXT PRIMARY KEY,
user_id INTEGER NOT NULL,
expires_at TEXT NOT NULL,
created_at TEXT NOT NULL,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);
CREATE TABLE IF NOT EXISTS password_reset_tokens (
token_hash TEXT PRIMARY KEY,
user_id INTEGER NOT NULL,
expires_at TEXT NOT NULL,
created_at TEXT NOT NULL,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);
"""
def _db_path() -> Path:
return Path(os.getenv("USERS_DB_PATH", "users.sqlite"))
def get_conn() -> sqlite3.Connection:
global _conn
with _conn_lock:
if _conn is None:
_conn = sqlite3.connect(
str(_db_path()), check_same_thread=False, isolation_level=None
)
_conn.row_factory = sqlite3.Row
_conn.execute("PRAGMA foreign_keys = ON")
_conn.execute("PRAGMA journal_mode = WAL")
return _conn
def reset_conn_for_tests() -> None:
global _conn
with _conn_lock:
if _conn is not None:
_conn.close()
_conn = None
def init_schema() -> None:
conn = get_conn()
conn.executescript(USERS_SCHEMA)