77 lines
2.2 KiB
Go
77 lines
2.2 KiB
Go
package importexport_test
|
|
|
|
import (
|
|
"archive/zip"
|
|
"bytes"
|
|
"context"
|
|
"io"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"git.zaynet.fr/DoGaMa/DoGaMa-serv/internal/auth"
|
|
"git.zaynet.fr/DoGaMa/DoGaMa-serv/internal/importexport"
|
|
"git.zaynet.fr/DoGaMa/DoGaMa-serv/internal/persistence/sqlite"
|
|
)
|
|
|
|
func TestStageValidZIPAndRejectTraversal(t *testing.T) {
|
|
ctx := context.Background()
|
|
root := t.TempDir()
|
|
db, err := sqlite.Open(ctx, filepath.Join(root, "dogama.db"))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer db.Close()
|
|
authService := auth.New(db)
|
|
if err := authService.BootstrapAdmin(ctx, "admin", "correct horse battery staple"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
session, err := authService.Login(ctx, "admin", "correct horse battery staple", "192.0.2.1:1234")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
actor, err := authService.Authenticate(ctx, session.Token)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
service, err := importexport.New(sqlite.NewRepository(db), filepath.Join(root, "imports"))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
policy := importexport.Policy{AcceptedFormats: []string{"zip"}, MaxExpandedBytes: 1 << 20, RequiredPaths: []string{"Level.sav", "Players"}}
|
|
valid := zipBytes(t, map[string]string{"Save/Level.sav": "world", "Save/Players/player.sav": "player"})
|
|
result, err := service.Stage(ctx, actor.ID, "zip", bytes.NewReader(valid), policy)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if result.Status != "validated" || result.Confidence != "confirmed" || result.FileCount != 2 {
|
|
t.Fatalf("import = %#v", result)
|
|
}
|
|
unsafe := zipBytes(t, map[string]string{"../escape": "bad", "Level.sav": "world", "Players/player": "player"})
|
|
if _, err := service.Stage(ctx, actor.ID, "zip", bytes.NewReader(unsafe), policy); err == nil {
|
|
t.Fatal("traversal archive was accepted")
|
|
}
|
|
if _, err := os.Stat(filepath.Join(root, "escape")); !os.IsNotExist(err) {
|
|
t.Fatalf("escape path exists: %v", err)
|
|
}
|
|
}
|
|
|
|
func zipBytes(t *testing.T, files map[string]string) []byte {
|
|
t.Helper()
|
|
var buffer bytes.Buffer
|
|
writer := zip.NewWriter(&buffer)
|
|
for name, body := range files {
|
|
entry, err := writer.Create(name)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err := io.WriteString(entry, body); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
if err := writer.Close(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
return buffer.Bytes()
|
|
}
|