feat: establish NekoNest Cloud control and relay
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
package tenantbackup
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/klarkxy/nekonest-cloud/relay/internal/tenantfs"
|
||||
"github.com/klarkxy/nekonest-cloud/relay/internal/tenantstore"
|
||||
"github.com/klarkxy/nekonest/relaycore/protocol"
|
||||
)
|
||||
|
||||
func TestCreateVerifyAndRestoreTenantBackup(t *testing.T) {
|
||||
const tenantID = "tenant_0123456789abcdef0123456789abcdef"
|
||||
sourceRoot := t.TempDir()
|
||||
paths, err := tenantfs.Resolve(sourceRoot, tenantID)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
store, err := tenantstore.NewWithTransportMode(paths.Database, string(protocol.TransportSealed))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
token, err := store.RegisterDevice("host_0123456789abcdef0123456789abcdef", "Host", "linux")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := store.Close(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
attachmentID := "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
if err := os.WriteFile(filepath.Join(paths.Attachments, attachmentID+".bin"), []byte("sealed payload"), 0o600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := os.WriteFile(filepath.Join(paths.Attachments, attachmentID+".json"), []byte(`{"id":"`+attachmentID+`"}`), 0o600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
result, err := Create(context.Background(), sourceRoot, t.TempDir(), tenantID, 7, time.Date(2026, 8, 12, 12, 0, 0, 0, time.UTC))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := Verify(context.Background(), result.Path, tenantID, 7, result.ManifestSHA256); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if resolved, err := ResolveReference(filepath.Dir(filepath.Dir(result.Path)), result.BackupRef); err != nil || resolved != result.Path {
|
||||
t.Fatalf("backup reference did not resolve: %q err=%v", resolved, err)
|
||||
}
|
||||
targetRoot := t.TempDir()
|
||||
restored, err := Restore(context.Background(), result.Path, targetRoot, tenantID, 7, result.ManifestSHA256)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if retried, err := Restore(context.Background(), result.Path, targetRoot, tenantID, 7, result.ManifestSHA256); err != nil || retried.Root != restored.Root {
|
||||
t.Fatalf("idempotent restore failed: %#v err=%v", retried, err)
|
||||
}
|
||||
restoredStore, err := tenantstore.NewWithTransportMode(restored.Database, string(protocol.TransportSealed))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer restoredStore.Close()
|
||||
if !restoredStore.ValidateDeviceToken("host_0123456789abcdef0123456789abcdef", token) {
|
||||
t.Fatal("restored database lost the device credential")
|
||||
}
|
||||
payload, err := os.ReadFile(filepath.Join(restored.Attachments, attachmentID+".bin"))
|
||||
if err != nil || string(payload) != "sealed payload" {
|
||||
t.Fatalf("restored attachment = %q err=%v", payload, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVerifyRejectsTamperedBackup(t *testing.T) {
|
||||
const tenantID = "tenant_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
root := t.TempDir()
|
||||
paths, err := tenantfs.Resolve(root, tenantID)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
store, err := tenantstore.NewWithTransportMode(paths.Database, string(protocol.TransportSealed))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := store.Close(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
result, err := Create(context.Background(), root, t.TempDir(), tenantID, 1, time.Now().UTC())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
file, err := os.OpenFile(filepath.Join(result.Path, "relay.db"), os.O_WRONLY|os.O_APPEND, 0)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
_, _ = file.Write([]byte("tamper"))
|
||||
_ = file.Close()
|
||||
if _, err := Verify(context.Background(), result.Path, tenantID, 1, result.ManifestSHA256); err == nil {
|
||||
t.Fatal("tampered backup was accepted")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user