1package server
 2
 3import (
 4	"fmt"
 5	"net"
 6	"path/filepath"
 7	"strings"
 8	"testing"
 9
10	"github.com/charmbracelet/keygen"
11	"github.com/charmbracelet/soft-serve/server/config"
12	"github.com/charmbracelet/ssh"
13	"github.com/matryer/is"
14	gossh "golang.org/x/crypto/ssh"
15)
16
17func randomPort() int {
18	addr, _ := net.Listen("tcp", ":0") //nolint:gosec
19	_ = addr.Close()
20	return addr.Addr().(*net.TCPAddr).Port
21}
22
23func setupServer(tb testing.TB) (*Server, *config.Config, string) {
24	tb.Helper()
25	tb.Log("creating keypair")
26	pub, pkPath := createKeyPair(tb)
27	dp := tb.TempDir()
28	sshPort := fmt.Sprintf(":%d", randomPort())
29	tb.Setenv("SOFT_SERVE_DATA_PATH", dp)
30	tb.Setenv("SOFT_SERVE_INITIAL_ADMIN_KEY", authorizedKey(pub))
31	tb.Setenv("SOFT_SERVE_SSH_LISTEN_ADDR", sshPort)
32	tb.Setenv("SOFT_SERVE_GIT_LISTEN_ADDR", fmt.Sprintf(":%d", randomPort()))
33	cfg := config.DefaultConfig()
34	tb.Log("configuring server")
35	s, err := NewServer(cfg)
36	if err != nil {
37		tb.Fatal(err)
38	}
39	go func() {
40		tb.Log("starting server")
41		s.Start()
42	}()
43	tb.Cleanup(func() {
44		s.Close()
45	})
46	return s, cfg, pkPath
47}
48
49func createKeyPair(tb testing.TB) (ssh.PublicKey, string) {
50	tb.Helper()
51	is := is.New(tb)
52	keyDir := tb.TempDir()
53	kp, err := keygen.NewWithWrite(filepath.Join(keyDir, "id"), nil, keygen.Ed25519)
54	is.NoErr(err)
55	pubkey, _, _, _, err := ssh.ParseAuthorizedKey(kp.PublicKey())
56	is.NoErr(err)
57	return pubkey, filepath.Join(keyDir, "id_ed25519")
58}
59
60func authorizedKey(pk ssh.PublicKey) string {
61	return strings.TrimSpace(string(gossh.MarshalAuthorizedKey(pk)))
62}