Files
atahango/main.go
Beyhan Oğur bbbf76b184 first commit
2026-04-26 21:35:24 +03:00

205 lines
6.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package main
import (
"fmt"
"log"
"os"
"gauth-central/api/middlewares"
"gauth-central/api/routes"
"gauth-central/config"
"gauth-central/internal/database"
"gauth-central/internal/models"
"gauth-central/internal/services"
"gauth-central/pkg/utils"
"github.com/gin-gonic/gin"
"github.com/gorilla/sessions"
"github.com/markbates/goth"
"github.com/markbates/goth/gothic"
"github.com/markbates/goth/providers/github"
"github.com/markbates/goth/providers/google"
)
// @title GAuth-Central API
// @version 1.0
// @description Centralized Authentication Service
// @BasePath /v1
// @securityDefinitions.apikey ApiKeyAuth
// @in header
// @name Authorization
func main() {
// 1. Load Config
config.LoadConfig()
// 2. Setup Database
database.ConnectDB()
database.Migrate()
// Check for seed-admin command
if len(os.Args) > 1 && os.Args[1] == "seed-admin" {
fmt.Println("Seeding default admin user...")
database.SeedDefaultAdmin()
fmt.Println("Admin seeding completed.")
return
}
// Check for add-cors command
if len(os.Args) > 2 && os.Args[1] == "add-cors" {
origin := os.Args[2]
fmt.Printf("Adding CORS origin: %s\n", origin)
settingsService := services.NewSettingsService()
err := settingsService.CreateCorsWhitelist(&models.CorsWhitelist{
Origin: origin,
Description: "Added via CLI",
IsActive: true,
CreatedBy: "system",
})
if err != nil {
if err == services.ErrCorsOriginExists {
fmt.Printf("Origin already exists: %s\n", origin)
} else {
log.Fatalf("Failed to add CORS origin: %v", err)
}
} else {
fmt.Println("Successfully added CORS origin.")
}
return
}
fmt.Println(`
___ __ __ ___ ___ _ __ ___ _ _ ___
| _ )| | / \| \ | _ ) / \| |/ / | __|| \| || \
| _ \| |_| () | |) || _ \| - | ' < | _| | . || |) |
|___/|____\__/|___/ |___/|_| |_|_|\_\ |___||_|\_||___/
`)
fmt.Println(" Go Backend | v1.0.0 | " + utils.ColorGreen + "Running" + utils.ColorReset)
fmt.Println()
// 3. Setup Redis
database.ConnectRedis()
if err := database.FlushAll(); err != nil {
log.Printf("Warning: Failed to flush Redis cache: %v", err)
}
// 4. Setup OAuth Providers
setupProviders()
// 5. Setup Services
settingsService := services.NewSettingsService()
// Display CORS configuration
displayCorsConfiguration(settingsService)
// 6. Setup Router
r := gin.New()
r.Use(gin.Recovery())
r.Use(gin.Logger())
// Dynamic CORS Middleware (uses database whitelist/blacklist)
r.Use(middlewares.DynamicCorsMiddleware(settingsService))
// Silence trusted proxy warning for dev
r.SetTrustedProxies(nil)
routes.SetupRoutes(r)
// 6. Run Server
log.Printf("Server running on port %s", config.AppConfig.Port)
log.Printf("Swagger Documentation: http://localhost:%s/docs/index.html", config.AppConfig.Port)
if err := r.Run(":" + config.AppConfig.Port); err != nil {
log.Fatal("Failed to start server:", err)
}
}
func setupProviders() {
// Configure Gothic session store
sessionSecret := os.Getenv("SESSION_SECRET")
if sessionSecret == "" {
log.Println("Warning: SESSION_SECRET not set, using default (not secure for production)")
sessionSecret = "default-session-secret-change-in-production"
}
maxAge := 86400 * 30 // 30 days
isProd := false // Set to true in production
store := sessions.NewCookieStore([]byte(sessionSecret))
store.MaxAge(maxAge)
store.Options.Path = "/"
store.Options.HttpOnly = true // HttpOnly for security
store.Options.Secure = isProd // Set true in production (HTTPS only)
gothic.Store = store
goth.UseProviders(
google.New(
config.AppConfig.GoogleClientID,
config.AppConfig.GoogleClientSecret,
config.AppConfig.ClientCallbackURL+"/google/callback", // e.g. http://localhost:8080/v1/auth/google/callback
),
github.New(
config.AppConfig.GithubClientID,
config.AppConfig.GithubClientSecret,
config.AppConfig.ClientCallbackURL+"/github/callback",
),
)
}
// displayCorsConfiguration - Startup'ta CORS ayarlarını göster
func displayCorsConfiguration(settingsService *services.SettingsService) {
fmt.Println(utils.ColorCyan + "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + utils.ColorReset)
fmt.Println(utils.ColorCyan + " CORS Configuration (Database-Driven)" + utils.ColorReset)
fmt.Println(utils.ColorCyan + "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + utils.ColorReset)
// Get Whitelist
whitelists, err := settingsService.GetAllCorsWhitelist()
if err != nil {
fmt.Println(utils.ColorRed + " ❌ Failed to load whitelist: " + err.Error() + utils.ColorReset)
} else {
fmt.Println(utils.ColorGreen + " ✅ WHITELIST (Allowed Origins):" + utils.ColorReset)
if len(whitelists) == 0 {
fmt.Println(utils.ColorYellow + " ⚠️ No origins whitelisted! Add origins via API." + utils.ColorReset)
} else {
for i, w := range whitelists {
status := utils.ColorGreen + "●" + utils.ColorReset
if !w.IsActive {
status = utils.ColorRed + "○" + utils.ColorReset
}
fmt.Printf(" %s %d. %s\n", status, i+1, w.Origin)
if w.Description != "" {
fmt.Printf(" └─ %s\n", utils.ColorCyan+w.Description+utils.ColorReset)
}
}
}
}
fmt.Println()
// Get Blacklist
blacklists, err := settingsService.GetAllCorsBlacklist()
if err != nil {
fmt.Println(utils.ColorRed + " ❌ Failed to load blacklist: " + err.Error() + utils.ColorReset)
} else {
fmt.Println(utils.ColorRed + " 🚫 BLACKLIST (Blocked Origins):" + utils.ColorReset)
if len(blacklists) == 0 {
fmt.Println(utils.ColorGreen + " ✅ No origins blacklisted." + utils.ColorReset)
} else {
for i, b := range blacklists {
status := utils.ColorRed + "●" + utils.ColorReset
if !b.IsActive {
status = utils.ColorYellow + "○" + utils.ColorReset
}
fmt.Printf(" %s %d. %s\n", status, i+1, b.Origin)
if b.Reason != "" {
fmt.Printf(" └─ Reason: %s\n", utils.ColorYellow+b.Reason+utils.ColorReset)
}
}
}
}
fmt.Println()
fmt.Println(utils.ColorCyan + " Legend: " + utils.ColorGreen + "● Active" + utils.ColorReset + " | " + utils.ColorRed + "○ Inactive" + utils.ColorReset)
fmt.Println(utils.ColorCyan + "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + utils.ColorReset)
fmt.Println()
}