~bigbes/sr-ht-dolt

84c33df2173045ab20c01e6f9db98ecb5472d8a4 — Eugene Blikh 9 days ago 0af9ccd
test: build the fixture config and the keyset with ecoretest

The hand-built ini in web_test.go, the random fernet key in authn's
TestMain and the same seeding copied into the git-hook test are one call
to ecoretest now. The keys are fixed rather than generated on purpose:
they secure nothing inside a test process, and a constant keyset is what
lets two packages of this service initialise without the second rotating
what the first sealed with.

The synthetic instance runs in production mode, so the environment
banner is off in tests unless one asks for it.
3 files changed, 24 insertions(+), 64 deletions(-)

M authn/authn_test.go
M cmd/dolt-git-hook/main_test.go
M web/web_test.go
M authn/authn_test.go => authn/authn_test.go +13 -24
@@ 3,7 3,6 @@ package authn
import (
	"context"
	"crypto/ed25519"
	"encoding/base64"
	"encoding/json"
	"os"
	"testing"


@@ 12,36 11,26 @@ import (
	"sourcecraft.dev/bigbes/sr-ht-core/auth"
	"sourcecraft.dev/bigbes/sr-ht-core/config"
	"sourcecraft.dev/bigbes/sr-ht-core/crypto"

	"sourcecraft.dev/bigbes/sr-ht-ecore/ecoretest"

	"github.com/dolthub/dolt/go/libraries/doltcore/creds"
	"github.com/fernet/fernet-go"
	"github.com/vaughan0/go-ini"
	jose "gopkg.in/go-jose/go-jose.v2"
	"gopkg.in/go-jose/go-jose.v2/jwt"
)

// TestMain synthesizes an in-memory instance config (random fernet network key +
// random ed25519 webhooks seed) and runs crypto.InitCrypto once, so that cookie
// encryption (crypto.Encrypt / DecryptWithoutExpiration) and bearer-token HMAC
// (auth.BearerToken.Encode / auth.DecodeBearerToken) share a keyset across the
// whole package's tests. No network, no Postgres.
// TestMain seeds the process-global crypto state from sr-ht-ecore's fixed test
// keyset, so that cookie encryption (crypto.Encrypt /
// DecryptWithoutExpiration) and bearer-token HMAC (auth.BearerToken.Encode /
// auth.DecodeBearerToken) share a keyset across the whole package's tests. No
// network, no Postgres.
//
// The keys are constants rather than generated ones: they secure nothing inside
// a test process, and a fixed keyset is what lets two packages of this service
// both initialise without the second rotating what the first sealed with.
func TestMain(m *testing.M) {
	var fk fernet.Key
	if err := fk.Generate(); err != nil {
		panic(err)
	}

	seed := make([]byte, ed25519.SeedSize)
	// Deterministic non-zero seed is fine; these keys never leave the test.
	for i := range seed {
		seed[i] = byte(i + 1)
	}

	conf := ini.File{
		"sr.ht":    ini.Section{"network-key": fk.Encode()},
		"webhooks": ini.Section{"private-key": base64.StdEncoding.EncodeToString(seed)},
	}
	crypto.InitCrypto(conf)

	ecoretest.InitCrypto()
	os.Exit(m.Run())
}


M cmd/dolt-git-hook/main_test.go => cmd/dolt-git-hook/main_test.go +6 -20
@@ 2,8 2,6 @@ package main

import (
	"bytes"
	"crypto/ed25519"
	"encoding/base64"
	"encoding/json"
	"io"
	"net/http"


@@ 12,29 10,17 @@ import (
	"testing"
	"time"

	"github.com/fernet/fernet-go"
	"github.com/vaughan0/go-ini"

	"sourcecraft.dev/bigbes/sr-ht-core/crypto"

	"sourcecraft.dev/bigbes/sr-ht-ecore/ecoretest"
)

// initTestCrypto installs a random network key + webhooks seed into the shared
// crypto globals, mirroring the sr-ht-core test pattern, so createCompanion's
// crypto.Encrypt and the test server's DecryptWithExpiration share a keyset.
// initTestCrypto installs sr-ht-ecore's fixed test keyset into the shared
// crypto globals, so createCompanion's crypto.Encrypt and the test server's
// DecryptWithExpiration share one.
func initTestCrypto(t *testing.T) {
	t.Helper()
	var fk fernet.Key
	if err := fk.Generate(); err != nil {
		t.Fatalf("fernet generate: %v", err)
	}
	seed := make([]byte, ed25519.SeedSize)
	for i := range seed {
		seed[i] = byte(i + 1)
	}
	crypto.InitCrypto(ini.File{
		"sr.ht":    ini.Section{"network-key": fk.Encode()},
		"webhooks": ini.Section{"private-key": base64.StdEncoding.EncodeToString(seed)},
	})
	ecoretest.InitCrypto()
}

func samplePush() pushContext {

M web/web_test.go => web/web_test.go +5 -20
@@ 18,10 18,10 @@ import (
	"github.com/go-chi/chi/v5"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	"github.com/vaughan0/go-ini"
	"sourcecraft.dev/bigbes/sr-ht-core/auth"

	"sourcecraft.dev/bigbes/sr-ht-ecore/csrf"
	"sourcecraft.dev/bigbes/sr-ht-ecore/ecoretest"
	"sourcecraft.dev/bigbes/sr-ht-ecore/pages"

	"sourcecraft.dev/bigbes/sr-ht-dolt/authn"


@@ 30,24 30,9 @@ import (
	"sourcecraft.dev/bigbes/sr-ht-dolt/db"
)

const selfOrigin = "https://dolt.example"

// testConfig synthesizes a config with the origins the chrome/CSRF checks read.
func testConfig() ini.File {
	return ini.File{
		"sr.ht": ini.Section{
			"environment": "development",
			"site-name":   "sr.ht",
			"owner-name":  "admin",
			"owner-email": "admin@example.com",
		},
		"dolt.sr.ht":  ini.Section{"origin": selfOrigin},
		"meta.sr.ht":  ini.Section{"origin": "https://meta.example"},
		"git.sr.ht":   ini.Section{"origin": "https://git.example"},
		"todo.sr.ht":  ini.Section{"origin": "https://todo.example"},
		"paste.sr.ht": ini.Section{"origin": "https://paste.example"},
	}
}
// selfOrigin is what the synthetic instance config gives this service, and so
// what the chrome and the same-origin guard read as ours.
var selfOrigin = ecoretest.Origin(serviceName)

// --- fakes -------------------------------------------------------------------



@@ 327,7 312,7 @@ func newHarnessWithStatic(t *testing.T, staticDir string) *harness {
	users := &fakeUsers{byName: map[string]*core.Caller{}}

	cfg := Config{
		Conf:      testConfig(),
		Conf:      ecoretest.Config(serviceName),
		ReposRoot: "/var/lib/dolt",
		StaticDir: staticDir,
		Stores:    stores,