1package server
 2
 3import (
 4	"bytes"
 5	"errors"
 6	"os"
 7	"strings"
 8	"testing"
 9	"time"
10
11	"github.com/charmbracelet/soft-serve/proto"
12	cm "github.com/charmbracelet/soft-serve/server/cmd"
13	"github.com/charmbracelet/soft-serve/server/config"
14	bm "github.com/charmbracelet/wish/bubbletea"
15	"github.com/charmbracelet/wish/testsession"
16	"github.com/gliderlabs/ssh"
17	"github.com/matryer/is"
18	"github.com/muesli/termenv"
19	gossh "golang.org/x/crypto/ssh"
20)
21
22func TestSession(t *testing.T) {
23	is := is.New(t)
24	t.Run("unauthorized repo access", func(t *testing.T) {
25		var out bytes.Buffer
26		s := setup(t)
27		s.Stderr = &out
28		defer s.Close()
29		err := s.RequestPty("xterm", 80, 40, nil)
30		is.NoErr(err)
31		err = s.Run("config")
32		// Session writes error and exits
33		is.True(strings.Contains(out.String(), cm.ErrUnauthorized.Error()))
34		var ee *gossh.ExitError
35		is.True(errors.As(err, &ee) && ee.ExitStatus() == 1)
36	})
37	t.Run("authorized repo access", func(t *testing.T) {
38		s := setup(t)
39		s.Stderr = os.Stderr
40		defer s.Close()
41		err := s.RequestPty("xterm", 80, 40, nil)
42		is.NoErr(err)
43		go func() {
44			time.Sleep(1 * time.Second)
45			s.Signal(gossh.SIGTERM)
46			// FIXME: exit with code 0 instead of forcibly closing the session
47			s.Close()
48		}()
49		err = s.Run("test")
50		var ee *gossh.ExitMissingError
51		is.True(errors.As(err, &ee))
52	})
53}
54
55func setup(tb testing.TB) *gossh.Session {
56	tb.Helper()
57	cfg := &config.Config{
58		Host:     "",
59		SSH:      config.SSHConfig{Port: randomPort()},
60		Git:      config.GitConfig{Port: 9418},
61		DataPath: tb.TempDir(),
62		InitialAdminKeys: []string{
63			"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMJlb/qf2B2kMNdBxfpCQqI2ctPcsOkdZGVh5zTRhKtH",
64		},
65		AnonAccess: proto.ReadOnlyAccess,
66	}
67	return testsession.New(tb, &ssh.Server{
68		Handler: bm.MiddlewareWithProgramHandler(SessionHandler(cfg), termenv.ANSI256)(func(s ssh.Session) {
69			_, _, active := s.Pty()
70			tb.Logf("PTY active %v", active)
71			tb.Log(s.Command())
72			s.Exit(0)
73		}),
74	}, nil)
75}