feat: Implement core Python FastAPI backend for user authentication, vault management, and file operations.

This commit is contained in:
Bruno Charest 2026-03-27 10:11:43 -04:00
parent 3506d6c45e
commit 0bbd793e97
4 changed files with 34 additions and 13 deletions

View File

@ -27,7 +27,8 @@ COPY backend/ ./backend/
COPY frontend/ ./frontend/ COPY frontend/ ./frontend/
# Create non-root user for security + data directory for auth persistence # Create non-root user for security + data directory for auth persistence
RUN groupadd -r obsigate && useradd -r -g obsigate -d /app -s /sbin/nologin obsigate \ # Using explicit UID/GID 1000 to match common host user and docker-compose settings
RUN groupadd -g 1000 obsigate && useradd -u 1000 -g obsigate -d /app -s /sbin/nologin obsigate \
&& mkdir -p /app/data \ && mkdir -p /app/data \
&& chown -R obsigate:obsigate /app && chown -R obsigate:obsigate /app
USER obsigate USER obsigate

View File

@ -31,6 +31,7 @@ def _read() -> dict:
def _write(data: dict): def _write(data: dict):
"""Atomic write: write to .tmp then rename to prevent corruption.""" """Atomic write: write to .tmp then rename to prevent corruption."""
try:
USERS_FILE.parent.mkdir(parents=True, exist_ok=True) USERS_FILE.parent.mkdir(parents=True, exist_ok=True)
tmp = USERS_FILE.with_suffix(".tmp") tmp = USERS_FILE.with_suffix(".tmp")
tmp.write_text(json.dumps(data, indent=2, default=str), encoding="utf-8") tmp.write_text(json.dumps(data, indent=2, default=str), encoding="utf-8")
@ -39,6 +40,13 @@ def _write(data: dict):
USERS_FILE.chmod(0o600) USERS_FILE.chmod(0o600)
except OSError: except OSError:
pass # Windows doesn't support Unix permissions pass # Windows doesn't support Unix permissions
except PermissionError as e:
logger.critical("=" * 60)
logger.critical(f"ERREUR DE PERMISSION : Impossible d'écrire dans {USERS_FILE.parent}")
logger.critical("Le conteneur n'a pas les droits sur le volume monté dans /app/data.")
logger.critical("FIX : Exécutez sur l'hôte (Linux) : sudo chown -R 1000:1000 /votre/chemin/data")
logger.critical("=" * 60)
raise e
def has_users() -> bool: def has_users() -> bool:

View File

@ -370,8 +370,17 @@ def bootstrap_admin():
logger.warning("CHANGEZ CE MOT DE PASSE dès la première connexion !") logger.warning("CHANGEZ CE MOT DE PASSE dès la première connexion !")
logger.warning("=" * 60) logger.warning("=" * 60)
try:
create_user(admin_user, admin_pass, role="admin", vaults=["*"]) create_user(admin_user, admin_pass, role="admin", vaults=["*"])
logger.info(f"Admin '{admin_user}' créé avec succès") logger.info(f"Admin '{admin_user}' créé avec succès")
except PermissionError as e:
logger.critical("=" * 60)
logger.critical("DÉMARRAGE IMPOSSIBLE : Erreur de permission sur le dossier 'data'")
logger.critical("L'indexation et l'authentification ne peuvent pas fonctionner.")
logger.critical("FIX : Vérifiez les droits du volume /app/data sur l'hôte.")
logger.critical("Exemple : sudo chown -R 1000:1000 /DOCKER_CONFIG/ObsiGate/data")
logger.critical("=" * 60)
raise e
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------

View File

@ -64,9 +64,12 @@ def save_vault_settings() -> None:
_SETTINGS_PATH.write_text(content, encoding="utf-8") _SETTINGS_PATH.write_text(content, encoding="utf-8")
logger.info(f"Successfully saved settings for {len(_vault_settings)} vaults to {_SETTINGS_PATH}") logger.info(f"Successfully saved settings for {len(_vault_settings)} vaults to {_SETTINGS_PATH}")
except PermissionError as e: except PermissionError as e:
logger.error(f"Permission denied writing to {_SETTINGS_PATH}: {e}") logger.critical("=" * 60)
logger.error(f"Check that user has write permissions to {_SETTINGS_PATH.parent}") logger.critical(f"ERREUR DE PERMISSION : Impossible d'écrire dans {_SETTINGS_PATH.parent}")
raise logger.critical("Le conteneur n'a pas les droits sur le volume monté dans /app/data.")
logger.critical("FIX : Exécutez sur l'hôte (Linux) : sudo chown -R 1000:1000 /votre/chemin/data")
logger.critical("=" * 60)
raise e
except Exception as e: except Exception as e:
logger.error(f"Failed to save vault settings to {_SETTINGS_PATH}: {e}") logger.error(f"Failed to save vault settings to {_SETTINGS_PATH}: {e}")
logger.error(f"Error type: {type(e).__name__}") logger.error(f"Error type: {type(e).__name__}")