session.go

 1package server
 2
 3import (
 4	"fmt"
 5
 6	"github.com/aymanbagabas/go-osc52"
 7	tea "github.com/charmbracelet/bubbletea"
 8	appCfg "github.com/charmbracelet/soft-serve/config"
 9	"github.com/charmbracelet/soft-serve/proto"
10	cm "github.com/charmbracelet/soft-serve/server/cmd"
11	"github.com/charmbracelet/soft-serve/ui"
12	"github.com/charmbracelet/soft-serve/ui/common"
13	"github.com/charmbracelet/soft-serve/ui/keymap"
14	"github.com/charmbracelet/soft-serve/ui/styles"
15	"github.com/charmbracelet/wish"
16	bm "github.com/charmbracelet/wish/bubbletea"
17	"github.com/gliderlabs/ssh"
18	zone "github.com/lrstanley/bubblezone"
19)
20
21// SessionHandler is the soft-serve bubbletea ssh session handler.
22func SessionHandler(ac *appCfg.Config) bm.ProgramHandler {
23	return func(s ssh.Session) *tea.Program {
24		pty, _, active := s.Pty()
25		if !active {
26			return nil
27		}
28		cmd := s.Command()
29		initialRepo := ""
30		if len(cmd) == 1 {
31			initialRepo = cmd[0]
32			auth := ac.AuthRepo(initialRepo, s.PublicKey())
33			if auth < proto.ReadOnlyAccess {
34				wish.Fatalln(s, cm.ErrUnauthorized)
35				return nil
36			}
37		}
38		if ac.Cfg.Callbacks != nil {
39			ac.Cfg.Callbacks.Tui("new session")
40		}
41		envs := s.Environ()
42		envs = append(envs, fmt.Sprintf("TERM=%s", pty.Term))
43		output := osc52.NewOutput(s, envs)
44		c := common.Common{
45			Copy:   output,
46			Styles: styles.DefaultStyles(),
47			KeyMap: keymap.DefaultKeyMap(),
48			Width:  pty.Window.Width,
49			Height: pty.Window.Height,
50			Zone:   zone.New(),
51		}
52		m := ui.New(
53			ac,
54			s,
55			c,
56			initialRepo,
57		)
58		p := tea.NewProgram(m,
59			tea.WithInput(s),
60			tea.WithOutput(s),
61			tea.WithAltScreen(),
62			tea.WithoutCatchPanics(),
63			tea.WithMouseCellMotion(),
64		)
65		return p
66	}
67}