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