2024-10-16 22:10:20 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
"net/http"
|
|
|
|
"os"
|
|
|
|
|
|
|
|
"github.com/gorilla/mux"
|
2024-10-17 15:03:07 +00:00
|
|
|
"golang.org/x/crypto/bcrypt"
|
2024-10-16 22:10:20 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// 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
|
|
|
|
}
|
2024-10-17 15:03:07 +00:00
|
|
|
|
|
|
|
// 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)
|
|
|
|
|
2024-10-16 22:10:20 +00:00
|
|
|
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) {
|
2024-10-16 22:28:00 +00:00
|
|
|
// 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
|
|
|
|
}
|
2024-10-17 05:08:28 +00:00
|
|
|
fmt.Println("Database restored successfully")
|
2024-10-16 22:10:20 +00:00
|
|
|
w.WriteHeader(http.StatusOK)
|
2024-10-16 22:28:00 +00:00
|
|
|
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
|
2024-10-16 22:10:20 +00:00
|
|
|
}
|