logging, environment und Datenbank connection
This commit is contained in:
+3
-10
@@ -20,8 +20,8 @@ import (
|
||||
// @BasePath /
|
||||
// @schemes http
|
||||
func main() {
|
||||
// Konfiguration laden
|
||||
cfg := config.LoadConfig()
|
||||
// Verwende die globale Konfigurationsvariable (bereits in config.init() geladen)
|
||||
cfg := config.Cfg
|
||||
|
||||
// Logger konfigurieren
|
||||
logger.SetDebugMode(cfg.DebugMode)
|
||||
@@ -38,6 +38,7 @@ func main() {
|
||||
logger.Info("Bamort Server wird gestartet...")
|
||||
logger.Debug("Debug-Modus ist aktiviert")
|
||||
logger.Info("Environment: %s", cfg.Environment)
|
||||
logger.Info("testingDB Set: %s", cfg.DevTesting)
|
||||
logger.Info("Server Port: %s", cfg.ServerPort)
|
||||
|
||||
// Gin-Modus basierend auf Environment setzen
|
||||
@@ -54,14 +55,6 @@ func main() {
|
||||
database.ConnectDatabase()
|
||||
logger.Info("Datenbankverbindung erfolgreich")
|
||||
|
||||
// Migrate Audit-Log table
|
||||
logger.Debug("Führe Audit-Log Migration durch...")
|
||||
if err := character.MigrateAuditLog(); err != nil {
|
||||
logger.Error("Fehler bei Audit-Log Migration: %s", err.Error())
|
||||
panic("Failed to migrate audit log table: " + err.Error())
|
||||
}
|
||||
logger.Debug("Audit-Log Migration erfolgreich")
|
||||
|
||||
r := gin.Default()
|
||||
router.SetupGin(r)
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package config
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -23,7 +24,16 @@ type Config struct {
|
||||
// Environment
|
||||
Environment string
|
||||
|
||||
Testing string // "yes" or "no", used to determine if we are in a test environment
|
||||
DevTesting string // "yes" or "no", used to determine if we are in a test environment
|
||||
}
|
||||
|
||||
// Cfg ist die globale Konfigurationsvariable
|
||||
// Sie wird beim Programmstart automatisch geladen
|
||||
var Cfg *Config
|
||||
|
||||
// init lädt die Konfiguration einmal beim Programmstart
|
||||
func init() {
|
||||
Cfg = LoadConfig()
|
||||
}
|
||||
|
||||
// defaultConfig gibt die Standard-Konfiguration zurück
|
||||
@@ -35,7 +45,7 @@ func defaultConfig() *Config {
|
||||
DebugMode: false,
|
||||
LogLevel: "INFO",
|
||||
Environment: "production",
|
||||
Testing: "no", // Default to "no", can be overridden in tests
|
||||
DevTesting: "no", // Default to "no", can be overridden in tests
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,6 +56,11 @@ func LoadConfig() *Config {
|
||||
|
||||
config := defaultConfig()
|
||||
|
||||
// Debug: Zeige geladene Umgebungsvariablen
|
||||
fmt.Printf("DEBUG LoadConfig - ENVIRONMENT aus ENV: '%s'\n", os.Getenv("ENVIRONMENT"))
|
||||
fmt.Printf("DEBUG LoadConfig - TESTING aus ENV: '%s'\n", os.Getenv("DEVTESTING"))
|
||||
fmt.Printf("DEBUG LoadConfig - DATABASE_TYPE aus ENV: '%s'\n", os.Getenv("DATABASE_TYPE"))
|
||||
|
||||
// Server Port
|
||||
if port := os.Getenv("PORT"); port != "" {
|
||||
config.ServerPort = port
|
||||
@@ -88,12 +103,17 @@ func LoadConfig() *Config {
|
||||
}
|
||||
}
|
||||
// Testing in Development
|
||||
if testing := os.Getenv("TESTING"); testing != "" {
|
||||
config.Testing = strings.ToLower(testing)
|
||||
if testing := os.Getenv("DEVTESTING"); testing != "" {
|
||||
config.DevTesting = strings.ToLower(testing)
|
||||
fmt.Printf("DEBUG LoadConfig - DEVTESTING gefunden: '%s' -> DevTesting: '%s'\n", testing, config.DevTesting)
|
||||
} else {
|
||||
config.Testing = "no" // Default to "no"
|
||||
config.DevTesting = "no" // Default to "no"
|
||||
fmt.Printf("DEBUG LoadConfig - DEVTESTING nicht gefunden, setze DevTesting auf 'no'\n")
|
||||
}
|
||||
|
||||
fmt.Printf("DEBUG LoadConfig - Finale Config: Environment='%s', DevTesting='%s', DatabaseType='%s'\n",
|
||||
config.Environment, config.DevTesting, config.DatabaseType)
|
||||
|
||||
return config
|
||||
}
|
||||
|
||||
@@ -103,21 +123,28 @@ func loadEnvFile() {
|
||||
|
||||
for _, envFile := range envFiles {
|
||||
if _, err := os.Stat(envFile); err == nil {
|
||||
fmt.Printf("DEBUG loadEnvFile - Lade .env-Datei: %s\n", envFile)
|
||||
loadEnvFileContent(envFile)
|
||||
} else {
|
||||
fmt.Printf("DEBUG loadEnvFile - .env-Datei nicht gefunden: %s\n", envFile)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// loadEnvFileContent lädt den Inhalt einer .env-Datei
|
||||
func loadEnvFileContent(filename string) {
|
||||
fmt.Printf("DEBUG loadEnvFileContent - Öffne Datei: %s\n", filename)
|
||||
file, err := os.Open(filename)
|
||||
if err != nil {
|
||||
fmt.Printf("DEBUG loadEnvFileContent - Fehler beim Öffnen von %s: %v\n", filename, err)
|
||||
return
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
scanner := bufio.NewScanner(file)
|
||||
lineNum := 0
|
||||
for scanner.Scan() {
|
||||
lineNum++
|
||||
line := strings.TrimSpace(scanner.Text())
|
||||
|
||||
// Überspringe leere Zeilen und Kommentare
|
||||
@@ -134,14 +161,29 @@ func loadEnvFileContent(filename string) {
|
||||
key := strings.TrimSpace(parts[0])
|
||||
value := strings.TrimSpace(parts[1])
|
||||
|
||||
// Behandle Kommentare am Ende der Zeile (nur wenn nicht in Anführungszeichen)
|
||||
if !strings.HasPrefix(value, `"`) && !strings.HasPrefix(value, `'`) {
|
||||
// Suche nach Kommentar am Ende der Zeile
|
||||
if commentPos := strings.Index(value, "#"); commentPos > 0 {
|
||||
// Entferne Kommentar und Leerzeichen davor
|
||||
value = strings.TrimSpace(value[:commentPos])
|
||||
}
|
||||
}
|
||||
|
||||
// Entferne Anführungszeichen falls vorhanden
|
||||
value = strings.Trim(value, `"'`)
|
||||
|
||||
fmt.Printf("DEBUG loadEnvFileContent - Zeile %d: %s='%s' (nach Kommentar-Behandlung)\n", lineNum, key, value)
|
||||
|
||||
// Setze die Umgebungsvariable nur, wenn sie noch nicht gesetzt ist
|
||||
if os.Getenv(key) == "" {
|
||||
os.Setenv(key, value)
|
||||
fmt.Printf("DEBUG loadEnvFileContent - Setze ENV %s='%s'\n", key, value)
|
||||
} else {
|
||||
fmt.Printf("DEBUG loadEnvFileContent - ENV %s bereits gesetzt, überspringe\n", key)
|
||||
}
|
||||
}
|
||||
fmt.Printf("DEBUG loadEnvFileContent - Datei %s vollständig verarbeitet (%d Zeilen)\n", filename, lineNum)
|
||||
}
|
||||
|
||||
// IsDevelopment prüft, ob die Anwendung im Development-Modus läuft
|
||||
|
||||
@@ -40,11 +40,18 @@ var (
|
||||
)
|
||||
|
||||
func ConnectDatabase() *gorm.DB {
|
||||
// Konfiguration laden um zu entscheiden, welche Datenbank verwendet werden soll
|
||||
cfg := config.LoadConfig()
|
||||
// Verwende die globale Konfigurationsvariable
|
||||
cfg := config.Cfg
|
||||
|
||||
logger.Debug("Datenbankverbindung - Environment: '%s', DevTesting: '%s'", cfg.Environment, cfg.DevTesting)
|
||||
|
||||
// Debug: Explizite Bedingungsauswertung
|
||||
envIsTest := cfg.Environment == "test"
|
||||
devTestingIsYes := cfg.DevTesting == "yes"
|
||||
logger.Debug("Bedingungsauswertung - Environment == 'test': %v, DevTesting == 'yes': %v", envIsTest, devTestingIsYes)
|
||||
|
||||
// In Test-Umgebung verwende Test-DB, sonst die konfigurierte Datenbank
|
||||
if cfg.Environment == "test" || cfg.Testing == "yes" {
|
||||
if envIsTest || devTestingIsYes {
|
||||
logger.Debug("Test-Umgebung erkannt, verwende Test-Datenbank")
|
||||
SetupTestDB()
|
||||
} else {
|
||||
@@ -55,8 +62,8 @@ func ConnectDatabase() *gorm.DB {
|
||||
return DB
|
||||
}
|
||||
func ConnectDatabaseOrig() *gorm.DB {
|
||||
// Konfiguration laden
|
||||
cfg := config.LoadConfig()
|
||||
// Verwende die globale Konfigurationsvariable
|
||||
cfg := config.Cfg
|
||||
|
||||
logger.Debug("Datenbank-Konfiguration geladen: Type=%s, URL=%s", cfg.DatabaseType, cfg.DatabaseURL)
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"bamort/logger"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -14,19 +15,29 @@ var testdbTempDir string
|
||||
|
||||
// copyFile copies a file from src to dst
|
||||
func copyFile(src, dst string) error {
|
||||
logger.Debug("copyFile: Kopiere Datei von %s nach %s", src, dst)
|
||||
|
||||
sourceFile, err := os.Open(src)
|
||||
if err != nil {
|
||||
logger.Error("copyFile: Fehler beim Öffnen der Quelldatei %s: %s", src, err.Error())
|
||||
return err
|
||||
}
|
||||
defer sourceFile.Close()
|
||||
|
||||
destFile, err := os.Create(dst)
|
||||
if err != nil {
|
||||
logger.Error("copyFile: Fehler beim Erstellen der Zieldatei %s: %s", dst, err.Error())
|
||||
return err
|
||||
}
|
||||
defer destFile.Close()
|
||||
|
||||
_, err = io.Copy(destFile, sourceFile)
|
||||
copied, err := io.Copy(destFile, sourceFile)
|
||||
if err != nil {
|
||||
logger.Error("copyFile: Fehler beim Kopieren der Datei: %s", err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
logger.Debug("copyFile: Erfolgreich %d Bytes kopiert von %s nach %s", copied, src, dst)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -38,47 +49,95 @@ func copyFile(src, dst string) error {
|
||||
// Parameters:
|
||||
// - opts[0]: isTestDb (bool) - whether to use precopied SQLite (true) or persistent (Live) MariaDB (false)
|
||||
func SetupTestDB(opts ...bool) {
|
||||
logger.Debug("SetupTestDB aufgerufen")
|
||||
|
||||
isTestDb = true
|
||||
|
||||
if len(opts) > 0 {
|
||||
isTestDb = opts[0]
|
||||
logger.Debug("SetupTestDB: isTestDb Parameter überschrieben auf %t", isTestDb)
|
||||
}
|
||||
|
||||
logger.Debug("SetupTestDB: Verwende Test-Datenbank: %t", isTestDb)
|
||||
|
||||
if DB == nil {
|
||||
logger.Debug("SetupTestDB: DB ist nil, erstelle neue Datenbankverbindung")
|
||||
var db *gorm.DB
|
||||
|
||||
if isTestDb {
|
||||
logger.Info("SetupTestDB: Erstelle SQLite Test-Datenbank")
|
||||
|
||||
testdbTempDir, err := os.MkdirTemp("", "bamort-test-")
|
||||
if err != nil {
|
||||
logger.Error("SetupTestDB: Fehler beim Erstellen des temporären Verzeichnisses: %s", err.Error())
|
||||
panic("failed to create temporary directory: " + err.Error())
|
||||
}
|
||||
logger.Debug("SetupTestDB: Temporäres Verzeichnis erstellt: %s", testdbTempDir)
|
||||
|
||||
targetFile := filepath.Join(testdbTempDir, "test_backup.db")
|
||||
logger.Debug("SetupTestDB: Ziel-Datei: %s", targetFile)
|
||||
logger.Debug("SetupTestDB: Quelle-Datei: %s", PreparedTestDB)
|
||||
|
||||
err = copyFile(PreparedTestDB, targetFile)
|
||||
if err != nil {
|
||||
logger.Error("SetupTestDB: Fehler beim Kopieren der Test-Datenbank: %s", err.Error())
|
||||
panic("failed to copy prepared test database: " + err.Error())
|
||||
}
|
||||
logger.Info("SetupTestDB: Test-Datenbank erfolgreich kopiert")
|
||||
|
||||
db, err = gorm.Open(sqlite.Open(targetFile), &gorm.Config{})
|
||||
if err != nil {
|
||||
logger.Error("SetupTestDB: Fehler beim Verbinden mit der Test-Datenbank: %s", err.Error())
|
||||
panic("failed to connect to the test database: " + err.Error())
|
||||
}
|
||||
logger.Info("SetupTestDB: Erfolgreich mit SQLite Test-Datenbank verbunden")
|
||||
//defer os.RemoveAll(testdbTempDir)
|
||||
} else {
|
||||
logger.Info("SetupTestDB: Verwende Live-Datenbank (MariaDB)")
|
||||
//* //testing with persistent MariaDB
|
||||
db = ConnectDatabase()
|
||||
if db == nil {
|
||||
logger.Error("SetupTestDB: Fehler beim Verbinden mit der Live-Datenbank")
|
||||
panic("failed to connect to the live database")
|
||||
}
|
||||
logger.Info("SetupTestDB: Erfolgreich mit Live-Datenbank verbunden")
|
||||
}
|
||||
DB = db
|
||||
logger.Info("SetupTestDB: Datenbankverbindung erfolgreich eingerichtet")
|
||||
} else {
|
||||
logger.Debug("SetupTestDB: DB bereits initialisiert, überspringe Setup")
|
||||
}
|
||||
|
||||
}
|
||||
func ResetTestDB() {
|
||||
logger.Debug("ResetTestDB aufgerufen")
|
||||
|
||||
if isTestDb {
|
||||
logger.Debug("ResetTestDB: Verwende Test-Datenbank, führe Cleanup durch")
|
||||
|
||||
sqlDB, err := DB.DB()
|
||||
if err == nil {
|
||||
logger.Debug("ResetTestDB: Schließe Datenbankverbindung")
|
||||
sqlDB.Close()
|
||||
|
||||
DB = nil
|
||||
os.RemoveAll(testdbTempDir)
|
||||
logger.Debug("ResetTestDB: DB auf nil gesetzt")
|
||||
|
||||
if testdbTempDir != "" {
|
||||
logger.Debug("ResetTestDB: Lösche temporäres Verzeichnis: %s", testdbTempDir)
|
||||
err = os.RemoveAll(testdbTempDir)
|
||||
if err != nil {
|
||||
logger.Error("ResetTestDB: Fehler beim Löschen des temporären Verzeichnisses: %s", err.Error())
|
||||
} else {
|
||||
logger.Info("ResetTestDB: Temporäres Verzeichnis erfolgreich gelöscht")
|
||||
}
|
||||
testdbTempDir = ""
|
||||
}
|
||||
} else {
|
||||
logger.Error("ResetTestDB: Fehler beim Abrufen der SQL-Datenbank: %s", err.Error())
|
||||
}
|
||||
} else {
|
||||
logger.Debug("ResetTestDB: Verwende Live-Datenbank, überspringe Cleanup")
|
||||
}
|
||||
|
||||
logger.Info("ResetTestDB: Cleanup abgeschlossen")
|
||||
}
|
||||
|
||||
+125
-27
@@ -1,7 +1,9 @@
|
||||
package maintenance
|
||||
|
||||
import (
|
||||
"bamort/config"
|
||||
"bamort/database"
|
||||
"bamort/logger"
|
||||
"bamort/models"
|
||||
"bamort/user"
|
||||
"fmt"
|
||||
@@ -28,35 +30,54 @@ func respondWithError(c *gin.Context, status int, message string) {
|
||||
|
||||
// migrateAllStructures migrates all database structures to the provided database
|
||||
func migrateAllStructures(db *gorm.DB) error {
|
||||
logger.Debug("Starte Migration aller Datenbankstrukturen...")
|
||||
|
||||
// Migrate all structures in the correct order
|
||||
logger.Debug("Migriere Datenbankstrukturen...")
|
||||
if err := database.MigrateStructure(db); err != nil {
|
||||
logger.Error("Fehler beim Migrieren der Datenbankstrukturen: %s", err.Error())
|
||||
return fmt.Errorf("failed to migrate database structures: %w", err)
|
||||
}
|
||||
|
||||
logger.Debug("Migriere Benutzerstrukturen...")
|
||||
if err := user.MigrateStructure(db); err != nil {
|
||||
logger.Error("Fehler beim Migrieren der Benutzerstrukturen: %s", err.Error())
|
||||
return fmt.Errorf("failed to migrate user structures: %w", err)
|
||||
}
|
||||
|
||||
logger.Debug("Migriere GSMaster-Strukturen...")
|
||||
if err := models.MigrateStructure(db); err != nil {
|
||||
logger.Error("Fehler beim Migrieren der GSMaster-Strukturen: %s", err.Error())
|
||||
return fmt.Errorf("failed to migrate gsmaster structures: %w", err)
|
||||
}
|
||||
|
||||
/*if err := importer.MigrateStructure(db); err != nil {
|
||||
return fmt.Errorf("failed to migrate importer structures: %w", err)
|
||||
}*/
|
||||
|
||||
logger.Info("Migration aller Datenbankstrukturen erfolgreich abgeschlossen")
|
||||
return nil
|
||||
}
|
||||
|
||||
func migrateDataIfNeeded(db *gorm.DB) error {
|
||||
logger.Debug("Starte Datenmigration falls erforderlich...")
|
||||
|
||||
// Kopiere categorie nach learning_category für Spells, wenn learning_category leer ist
|
||||
logger.Debug("Migriere Spell Learning Categories...")
|
||||
err := migrateSpellLearningCategories(db)
|
||||
if err != nil {
|
||||
logger.Error("Fehler beim Migrieren der Spell Learning Categories: %s", err.Error())
|
||||
return fmt.Errorf("failed to migrate spell learning categories: %w", err)
|
||||
}
|
||||
|
||||
logger.Info("Datenmigration erfolgreich abgeschlossen")
|
||||
return nil
|
||||
}
|
||||
|
||||
// migrateSpellLearningCategories kopiert categorie-Werte in learning_category wenn diese leer sind
|
||||
func migrateSpellLearningCategories(db *gorm.DB) error {
|
||||
logger.Debug("Starte Migration der Spell Learning Categories...")
|
||||
|
||||
// SQL-Statement um categorie nach learning_category zu kopieren, wo learning_category leer oder NULL ist
|
||||
sql := `
|
||||
UPDATE gsm_spells
|
||||
@@ -66,34 +87,46 @@ func migrateSpellLearningCategories(db *gorm.DB) error {
|
||||
AND category != ''
|
||||
`
|
||||
|
||||
logger.Debug("Führe SQL-Update aus: %s", strings.ReplaceAll(sql, "\n", " "))
|
||||
result := db.Exec(sql)
|
||||
if result.Error != nil {
|
||||
logger.Error("Fehler beim SQL-Update der Spell Learning Categories: %s", result.Error.Error())
|
||||
return fmt.Errorf("failed to update spell learning categories: %w", result.Error)
|
||||
}
|
||||
|
||||
// Log der Anzahl der aktualisierten Datensätze
|
||||
if result.RowsAffected > 0 {
|
||||
logger.Info("Updated %d spell records with learning_category from categorie", result.RowsAffected)
|
||||
fmt.Printf("Updated %d spell records with learning_category from categorie\n", result.RowsAffected)
|
||||
} else {
|
||||
logger.Debug("Keine Spell-Datensätze benötigten ein Update der learning_category")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func MakeTestdataFromLive(c *gin.Context) {
|
||||
logger.Info("Starte Testdaten-Erstellung aus Live-Datenbank...")
|
||||
|
||||
liveDB := database.ConnectDatabase()
|
||||
if liveDB == nil {
|
||||
logger.Error("Fehler beim Verbinden mit der Live-Datenbank")
|
||||
respondWithError(c, http.StatusInternalServerError, "Failed to connect to live database")
|
||||
return
|
||||
}
|
||||
logger.Debug("Erfolgreich mit Live-Datenbank verbunden")
|
||||
|
||||
// Live-Datenbank in SQLite-Datei kopieren
|
||||
backupFile := preparedTestDB
|
||||
logger.Info("Kopiere Live-Datenbank nach: %s", backupFile)
|
||||
err := copyLiveDatabaseToFile(liveDB, backupFile)
|
||||
if err != nil {
|
||||
logger.Error("Fehler beim Kopieren der Datenbank: %s", err.Error())
|
||||
respondWithError(c, http.StatusInternalServerError, fmt.Sprintf("Failed to copy database: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
logger.Info("Live-Datenbank erfolgreich in Datei kopiert: %s", backupFile)
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "Live database copied to file successfully",
|
||||
"test_data_file": backupFile,
|
||||
@@ -107,47 +140,64 @@ func CopyLiveDatabaseToFile(liveDB *gorm.DB, targetFile string) error {
|
||||
|
||||
// copyLiveDatabaseToFile kopiert die MariaDB-Datenbank in eine SQLite-Datei
|
||||
func copyLiveDatabaseToFile(liveDB *gorm.DB, targetFile string) error {
|
||||
logger.Debug("Starte Kopiervorgang von Live-DB nach SQLite-Datei: %s", targetFile)
|
||||
|
||||
// Verzeichnis erstellen falls es nicht existiert
|
||||
dir := filepath.Dir(targetFile)
|
||||
logger.Debug("Erstelle Zielverzeichnis falls erforderlich: %s", dir)
|
||||
if err := os.MkdirAll(dir, 0755); err != nil {
|
||||
logger.Error("Fehler beim Erstellen des Verzeichnisses %s: %s", dir, err.Error())
|
||||
return fmt.Errorf("failed to create directory: %w", err)
|
||||
}
|
||||
|
||||
// Backup der existierenden Datei erstellen
|
||||
if _, err := os.Stat(targetFile); err == nil {
|
||||
backupFile := targetFile + ".backup"
|
||||
logger.Debug("Existierende Datei gefunden, erstelle Backup: %s", backupFile)
|
||||
os.Remove(backupFile) // Alte Backup entfernen
|
||||
if err := os.Rename(targetFile, backupFile); err != nil {
|
||||
logger.Error("Fehler beim Erstellen des Backups %s: %s", backupFile, err.Error())
|
||||
return fmt.Errorf("failed to backup existing file: %w", err)
|
||||
}
|
||||
logger.Debug("Backup erfolgreich erstellt")
|
||||
}
|
||||
|
||||
// SQLite-Zieldatenbank erstellen
|
||||
logger.Debug("Erstelle neue SQLite-Zieldatenbank: %s", targetFile)
|
||||
targetDB, err := gorm.Open(sqlite.Open(targetFile), &gorm.Config{})
|
||||
if err != nil {
|
||||
logger.Error("Fehler beim Erstellen der SQLite-Zieldatenbank: %s", err.Error())
|
||||
return fmt.Errorf("failed to create target SQLite database: %w", err)
|
||||
}
|
||||
defer func() {
|
||||
if sqlDB, err := targetDB.DB(); err == nil {
|
||||
logger.Debug("Schließe SQLite-Datenbankverbindung")
|
||||
sqlDB.Close()
|
||||
}
|
||||
}()
|
||||
|
||||
// Strukturen in SQLite-DB migrieren
|
||||
logger.Debug("Migriere Strukturen in SQLite-Datenbank...")
|
||||
if err := migrateAllStructures(targetDB); err != nil {
|
||||
logger.Error("Fehler beim Migrieren der Strukturen in SQLite: %s", err.Error())
|
||||
return fmt.Errorf("failed to migrate structures to SQLite: %w", err)
|
||||
}
|
||||
|
||||
// Daten von MariaDB zu SQLite kopieren
|
||||
logger.Info("Kopiere Daten von MariaDB zu SQLite...")
|
||||
if err := copyMariaDBToSQLite(liveDB, targetDB); err != nil {
|
||||
logger.Error("Fehler beim Kopieren der Daten von MariaDB zu SQLite: %s", err.Error())
|
||||
return fmt.Errorf("failed to copy data from MariaDB to SQLite: %w", err)
|
||||
}
|
||||
|
||||
logger.Info("Kopiervorgang erfolgreich abgeschlossen")
|
||||
return nil
|
||||
}
|
||||
|
||||
// copyMariaDBToSQLite kopiert alle Daten von MariaDB zu SQLite
|
||||
func copyMariaDBToSQLite(mariaDB, sqliteDB *gorm.DB) error {
|
||||
logger.Debug("Starte Kopiervorgang aller Daten von MariaDB zu SQLite...")
|
||||
|
||||
// Vollständige Liste aller Strukturen mit GORM-Tags in der richtigen Reihenfolge
|
||||
// (Basis-Tabellen zuerst wegen Foreign Key-Abhängigkeiten)
|
||||
tables := []interface{}{
|
||||
@@ -207,43 +257,62 @@ func copyMariaDBToSQLite(mariaDB, sqliteDB *gorm.DB) error {
|
||||
// SkillLearningInfo, SpellLearningInfo, CharList, FeChar, etc.
|
||||
}
|
||||
|
||||
for _, model := range tables {
|
||||
logger.Info("Kopiere Daten für %d Tabellen...", len(tables))
|
||||
for i, model := range tables {
|
||||
logger.Debug("Kopiere Tabelle %d/%d: %T", i+1, len(tables), model)
|
||||
if err := copyTableData(mariaDB, sqliteDB, model); err != nil {
|
||||
logger.Error("Fehler beim Kopieren der Tabellendaten für %T: %s", model, err.Error())
|
||||
return fmt.Errorf("failed to copy table data for %T: %w", model, err)
|
||||
}
|
||||
}
|
||||
|
||||
logger.Info("Alle Tabellendaten erfolgreich kopiert")
|
||||
return nil
|
||||
}
|
||||
|
||||
// copyTableData kopiert alle Daten einer Tabelle von MariaDB zu SQLite
|
||||
func copyTableData(sourceDB, targetDB *gorm.DB, model interface{}) error {
|
||||
tableName := fmt.Sprintf("%T", model)
|
||||
logger.Debug("Starte Kopiervorgang für Tabelle: %s", tableName)
|
||||
|
||||
// Anzahl der Datensätze prüfen
|
||||
var count int64
|
||||
err := sourceDB.Model(model).Count(&count).Error
|
||||
if err != nil {
|
||||
// If table doesn't exist, skip silently (useful for testing with partial schemas)
|
||||
if isTableNotExistError(err) {
|
||||
logger.Debug("Tabelle %s existiert nicht in der Quelle, überspringe", tableName)
|
||||
return nil
|
||||
}
|
||||
logger.Error("Fehler beim Zählen der Datensätze für %s: %s", tableName, err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
if count == 0 {
|
||||
logger.Debug("Tabelle %s ist leer, keine Daten zu kopieren", tableName)
|
||||
return nil // Keine Daten zu kopieren
|
||||
}
|
||||
|
||||
logger.Debug("Kopiere %d Datensätze für Tabelle %s", count, tableName)
|
||||
|
||||
// Daten in Blöcken kopieren (für große Tabellen)
|
||||
batchSize := 100
|
||||
totalBatches := (int(count) + batchSize - 1) / batchSize
|
||||
|
||||
for offset := 0; offset < int(count); offset += batchSize {
|
||||
batchNum := (offset / batchSize) + 1
|
||||
logger.Debug("Kopiere Batch %d/%d für %s (Offset: %d, Limit: %d)", batchNum, totalBatches, tableName, offset, batchSize)
|
||||
|
||||
var records []map[string]interface{}
|
||||
|
||||
// Batch aus MariaDB lesen
|
||||
if err := sourceDB.Model(model).Offset(offset).Limit(batchSize).Find(&records).Error; err != nil {
|
||||
logger.Error("Fehler beim Lesen von Batch %d für %s: %s", batchNum, tableName, err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
if len(records) == 0 {
|
||||
logger.Debug("Keine weiteren Datensätze für %s", tableName)
|
||||
break
|
||||
}
|
||||
|
||||
@@ -252,10 +321,14 @@ func copyTableData(sourceDB, targetDB *gorm.DB, model interface{}) error {
|
||||
if err := targetDB.Model(model).Clauses(clause.OnConflict{
|
||||
UpdateAll: true,
|
||||
}).Create(&records).Error; err != nil {
|
||||
logger.Error("Fehler beim Einfügen von Batch %d für %s: %s", batchNum, tableName, err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
logger.Debug("Batch %d/%d für %s erfolgreich kopiert (%d Datensätze)", batchNum, totalBatches, tableName, len(records))
|
||||
}
|
||||
|
||||
logger.Info("Tabelle %s erfolgreich kopiert (%d Datensätze total)", tableName, count)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -269,23 +342,32 @@ func isTableNotExistError(err error) bool {
|
||||
|
||||
// LoadPredefinedTestDataFromFile loads predefined test data from a specific file into the provided database
|
||||
func LoadPredefinedTestDataFromFile(targetDB *gorm.DB, dataFile string) error {
|
||||
logger.Debug("Lade vordefinierte Testdaten aus Datei: %s", dataFile)
|
||||
|
||||
// Check if file exists
|
||||
if _, err := os.Stat(dataFile); os.IsNotExist(err) {
|
||||
logger.Error("Vordefinierte Testdaten-Datei nicht gefunden: %s", dataFile)
|
||||
return fmt.Errorf("predefined test data file not found: %s", dataFile)
|
||||
}
|
||||
logger.Debug("Testdaten-Datei existiert: %s", dataFile)
|
||||
|
||||
// Migrate structures to target DB
|
||||
logger.Debug("Migriere Strukturen in Zieldatenbank...")
|
||||
err := migrateAllStructures(targetDB)
|
||||
if err != nil {
|
||||
logger.Error("Fehler beim Migrieren der Strukturen: %s", err.Error())
|
||||
return fmt.Errorf("failed to migrate structures: %w", err)
|
||||
}
|
||||
|
||||
// Copy data from file database to target database
|
||||
logger.Info("Kopiere Testdaten in Zieldatenbank...")
|
||||
err = copyDataFromFileToMemory(dataFile, targetDB)
|
||||
if err != nil {
|
||||
logger.Error("Fehler beim Kopieren der Testdaten: %s", err.Error())
|
||||
return fmt.Errorf("failed to copy test data to database: %w", err)
|
||||
}
|
||||
|
||||
logger.Info("Vordefinierte Testdaten erfolgreich geladen")
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -327,31 +409,44 @@ func LoadPredefinedTestData(c *gin.Context) {
|
||||
|
||||
// copyDataFromFileToMemory copies data from a SQLite file to an in-memory database
|
||||
func copyDataFromFileToMemory(sourceFile string, targetDB *gorm.DB) error {
|
||||
logger.Debug("Kopiere Daten von SQLite-Datei in Memory-Datenbank: %s", sourceFile)
|
||||
|
||||
// Copy all tables using ATTACH and INSERT
|
||||
attachSQL := fmt.Sprintf("ATTACH DATABASE '%s' AS source", sourceFile)
|
||||
logger.Debug("Hänge Quell-Datenbank an: %s", attachSQL)
|
||||
if err := targetDB.Exec(attachSQL).Error; err != nil {
|
||||
logger.Error("Fehler beim Anhängen der Quell-Datenbank: %s", err.Error())
|
||||
return fmt.Errorf("failed to attach source database: %w", err)
|
||||
}
|
||||
|
||||
// Get list of tables from source database
|
||||
logger.Debug("Ermittle Tabellenliste aus Quell-Datenbank...")
|
||||
var tables []string
|
||||
if err := targetDB.Raw("SELECT name FROM source.sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'").Scan(&tables).Error; err != nil {
|
||||
logger.Error("Fehler beim Ermitteln der Tabellenliste: %s", err.Error())
|
||||
return fmt.Errorf("failed to get table list: %w", err)
|
||||
}
|
||||
logger.Info("Gefundene Tabellen zum Kopieren: %d (%v)", len(tables), tables)
|
||||
|
||||
// Copy each table
|
||||
for _, table := range tables {
|
||||
for i, table := range tables {
|
||||
logger.Debug("Kopiere Tabelle %d/%d: %s", i+1, len(tables), table)
|
||||
copySQL := fmt.Sprintf("INSERT OR REPLACE INTO main.%s SELECT * FROM source.%s", table, table)
|
||||
if err := targetDB.Exec(copySQL).Error; err != nil {
|
||||
logger.Error("Fehler beim Kopieren der Tabelle %s: %s", table, err.Error())
|
||||
return fmt.Errorf("failed to copy table %s: %w", table, err)
|
||||
}
|
||||
logger.Debug("Tabelle %s erfolgreich kopiert", table)
|
||||
}
|
||||
|
||||
// Detach the source database
|
||||
logger.Debug("Löse Quell-Datenbank-Verbindung...")
|
||||
if err := targetDB.Exec("DETACH DATABASE source").Error; err != nil {
|
||||
logger.Error("Fehler beim Lösen der Quell-Datenbank-Verbindung: %s", err.Error())
|
||||
return fmt.Errorf("failed to detach source database: %w", err)
|
||||
}
|
||||
|
||||
logger.Info("Daten erfolgreich von Datei in Memory-Datenbank kopiert")
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -385,51 +480,54 @@ func getTestDataStatistics(db *gorm.DB) (map[string]int64, error) {
|
||||
}
|
||||
|
||||
func SetupCheck(c *gin.Context) {
|
||||
logger.Info("Starte Setup-Check...")
|
||||
|
||||
db := database.ConnectDatabase()
|
||||
if db == nil {
|
||||
logger.Error("Fehler beim Verbinden mit der Datenbank für Setup-Check")
|
||||
respondWithError(c, http.StatusInternalServerError, "Failed to connect to DataBase")
|
||||
return
|
||||
}
|
||||
logger.Debug("Erfolgreich mit Datenbank für Setup-Check verbunden")
|
||||
|
||||
logger.Debug("Führe Strukturmigration durch...")
|
||||
err := migrateAllStructures(db)
|
||||
if err != nil {
|
||||
logger.Error("Fehler bei der Strukturmigration: %s", err.Error())
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
logger.Debug("Führe Datenmigration durch...")
|
||||
err = migrateDataIfNeeded(db)
|
||||
if err != nil {
|
||||
logger.Error("Fehler bei der Datenmigration: %s", err.Error())
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to migrate data: " + err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
logger.Info("Setup-Check erfolgreich abgeschlossen")
|
||||
c.JSON(http.StatusOK, gin.H{"message": "Setup Check OK"})
|
||||
}
|
||||
|
||||
/*
|
||||
// InitializeLearningCosts initialisiert das Lernkosten-System
|
||||
// Wird danach nicht mehr benötigt
|
||||
func InitializeLearningCosts(c *gin.Context) {
|
||||
err := gsmaster.InitializeLearningCostsSystem()
|
||||
if err != nil {
|
||||
respondWithError(c, http.StatusInternalServerError, fmt.Sprintf("Failed to initialize learning costs: %v", err))
|
||||
func ReconnectDataBase(c *gin.Context) {
|
||||
logger.Info("Führe Datenbank-Reconnect durch...")
|
||||
|
||||
db := database.ConnectDatabase()
|
||||
if db == nil {
|
||||
logger.Error("Fehler beim Reconnect zur Datenbank")
|
||||
respondWithError(c, http.StatusInternalServerError, "Failed to reconnect to DataBase")
|
||||
return
|
||||
}
|
||||
|
||||
// Validierung
|
||||
if err := gsmaster.ValidateLearningCostsData(); err != nil {
|
||||
respondWithError(c, http.StatusInternalServerError, fmt.Sprintf("Learning costs initialized but validation failed: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
// Zusammenfassung
|
||||
summary, err := gsmaster.GetLearningCostsSummary()
|
||||
if err != nil {
|
||||
respondWithError(c, http.StatusInternalServerError, fmt.Sprintf("Failed to get summary: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "Learning costs system initialized successfully",
|
||||
"summary": summary,
|
||||
})
|
||||
logger.Info("Datenbank-Reconnect erfolgreich")
|
||||
c.JSON(http.StatusOK, gin.H{"message": "Database reconnected successfully"})
|
||||
}
|
||||
|
||||
func ReloadENV(c *gin.Context) {
|
||||
logger.Info("Starte Reload der Umgebungsvariablen...")
|
||||
|
||||
// Reload the environment variables
|
||||
config.LoadConfig()
|
||||
c.JSON(http.StatusOK, gin.H{"message": "Environment variables reloaded successfully"})
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -8,6 +8,8 @@ func RegisterRoutes(r *gin.RouterGroup) {
|
||||
charGrp := r.Group("/maintenance")
|
||||
charGrp.GET("/setupcheck", SetupCheck)
|
||||
charGrp.GET("/mktestdata", MakeTestdataFromLive)
|
||||
charGrp.GET("/reconndb", ReconnectDataBase) // Datenbank neu verbinden
|
||||
charGrp.GET("/reloadenv", ReloadENV)
|
||||
/*
|
||||
//nur zur einmaligen Ausführung, um das Lernkosten-System zu initialisieren
|
||||
charGrp.POST("/initialize-learning-costs", InitializeLearningCosts)
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bamort/database"
|
||||
"bamort/models"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println("Starte Migration...")
|
||||
|
||||
database.ConnectDatabase()
|
||||
|
||||
err := database.DB.AutoMigrate(&models.CharacterCreationSession{})
|
||||
if err != nil {
|
||||
fmt.Printf("Migration Fehler: %v\n", err)
|
||||
} else {
|
||||
fmt.Println("Migration erfolgreich!")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bamort/config"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Teste, ob die globale Konfigurationsvariable funktioniert
|
||||
fmt.Printf("Globale Konfiguration:\n")
|
||||
fmt.Printf("Environment: %s\n", config.Cfg.Environment)
|
||||
fmt.Printf("DatabaseType: %s\n", config.Cfg.DatabaseType)
|
||||
fmt.Printf("DatabaseURL: %s\n", config.Cfg.DatabaseURL)
|
||||
fmt.Printf("ServerPort: %s\n", config.Cfg.ServerPort)
|
||||
fmt.Printf("DebugMode: %v\n", config.Cfg.DebugMode)
|
||||
fmt.Printf("LogLevel: %s\n", config.Cfg.LogLevel)
|
||||
fmt.Printf("Testing: %s\n", config.Cfg.DevTesting)
|
||||
}
|
||||
@@ -6,6 +6,7 @@ Add handlers for user registration and login:
|
||||
package user
|
||||
|
||||
import (
|
||||
"bamort/logger"
|
||||
"crypto/md5"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
@@ -21,25 +22,37 @@ func respondWithError(c *gin.Context, status int, message string) {
|
||||
}
|
||||
|
||||
func RegisterUser(c *gin.Context) {
|
||||
logger.Debug("Starte Benutzerregistrierung...")
|
||||
|
||||
var user User
|
||||
if err := c.ShouldBindJSON(&user); err != nil {
|
||||
logger.Error("Fehler beim Parsen der Registrierungsdaten: %s", err.Error())
|
||||
respondWithError(c, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
logger.Debug("Registriere Benutzer: %s", user.Username)
|
||||
//fmt.Printf("User input: '%s'", user.PasswordHash)
|
||||
//hashedPassword, _ := bcrypt.GenerateFromPassword([]byte(user.PasswordHash), bcrypt.DefaultCost)
|
||||
hashedPassword := md5.Sum([]byte(user.PasswordHash))
|
||||
user.PasswordHash = hex.EncodeToString(hashedPassword[:])
|
||||
logger.Debug("Passwort-Hash erstellt für Benutzer: %s", user.Username)
|
||||
|
||||
//fmt.Printf("pwdh: %s", user.PasswordHash)
|
||||
if err := user.Create(); err != nil {
|
||||
logger.Error("Fehler beim Erstellen des Benutzers %s: %s", user.Username, err.Error())
|
||||
respondWithError(c, http.StatusInternalServerError, fmt.Sprintf("Failed to create user: %s", err))
|
||||
return
|
||||
}
|
||||
|
||||
logger.Info("Benutzer erfolgreich registriert: %s (ID: %d)", user.Username, user.UserID)
|
||||
//fmt.Printf(" ___ pwdh2: %s", user.PasswordHash)
|
||||
c.JSON(http.StatusCreated, gin.H{"message": "User registered successfully:"})
|
||||
}
|
||||
|
||||
func GenerateToken(u *User) string {
|
||||
logger.Debug("Generiere Token für Benutzer: %s (ID: %d)", u.Username, u.UserID)
|
||||
|
||||
//u.Username + "lkiuztrew" + u.CreatedAt.String()
|
||||
tx := md5.Sum([]byte(u.Username + u.CreatedAt.String()))
|
||||
// Convert hash to raw string
|
||||
@@ -48,9 +61,13 @@ func GenerateToken(u *User) string {
|
||||
idm := "." + fmt.Sprintf("%d", u.UserID) + ":"
|
||||
// Insert the character
|
||||
token := hashString[:pos] + string(idm) + hashString[pos:]
|
||||
|
||||
logger.Debug("Token erfolgreich generiert für Benutzer: %s", u.Username)
|
||||
return token
|
||||
}
|
||||
func CheckToken(token string) *User {
|
||||
logger.Debug("Prüfe Token-Gültigkeit...")
|
||||
|
||||
//fmt.Print("CheckToken1: " + token)
|
||||
var u User
|
||||
var err error
|
||||
@@ -58,6 +75,7 @@ func CheckToken(token string) *User {
|
||||
userid := 0
|
||||
// Check if a `.` is at position 7 (zero-indexed)
|
||||
if len(token) > pos && token[pos] == '.' {
|
||||
logger.Debug("Token-Format erkannt, extrahiere Benutzer-ID...")
|
||||
//fmt.Print("CheckToken2: " + token + "\n")
|
||||
// Find the next `:` after the `.`
|
||||
colonPos := strings.Index(token[pos+1:], ":") // Start searching after position 7
|
||||
@@ -69,34 +87,44 @@ func CheckToken(token string) *User {
|
||||
userid, err = strconv.Atoi(uu)
|
||||
//fmt.Printf("Extracted UserID: %v \n", userid)
|
||||
if err != nil {
|
||||
logger.Error("Fehler beim Parsen der Benutzer-ID aus Token: %s", err.Error())
|
||||
//fmt.Print("CheckToken4: " + err.Error() + "\n")
|
||||
return nil
|
||||
}
|
||||
logger.Debug("Benutzer-ID aus Token extrahiert: %d", userid)
|
||||
} else {
|
||||
logger.Debug("Token-Format ungültig: Kein ':' nach '.' gefunden")
|
||||
//fmt.Print("CheckToken5: not found\n")
|
||||
return nil
|
||||
}
|
||||
} else {
|
||||
logger.Debug("Token-Format ungültig: Kein '.' an erwarteter Position")
|
||||
//fmt.Print("CheckToken6: not found\n")
|
||||
return nil
|
||||
}
|
||||
|
||||
if userid > 0 {
|
||||
logger.Debug("Lade Benutzer mit ID: %d", userid)
|
||||
//fmt.Printf("CheckToken6-1: userid %v\n", userid)
|
||||
//fmt.Printf("CheckToken6-1: userid %v\n", uint(userid))
|
||||
err := u.FirstId(uint(userid))
|
||||
if err != nil {
|
||||
logger.Error("Benutzer mit ID %d nicht gefunden: %s", userid, err.Error())
|
||||
//fmt.Printf("CheckToken7: not found error %s\n", err.Error())
|
||||
return nil
|
||||
}
|
||||
logger.Debug("Benutzer gefunden und Token validiert: %s (ID: %d)", u.Username, u.UserID)
|
||||
//fmt.Printf("CheckToken8: found:%s \n", u.Username)
|
||||
return &u
|
||||
}
|
||||
logger.Debug("Token-Validierung fehlgeschlagen: Ungültige Benutzer-ID")
|
||||
//fmt.Print("CheckToken9: not found\n")
|
||||
return nil
|
||||
}
|
||||
|
||||
func LoginUser(c *gin.Context) {
|
||||
logger.Debug("Starte Benutzer-Anmeldung...")
|
||||
|
||||
var user User
|
||||
var input struct {
|
||||
Username string `json:"username"`
|
||||
@@ -104,19 +132,25 @@ func LoginUser(c *gin.Context) {
|
||||
}
|
||||
|
||||
if err := c.ShouldBindJSON(&input); err != nil {
|
||||
logger.Error("Fehler beim Parsen der Login-Daten: %s", err.Error())
|
||||
respondWithError(c, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
logger.Debug("Login-Versuch für Benutzer: %s", input.Username)
|
||||
|
||||
//if err := database.DB.Where("username = ?", input.Username).First(&user).Error; err != nil {
|
||||
if err := user.First(input.Username); err != nil {
|
||||
logger.Warn("Login fehlgeschlagen - Benutzer nicht gefunden: %s", input.Username)
|
||||
respondWithError(c, http.StatusUnauthorized, fmt.Sprintf("Invalid username. or password %v", input))
|
||||
return
|
||||
}
|
||||
|
||||
logger.Debug("Benutzer gefunden, prüfe Passwort für: %s", input.Username)
|
||||
hashedPassword := md5.Sum([]byte(input.Password))
|
||||
fmt.Printf("pwdh: %s", hex.EncodeToString(hashedPassword[:]))
|
||||
if user.PasswordHash != hex.EncodeToString(hashedPassword[:]) {
|
||||
logger.Warn("Login fehlgeschlagen - Ungültiges Passwort für Benutzer: %s", input.Username)
|
||||
respondWithError(c, http.StatusUnauthorized, fmt.Sprintf("Invalid username. or password. %s %s", input.Password, hex.EncodeToString(hashedPassword[:])))
|
||||
return
|
||||
}
|
||||
@@ -127,26 +161,37 @@ func LoginUser(c *gin.Context) {
|
||||
}
|
||||
*/
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"message": "Login successful", "token": GenerateToken(&user)})
|
||||
logger.Info("Login erfolgreich für Benutzer: %s (ID: %d)", user.Username, user.UserID)
|
||||
token := GenerateToken(&user)
|
||||
logger.Debug("Login-Token generiert für Benutzer: %s", user.Username)
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"message": "Login successful", "token": token})
|
||||
}
|
||||
|
||||
// Apply middleware to protected routes
|
||||
func AuthMiddleware() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
logger.Debug("Prüfe Authentifizierung für Request: %s %s", c.Request.Method, c.Request.URL.Path)
|
||||
|
||||
token := c.GetHeader("Authorization")
|
||||
if token == "" {
|
||||
logger.Warn("Authentifizierung fehlgeschlagen - Kein Authorization-Header für %s %s", c.Request.Method, c.Request.URL.Path)
|
||||
respondWithError(c, http.StatusUnauthorized, "Unauthorized")
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
|
||||
logger.Debug("Authorization-Header gefunden, prüfe Token...")
|
||||
user := CheckToken(token)
|
||||
if user == nil {
|
||||
logger.Warn("Authentifizierung fehlgeschlagen - Ungültiger Token für %s %s", c.Request.Method, c.Request.URL.Path)
|
||||
respondWithError(c, http.StatusUnauthorized, "Unauthorized.")
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
|
||||
logger.Debug("Authentifizierung erfolgreich für Benutzer: %s (ID: %d) - %s %s", user.Username, user.UserID, c.Request.Method, c.Request.URL.Path)
|
||||
|
||||
// Set user information in context
|
||||
c.Set("userID", user.UserID)
|
||||
c.Set("username", user.Username)
|
||||
|
||||
Reference in New Issue
Block a user