83 lines
2.7 KiB
Go
83 lines
2.7 KiB
Go
package builder
|
|
|
|
import (
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"net/url"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/novox/mesh-controller/internal/facts"
|
|
)
|
|
|
|
// **A check's container never sees the forge credential** (novox/hq issue 462): the toolchain container
|
|
// mounts the workspace as HOME, so a credential kept there — or a clone's .git/config carrying one — is
|
|
// readable by any pull request's merge-check.sh, and printed, kept on the bus for days.
|
|
|
|
const (
|
|
forgeSecret = "sw0rdfi5h-forge"
|
|
forgeURL = "http://mesh_novox_builder:" + forgeSecret + "@forge.invalid:20000"
|
|
besideSecret = "b3side-t0ken"
|
|
npmSecret = "npm-s3cret-t0ken"
|
|
)
|
|
|
|
// aFactsRegistry is an artifact store holding the facts snapshot, and nothing else.
|
|
func aFactsRegistry(t *testing.T) string {
|
|
t.Helper()
|
|
body, err := json.Marshal(facts.Facts{Format: facts.Format, Taken: time.Now().UTC(),
|
|
Versions: facts.Versions{Bus: "2.11.17", Store: "17.11"}, Machines: []facts.Machine{{Name: "abcdef", Length: 6}}})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
sum := sha256.Sum256(body)
|
|
digest := "sha256:" + hex.EncodeToString(sum[:])
|
|
manifest, _ := json.Marshal(map[string]any{"schemaVersion": 2, "layers": []map[string]any{
|
|
{"mediaType": facts.MediaType, "digest": digest, "size": len(body)}}})
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
switch {
|
|
case strings.Contains(r.URL.Path, "/manifests/"):
|
|
w.Write(manifest)
|
|
case strings.HasSuffix(r.URL.Path, "/blobs/"+digest):
|
|
w.Write(body)
|
|
default:
|
|
http.NotFound(w, r)
|
|
}
|
|
}))
|
|
t.Cleanup(srv.Close)
|
|
return strings.TrimPrefix(srv.URL, "http://")
|
|
}
|
|
|
|
// bareURL is a URL with its userinfo left out.
|
|
func bareURL(t *testing.T, raw string) string {
|
|
u, err := url.Parse(raw)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
u.User = nil
|
|
return u.String()
|
|
}
|
|
|
|
// Every line a repository's own check prints is published to the build's log redacted.
|
|
|
|
func TestTheRedactorHidesTheForgeCredentialAndShapes(t *testing.T) {
|
|
r := redactorFor(GitCredential{URL: forgeURL})
|
|
for in, want := range map[string]string{
|
|
"the secret alone: " + forgeSecret: "the secret alone: [redacted: the forge credential]",
|
|
"go test ./... ok": "go test ./... ok",
|
|
"--password hunter22 and done": "--password [redacted: the word after --password] and done",
|
|
"commit 3b6b54a0c1d2e3f4a5b6c7d8e9f0": "commit 3b6b54a0c1d2e3f4a5b6c7d8e9f0",
|
|
} {
|
|
if got := r.redact(in); got != want {
|
|
t.Errorf("%q redacted as %q, want %q", in, got, want)
|
|
}
|
|
}
|
|
}
|
|
|
|
// A build's clone of a URL carrying userinfo records it without, so no build leaves a credential in
|
|
// workspace/source/.git/config while it runs either (novox/hq issue 462); the tree itself is gone when the
|
|
// build ends.
|