chore: refacto
This commit is contained in:
@@ -5,13 +5,17 @@ import (
|
||||
"fmt"
|
||||
"gestion/models"
|
||||
"log"
|
||||
"slices"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// ============================================
|
||||
// VALIDATION HELPERS
|
||||
// ============================================
|
||||
type MediaInterface interface {
|
||||
GetProductID() int
|
||||
GetType() string
|
||||
GetURL() string
|
||||
SetID(int)
|
||||
}
|
||||
|
||||
// validateMediaID vérifie la validité d'un ID média
|
||||
func validateMediaID(mediaID int) error {
|
||||
@@ -40,13 +44,9 @@ func validateMediaType(mediaType string) error {
|
||||
validTypes := []string{"image", "video"}
|
||||
|
||||
mediaType = strings.ToLower(strings.TrimSpace(mediaType))
|
||||
|
||||
for _, valid := range validTypes {
|
||||
if mediaType == valid {
|
||||
return nil
|
||||
}
|
||||
if slices.Contains(validTypes, mediaType) {
|
||||
return nil
|
||||
}
|
||||
|
||||
return fmt.Errorf("type de média invalide: %s (autorisé: image, video)", mediaType)
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ func validateMediaURL(url string) error {
|
||||
}
|
||||
|
||||
// ✅ PROTECTION PATH TRAVERSAL
|
||||
if strings.Contains(url, "..") {
|
||||
if strings.Contains(url, "..") || strings.Contains(url, "...") || strings.Contains(url, "..//") {
|
||||
return fmt.Errorf("path traversal détecté dans l'URL")
|
||||
}
|
||||
|
||||
@@ -88,16 +88,9 @@ func validateMediaURL(url string) error {
|
||||
// CREATE MEDIA - VERSION SÉCURISÉE
|
||||
// ============================================
|
||||
|
||||
func (db *Database) CreateMedia(media interface{}) error {
|
||||
func (db *Database) CreateMedia(media any) error {
|
||||
log.Printf("🔒 [CreateMedia] START - Type: %T", media)
|
||||
|
||||
type MediaInterface interface {
|
||||
GetProductID() int
|
||||
GetType() string
|
||||
GetURL() string
|
||||
SetID(int)
|
||||
}
|
||||
|
||||
// ✅ TYPE ASSERTION SÉCURISÉE
|
||||
m, ok := media.(MediaInterface)
|
||||
if !ok {
|
||||
@@ -115,32 +108,33 @@ func (db *Database) CreateMedia(media interface{}) error {
|
||||
return fmt.Errorf("type de média invalide")
|
||||
}
|
||||
|
||||
// ✅ VALIDATION COMPLÈTE
|
||||
productID := m.GetProductID()
|
||||
mediaType := m.GetType()
|
||||
mediaURL := m.GetURL()
|
||||
|
||||
log.Printf("📋 [CreateMedia] ProductID=%d, Type=%s, URL=%s", productID, mediaType, mediaURL)
|
||||
|
||||
// Valider le product ID
|
||||
if err := validateProductID(productID); err != nil {
|
||||
log.Printf("❌ [CreateMedia] %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Valider le type
|
||||
if err := validateMediaType(mediaType); err != nil {
|
||||
log.Printf("❌ [CreateMedia] %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Valider l'URL
|
||||
if err := validateMediaURL(mediaURL); err != nil {
|
||||
log.Printf("❌ [CreateMedia] %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// ✅ VÉRIFIER QUE LE PRODUIT EXISTE
|
||||
if err := db.InsertMedia(m, productID, mediaURL, mediaType); err != nil {
|
||||
log.Printf("❌ [InsertMedia] %v", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) InsertMedia(m any, productID int, mediaURL any, mediaType string) error {
|
||||
var exists bool
|
||||
checkQuery := `SELECT EXISTS(SELECT 1 FROM products WHERE id = $1)`
|
||||
err := db.QueryRow(checkQuery, productID).Scan(&exists)
|
||||
@@ -153,7 +147,6 @@ func (db *Database) CreateMedia(media interface{}) error {
|
||||
return fmt.Errorf("produit %d n'existe pas", productID)
|
||||
}
|
||||
|
||||
// ✅ INSÉRER LE MÉDIA
|
||||
query := `INSERT INTO media (product_id, url, type, created_at)
|
||||
VALUES ($1, $2, $3, $4) RETURNING id`
|
||||
|
||||
@@ -165,10 +158,10 @@ func (db *Database) CreateMedia(media interface{}) error {
|
||||
log.Printf("❌ [CreateMedia] Erreur INSERT: %v", err)
|
||||
return fmt.Errorf("erreur création média: %w", err)
|
||||
}
|
||||
|
||||
m.SetID(mediaID)
|
||||
if mi, ok := m.(MediaInterface); ok {
|
||||
mi.SetID(mediaID)
|
||||
}
|
||||
log.Printf("✅ [CreateMedia] Média créé: ID=%d, Type=%s", mediaID, mediaType)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -274,9 +267,6 @@ func (db *Database) GetMediaByProductID(productID int) ([]models.Media, error) {
|
||||
// ============================================
|
||||
|
||||
func (db *Database) UpdateMedia(media *models.Media) error {
|
||||
log.Printf("🔄 [UpdateMedia] START - ID=%d", media.ID)
|
||||
|
||||
// ✅ VALIDATION
|
||||
if media == nil {
|
||||
return fmt.Errorf("média nil")
|
||||
}
|
||||
@@ -297,16 +287,9 @@ func (db *Database) UpdateMedia(media *models.Media) error {
|
||||
}
|
||||
|
||||
// ✅ VÉRIFIER QUE LE MÉDIA EXISTE
|
||||
var exists bool
|
||||
checkQuery := `SELECT EXISTS(SELECT 1 FROM media WHERE id = $1)`
|
||||
err := db.QueryRow(checkQuery, media.ID).Scan(&exists)
|
||||
if err != nil {
|
||||
log.Printf("❌ [UpdateMedia] Erreur vérification: %v", err)
|
||||
return fmt.Errorf("erreur vérification média: %w", err)
|
||||
}
|
||||
if !exists {
|
||||
log.Printf("❌ [UpdateMedia] Média %d n'existe pas", media.ID)
|
||||
return fmt.Errorf("média %d non trouvé", media.ID)
|
||||
if err := db.CheckMediaExists(media); err != nil {
|
||||
log.Printf("❌ [UpdateMedia] %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// ✅ UPDATE
|
||||
@@ -331,33 +314,33 @@ func (db *Database) UpdateMedia(media *models.Media) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// DELETE MEDIA - VERSION SÉCURISÉE
|
||||
// ============================================
|
||||
func (db *Database) CheckMediaExists(media *models.Media) error {
|
||||
var exists bool
|
||||
checkQuery := `SELECT EXISTS(SELECT 1 FROM media WHERE id = $1)`
|
||||
err := db.QueryRow(checkQuery, media.ID).Scan(&exists)
|
||||
if err != nil {
|
||||
log.Printf("❌ [UpdateMedia] Erreur vérification: %v", err)
|
||||
return fmt.Errorf("erreur vérification média: %w", err)
|
||||
}
|
||||
if !exists {
|
||||
log.Printf("❌ [UpdateMedia] Média %d n'existe pas", media.ID)
|
||||
return fmt.Errorf("média %d non trouvé", media.ID)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) DeleteMedia(mediaID int) error {
|
||||
log.Printf("🗑️ [DeleteMedia] START - ID=%d", mediaID)
|
||||
|
||||
// ✅ VALIDATION
|
||||
if err := validateMediaID(mediaID); err != nil {
|
||||
log.Printf("❌ [DeleteMedia] %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// ✅ VÉRIFIER QUE LE MÉDIA EXISTE
|
||||
var exists bool
|
||||
checkQuery := `SELECT EXISTS(SELECT 1 FROM media WHERE id = $1)`
|
||||
err := db.QueryRow(checkQuery, mediaID).Scan(&exists)
|
||||
if err != nil {
|
||||
log.Printf("❌ [DeleteMedia] Erreur vérification: %v", err)
|
||||
return fmt.Errorf("erreur vérification média: %w", err)
|
||||
}
|
||||
if !exists {
|
||||
log.Printf("❌ [DeleteMedia] Média %d n'existe pas", mediaID)
|
||||
return fmt.Errorf("média %d non trouvé", mediaID)
|
||||
media := models.Media{ID: mediaID}
|
||||
if err := db.CheckMediaExists(&media); err != nil {
|
||||
log.Printf("❌ [DeleteMedia] %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// ✅ DELETE
|
||||
query := `DELETE FROM media WHERE id = $1`
|
||||
|
||||
result, err := db.Exec(query, mediaID)
|
||||
@@ -377,20 +360,14 @@ func (db *Database) DeleteMedia(mediaID int) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// DELETE MEDIA BY PRODUCT ID - VERSION SÉCURISÉE
|
||||
// ============================================
|
||||
|
||||
func (db *Database) DeleteMediaByProductID(productID int) error {
|
||||
log.Printf("🗑️ [DeleteMediaByProductID] START - ProductID=%d", productID)
|
||||
|
||||
// ✅ VALIDATION
|
||||
if err := validateProductID(productID); err != nil {
|
||||
log.Printf("❌ [DeleteMediaByProductID] %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// ✅ VÉRIFIER QUE LE PRODUIT EXISTE
|
||||
var exists bool
|
||||
checkQuery := `SELECT EXISTS(SELECT 1 FROM products WHERE id = $1)`
|
||||
err := db.QueryRow(checkQuery, productID).Scan(&exists)
|
||||
@@ -403,7 +380,6 @@ func (db *Database) DeleteMediaByProductID(productID int) error {
|
||||
return fmt.Errorf("produit %d non trouvé", productID)
|
||||
}
|
||||
|
||||
// ✅ DELETE
|
||||
query := `DELETE FROM media WHERE product_id = $1`
|
||||
|
||||
result, err := db.Exec(query, productID)
|
||||
|
||||
Reference in New Issue
Block a user