main.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. package main
  2. import (
  3. "log"
  4. "net/http"
  5. "strings"
  6. "aws-sts-mock/internal/config"
  7. "aws-sts-mock/internal/handler"
  8. "aws-sts-mock/internal/kvdb"
  9. "aws-sts-mock/internal/middleware"
  10. "aws-sts-mock/internal/service"
  11. "aws-sts-mock/internal/storage"
  12. "aws-sts-mock/pkg/sigv4"
  13. )
  14. func main() {
  15. // Load configuration
  16. cfg := config.Load()
  17. // Initialize BoltDB
  18. log.Println("Initializing BoltDB...")
  19. db, err := kvdb.NewBoltKVDB(cfg.DBPath)
  20. if err != nil {
  21. log.Fatalf("Failed to initialize BoltDB: %v", err)
  22. }
  23. defer db.Close()
  24. // Initialize default users
  25. log.Println("Initializing default users...")
  26. if err := db.InitializeDefaultUsers(); err != nil {
  27. log.Fatalf("Failed to initialize default users: %v", err)
  28. }
  29. log.Println("Default users initialized:")
  30. log.Println(" - User 1: AKIAIOSFODNN7EXAMPLE (Account: 123456789012)")
  31. log.Println(" - User 2: AKIAJSIE27KKMHXI3BJQ (Account: 987654321098)")
  32. // Initialize user-aware storage
  33. userStorage, err := storage.NewUserAwareStorage(cfg.UploadsDir)
  34. if err != nil {
  35. log.Fatalf("Failed to initialize storage: %v", err)
  36. }
  37. // Initialize services
  38. s3Service := service.NewS3Service(userStorage, db)
  39. stsService := service.NewSTSService()
  40. // Initialize handlers
  41. s3Handler := handler.NewS3Handler(s3Service)
  42. stsHandler := handler.NewSTSHandler(stsService)
  43. healthHandler := handler.NewHealthHandler()
  44. publicViewHandler := handler.NewPublicViewHandler(userStorage, db)
  45. // Initialize middleware
  46. sigv4Middleware := sigv4.ValidateSigV4Middleware
  47. userValidationMiddleware := middleware.UserValidationMiddleware(db)
  48. // Setup routes
  49. mux := http.NewServeMux()
  50. // Health check endpoint - no authentication
  51. mux.HandleFunc("/health", healthHandler.Handle)
  52. // Main endpoint - handles both authenticated and public requests
  53. mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
  54. // Check if Authorization header exists (indicates authenticated request)
  55. authHeader := r.Header.Get("Authorization")
  56. if authHeader != "" {
  57. // Authenticated request - determine if STS or S3 based on Content-Type
  58. // STS requests use application/x-www-form-urlencoded
  59. // S3 requests typically don't, or use application/xml
  60. contentType := r.Header.Get("Content-Type")
  61. // If it's a POST with form-urlencoded content type, it's likely STS
  62. if r.Method == "POST" && strings.Contains(contentType, "application/x-www-form-urlencoded") {
  63. // STS request
  64. sigv4Handler := sigv4Middleware(func(w http.ResponseWriter, r *http.Request) {
  65. userValidationMiddleware(http.HandlerFunc(stsHandler.Handle)).ServeHTTP(w, r)
  66. })
  67. sigv4Handler(w, r)
  68. } else {
  69. // S3 request
  70. sigv4Handler := sigv4Middleware(func(w http.ResponseWriter, r *http.Request) {
  71. userValidationMiddleware(http.HandlerFunc(s3Handler.Handle)).ServeHTTP(w, r)
  72. })
  73. sigv4Handler(w, r)
  74. }
  75. } else {
  76. // Unauthenticated request - try public viewing
  77. publicViewHandler.Handle(w, r)
  78. }
  79. })
  80. // Start server
  81. log.Printf("========================================")
  82. log.Printf("AWS STS/S3 Mock Server with BoltDB")
  83. log.Printf("========================================")
  84. log.Printf("Server running on port: %s", cfg.Port)
  85. log.Printf("Database: %s", cfg.DBPath)
  86. log.Printf("Uploads directory: %s", cfg.UploadsDir)
  87. log.Printf("User isolation: ENABLED")
  88. log.Printf("Folder structure: ./uploads/{accountID}/{bucketID}/")
  89. log.Printf("")
  90. log.Printf("Endpoints:")
  91. log.Printf(" - AWS S3/STS (authenticated): http://localhost:%s/", cfg.Port)
  92. log.Printf(" - Public View (unauthenticated): http://localhost:%s/{bucketName}/{objectKey}", cfg.Port)
  93. log.Printf(" - Health Check: http://localhost:%s/health", cfg.Port)
  94. log.Printf("========================================")
  95. if err := http.ListenAndServe(":"+cfg.Port, mux); err != nil {
  96. log.Fatal(err)
  97. }
  98. }