2026-08-14 18:02:25 +02:00
|
|
|
"""Configuration Flask Application - GMAO Collège"""
|
|
|
|
|
import os
|
|
|
|
|
from datetime import timedelta
|
|
|
|
|
|
|
|
|
|
class Config:
|
|
|
|
|
"""Configuration de base."""
|
|
|
|
|
SECRET_KEY = os.environ.get('SECRET_KEY', 'change-me-in-production-2025')
|
|
|
|
|
# MariaDB obligatoire, pas de fallback SQLite
|
|
|
|
|
SQLALCHEMY_DATABASE_URI = os.environ.get(
|
|
|
|
|
'DATABASE_URL',
|
|
|
|
|
'mysql+pymysql://gmao:***@/gmao_db?unix_socket=/var/run/mysqld/mysqld.sock&charset=utf8mb4'
|
|
|
|
|
)
|
|
|
|
|
SQLALCHEMY_TRACK_MODIFICATIONS = False
|
|
|
|
|
SQLALCHEMY_ECHO = os.environ.get('FLASK_DEBUG', '0') == '1'
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
def init_app(cls, app):
|
|
|
|
|
database_uri = app.config.get('SQLALCHEMY_DATABASE_URI', '')
|
|
|
|
|
if 'sqlite' in database_uri.lower():
|
|
|
|
|
raise RuntimeError('SQLite is not allowed; configure DATABASE_URL for MariaDB')
|
|
|
|
|
|
|
|
|
|
secret_key = str(app.config.get('SECRET_KEY', ''))
|
|
|
|
|
normalized_key = secret_key.strip().lower()
|
|
|
|
|
insecure_markers = ('change-me', 'change_me', 'replace-me', 'remplacer')
|
|
|
|
|
if len(secret_key) < 32 or any(
|
|
|
|
|
marker in normalized_key for marker in insecure_markers
|
|
|
|
|
):
|
|
|
|
|
raise RuntimeError(
|
|
|
|
|
'SECRET_KEY is missing or insecure; configure a strong, unique value'
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
# Configuration de session
|
|
|
|
|
PERMANENT_SESSION_LIFETIME = timedelta(hours=12)
|
|
|
|
|
SESSION_COOKIE_SECURE = os.environ.get('SESSION_COOKIE_SECURE', '0') == '1'
|
|
|
|
|
SESSION_COOKIE_HTTPONLY = True
|
|
|
|
|
SESSION_COOKIE_SAMESITE = 'Lax'
|
|
|
|
|
|
|
|
|
|
# Uploads
|
|
|
|
|
UPLOAD_FOLDER = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'uploads')
|
|
|
|
|
MAX_CONTENT_LENGTH = 50 * 1024 * 1024 # 50 MB max
|
|
|
|
|
|
|
|
|
|
# Pagination
|
|
|
|
|
ITEMS_PER_PAGE = 20
|
|
|
|
|
|
|
|
|
|
# CSRF Protection
|
|
|
|
|
WTF_CSRF_ENABLED = True
|
|
|
|
|
WTF_CSRF_TIME_LIMIT = None
|
|
|
|
|
|
|
|
|
|
class DevelopmentConfig(Config):
|
|
|
|
|
"""Configuration développement."""
|
|
|
|
|
DEBUG = True
|
2026-08-14 20:55:47 +02:00
|
|
|
# La machine de développement est accessible à distance : les protections
|
|
|
|
|
# navigateur doivent y être identiques à celles de la production.
|
|
|
|
|
WTF_CSRF_ENABLED = True
|
2026-08-14 18:02:25 +02:00
|
|
|
basedir = os.path.abspath(os.path.dirname(__file__))
|
|
|
|
|
# MariaDB obligatoire
|
|
|
|
|
SQLALCHEMY_DATABASE_URI = os.environ.get(
|
|
|
|
|
'DATABASE_URL',
|
|
|
|
|
'mysql+pymysql://gmao:***@/gmao_db?unix_socket=/var/run/mysqld/mysqld.sock&charset=utf8mb4'
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
class ProductionConfig(Config):
|
|
|
|
|
"""Configuration production."""
|
|
|
|
|
DEBUG = False
|
|
|
|
|
SESSION_COOKIE_SECURE = True
|
|
|
|
|
|
|
|
|
|
class TestingConfig(Config):
|
|
|
|
|
"""Configuration tests."""
|
|
|
|
|
TESTING = True
|
|
|
|
|
# Tests doivent aussi utiliser MariaDB via socket Unix
|
|
|
|
|
SQLALCHEMY_DATABASE_URI = os.environ.get(
|
|
|
|
|
'DATABASE_URL',
|
|
|
|
|
'mysql+pymysql://gmao:***@/gmao_test_db?unix_socket=/var/run/mysqld/mysqld.sock&charset=utf8mb4'
|
|
|
|
|
)
|
|
|
|
|
WTF_CSRF_ENABLED = False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
config = {
|
|
|
|
|
'development': DevelopmentConfig,
|
|
|
|
|
'production': ProductionConfig,
|
|
|
|
|
'testing': TestingConfig,
|
|
|
|
|
'default': DevelopmentConfig
|
|
|
|
|
}
|