first commit
This commit is contained in:
204
main.go
Normal file
204
main.go
Normal file
@@ -0,0 +1,204 @@
|
||||
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()
|
||||
}
|
||||
Reference in New Issue
Block a user