server.go

 1package server
 2
 3import (
 4	"fmt"
 5	"log"
 6
 7	"github.com/charmbracelet/soft/config"
 8	appCfg "github.com/charmbracelet/soft/internal/config"
 9	"github.com/charmbracelet/soft/internal/tui"
10
11	"github.com/charmbracelet/wish"
12	bm "github.com/charmbracelet/wish/bubbletea"
13	gm "github.com/charmbracelet/wish/git"
14	lm "github.com/charmbracelet/wish/logging"
15	"github.com/gliderlabs/ssh"
16)
17
18type Server struct {
19	SSHServer *ssh.Server
20	Config    *config.Config
21}
22
23// NewServer returns a new *ssh.Server configured to serve Soft Serve. The SSH
24// server key-pair will be created if none exists. An initial admin SSH public
25// key can be provided with authKey. If authKey is provided, access will be
26// restricted to that key. If authKey is not provided, the server will be
27// publicly writable until configured otherwise by cloning the `config` repo.
28func NewServer(cfg *config.Config) *Server {
29	ac, err := appCfg.NewConfig(cfg)
30	if err != nil {
31		log.Fatal(err)
32	}
33	mw := []wish.Middleware{
34		bm.Middleware(tui.SessionHandler(ac)),
35		gm.Middleware(cfg.RepoPath, ac),
36		lm.Middleware(),
37	}
38	s, err := wish.NewServer(
39		ssh.PublicKeyAuth(ac.PublicKeyHandler),
40		ssh.PasswordAuth(ac.PasswordHandler),
41		wish.WithAddress(fmt.Sprintf("%s:%d", cfg.Host, cfg.Port)),
42		wish.WithHostKeyPath(cfg.KeyPath),
43		wish.WithMiddleware(mw...),
44	)
45	if err != nil {
46		log.Fatalln(err)
47	}
48	return &Server{
49		SSHServer: s,
50		Config:    cfg,
51	}
52}
53
54func (srv *Server) Start() error {
55	return srv.SSHServer.ListenAndServe()
56}