Export and import working

This commit is contained in:
2025-12-29 23:06:04 +01:00
parent 78b0582879
commit af967fc0ea
5 changed files with 25 additions and 5 deletions
+5 -1
View File
@@ -12,6 +12,7 @@ The transfer package provides character export and import functionality for the
- Learning data (all learning_* tables)
- Audit log entries
- GSM master data (skills, spells, weapons, equipment definitions)
- **Security**: Sensitive user data (password, updated_at, reset tokens) is removed from exports
- **Smart Import**:
- Identifies existing GSM data by name (not ID) to avoid duplicates
@@ -52,7 +53,9 @@ Imports a character from JSON data
### Export a Character
```bash
curl http://localhost:8180/api/transfer/export/18 > character_export.json
curl http://localhost:8180/api/transfer/export/18 \
-H "Authorization: Bearer XXXXXXXXXXX" \
> character_export.json
```
### Download a Character
@@ -64,6 +67,7 @@ wget http://localhost:8180/api/transfer/download/18
```bash
curl -X POST http://localhost:8180/api/transfer/import \
-H "Content-Type: application/json" \
-H "Authorization: Bearer XXXXXXXXXXX" \
-d @character_export.json
```
+7
View File
@@ -4,6 +4,7 @@ import (
"bamort/database"
"bamort/models"
"fmt"
"time"
)
// CharacterExport contains all data needed to export and import a character
@@ -61,6 +62,12 @@ func ExportCharacter(characterID uint) (*CharacterExport, error) {
return nil, fmt.Errorf("failed to load character: %w", err)
}
// Remove sensitive user information from export
char.User.PasswordHash = ""
char.User.UpdatedAt = time.Time{}
char.User.ResetPwHash = nil
char.User.ResetPwHashExpires = nil
export := &CharacterExport{
Character: char,
}
+9
View File
@@ -63,6 +63,15 @@ func TestExportCharacter(t *testing.T) {
if reimported.Character.ID != characterID {
t.Errorf("After JSON round-trip, expected character ID %d, got %d", characterID, reimported.Character.ID)
}
// Verify sensitive user data is removed
if exportData.Character.User.PasswordHash != "" {
t.Error("Password hash should be empty in export")
}
if !exportData.Character.User.UpdatedAt.IsZero() {
t.Error("UpdatedAt should be zero time in export")
}
}
func TestExportCharacterIncludesSkills(t *testing.T) {
+1 -1
View File
@@ -64,7 +64,7 @@ func DownloadCharacterHandler(c *gin.Context) {
// ImportCharacterHandler handles character import requests
func ImportCharacterHandler(c *gin.Context) {
// Get user ID from context (set by auth middleware)
userID, exists := c.Get("user_id")
userID, exists := c.Get("userID")
if !exists {
c.JSON(http.StatusUnauthorized, gin.H{"error": "User not authenticated"})
return
+3 -3
View File
@@ -117,11 +117,11 @@ func TestImportCharacterHandlerAPI(t *testing.T) {
req, _ := http.NewRequest("POST", "/api/transfer/import", bytes.NewBuffer(jsonData))
req.Header.Set("Content-Type", "application/json")
// Mock user_id in context (normally set by auth middleware)
// Mock userID in context (normally set by auth middleware)
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
c.Request = req
c.Set("user_id", uint(1))
c.Set("userID", uint(1))
ImportCharacterHandler(c)
@@ -170,7 +170,7 @@ func TestImportInvalidJSONAPI(t *testing.T) {
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
c.Request = req
c.Set("user_id", uint(1))
c.Set("userID", uint(1))
ImportCharacterHandler(c)