1package server
2
3import (
4 "fmt"
5 "path/filepath"
6 "testing"
7
8 "github.com/charmbracelet/keygen"
9 ggit "github.com/charmbracelet/soft-serve/git"
10 "github.com/charmbracelet/soft-serve/server/config"
11 "github.com/gliderlabs/ssh"
12 "github.com/go-git/go-git/v5"
13 gconfig "github.com/go-git/go-git/v5/config"
14 "github.com/go-git/go-git/v5/plumbing/object"
15 gssh "github.com/go-git/go-git/v5/plumbing/transport/ssh"
16 "github.com/matryer/is"
17 cssh "golang.org/x/crypto/ssh"
18)
19
20var (
21 cfg = &config.Config{
22 Host: "",
23 SSH: config.SSHConfig{
24 Port: 22222,
25 },
26 }
27)
28
29func TestPushRepo(t *testing.T) {
30 is := is.New(t)
31 _, pkPath := createKeyPair(t)
32 s := setupServer(t)
33 defer s.Close()
34 err := s.Reload()
35 is.NoErr(err)
36
37 rp := t.TempDir()
38 r, err := git.PlainInit(rp, false)
39 is.NoErr(err)
40 wt, err := r.Worktree()
41 is.NoErr(err)
42 _, err = wt.Filesystem.Create("testfile")
43 is.NoErr(err)
44 _, err = wt.Add("testfile")
45 is.NoErr(err)
46 author := &object.Signature{
47 Name: "test",
48 Email: "",
49 }
50 _, err = wt.Commit("test commit", &git.CommitOptions{
51 All: true,
52 Author: author,
53 Committer: author,
54 })
55 is.NoErr(err)
56 _, err = r.CreateRemote(&gconfig.RemoteConfig{
57 Name: "origin",
58 URLs: []string{fmt.Sprintf("ssh://%s:%d/%s", cfg.Host, cfg.SSH.Port, "testrepo")},
59 })
60 auth, err := gssh.NewPublicKeysFromFile("git", pkPath, "")
61 is.NoErr(err)
62 auth.HostKeyCallbackHelper = gssh.HostKeyCallbackHelper{
63 HostKeyCallback: cssh.InsecureIgnoreHostKey(),
64 }
65 err = r.Push(&git.PushOptions{
66 RemoteName: "origin",
67 Auth: auth,
68 })
69 is.NoErr(err)
70}
71
72func TestCloneRepo(t *testing.T) {
73 is := is.New(t)
74 _, pkPath := createKeyPair(t)
75 s := setupServer(t)
76 defer s.Close()
77 err := s.Reload()
78 is.NoErr(err)
79
80 dst := t.TempDir()
81 url := fmt.Sprintf("ssh://%s:%d/config", cfg.Host, cfg.SSH.Port)
82 err = ggit.Clone(url, dst, ggit.CloneOptions{
83 CommandOptions: ggit.CommandOptions{
84 Envs: []string{
85 fmt.Sprintf(`GIT_SSH_COMMAND=ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i %s -F /dev/null`, pkPath),
86 },
87 },
88 })
89 is.NoErr(err)
90}
91
92func setupServer(t *testing.T) *Server {
93 t.Helper()
94 tmpdir := t.TempDir()
95 cfg.DataPath = tmpdir
96 s := NewServer(cfg)
97 go func() {
98 s.Start()
99 }()
100 t.Cleanup(func() {
101 s.Close()
102 })
103 return s
104}
105
106func createKeyPair(t *testing.T) (ssh.PublicKey, string) {
107 t.Helper()
108 is := is.New(t)
109 keyDir := t.TempDir()
110 kp, err := keygen.NewWithWrite(filepath.Join(keyDir, "id"), nil, keygen.Ed25519)
111 is.NoErr(err)
112 pubkey, _, _, _, err := ssh.ParseAuthorizedKey(kp.PublicKey())
113 is.NoErr(err)
114 return pubkey, filepath.Join(keyDir, "id_ed25519")
115}