//go:build security // +build security package security import ( "bytes" "encoding/json" "fmt" "net/http" "net/http/httptest" "testing" "github.com/gin-gonic/gin" "github.com/google/uuid" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.uber.org/zap/zaptest" "gorm.io/driver/sqlite" "gorm.io/gorm" "veza-backend-api/internal/core/auth" "veza-backend-api/internal/core/track" "veza-backend-api/internal/database" "veza-backend-api/internal/handlers" "veza-backend-api/internal/models" "veza-backend-api/internal/repositories" "veza-backend-api/internal/services" "veza-backend-api/internal/utils" "veza-backend-api/internal/validators" ) // setupSecurityTestRouter crée un router de test pour les tests de sécurité func setupSecurityTestRouter(t *testing.T) (*gin.Engine, *gorm.DB, uuid.UUID, func()) { gin.SetMode(gin.TestMode) logger := zaptest.NewLogger(t) // Setup in-memory SQLite database db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{}) require.NoError(t, err) db.Exec("PRAGMA foreign_keys = ON") // Auto-migrate models err = db.AutoMigrate( &models.User{}, &models.Track{}, &models.Playlist{}, &models.PlaylistTrack{}, &models.RefreshToken{}, &models.Session{}, &models.Role{}, &models.UserRole{}, &models.Permission{}, ) require.NoError(t, err) dbWrapper := &database.Database{GormDB: db} // Create test user userID := uuid.New() user := &models.User{ ID: userID, Email: "test@example.com", Username: "testuser", PasswordHash: "$2a$10$abcdefghijklmnopqrstuvwxyz1234567890", IsVerified: true, } err = db.Create(user).Error require.NoError(t, err) // Setup services emailValidator := validators.NewEmailValidator(db) passwordValidator := validators.NewPasswordValidator() passwordService := services.NewPasswordService(dbWrapper, logger) jwtService, err := services.NewJWTService("", "", "test-secret-key-must-be-32-chars-long", "test-issuer", "test-audience") require.NoError(t, err) refreshTokenService := services.NewRefreshTokenService(db) emailVerificationService := services.NewEmailVerificationService(dbWrapper, logger) passwordResetService := services.NewPasswordResetService(dbWrapper, logger) emailService := services.NewEmailService(dbWrapper, logger) authService := auth.NewAuthService( db, emailValidator, passwordValidator, passwordService, jwtService, refreshTokenService, emailVerificationService, passwordResetService, emailService, nil, nil, logger, ) uploadDir := t.TempDir() trackService := track.NewTrackService(db, logger, uploadDir) trackUploadService := services.NewTrackUploadService(db, logger) chunkService := services.NewTrackChunkService(t.TempDir(), nil, logger) likeService := services.NewTrackLikeService(db, logger) streamService := services.NewStreamService("http://localhost:8082", logger) trackHandler := track.NewTrackHandler(trackService, trackUploadService, chunkService, likeService, streamService) playlistRepo := repositories.NewPlaylistRepository(db) playlistTrackRepo := repositories.NewPlaylistTrackRepository(db) playlistCollaboratorRepo := repositories.NewPlaylistCollaboratorRepository(db) userRepo := repositories.NewGormUserRepository(db) playlistService := services.NewPlaylistService(playlistRepo, playlistTrackRepo, playlistCollaboratorRepo, userRepo, logger) playlistHandler := handlers.NewPlaylistHandler(playlistService, db, logger) userService := services.NewUserServiceWithDB(userRepo, db) profileHandler := handlers.NewProfileHandler(userService, logger) // Create router router := gin.New() // Mock auth middleware - set user_id in context router.Use(func(c *gin.Context) { c.Set("user_id", userID) c.Next() }) // Auth routes authGroup := router.Group("/api/v1/auth") { authGroup.POST("/login", handlers.Login(authService, services.NewSessionService(dbWrapper, logger), services.NewTwoFactorService(dbWrapper, logger), logger)) authGroup.POST("/register", handlers.Register(authService, logger)) } // Track routes tracksGroup := router.Group("/api/v1/tracks") { tracksGroup.GET("", trackHandler.ListTracks) tracksGroup.GET("/:id", trackHandler.GetTrack) tracksGroup.POST("", trackHandler.UploadTrack) tracksGroup.PUT("/:id", trackHandler.UpdateTrack) tracksGroup.DELETE("/:id", trackHandler.DeleteTrack) } // Playlist routes playlistsGroup := router.Group("/api/v1/playlists") { playlistsGroup.GET("", playlistHandler.GetPlaylists) playlistsGroup.POST("", playlistHandler.CreatePlaylist) playlistsGroup.GET("/:id", playlistHandler.GetPlaylist) playlistsGroup.PUT("/:id", playlistHandler.UpdatePlaylist) playlistsGroup.DELETE("/:id", playlistHandler.DeletePlaylist) } // User routes usersGroup := router.Group("/api/v1/users") { usersGroup.GET("", profileHandler.ListUsers) usersGroup.GET("/:id", profileHandler.GetProfile) usersGroup.PUT("/:id", profileHandler.UpdateProfile) } cleanup := func() { // Cleanup handled by t.TempDir() } return router, db, userID, cleanup } // SQL Injection Test Payloads var sqlInjectionPayloads = []string{ "' OR '1'='1", "' OR '1'='1' --", "' OR '1'='1' /*", "admin'--", "admin'/*", "' UNION SELECT NULL--", "' UNION SELECT * FROM users--", "1' OR '1'='1", "1' AND '1'='1", "'; DROP TABLE users; --", "1'; DROP TABLE users; --", "' OR 1=1--", "' OR 'a'='a", "') OR ('a'='a", "1' OR '1'='1", "admin' OR '1'='1", "' OR 1=1#", "' OR 1=1/*", "') OR ('1'='1", "1' OR '1'='1'--", "1' OR '1'='1'/*", "1' OR '1'='1'#", "' OR 'x'='x", "' OR 'x'='x'--", "' OR 'x'='x'/*", "' OR 'x'='x'#", "') OR ('x'='x", "') OR ('x'='x'--", "') OR ('x'='x'/*", "') OR ('x'='x'#", "1' OR '1'='1", "1' OR '1'='1'--", "1' OR '1'='1'/*", "1' OR '1'='1'#", "' OR 1=1", "' OR 1=1--", "' OR 1=1/*", "' OR 1=1#", "1' OR 1=1", "1' OR 1=1--", "1' OR 1=1/*", "1' OR 1=1#", } // XSS Test Payloads var xssPayloads = []string{ "", "", "", "", "