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}