Refactor gateway into modular architecture
Split 1878-line server.py into 15 focused modules: - config.py: all env vars and constants - database.py: schema, init, seed logic - sessions.py: session/token CRUD - proxy.py: proxy_request, SERVICE_MAP, resolve_service - responses.py: ResponseMixin for handler helpers - auth.py: login/logout/register handlers - dashboard.py: dashboard, apps, connections, pinning - command.py: AI command bar - integrations/booklore.py: auth, books, cover, import - integrations/kindle.py: send-to-kindle, file finder - integrations/karakeep.py: save/delete bookmarks - integrations/qbittorrent.py: download status - integrations/image_proxy.py: external image proxy server.py is now thin routing only (~344 lines). All routes, methods, status codes, and responses preserved exactly. Added PYTHONUNBUFFERED=1 to Dockerfile for live logging.
This commit is contained in:
71
gateway/sessions.py
Normal file
71
gateway/sessions.py
Normal file
@@ -0,0 +1,71 @@
|
||||
"""
|
||||
Platform Gateway — Session and service-connection helpers.
|
||||
"""
|
||||
|
||||
import secrets
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from config import SESSION_MAX_AGE
|
||||
from database import get_db
|
||||
|
||||
|
||||
def create_session(user_id):
|
||||
token = secrets.token_hex(32)
|
||||
expires = (datetime.now() + timedelta(seconds=SESSION_MAX_AGE)).isoformat()
|
||||
conn = get_db()
|
||||
conn.execute("INSERT INTO sessions (token, user_id, expires_at) VALUES (?, ?, ?)",
|
||||
(token, user_id, expires))
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return token
|
||||
|
||||
|
||||
def get_session_user(token):
|
||||
if not token:
|
||||
return None
|
||||
conn = get_db()
|
||||
row = conn.execute("""
|
||||
SELECT u.* FROM sessions s
|
||||
JOIN users u ON s.user_id = u.id
|
||||
WHERE s.token = ? AND s.expires_at > ?
|
||||
""", (token, datetime.now().isoformat())).fetchone()
|
||||
conn.close()
|
||||
return dict(row) if row else None
|
||||
|
||||
|
||||
def delete_session(token):
|
||||
if not token:
|
||||
return
|
||||
conn = get_db()
|
||||
conn.execute("DELETE FROM sessions WHERE token = ?", (token,))
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
|
||||
def get_service_token(user_id, service):
|
||||
conn = get_db()
|
||||
row = conn.execute(
|
||||
"SELECT auth_type, auth_token FROM service_connections WHERE user_id = ? AND service = ?",
|
||||
(user_id, service)
|
||||
).fetchone()
|
||||
conn.close()
|
||||
return dict(row) if row else None
|
||||
|
||||
|
||||
def set_service_token(user_id, service, auth_token, auth_type="bearer"):
|
||||
conn = get_db()
|
||||
conn.execute("""
|
||||
INSERT INTO service_connections (user_id, service, auth_type, auth_token)
|
||||
VALUES (?, ?, ?, ?)
|
||||
ON CONFLICT(user_id, service) DO UPDATE SET auth_token = ?, auth_type = ?
|
||||
""", (user_id, service, auth_type, auth_token, auth_token, auth_type))
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
|
||||
def delete_service_token(user_id, service):
|
||||
conn = get_db()
|
||||
conn.execute("DELETE FROM service_connections WHERE user_id = ? AND service = ?",
|
||||
(user_id, service))
|
||||
conn.commit()
|
||||
conn.close()
|
||||
Reference in New Issue
Block a user