288 lines
10 KiB
Python
288 lines
10 KiB
Python
from fastapi import APIRouter, Depends, HTTPException, status
|
|
from sqlalchemy.orm import Session
|
|
from typing import List, Dict, Any
|
|
from datetime import datetime
|
|
from config.database import get_db
|
|
from models.settings import SystemSettings
|
|
from models.user import User
|
|
from schemas.settings import (
|
|
SystemSettingCreate,
|
|
SystemSettingUpdate,
|
|
SystemSettingResponse,
|
|
SettingsCategoryResponse,
|
|
UploadLimitsResponse
|
|
)
|
|
from utils.security import get_admin_user
|
|
|
|
router = APIRouter()
|
|
|
|
@router.get("/", response_model=List[SystemSettingResponse])
|
|
async def get_all_settings(
|
|
db: Session = Depends(get_db),
|
|
current_user: User = Depends(get_admin_user)
|
|
):
|
|
"""Get all system settings (admin only)."""
|
|
settings = db.query(SystemSettings).order_by(SystemSettings.category, SystemSettings.key).all()
|
|
return settings
|
|
|
|
@router.get("/category/{category}", response_model=SettingsCategoryResponse)
|
|
async def get_settings_by_category(
|
|
category: str,
|
|
db: Session = Depends(get_db),
|
|
current_user: User = Depends(get_admin_user)
|
|
):
|
|
"""Get settings by category (admin only)."""
|
|
settings = db.query(SystemSettings).filter(SystemSettings.category == category).all()
|
|
return SettingsCategoryResponse(category=category, settings=settings)
|
|
|
|
@router.get("/upload-limits", response_model=UploadLimitsResponse)
|
|
async def get_upload_limits(
|
|
db: Session = Depends(get_db),
|
|
current_user: User = Depends(get_admin_user)
|
|
):
|
|
"""Get current upload limits configuration."""
|
|
settings = db.query(SystemSettings).filter(
|
|
SystemSettings.category == "uploads"
|
|
).all()
|
|
|
|
# Convertir en dictionnaire pour faciliter l'accès
|
|
settings_dict = {s.key: s.value for s in settings}
|
|
|
|
# Debug: afficher les valeurs récupérées
|
|
print(f"DEBUG - Upload limits from DB: {settings_dict}")
|
|
|
|
return UploadLimitsResponse(
|
|
max_album_size_mb=int(settings_dict.get("max_album_size_mb", "100")),
|
|
max_vlog_size_mb=int(settings_dict.get("max_vlog_size_mb", "500")),
|
|
max_image_size_mb=int(settings_dict.get("max_image_size_mb", "10")),
|
|
max_video_size_mb=int(settings_dict.get("max_video_size_mb", "100")),
|
|
max_media_per_album=int(settings_dict.get("max_media_per_album", "50")),
|
|
allowed_image_types=settings_dict.get("allowed_image_types", "image/jpeg,image/png,image/gif,image/webp").split(","),
|
|
allowed_video_types=settings_dict.get("allowed_video_types", "video/mp4,video/mpeg,video/quicktime,video/webm").split(",")
|
|
)
|
|
|
|
@router.post("/", response_model=SystemSettingResponse)
|
|
async def create_setting(
|
|
setting_data: SystemSettingCreate,
|
|
db: Session = Depends(get_db),
|
|
current_user: User = Depends(get_admin_user)
|
|
):
|
|
"""Create a new system setting (admin only)."""
|
|
# Vérifier si la clé existe déjà
|
|
existing = db.query(SystemSettings).filter(SystemSettings.key == setting_data.key).first()
|
|
if existing:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_400_BAD_REQUEST,
|
|
detail="Setting key already exists"
|
|
)
|
|
|
|
setting = SystemSettings(**setting_data.dict())
|
|
db.add(setting)
|
|
db.commit()
|
|
db.refresh(setting)
|
|
return setting
|
|
|
|
@router.put("/{setting_key}", response_model=SystemSettingResponse)
|
|
async def update_setting(
|
|
setting_key: str,
|
|
setting_update: SystemSettingUpdate,
|
|
db: Session = Depends(get_db),
|
|
current_user: User = Depends(get_admin_user)
|
|
):
|
|
"""Update a system setting (admin only)."""
|
|
setting = db.query(SystemSettings).filter(SystemSettings.key == setting_key).first()
|
|
if not setting:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_404_NOT_FOUND,
|
|
detail="Setting not found"
|
|
)
|
|
|
|
if not setting.is_editable:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_400_BAD_REQUEST,
|
|
detail="This setting cannot be modified"
|
|
)
|
|
|
|
# Validation des valeurs selon le type de paramètre
|
|
if setting_key.startswith("max_") and setting_key.endswith("_mb"):
|
|
try:
|
|
size_mb = int(setting_update.value)
|
|
if size_mb <= 0 or size_mb > 10000: # Max 10GB
|
|
raise ValueError("Size must be between 1 and 10000 MB")
|
|
except ValueError as e:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_400_BAD_REQUEST,
|
|
detail=f"Invalid size value: {str(e)}"
|
|
)
|
|
|
|
setting.value = setting_update.value
|
|
setting.updated_at = datetime.utcnow()
|
|
db.commit()
|
|
db.refresh(setting)
|
|
return setting
|
|
|
|
@router.delete("/{setting_key}")
|
|
async def delete_setting(
|
|
setting_key: str,
|
|
db: Session = Depends(get_db),
|
|
current_user: User = Depends(get_admin_user)
|
|
):
|
|
"""Delete a system setting (admin only)."""
|
|
setting = db.query(SystemSettings).filter(SystemSettings.key == setting_key).first()
|
|
if not setting:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_404_NOT_FOUND,
|
|
detail="Setting not found"
|
|
)
|
|
|
|
if not setting.is_editable:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_400_BAD_REQUEST,
|
|
detail="This setting cannot be deleted"
|
|
)
|
|
|
|
db.delete(setting)
|
|
db.commit()
|
|
return {"message": "Setting deleted successfully"}
|
|
|
|
@router.get("/test-upload-limits")
|
|
async def test_upload_limits(
|
|
db: Session = Depends(get_db),
|
|
current_user: User = Depends(get_admin_user)
|
|
):
|
|
"""Test endpoint to verify upload limits are working correctly."""
|
|
from utils.settings_service import SettingsService
|
|
|
|
# Test image upload limit
|
|
image_limit = SettingsService.get_max_upload_size(db, "image/jpeg")
|
|
image_limit_mb = image_limit // (1024 * 1024)
|
|
|
|
# Test video upload limit
|
|
video_limit = SettingsService.get_max_upload_size(db, "video/mp4")
|
|
video_limit_mb = video_limit // (1024 * 1024)
|
|
|
|
# Test file type validation
|
|
image_allowed = SettingsService.is_file_type_allowed(db, "image/jpeg")
|
|
video_allowed = SettingsService.is_file_type_allowed(db, "video/mp4")
|
|
invalid_allowed = SettingsService.is_file_type_allowed(db, "application/pdf")
|
|
|
|
return {
|
|
"image_upload_limit": {
|
|
"bytes": image_limit,
|
|
"mb": image_limit_mb,
|
|
"content_type": "image/jpeg"
|
|
},
|
|
"video_upload_limit": {
|
|
"bytes": video_limit,
|
|
"mb": video_limit_mb,
|
|
"content_type": "video/mp4"
|
|
},
|
|
"file_type_validation": {
|
|
"image_jpeg_allowed": image_allowed,
|
|
"video_mp4_allowed": video_allowed,
|
|
"pdf_not_allowed": not invalid_allowed
|
|
},
|
|
"message": "Upload limits test completed"
|
|
}
|
|
|
|
@router.get("/public/registration-status")
|
|
async def get_public_registration_status(
|
|
db: Session = Depends(get_db)
|
|
):
|
|
"""Get registration status without authentication (public endpoint)."""
|
|
from utils.settings_service import SettingsService
|
|
|
|
try:
|
|
enable_registration = SettingsService.get_setting(db, "enable_registration", True)
|
|
max_users = SettingsService.get_setting(db, "max_users", 50)
|
|
current_users_count = db.query(User).count()
|
|
|
|
return {
|
|
"registration_enabled": enable_registration,
|
|
"max_users": max_users,
|
|
"current_users_count": current_users_count,
|
|
"can_register": enable_registration and current_users_count < max_users
|
|
}
|
|
except Exception as e:
|
|
# En cas d'erreur, on retourne des valeurs par défaut sécurisées
|
|
return {
|
|
"registration_enabled": False,
|
|
"max_users": 50,
|
|
"current_users_count": 0,
|
|
"can_register": False
|
|
}
|
|
|
|
@router.post("/initialize-defaults")
|
|
async def initialize_default_settings(
|
|
db: Session = Depends(get_db),
|
|
current_user: User = Depends(get_admin_user)
|
|
):
|
|
"""Initialize default system settings (admin only)."""
|
|
default_settings = [
|
|
{
|
|
"key": "max_album_size_mb",
|
|
"value": "100",
|
|
"description": "Taille maximale des albums en MB",
|
|
"category": "uploads"
|
|
},
|
|
{
|
|
"key": "max_vlog_size_mb",
|
|
"value": "500",
|
|
"description": "Taille maximale des vlogs en MB",
|
|
"category": "uploads"
|
|
},
|
|
{
|
|
"key": "max_image_size_mb",
|
|
"value": "10",
|
|
"description": "Taille maximale des images en MB",
|
|
"category": "uploads"
|
|
},
|
|
{
|
|
"key": "max_video_size_mb",
|
|
"value": "100",
|
|
"description": "Taille maximale des vidéos en MB",
|
|
"category": "uploads"
|
|
},
|
|
{
|
|
"key": "max_media_per_album",
|
|
"value": "50",
|
|
"description": "Nombre maximum de médias par album",
|
|
"category": "uploads"
|
|
},
|
|
{
|
|
"key": "allowed_image_types",
|
|
"value": "image/jpeg,image/png,image/gif,image/webp",
|
|
"description": "Types d'images autorisés (séparés par des virgules)",
|
|
"category": "uploads"
|
|
},
|
|
{
|
|
"key": "allowed_video_types",
|
|
"value": "video/mp4,video/mpeg,video/quicktime,video/webm",
|
|
"description": "Types de vidéos autorisés (séparés par des virgules)",
|
|
"category": "uploads"
|
|
},
|
|
{
|
|
"key": "max_users",
|
|
"value": "50",
|
|
"description": "Nombre maximum d'utilisateurs",
|
|
"category": "general"
|
|
},
|
|
{
|
|
"key": "enable_registration",
|
|
"value": "true",
|
|
"description": "Autoriser les nouvelles inscriptions",
|
|
"category": "general"
|
|
}
|
|
]
|
|
|
|
created_count = 0
|
|
for setting_data in default_settings:
|
|
existing = db.query(SystemSettings).filter(SystemSettings.key == setting_data["key"]).first()
|
|
if not existing:
|
|
setting = SystemSettings(**setting_data)
|
|
db.add(setting)
|
|
created_count += 1
|
|
|
|
db.commit()
|
|
return {"message": f"{created_count} default settings created"}
|