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