//go:build linux package backup import ( "context" "io" "testing" "github.com/aritmolab/thothii/tools/tht/internal/config" "github.com/aritmolab/thothii/tools/tht/internal/lifecycle" ) func TestRestoreAuthBearingArchiveRefusesNonRootBeforeTransactionOrWrite(t *testing.T) { installation, archive := projectedRestoreFixture(t) deps := restoreTestDependencies(t, newBackupRunner(installation, false)) deps.requireAuthProjection = requireAuthProjectionRestorePrivilege checkpointCalled := false beginCalled := false writeCalled := false deps.checkpoint = func(context.Context, *lifecycle.Transaction, config.Installation, CreateRequest) (Result, error) { checkpointCalled = true return Result{}, nil } deps.beginAuthProjection = func(context.Context, config.Installation) (authProjectionRestoreTransaction, error) { beginCalled = true return nil, nil } deps.restoreFile = func(context.Context, config.Installation, ArchiveEntryMetadata, io.Reader) error { writeCalled = true return nil } previous := restoreProjectionEffectiveUID restoreProjectionEffectiveUID = func() int { return 1000 } t.Cleanup(func() { restoreProjectionEffectiveUID = previous }) if _, err := restoreWithDependencies(context.Background(), installation, RestoreRequest{Archive: archive, Confirm: true}, deps); err == nil { t.Fatal("projected authentication restore unexpectedly accepted non-root execution") } if checkpointCalled || beginCalled || writeCalled { t.Fatalf("non-root restore crossed mutation boundary: checkpoint=%t begin=%t write=%t", checkpointCalled, beginCalled, writeCalled) } }