82 lines
2.6 KiB
Go
82 lines
2.6 KiB
Go
//go:build !windows
|
|
|
|
package backup
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/aritmolab/thothii/tools/tht/internal/config"
|
|
"github.com/aritmolab/thothii/tools/tht/internal/safeio"
|
|
)
|
|
|
|
func TestStageArchiveRejectsSymlinkedInstallationAncestor(t *testing.T) {
|
|
root, err := filepath.EvalSymlinks(t.TempDir())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
realProject := filepath.Join(root, "real-project")
|
|
linkedProject := filepath.Join(root, "linked-project")
|
|
if err := os.Mkdir(realProject, 0o700); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := os.Symlink(realProject, linkedProject); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
installation := config.Installation{
|
|
Path: filepath.Join(linkedProject, "deploy", "local-dev", "thothii-installation.yaml"),
|
|
ProjectDirectory: linkedProject,
|
|
}
|
|
if err := os.MkdirAll(installation.ControlDirectory(), 0o700); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
archive := filepath.Join(root, "valid.zip")
|
|
writePreflightArchive(t, archive, preflightArchiveSpec{
|
|
entries: []preflightArchiveEntry{{path: "configuration/operator.env", body: []byte("safe")}},
|
|
})
|
|
result, err := Preflight(context.Background(), installation, PreflightRequest{Archive: archive, Confirm: true}, permissivePreflightDependencies())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer result.CloseArchive()
|
|
|
|
if _, err := result.StageArchive(context.Background()); err == nil || !strings.Contains(err.Error(), "staging root") {
|
|
t.Fatalf("StageArchive() error = %v, want unsafe symlinked staging-root rejection", err)
|
|
}
|
|
}
|
|
|
|
func TestStageArchiveCreatesUnixPrivateRegularFile(t *testing.T) {
|
|
installation := preflightTestInstallation(t)
|
|
if err := os.MkdirAll(installation.ControlDirectory(), 0o700); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
archive := filepath.Join(t.TempDir(), "valid.zip")
|
|
writePreflightArchive(t, archive, preflightArchiveSpec{
|
|
entries: []preflightArchiveEntry{{path: "configuration/operator.env", body: []byte("safe")}},
|
|
})
|
|
result, err := Preflight(context.Background(), installation, PreflightRequest{Archive: archive, Confirm: true}, permissivePreflightDependencies())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer result.CloseArchive()
|
|
|
|
staged, err := result.StageArchive(context.Background())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer staged.Close()
|
|
if err := safeio.ValidatePrivateRegular(staged.path); err != nil {
|
|
t.Fatalf("staged archive privacy = %v, want owner-private regular file", err)
|
|
}
|
|
info, err := os.Lstat(staged.path)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if got := info.Mode().Perm(); got != 0o600 {
|
|
t.Fatalf("staged archive mode = %#o, want 0600", got)
|
|
}
|
|
}
|