build / Garde-fou (pull_request) Failing after 7s
build / Images Harbor (catalog-sync, Dockerfile.catalog-sync) (pull_request) Skipped
build / Images Harbor (web, Dockerfile) (pull_request) Skipped
build / Garde-fou (push) Failing after 8s
build / Images Harbor (catalog-sync, Dockerfile.catalog-sync) (push) Skipped
build / Images Harbor (web, Dockerfile) (push) Skipped
106 lines
4.5 KiB
Python
106 lines
4.5 KiB
Python
"""Configuration lue depuis l'environnement.
|
|
|
|
Toutes les fonctionnalites ajoutees aux chantiers 3 a 5 sont facultatives :
|
|
sans base de donnees, sans OIDC et sans jeton Gitea, l'application reste
|
|
exactement ce qu'elle etait — un editeur qui genere du CLAPI. C'est ce qui
|
|
permet a n'importe qui de l'auto-heberger en trois lignes.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
import secrets
|
|
|
|
|
|
def _bool(nom: str, defaut: bool = False) -> bool:
|
|
brut = os.environ.get(nom)
|
|
if brut is None:
|
|
return defaut
|
|
return brut.strip().lower() in {"1", "true", "oui", "yes", "on"}
|
|
|
|
|
|
def _int(nom: str, defaut: int) -> int:
|
|
try:
|
|
return int(os.environ.get(nom, defaut))
|
|
except (TypeError, ValueError):
|
|
return defaut
|
|
|
|
|
|
class Config:
|
|
# --- Identite du service ------------------------------------------------
|
|
VERSION = os.environ.get("ENCLUME_VERSION", "dev")
|
|
COMMIT = os.environ.get("ENCLUME_COMMIT", "inconnu")
|
|
URL_PUBLIQUE = os.environ.get("ENCLUME_URL_PUBLIQUE", "").rstrip("/")
|
|
|
|
# --- Sessions -----------------------------------------------------------
|
|
# Sans cle fournie, on en tire une au demarrage : les sessions ne survivent
|
|
# pas a un redemarrage, ce qui est acceptable en developpement et bruyant
|
|
# en production, donc visible.
|
|
SECRET_KEY = os.environ.get("ENCLUME_SECRET_KEY") or secrets.token_hex(32)
|
|
SECRET_KEY_FOURNIE = bool(os.environ.get("ENCLUME_SECRET_KEY"))
|
|
SESSION_COOKIE_NAME = "enclume"
|
|
SESSION_COOKIE_HTTPONLY = True
|
|
SESSION_COOKIE_SAMESITE = "Lax"
|
|
SESSION_COOKIE_SECURE = _bool("ENCLUME_COOKIE_SECURE", True)
|
|
PERMANENT_SESSION_LIFETIME = _int("ENCLUME_SESSION_JOURS", 30) * 86400
|
|
|
|
# --- Base de donnees ----------------------------------------------------
|
|
SQLALCHEMY_DATABASE_URI = os.environ.get("ENCLUME_DATABASE_URL", "")
|
|
SQLALCHEMY_ENGINE_OPTIONS = {"pool_pre_ping": True, "pool_recycle": 1800}
|
|
|
|
# --- Partage ------------------------------------------------------------
|
|
PARTAGE_JOURS = _int("ENCLUME_PARTAGE_JOURS", 90)
|
|
PROJETS_PAR_COMPTE = _int("ENCLUME_PROJETS_PAR_COMPTE", 50)
|
|
|
|
# --- Authentification OIDC (Authentik) ----------------------------------
|
|
OIDC_NOM = os.environ.get("ENCLUME_OIDC_NOM", "Authentik")
|
|
OIDC_METADATA = os.environ.get("ENCLUME_OIDC_METADATA", "")
|
|
OIDC_CLIENT_ID = os.environ.get("ENCLUME_OIDC_CLIENT_ID", "")
|
|
OIDC_CLIENT_SECRET = os.environ.get("ENCLUME_OIDC_CLIENT_SECRET", "")
|
|
OIDC_SCOPES = os.environ.get("ENCLUME_OIDC_SCOPES", "openid email profile")
|
|
# Le groupe qui donne acces a la moderation. Necessite que le fournisseur
|
|
# place la revendication "groups" dans le jeton (mapping de portee dedie
|
|
# cote Authentik).
|
|
ADMIN_GROUPE = os.environ.get("ENCLUME_ADMIN_GROUPE", "enclume-admins")
|
|
ADMIN_COMPTES = [
|
|
c.strip().lower()
|
|
for c in os.environ.get("ENCLUME_ADMIN_COMPTES", "").split(",")
|
|
if c.strip()
|
|
]
|
|
|
|
# --- Depot du catalogue, pour les soumissions ---------------------------
|
|
GITEA_URL = os.environ.get("ENCLUME_GITEA_URL", "").rstrip("/")
|
|
GITEA_TOKEN = os.environ.get("ENCLUME_GITEA_TOKEN", "")
|
|
GITEA_PROPRIETAIRE = os.environ.get("ENCLUME_GITEA_PROPRIETAIRE", "")
|
|
GITEA_DEPOT = os.environ.get("ENCLUME_GITEA_DEPOT", "")
|
|
GITEA_BRANCHE = os.environ.get("ENCLUME_GITEA_BRANCHE", "main")
|
|
GITEA_SOUS_DOSSIER = os.environ.get("ENCLUME_GITEA_SOUS_DOSSIER", "catalog")
|
|
|
|
# --- Limites ------------------------------------------------------------
|
|
TAILLE_MAX_PROJET = _int("ENCLUME_TAILLE_MAX_PROJET", 2 * 1024 * 1024)
|
|
TAILLE_MAX_PACK = _int("ENCLUME_TAILLE_MAX_PACK", 256 * 1024)
|
|
SOUMISSIONS_PAR_JOUR = _int("ENCLUME_SOUMISSIONS_PAR_JOUR", 10)
|
|
|
|
@classmethod
|
|
def base_active(cls) -> bool:
|
|
return bool(cls.SQLALCHEMY_DATABASE_URI)
|
|
|
|
@classmethod
|
|
def oidc_actif(cls) -> bool:
|
|
return bool(cls.OIDC_METADATA and cls.OIDC_CLIENT_ID and cls.OIDC_CLIENT_SECRET)
|
|
|
|
@classmethod
|
|
def gitea_actif(cls) -> bool:
|
|
return bool(cls.GITEA_URL and cls.GITEA_TOKEN and cls.GITEA_PROPRIETAIRE and cls.GITEA_DEPOT)
|
|
|
|
@classmethod
|
|
def etat(cls) -> dict[str, bool]:
|
|
"""Ce que le site sait faire, tel qu'annonce a l'interface."""
|
|
return {
|
|
"comptes": cls.base_active() and cls.oidc_actif(),
|
|
"partage": cls.base_active(),
|
|
"projets_enregistres": cls.base_active() and cls.oidc_actif(),
|
|
"soumissions": cls.base_active() and cls.oidc_actif(),
|
|
"publication_gitea": cls.gitea_actif(),
|
|
}
|