package executor
import (
"context"
"encoding/base64"
"io"
"log/slog"
"strings"
"testing"
"github.com/bluesky-social/indigo/atproto/syntax"
"tangled.org/core/notifier"
"tangled.org/core/spindle/config"
millv1 "tangled.org/core/spindle/mill/proto/gen"
"tangled.org/core/spindle/models"
"tangled.org/core/spindle/secrets"
"tangled.org/core/workflow"
)
const maskedToken = "eyJhbGciOiJFUzI1NiJ9.eyJzdWIiOiJkaWQ6cGxjOnJlcG8ifQ.c2ln"
// the live frames the mill serves unauthenticated must hide everything the
// persisted log hides, encoded variants included
func TestLiveStreamMasksEncodedCredentials(t *testing.T) {
d := testDB(t)
n := notifier.New()
enc := newCaptureEncoder()
e := &Executor{
cfg: &config.Config{Server: config.Server{LogDir: t.TempDir()}},
db: d,
n: &n,
l: slog.New(slog.NewTextHandler(io.Discard, nil)),
active: make(map[string]*reservation),
maxOutboxBytes: 10 * 1024 * 1024,
enc: enc,
}
if err := e.initOutbox(); err != nil {
t.Fatal(err)
}
e.lifecycleCtx = context.Background()
inner := &fakeEngine{secrets: make(chan []secrets.UnlockedSecret, 1), done: make(chan struct{})}
slot := &fakeSlot{}
repoDid, err := syntax.ParseDID("did:web:example.com")
if err != nil {
t.Fatal(err)
}
repoDidString := repoDid.String()
res := &reservation{
leaseID: "lease-1",
wid: models.WorkflowId{PipelineId: models.PipelineId("r"), Name: "build"},
realEngine: inner,
slot: slot,
wf: &models.Workflow{Name: "build", Steps: []models.Step{fakeStep{}}},
pipeline: &models.Pipeline{
RepoDid: repoDid,
TriggerMetadata: &workflow.TriggerMetadata{
Repo: &workflow.TriggerRepo{RepoDid: &repoDidString},
},
TrustedSource: true,
},
}
e.active[res.leaseID] = res
e.handleCommit(context.Background(), &millv1.CommitLease{
LeaseId: res.leaseID,
Secrets: []*millv1.Secret{{Key: models.IDTokenEnvVar, Value: maskedToken}},
})
encoded := base64.StdEncoding.EncodeToString([]byte(maskedToken))
for name, line := range map[string]string{
"raw": models.IDTokenEnvVar + "=" + maskedToken,
"base64": "echo $" + models.IDTokenEnvVar + " | base64: " + encoded,
"unpadded": "no-pad: " + strings.TrimRight(encoded, "="),
} {
masked := e.maskSecrets(res, line)
if strings.Contains(masked, maskedToken) || strings.Contains(masked, encoded) {
t.Fatalf("%s line reached the live stream: %q", name, masked)
}
if !strings.Contains(masked, "***") {
t.Fatalf("%s line was not masked at all: %q", name, masked)
}
}
if res.stopTail != nil {
res.stopTail()
}
e.jobsWG.Wait()
}