session_test.go

 1package server
 2
 3import (
 4	"bytes"
 5	"errors"
 6	"os"
 7	"strconv"
 8	"strings"
 9	"testing"
10	"time"
11
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		go func() {
32			time.Sleep(1 * time.Second)
33			s.Signal(gossh.SIGTERM)
34			// FIXME: exit with code 0 instead of forcibly closing the session
35			s.Close()
36		}()
37		err = s.Run("config")
38		// Session writes error and exits
39		is.True(strings.Contains(out.String(), cm.ErrUnauthorized.Error()))
40		var ee *gossh.ExitError
41		is.True(errors.As(err, &ee) && ee.ExitStatus() == 1)
42	})
43	t.Run("authorized repo access", func(t *testing.T) {
44		s := setup(t)
45		s.Stderr = os.Stderr
46		defer s.Close()
47		err := s.RequestPty("xterm", 80, 40, nil)
48		is.NoErr(err)
49		go func() {
50			time.Sleep(1 * time.Second)
51			s.Signal(gossh.SIGTERM)
52			// FIXME: exit with code 0 instead of forcibly closing the session
53			s.Close()
54		}()
55		err = s.Run("test")
56		var ee *gossh.ExitMissingError
57		is.True(errors.As(err, &ee))
58	})
59}
60
61func setup(tb testing.TB) *gossh.Session {
62	tb.Helper()
63	is := is.New(tb)
64	dp := tb.TempDir()
65	is.NoErr(os.Setenv("SOFT_SERVE_DATA_PATH", dp))
66	is.NoErr(os.Setenv("SOFT_SERVE_ANON_ACCESS", "read-only"))
67	is.NoErr(os.Setenv("SOFT_SERVE_GIT_PORT", "9418"))
68	is.NoErr(os.Setenv("SOFT_SERVE_SSH_PORT", strconv.Itoa(randomPort())))
69	tb.Cleanup(func() {
70		is.NoErr(os.Unsetenv("SOFT_SERVE_DATA_PATH"))
71		is.NoErr(os.Unsetenv("SOFT_SERVE_ANON_ACCESS"))
72		is.NoErr(os.Unsetenv("SOFT_SERVE_GIT_PORT"))
73		is.NoErr(os.Unsetenv("SOFT_SERVE_SSH_PORT"))
74		is.NoErr(os.RemoveAll(dp))
75	})
76	cfg := config.DefaultConfig()
77	return testsession.New(tb, &ssh.Server{
78		Handler: bm.MiddlewareWithProgramHandler(SessionHandler(cfg), termenv.ANSI256)(func(s ssh.Session) {
79			_, _, active := s.Pty()
80			tb.Logf("PTY active %v", active)
81			tb.Log(s.Command())
82			s.Exit(0)
83		}),
84	}, nil)
85}