Test isolation fixes: - auth_db.get_db(): read TURF_SAAS_DB dynamically (not frozen at import) - api_v1/utils.get_db(): read TURF_SAAS_DB dynamically (not frozen at import) - api_tokens_db.get_db(): read TURF_SAAS_DB dynamically (not frozen at import) - tests/test_history.py: enforce _tmp_db.name + call init_auth_tables() in fixtures - tests/test_user_tokens.py: enforce _tmp_db.name + call migrate_api_tokens_tables() in app fixture Auth compatibility fixes: - api_v1/routes/history.py: use auth.jwt_required_middleware (flask_jwt_extended) with saas_auth fallback for portal_server context - api_v1/routes/ml_feedback.py: same auth import strategy - api_v1/routes/user.py: same auth import strategy Dependencies: - requirements.txt: add optuna>=4.0.0 (used in ML ensemble tests and training) Co-Authored-By: Paperclip <noreply@paperclip.ing>
60 lines
2.0 KiB
Python
60 lines
2.0 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
api_tokens_db.py — DB migration for personal API tokens + user webhooks
|
|
HRT-80: API Token personnel + Webhook alertes (Pro)
|
|
"""
|
|
|
|
import logging
|
|
import os
|
|
import sqlite3
|
|
|
|
DB_PATH = os.environ.get("TURF_SAAS_DB", "/home/h3r7/turf_saas/turf_saas.db")
|
|
logger = logging.getLogger("turf_saas.api_tokens_db")
|
|
|
|
|
|
def get_db() -> sqlite3.Connection:
|
|
"""Return a SQLite connection (reads TURF_SAAS_DB dynamically for test isolation)."""
|
|
db_path = os.environ.get("TURF_SAAS_DB", DB_PATH)
|
|
conn = sqlite3.connect(db_path)
|
|
conn.row_factory = sqlite3.Row
|
|
return conn
|
|
|
|
|
|
def migrate_api_tokens_tables() -> None:
|
|
"""Idempotent migration: create user_api_tokens and user_webhooks."""
|
|
conn = get_db()
|
|
c = conn.cursor()
|
|
c.executescript("""
|
|
CREATE TABLE IF NOT EXISTS user_api_tokens (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
user_id TEXT NOT NULL,
|
|
token_hash TEXT NOT NULL UNIQUE,
|
|
token_prefix TEXT NOT NULL,
|
|
created_at DATETIME NOT NULL DEFAULT (datetime('now')),
|
|
last_used_at DATETIME,
|
|
revoked INTEGER NOT NULL DEFAULT 0
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_api_tokens_user ON user_api_tokens(user_id);
|
|
CREATE INDEX IF NOT EXISTS idx_api_tokens_hash ON user_api_tokens(token_hash);
|
|
|
|
CREATE TABLE IF NOT EXISTS user_webhooks (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
user_id TEXT NOT NULL UNIQUE,
|
|
url TEXT NOT NULL,
|
|
secret TEXT NOT NULL,
|
|
created_at DATETIME NOT NULL DEFAULT (datetime('now'))
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_webhooks_user ON user_webhooks(user_id);
|
|
""")
|
|
conn.commit()
|
|
conn.close()
|
|
logger.info(
|
|
"[api_tokens_db] Tables user_api_tokens + user_webhooks created/verified."
|
|
)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
logging.basicConfig(level=logging.INFO)
|
|
migrate_api_tokens_tables()
|
|
print("[api_tokens_db] Migration complete.")
|