Detailed changes
@@ -2,6 +2,10 @@ package main
import (
"log"
+ "smoothie/server"
+ bm "smoothie/server/middleware/bubbletea"
+ gm "smoothie/server/middleware/git"
+ lm "smoothie/server/middleware/logging"
"smoothie/tui"
tea "github.com/charmbracelet/bubbletea"
@@ -20,9 +24,13 @@ func main() {
if err != nil {
log.Fatalln(err)
}
- btm := BubbleTeaMiddleware(tui.SessionHandler, tea.WithAltScreen())
- gm := GitMiddleware(cfg.RepoPath)
- s, err := NewServer(cfg.Port, cfg.KeyPath, btm, gm, LoggingMiddleware())
+ s, err := server.NewServer(
+ cfg.Port,
+ cfg.KeyPath,
+ bm.Middleware(tui.SessionHandler, tea.WithAltScreen()),
+ gm.Middleware(cfg.RepoPath),
+ lm.Middleware(),
+ )
if err != nil {
log.Fatalln(err)
}
@@ -0,0 +1,22 @@
+package bubbletea
+
+import (
+ "smoothie/server/middleware"
+
+ tea "github.com/charmbracelet/bubbletea"
+ "github.com/gliderlabs/ssh"
+)
+
+func Middleware(bth func(ssh.Session) tea.Model, opts ...tea.ProgramOption) middleware.Middleware {
+ return func(sh ssh.Handler) ssh.Handler {
+ return func(s ssh.Session) {
+ m := bth(s)
+ if m != nil {
+ opts = append(opts, tea.WithInput(s), tea.WithOutput(s))
+ p := tea.NewProgram(m, opts...)
+ _ = p.Start()
+ }
+ sh(s)
+ }
+ }
+}
@@ -1,15 +1,16 @@
-package main
+package git
import (
"context"
"fmt"
"os"
"os/exec"
+ "smoothie/server/middleware"
"github.com/gliderlabs/ssh"
)
-func GitMiddleware(repoDir string) Middleware {
+func Middleware(repoDir string) middleware.Middleware {
return func(sh ssh.Handler) ssh.Handler {
return func(s ssh.Session) {
cmd := s.Command()
@@ -53,13 +54,9 @@ func fileExists(path string) (bool, error) {
func fatalGit(s ssh.Session, err error) {
// hex length includes 4 byte length prefix and ending newline
- logError(s, err)
msg := err.Error()
pktLine := fmt.Sprintf("%04x%s\n", len(msg)+5, msg)
- _, err = s.Write([]byte(pktLine))
- if err != nil {
- logError(s, err)
- }
+ _, _ = s.Write([]byte(pktLine))
s.Exit(1)
}
@@ -0,0 +1,19 @@
+package logging
+
+import (
+ "log"
+ "smoothie/server/middleware"
+
+ "github.com/gliderlabs/ssh"
+)
+
+func Middleware() middleware.Middleware {
+ return func(sh ssh.Handler) ssh.Handler {
+ return func(s ssh.Session) {
+ hpk := s.PublicKey() != nil
+ log.Printf("%s connect %v %v\n", s.RemoteAddr().String(), hpk, s.Command())
+ sh(s)
+ log.Printf("%s disconnect %v %v\n", s.RemoteAddr().String(), hpk, s.Command())
+ }
+ }
+}
@@ -0,0 +1,5 @@
+package middleware
+
+import "github.com/gliderlabs/ssh"
+
+type Middleware func(ssh.Handler) ssh.Handler
@@ -1,57 +1,27 @@
-package main
+package server
import (
"fmt"
"log"
"path/filepath"
+ "smoothie/server/middleware"
"strings"
- tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/charm/keygen"
"github.com/gliderlabs/ssh"
gossh "golang.org/x/crypto/ssh"
)
-type Middleware func(ssh.Handler) ssh.Handler
-
-func LoggingMiddleware() Middleware {
- return func(sh ssh.Handler) ssh.Handler {
- return func(s ssh.Session) {
- hpk := s.PublicKey() != nil
- log.Printf("%s connect %v %v\n", s.RemoteAddr().String(), hpk, s.Command())
- sh(s)
- log.Printf("%s disconnect %v %v\n", s.RemoteAddr().String(), hpk, s.Command())
- }
- }
-}
-
func logError(s ssh.Session, err error) {
log.Printf("%s error %v: %s\n", s.RemoteAddr().String(), s.Command(), err)
}
-func BubbleTeaMiddleware(bth func(ssh.Session) tea.Model, opts ...tea.ProgramOption) Middleware {
- return func(sh ssh.Handler) ssh.Handler {
- return func(s ssh.Session) {
- m := bth(s)
- if m != nil {
- opts = append(opts, tea.WithInput(s), tea.WithOutput(s))
- p := tea.NewProgram(m, opts...)
- err := p.Start()
- if err != nil {
- logError(s, err)
- }
- }
- sh(s)
- }
- }
-}
-
type Server struct {
server *ssh.Server
key gossh.PublicKey
}
-func NewServer(port int, keyPath string, mw ...Middleware) (*Server, error) {
+func NewServer(port int, keyPath string, mw ...middleware.Middleware) (*Server, error) {
s := &Server{server: &ssh.Server{}}
s.server.Version = "OpenSSH_7.6p1"
s.server.Addr = fmt.Sprintf(":%d", port)