first commit

This commit is contained in:
Beyhan Oğur
2026-04-26 21:35:24 +03:00
commit bbbf76b184
592 changed files with 246870 additions and 0 deletions

204
main.go Normal file
View 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()
}