package main import ( "encoding/json" "fmt" "io" "net/http" "os" "github.com/gorilla/mux" "golang.org/x/crypto/bcrypt" ) // GetUsersHandler handles GET requests to /admin/user func GetUsersHandler(w http.ResponseWriter, r *http.Request) { var users []User db.Find(&users) json.NewEncoder(w).Encode(users) } // CreateUserHandler handles POST requests to /admin/user func CreateUserHandler(w http.ResponseWriter, r *http.Request) { var user User err := json.NewDecoder(r.Body).Decode(&user) if err != nil { http.Error(w, "Invalid request body", http.StatusBadRequest) return } // Hash the password before storing hashedPassword, err := bcrypt.GenerateFromPassword([]byte(user.Password), 12) if err != nil { http.Error(w, "Failed to hash password", http.StatusInternalServerError) return } user.Password = string(hashedPassword) db.Create(&user) json.NewEncoder(w).Encode(user) } // GetUserHandler handles GET requests to /admin/user/{id} func GetUserHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) id := vars["id"] var user User db.First(&user, id) if user.ID == 0 { http.Error(w, "User not found", http.StatusNotFound) return } json.NewEncoder(w).Encode(user) } // DeleteUserHandler handles DELETE requests to /admin/user/{id} func DeleteUserHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) id := vars["id"] var user User db.First(&user, id) if user.ID == 0 { http.Error(w, "User not found", http.StatusNotFound) return } db.Delete(&user) w.WriteHeader(http.StatusNoContent) } // BackupDatabaseHandler handles GET requests to /admin/db func BackupDatabaseHandler(w http.ResponseWriter, r *http.Request) { // ... fmt.Println("BackupDatabaseHandler called") // Open the database file using the path from the config file, err := os.Open(config.DatabasePath) if err != nil { http.Error(w, "Failed to open database file", http.StatusInternalServerError) return } defer file.Close() // Copy the file to the response writer _, err = io.Copy(w, file) if err != nil { http.Error(w, "Failed to send database file", http.StatusInternalServerError) return } } // RestoreDatabaseHandler handles POST requests to /admin/db func RestoreDatabaseHandler(w http.ResponseWriter, r *http.Request) { // Create a backup of the existing database err := createDatabaseBackup() if err != nil { http.Error(w, "Failed to create database backup", http.StatusInternalServerError) return } // Save the new database err = saveNewDatabase(r) if err != nil { http.Error(w, "Failed to save new database", http.StatusInternalServerError) return } // Validate the new database is properly initialized err = validateNewDatabase() if err != nil { http.Error(w, "New database is not properly initialized", http.StatusInternalServerError) return } // Switch to the new database app-wide err = switchToNewDatabase() if err != nil { http.Error(w, "Failed to switch to new database", http.StatusInternalServerError) return } fmt.Println("Database restored successfully") w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(map[string]string{"message": "Database restored successfully"}) } func createDatabaseBackup() error { // Create a backup of the existing database src, err := os.Open(config.DatabasePath) if err != nil { return err } defer src.Close() dst, err := os.Create(config.DatabasePath + ".bak") if err != nil { return err } defer dst.Close() _, err = io.Copy(dst, src) return err } func saveNewDatabase(r *http.Request) error { // Save the new database file, _, err := r.FormFile("database") if err != nil { return err } defer file.Close() dst, err := os.Create(config.DatabasePath) if err != nil { return err } defer dst.Close() _, err = io.Copy(dst, file) return err } func validateNewDatabase() error { // Validate the new database is properly initialized db, err := ConnectDB(config.DatabasePath) if err != nil { return err } defer db.Close() // Check if required tables exist tables := []string{"users", "boxes", "items"} for _, table := range tables { var count int db.Debug().Raw("SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name=?;", table).Row().Scan(&count) if count == 0 { return fmt.Errorf("table %s does not exist", table) } } return nil } func switchToNewDatabase() error { // Switch to the new database app-wide db, err := ConnectDB(config.DatabasePath) if err != nil { return err } // Update the db variable with the new database connection db = db return nil }