Spaces:
Sleeping
Sleeping
| import sqlite3 | |
| import bcrypt | |
| import secrets | |
| import os | |
| # Use /data/ for persistent storage on HF Spaces, fallback for local dev | |
| DATA_DIR = "/data" if os.path.isdir("/data") else "." | |
| os.makedirs(DATA_DIR, exist_ok=True) | |
| DB_PATH = os.path.join(DATA_DIR, "dockey.db") | |
| def init_db(): | |
| conn = sqlite3.connect(DB_PATH) | |
| c = conn.cursor() | |
| # Users table | |
| c.execute(''' | |
| CREATE TABLE IF NOT EXISTS users ( | |
| id INTEGER PRIMARY KEY AUTOINCREMENT, | |
| username TEXT UNIQUE NOT NULL, | |
| password_hash TEXT NOT NULL, | |
| api_key TEXT UNIQUE NOT NULL | |
| ) | |
| ''') | |
| # Documents table | |
| c.execute(''' | |
| CREATE TABLE IF NOT EXISTS documents ( | |
| id INTEGER PRIMARY KEY AUTOINCREMENT, | |
| user_id INTEGER NOT NULL, | |
| filename TEXT NOT NULL, | |
| status TEXT DEFAULT 'processed', | |
| FOREIGN KEY(user_id) REFERENCES users(id) | |
| ) | |
| ''') | |
| # Sessions table | |
| c.execute(''' | |
| CREATE TABLE IF NOT EXISTS sessions ( | |
| session_token TEXT PRIMARY KEY, | |
| user_id INTEGER NOT NULL, | |
| FOREIGN KEY(user_id) REFERENCES users(id) | |
| ) | |
| ''') | |
| conn.commit() | |
| conn.close() | |
| def hash_password(password: str) -> str: | |
| return bcrypt.hashpw(password.encode(), bcrypt.gensalt()).decode() | |
| def verify_password(password: str, hashed: str) -> bool: | |
| return bcrypt.checkpw(password.encode(), hashed.encode()) | |
| def generate_api_key() -> str: | |
| return "dk_" + secrets.token_hex(16) | |
| def create_user(username, password): | |
| conn = sqlite3.connect(DB_PATH) | |
| c = conn.cursor() | |
| try: | |
| api_key = generate_api_key() | |
| c.execute("INSERT INTO users (username, password_hash, api_key) VALUES (?, ?, ?)", | |
| (username, hash_password(password), api_key)) | |
| user_id = c.lastrowid | |
| conn.commit() | |
| return user_id, api_key | |
| except sqlite3.IntegrityError: | |
| return None, None | |
| finally: | |
| conn.close() | |
| def get_user_by_username(username): | |
| conn = sqlite3.connect(DB_PATH) | |
| conn.row_factory = sqlite3.Row | |
| c = conn.cursor() | |
| c.execute("SELECT * FROM users WHERE username = ?", (username,)) | |
| user = c.fetchone() | |
| conn.close() | |
| return dict(user) if user else None | |
| def get_user_by_id(user_id): | |
| conn = sqlite3.connect(DB_PATH) | |
| conn.row_factory = sqlite3.Row | |
| c = conn.cursor() | |
| c.execute("SELECT * FROM users WHERE id = ?", (user_id,)) | |
| user = c.fetchone() | |
| conn.close() | |
| return dict(user) if user else None | |
| def get_user_by_api_key(api_key): | |
| conn = sqlite3.connect(DB_PATH) | |
| conn.row_factory = sqlite3.Row | |
| c = conn.cursor() | |
| c.execute("SELECT * FROM users WHERE api_key = ?", (api_key,)) | |
| user = c.fetchone() | |
| conn.close() | |
| return dict(user) if user else None | |
| def add_document(user_id, filename): | |
| conn = sqlite3.connect(DB_PATH) | |
| c = conn.cursor() | |
| c.execute("INSERT INTO documents (user_id, filename) VALUES (?, ?)", (user_id, filename)) | |
| doc_id = c.lastrowid | |
| conn.commit() | |
| conn.close() | |
| return doc_id | |
| def get_user_documents(user_id): | |
| conn = sqlite3.connect(DB_PATH) | |
| conn.row_factory = sqlite3.Row | |
| c = conn.cursor() | |
| c.execute("SELECT * FROM documents WHERE user_id = ?", (user_id,)) | |
| docs = c.fetchall() | |
| conn.close() | |
| return [dict(doc) for doc in docs] | |
| def create_session(user_id): | |
| conn = sqlite3.connect(DB_PATH) | |
| c = conn.cursor() | |
| session_token = secrets.token_urlsafe(32) | |
| c.execute("INSERT INTO sessions (session_token, user_id) VALUES (?, ?)", (session_token, user_id)) | |
| conn.commit() | |
| conn.close() | |
| return session_token | |
| def get_user_by_session(session_token): | |
| conn = sqlite3.connect(DB_PATH) | |
| conn.row_factory = sqlite3.Row | |
| c = conn.cursor() | |
| c.execute("SELECT u.* FROM users u JOIN sessions s ON u.id = s.user_id WHERE s.session_token = ?", (session_token,)) | |
| user = c.fetchone() | |
| conn.close() | |
| return dict(user) if user else None | |
| def delete_session(session_token): | |
| conn = sqlite3.connect(DB_PATH) | |
| c = conn.cursor() | |
| c.execute("DELETE FROM sessions WHERE session_token = ?", (session_token,)) | |
| conn.commit() | |
| conn.close() | |