repos / pico

pico services - prose.sh, pastes.sh, imgs.sh, feeds.sh, pgs.sh
git clone https://github.com/picosh/pico.git

commit
6ec5e62
parent
362af57
author
Eric Bower
date
2024-01-11 14:42:26 +0000 UTC
refactor: move ssh services into service packages

The only excpetion is imgs.sh which contains a circular dep.
6 files changed,  +362, -344
M cmd/feeds/ssh/main.go
+2, -115
  1@@ -1,120 +1,7 @@
  2 package main
  3 
  4-import (
  5-	"context"
  6-	"fmt"
  7-	"os"
  8-	"os/signal"
  9-	"syscall"
 10-	"time"
 11-
 12-	"github.com/charmbracelet/promwish"
 13-	"github.com/charmbracelet/ssh"
 14-	"github.com/charmbracelet/wish"
 15-	bm "github.com/charmbracelet/wish/bubbletea"
 16-	lm "github.com/charmbracelet/wish/logging"
 17-	"github.com/picosh/pico/db/postgres"
 18-	"github.com/picosh/pico/feeds"
 19-	"github.com/picosh/pico/filehandlers"
 20-	"github.com/picosh/pico/shared"
 21-	"github.com/picosh/pico/shared/storage"
 22-	"github.com/picosh/pico/wish/cms"
 23-	"github.com/picosh/send/list"
 24-	"github.com/picosh/send/pipe"
 25-	"github.com/picosh/send/proxy"
 26-	"github.com/picosh/send/send/auth"
 27-	wishrsync "github.com/picosh/send/send/rsync"
 28-	"github.com/picosh/send/send/scp"
 29-	"github.com/picosh/send/send/sftp"
 30-)
 31-
 32-type SSHServer struct{}
 33-
 34-func (me *SSHServer) authHandler(ctx ssh.Context, key ssh.PublicKey) bool {
 35-	return true
 36-}
 37-
 38-func createRouter(handler *filehandlers.ScpUploadHandler) proxy.Router {
 39-	return func(sh ssh.Handler, s ssh.Session) []wish.Middleware {
 40-		return []wish.Middleware{
 41-			pipe.Middleware(handler, ".txt"),
 42-			list.Middleware(handler),
 43-			scp.Middleware(handler),
 44-			wishrsync.Middleware(handler),
 45-			auth.Middleware(handler),
 46-			bm.Middleware(cms.Middleware(&handler.Cfg.ConfigCms, handler.Cfg)),
 47-			lm.Middleware(),
 48-		}
 49-	}
 50-}
 51-
 52-func withProxy(handler *filehandlers.ScpUploadHandler, otherMiddleware ...wish.Middleware) ssh.Option {
 53-	return func(server *ssh.Server) error {
 54-		err := sftp.SSHOption(handler)(server)
 55-		if err != nil {
 56-			return err
 57-		}
 58-
 59-		return proxy.WithProxy(createRouter(handler), otherMiddleware...)(server)
 60-	}
 61-}
 62+import "github.com/picosh/pico/feeds"
 63 
 64 func main() {
 65-	host := shared.GetEnv("LISTS_HOST", "0.0.0.0")
 66-	port := shared.GetEnv("LISTS_SSH_PORT", "2222")
 67-	promPort := shared.GetEnv("LISTS_PROM_PORT", "9222")
 68-	cfg := feeds.NewConfigSite()
 69-	logger := cfg.Logger
 70-	dbh := postgres.NewDB(cfg.DbURL, cfg.Logger)
 71-	defer dbh.Close()
 72-
 73-	hooks := &feeds.FeedHooks{
 74-		Cfg: cfg,
 75-		Db:  dbh,
 76-	}
 77-
 78-	var st storage.ObjectStorage
 79-	var err error
 80-	if cfg.MinioURL == "" {
 81-		st, err = storage.NewStorageFS(cfg.StorageDir)
 82-	} else {
 83-		st, err = storage.NewStorageMinio(cfg.MinioURL, cfg.MinioUser, cfg.MinioPass)
 84-	}
 85-
 86-	if err != nil {
 87-		logger.Fatal(err)
 88-	}
 89-
 90-	handler := filehandlers.NewScpPostHandler(dbh, cfg, hooks, st)
 91-
 92-	sshServer := &SSHServer{}
 93-	s, err := wish.NewServer(
 94-		wish.WithAddress(fmt.Sprintf("%s:%s", host, port)),
 95-		wish.WithHostKeyPath("ssh_data/term_info_ed25519"),
 96-		wish.WithPublicKeyAuth(sshServer.authHandler),
 97-		withProxy(
 98-			handler,
 99-			promwish.Middleware(fmt.Sprintf("%s:%s", host, promPort), "feeds-ssh"),
100-		),
101-	)
102-	if err != nil {
103-		logger.Fatal(err)
104-	}
105-
106-	done := make(chan os.Signal, 1)
107-	signal.Notify(done, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
108-	logger.Infof("Starting SSH server on %s:%s", host, port)
109-	go func() {
110-		if err = s.ListenAndServe(); err != nil {
111-			logger.Fatal(err)
112-		}
113-	}()
114-
115-	<-done
116-	logger.Info("Stopping SSH server")
117-	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
118-	defer func() { cancel() }()
119-	if err := s.Shutdown(ctx); err != nil {
120-		logger.Fatal(err)
121-	}
122+	feeds.StartSshServer()
123 }
M cmd/lists/ssh/main.go
+2, -115
  1@@ -1,120 +1,7 @@
  2 package main
  3 
  4-import (
  5-	"context"
  6-	"fmt"
  7-	"os"
  8-	"os/signal"
  9-	"syscall"
 10-	"time"
 11-
 12-	"github.com/charmbracelet/promwish"
 13-	"github.com/charmbracelet/ssh"
 14-	"github.com/charmbracelet/wish"
 15-	bm "github.com/charmbracelet/wish/bubbletea"
 16-	lm "github.com/charmbracelet/wish/logging"
 17-	"github.com/picosh/pico/db/postgres"
 18-	"github.com/picosh/pico/filehandlers"
 19-	"github.com/picosh/pico/lists"
 20-	"github.com/picosh/pico/shared"
 21-	"github.com/picosh/pico/shared/storage"
 22-	"github.com/picosh/pico/wish/cms"
 23-	"github.com/picosh/send/list"
 24-	"github.com/picosh/send/pipe"
 25-	"github.com/picosh/send/proxy"
 26-	"github.com/picosh/send/send/auth"
 27-	wishrsync "github.com/picosh/send/send/rsync"
 28-	"github.com/picosh/send/send/scp"
 29-	"github.com/picosh/send/send/sftp"
 30-)
 31-
 32-type SSHServer struct{}
 33-
 34-func (me *SSHServer) authHandler(ctx ssh.Context, key ssh.PublicKey) bool {
 35-	return true
 36-}
 37-
 38-func createRouter(handler *filehandlers.ScpUploadHandler) proxy.Router {
 39-	return func(sh ssh.Handler, s ssh.Session) []wish.Middleware {
 40-		return []wish.Middleware{
 41-			pipe.Middleware(handler, ".txt"),
 42-			list.Middleware(handler),
 43-			scp.Middleware(handler),
 44-			wishrsync.Middleware(handler),
 45-			auth.Middleware(handler),
 46-			bm.Middleware(cms.Middleware(&handler.Cfg.ConfigCms, handler.Cfg)),
 47-			lm.Middleware(),
 48-		}
 49-	}
 50-}
 51-
 52-func withProxy(handler *filehandlers.ScpUploadHandler, otherMiddleware ...wish.Middleware) ssh.Option {
 53-	return func(server *ssh.Server) error {
 54-		err := sftp.SSHOption(handler)(server)
 55-		if err != nil {
 56-			return err
 57-		}
 58-
 59-		return proxy.WithProxy(createRouter(handler), otherMiddleware...)(server)
 60-	}
 61-}
 62+import "github.com/picosh/pico/lists"
 63 
 64 func main() {
 65-	host := shared.GetEnv("LISTS_HOST", "0.0.0.0")
 66-	port := shared.GetEnv("LISTS_SSH_PORT", "2222")
 67-	promPort := shared.GetEnv("LISTS_PROM_PORT", "9222")
 68-	cfg := lists.NewConfigSite()
 69-	logger := cfg.Logger
 70-	dbh := postgres.NewDB(cfg.DbURL, cfg.Logger)
 71-	defer dbh.Close()
 72-
 73-	hooks := &lists.ListHooks{
 74-		Cfg: cfg,
 75-		Db:  dbh,
 76-	}
 77-
 78-	var st storage.ObjectStorage
 79-	var err error
 80-	if cfg.MinioURL == "" {
 81-		st, err = storage.NewStorageFS(cfg.StorageDir)
 82-	} else {
 83-		st, err = storage.NewStorageMinio(cfg.MinioURL, cfg.MinioUser, cfg.MinioPass)
 84-	}
 85-
 86-	if err != nil {
 87-		logger.Fatal(err)
 88-	}
 89-
 90-	handler := filehandlers.NewScpPostHandler(dbh, cfg, hooks, st)
 91-
 92-	sshServer := &SSHServer{}
 93-	s, err := wish.NewServer(
 94-		wish.WithAddress(fmt.Sprintf("%s:%s", host, port)),
 95-		wish.WithHostKeyPath("ssh_data/term_info_ed25519"),
 96-		wish.WithPublicKeyAuth(sshServer.authHandler),
 97-		withProxy(
 98-			handler,
 99-			promwish.Middleware(fmt.Sprintf("%s:%s", host, promPort), "lists-ssh"),
100-		),
101-	)
102-	if err != nil {
103-		logger.Fatal(err)
104-	}
105-
106-	done := make(chan os.Signal, 1)
107-	signal.Notify(done, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
108-	logger.Infof("Starting SSH server on %s:%s", host, port)
109-	go func() {
110-		if err = s.ListenAndServe(); err != nil {
111-			logger.Fatal(err)
112-		}
113-	}()
114-
115-	<-done
116-	logger.Info("Stopping SSH server")
117-	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
118-	defer func() { cancel() }()
119-	if err := s.Shutdown(ctx); err != nil {
120-		logger.Fatal(err)
121-	}
122+	lists.StartSshServer()
123 }
M cmd/prose/ssh/main.go
+2, -114
  1@@ -1,119 +1,7 @@
  2 package main
  3 
  4-import (
  5-	"context"
  6-	"fmt"
  7-	"os"
  8-	"os/signal"
  9-	"syscall"
 10-	"time"
 11-
 12-	"github.com/charmbracelet/promwish"
 13-	"github.com/charmbracelet/ssh"
 14-	"github.com/charmbracelet/wish"
 15-	bm "github.com/charmbracelet/wish/bubbletea"
 16-	lm "github.com/charmbracelet/wish/logging"
 17-	"github.com/picosh/pico/db/postgres"
 18-	"github.com/picosh/pico/filehandlers"
 19-	"github.com/picosh/pico/prose"
 20-	"github.com/picosh/pico/shared"
 21-	"github.com/picosh/pico/shared/storage"
 22-	"github.com/picosh/pico/wish/cms"
 23-	"github.com/picosh/send/list"
 24-	"github.com/picosh/send/pipe"
 25-	"github.com/picosh/send/proxy"
 26-	"github.com/picosh/send/send/auth"
 27-	wishrsync "github.com/picosh/send/send/rsync"
 28-	"github.com/picosh/send/send/scp"
 29-	"github.com/picosh/send/send/sftp"
 30-)
 31-
 32-type SSHServer struct{}
 33-
 34-func (me *SSHServer) authHandler(ctx ssh.Context, key ssh.PublicKey) bool {
 35-	return true
 36-}
 37-
 38-func createRouter(handler *filehandlers.ScpUploadHandler) proxy.Router {
 39-	return func(sh ssh.Handler, s ssh.Session) []wish.Middleware {
 40-		return []wish.Middleware{
 41-			pipe.Middleware(handler, ".md"),
 42-			list.Middleware(handler),
 43-			scp.Middleware(handler),
 44-			wishrsync.Middleware(handler),
 45-			auth.Middleware(handler),
 46-			bm.Middleware(cms.Middleware(&handler.Cfg.ConfigCms, handler.Cfg)),
 47-			lm.Middleware(),
 48-		}
 49-	}
 50-}
 51-
 52-func withProxy(handler *filehandlers.ScpUploadHandler, otherMiddleware ...wish.Middleware) ssh.Option {
 53-	return func(server *ssh.Server) error {
 54-		err := sftp.SSHOption(handler)(server)
 55-		if err != nil {
 56-			return err
 57-		}
 58-
 59-		return proxy.WithProxy(createRouter(handler), otherMiddleware...)(server)
 60-	}
 61-}
 62+import "github.com/picosh/pico/prose"
 63 
 64 func main() {
 65-	host := shared.GetEnv("PROSE_HOST", "0.0.0.0")
 66-	port := shared.GetEnv("PROSE_SSH_PORT", "2222")
 67-	promPort := shared.GetEnv("PROSE_PROM_PORT", "9222")
 68-	cfg := prose.NewConfigSite()
 69-	logger := cfg.Logger
 70-	dbh := postgres.NewDB(cfg.DbURL, cfg.Logger)
 71-	defer dbh.Close()
 72-	hooks := &prose.MarkdownHooks{
 73-		Cfg: cfg,
 74-		Db:  dbh,
 75-	}
 76-
 77-	var st storage.ObjectStorage
 78-	var err error
 79-	if cfg.MinioURL == "" {
 80-		st, err = storage.NewStorageFS(cfg.StorageDir)
 81-	} else {
 82-		st, err = storage.NewStorageMinio(cfg.MinioURL, cfg.MinioUser, cfg.MinioPass)
 83-	}
 84-
 85-	if err != nil {
 86-		logger.Fatal(err)
 87-	}
 88-
 89-	handler := filehandlers.NewScpPostHandler(dbh, cfg, hooks, st)
 90-
 91-	sshServer := &SSHServer{}
 92-	s, err := wish.NewServer(
 93-		wish.WithAddress(fmt.Sprintf("%s:%s", host, port)),
 94-		wish.WithHostKeyPath("ssh_data/term_info_ed25519"),
 95-		wish.WithPublicKeyAuth(sshServer.authHandler),
 96-		withProxy(
 97-			handler,
 98-			promwish.Middleware(fmt.Sprintf("%s:%s", host, promPort), "prose-ssh"),
 99-		),
100-	)
101-	if err != nil {
102-		logger.Fatal(err)
103-	}
104-
105-	done := make(chan os.Signal, 1)
106-	signal.Notify(done, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
107-	logger.Infof("Starting SSH server on %s:%s", host, port)
108-	go func() {
109-		if err = s.ListenAndServe(); err != nil {
110-			logger.Fatal(err)
111-		}
112-	}()
113-
114-	<-done
115-	logger.Info("Stopping SSH server")
116-	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
117-	defer func() { cancel() }()
118-	if err := s.Shutdown(ctx); err != nil {
119-		logger.Fatal(err)
120-	}
121+	prose.StartSshServer()
122 }
A feeds/ssh.go
+119, -0
  1@@ -0,0 +1,119 @@
  2+package feeds
  3+
  4+import (
  5+	"context"
  6+	"fmt"
  7+	"os"
  8+	"os/signal"
  9+	"syscall"
 10+	"time"
 11+
 12+	"github.com/charmbracelet/promwish"
 13+	"github.com/charmbracelet/ssh"
 14+	"github.com/charmbracelet/wish"
 15+	bm "github.com/charmbracelet/wish/bubbletea"
 16+	lm "github.com/charmbracelet/wish/logging"
 17+	"github.com/picosh/pico/db/postgres"
 18+	"github.com/picosh/pico/filehandlers"
 19+	"github.com/picosh/pico/shared"
 20+	"github.com/picosh/pico/shared/storage"
 21+	"github.com/picosh/pico/wish/cms"
 22+	"github.com/picosh/send/list"
 23+	"github.com/picosh/send/pipe"
 24+	"github.com/picosh/send/proxy"
 25+	"github.com/picosh/send/send/auth"
 26+	wishrsync "github.com/picosh/send/send/rsync"
 27+	"github.com/picosh/send/send/scp"
 28+	"github.com/picosh/send/send/sftp"
 29+)
 30+
 31+type SSHServer struct{}
 32+
 33+func (me *SSHServer) authHandler(ctx ssh.Context, key ssh.PublicKey) bool {
 34+	return true
 35+}
 36+
 37+func createRouter(handler *filehandlers.ScpUploadHandler) proxy.Router {
 38+	return func(sh ssh.Handler, s ssh.Session) []wish.Middleware {
 39+		return []wish.Middleware{
 40+			pipe.Middleware(handler, ".txt"),
 41+			list.Middleware(handler),
 42+			scp.Middleware(handler),
 43+			wishrsync.Middleware(handler),
 44+			auth.Middleware(handler),
 45+			bm.Middleware(cms.Middleware(&handler.Cfg.ConfigCms, handler.Cfg)),
 46+			lm.Middleware(),
 47+		}
 48+	}
 49+}
 50+
 51+func withProxy(handler *filehandlers.ScpUploadHandler, otherMiddleware ...wish.Middleware) ssh.Option {
 52+	return func(server *ssh.Server) error {
 53+		err := sftp.SSHOption(handler)(server)
 54+		if err != nil {
 55+			return err
 56+		}
 57+
 58+		return proxy.WithProxy(createRouter(handler), otherMiddleware...)(server)
 59+	}
 60+}
 61+
 62+func StartSshServer() {
 63+	host := shared.GetEnv("LISTS_HOST", "0.0.0.0")
 64+	port := shared.GetEnv("LISTS_SSH_PORT", "2222")
 65+	promPort := shared.GetEnv("LISTS_PROM_PORT", "9222")
 66+	cfg := NewConfigSite()
 67+	logger := cfg.Logger
 68+	dbh := postgres.NewDB(cfg.DbURL, cfg.Logger)
 69+	defer dbh.Close()
 70+
 71+	hooks := &FeedHooks{
 72+		Cfg: cfg,
 73+		Db:  dbh,
 74+	}
 75+
 76+	var st storage.ObjectStorage
 77+	var err error
 78+	if cfg.MinioURL == "" {
 79+		st, err = storage.NewStorageFS(cfg.StorageDir)
 80+	} else {
 81+		st, err = storage.NewStorageMinio(cfg.MinioURL, cfg.MinioUser, cfg.MinioPass)
 82+	}
 83+
 84+	if err != nil {
 85+		logger.Fatal(err)
 86+	}
 87+
 88+	handler := filehandlers.NewScpPostHandler(dbh, cfg, hooks, st)
 89+
 90+	sshServer := &SSHServer{}
 91+	s, err := wish.NewServer(
 92+		wish.WithAddress(fmt.Sprintf("%s:%s", host, port)),
 93+		wish.WithHostKeyPath("ssh_data/term_info_ed25519"),
 94+		wish.WithPublicKeyAuth(sshServer.authHandler),
 95+		withProxy(
 96+			handler,
 97+			promwish.Middleware(fmt.Sprintf("%s:%s", host, promPort), "feeds-ssh"),
 98+		),
 99+	)
100+	if err != nil {
101+		logger.Fatal(err)
102+	}
103+
104+	done := make(chan os.Signal, 1)
105+	signal.Notify(done, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
106+	logger.Infof("Starting SSH server on %s:%s", host, port)
107+	go func() {
108+		if err = s.ListenAndServe(); err != nil {
109+			logger.Fatal(err)
110+		}
111+	}()
112+
113+	<-done
114+	logger.Info("Stopping SSH server")
115+	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
116+	defer func() { cancel() }()
117+	if err := s.Shutdown(ctx); err != nil {
118+		logger.Fatal(err)
119+	}
120+}
A lists/ssh.go
+119, -0
  1@@ -0,0 +1,119 @@
  2+package lists
  3+
  4+import (
  5+	"context"
  6+	"fmt"
  7+	"os"
  8+	"os/signal"
  9+	"syscall"
 10+	"time"
 11+
 12+	"github.com/charmbracelet/promwish"
 13+	"github.com/charmbracelet/ssh"
 14+	"github.com/charmbracelet/wish"
 15+	bm "github.com/charmbracelet/wish/bubbletea"
 16+	lm "github.com/charmbracelet/wish/logging"
 17+	"github.com/picosh/pico/db/postgres"
 18+	"github.com/picosh/pico/filehandlers"
 19+	"github.com/picosh/pico/shared"
 20+	"github.com/picosh/pico/shared/storage"
 21+	"github.com/picosh/pico/wish/cms"
 22+	"github.com/picosh/send/list"
 23+	"github.com/picosh/send/pipe"
 24+	"github.com/picosh/send/proxy"
 25+	"github.com/picosh/send/send/auth"
 26+	wishrsync "github.com/picosh/send/send/rsync"
 27+	"github.com/picosh/send/send/scp"
 28+	"github.com/picosh/send/send/sftp"
 29+)
 30+
 31+type SSHServer struct{}
 32+
 33+func (me *SSHServer) authHandler(ctx ssh.Context, key ssh.PublicKey) bool {
 34+	return true
 35+}
 36+
 37+func createRouter(handler *filehandlers.ScpUploadHandler) proxy.Router {
 38+	return func(sh ssh.Handler, s ssh.Session) []wish.Middleware {
 39+		return []wish.Middleware{
 40+			pipe.Middleware(handler, ".txt"),
 41+			list.Middleware(handler),
 42+			scp.Middleware(handler),
 43+			wishrsync.Middleware(handler),
 44+			auth.Middleware(handler),
 45+			bm.Middleware(cms.Middleware(&handler.Cfg.ConfigCms, handler.Cfg)),
 46+			lm.Middleware(),
 47+		}
 48+	}
 49+}
 50+
 51+func withProxy(handler *filehandlers.ScpUploadHandler, otherMiddleware ...wish.Middleware) ssh.Option {
 52+	return func(server *ssh.Server) error {
 53+		err := sftp.SSHOption(handler)(server)
 54+		if err != nil {
 55+			return err
 56+		}
 57+
 58+		return proxy.WithProxy(createRouter(handler), otherMiddleware...)(server)
 59+	}
 60+}
 61+
 62+func StartSshServer() {
 63+	host := shared.GetEnv("LISTS_HOST", "0.0.0.0")
 64+	port := shared.GetEnv("LISTS_SSH_PORT", "2222")
 65+	promPort := shared.GetEnv("LISTS_PROM_PORT", "9222")
 66+	cfg := NewConfigSite()
 67+	logger := cfg.Logger
 68+	dbh := postgres.NewDB(cfg.DbURL, cfg.Logger)
 69+	defer dbh.Close()
 70+
 71+	hooks := &ListHooks{
 72+		Cfg: cfg,
 73+		Db:  dbh,
 74+	}
 75+
 76+	var st storage.ObjectStorage
 77+	var err error
 78+	if cfg.MinioURL == "" {
 79+		st, err = storage.NewStorageFS(cfg.StorageDir)
 80+	} else {
 81+		st, err = storage.NewStorageMinio(cfg.MinioURL, cfg.MinioUser, cfg.MinioPass)
 82+	}
 83+
 84+	if err != nil {
 85+		logger.Fatal(err)
 86+	}
 87+
 88+	handler := filehandlers.NewScpPostHandler(dbh, cfg, hooks, st)
 89+
 90+	sshServer := &SSHServer{}
 91+	s, err := wish.NewServer(
 92+		wish.WithAddress(fmt.Sprintf("%s:%s", host, port)),
 93+		wish.WithHostKeyPath("ssh_data/term_info_ed25519"),
 94+		wish.WithPublicKeyAuth(sshServer.authHandler),
 95+		withProxy(
 96+			handler,
 97+			promwish.Middleware(fmt.Sprintf("%s:%s", host, promPort), "lists-ssh"),
 98+		),
 99+	)
100+	if err != nil {
101+		logger.Fatal(err)
102+	}
103+
104+	done := make(chan os.Signal, 1)
105+	signal.Notify(done, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
106+	logger.Infof("Starting SSH server on %s:%s", host, port)
107+	go func() {
108+		if err = s.ListenAndServe(); err != nil {
109+			logger.Fatal(err)
110+		}
111+	}()
112+
113+	<-done
114+	logger.Info("Stopping SSH server")
115+	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
116+	defer func() { cancel() }()
117+	if err := s.Shutdown(ctx); err != nil {
118+		logger.Fatal(err)
119+	}
120+}
A prose/ssh.go
+118, -0
  1@@ -0,0 +1,118 @@
  2+package prose
  3+
  4+import (
  5+	"context"
  6+	"fmt"
  7+	"os"
  8+	"os/signal"
  9+	"syscall"
 10+	"time"
 11+
 12+	"github.com/charmbracelet/promwish"
 13+	"github.com/charmbracelet/ssh"
 14+	"github.com/charmbracelet/wish"
 15+	bm "github.com/charmbracelet/wish/bubbletea"
 16+	lm "github.com/charmbracelet/wish/logging"
 17+	"github.com/picosh/pico/db/postgres"
 18+	"github.com/picosh/pico/filehandlers"
 19+	"github.com/picosh/pico/shared"
 20+	"github.com/picosh/pico/shared/storage"
 21+	"github.com/picosh/pico/wish/cms"
 22+	"github.com/picosh/send/list"
 23+	"github.com/picosh/send/pipe"
 24+	"github.com/picosh/send/proxy"
 25+	"github.com/picosh/send/send/auth"
 26+	wishrsync "github.com/picosh/send/send/rsync"
 27+	"github.com/picosh/send/send/scp"
 28+	"github.com/picosh/send/send/sftp"
 29+)
 30+
 31+type SSHServer struct{}
 32+
 33+func (me *SSHServer) authHandler(ctx ssh.Context, key ssh.PublicKey) bool {
 34+	return true
 35+}
 36+
 37+func createRouter(handler *filehandlers.ScpUploadHandler) proxy.Router {
 38+	return func(sh ssh.Handler, s ssh.Session) []wish.Middleware {
 39+		return []wish.Middleware{
 40+			pipe.Middleware(handler, ".md"),
 41+			list.Middleware(handler),
 42+			scp.Middleware(handler),
 43+			wishrsync.Middleware(handler),
 44+			auth.Middleware(handler),
 45+			bm.Middleware(cms.Middleware(&handler.Cfg.ConfigCms, handler.Cfg)),
 46+			lm.Middleware(),
 47+		}
 48+	}
 49+}
 50+
 51+func withProxy(handler *filehandlers.ScpUploadHandler, otherMiddleware ...wish.Middleware) ssh.Option {
 52+	return func(server *ssh.Server) error {
 53+		err := sftp.SSHOption(handler)(server)
 54+		if err != nil {
 55+			return err
 56+		}
 57+
 58+		return proxy.WithProxy(createRouter(handler), otherMiddleware...)(server)
 59+	}
 60+}
 61+
 62+func StartSshServer() {
 63+	host := shared.GetEnv("PROSE_HOST", "0.0.0.0")
 64+	port := shared.GetEnv("PROSE_SSH_PORT", "2222")
 65+	promPort := shared.GetEnv("PROSE_PROM_PORT", "9222")
 66+	cfg := NewConfigSite()
 67+	logger := cfg.Logger
 68+	dbh := postgres.NewDB(cfg.DbURL, cfg.Logger)
 69+	defer dbh.Close()
 70+	hooks := &MarkdownHooks{
 71+		Cfg: cfg,
 72+		Db:  dbh,
 73+	}
 74+
 75+	var st storage.ObjectStorage
 76+	var err error
 77+	if cfg.MinioURL == "" {
 78+		st, err = storage.NewStorageFS(cfg.StorageDir)
 79+	} else {
 80+		st, err = storage.NewStorageMinio(cfg.MinioURL, cfg.MinioUser, cfg.MinioPass)
 81+	}
 82+
 83+	if err != nil {
 84+		logger.Fatal(err)
 85+	}
 86+
 87+	handler := filehandlers.NewScpPostHandler(dbh, cfg, hooks, st)
 88+
 89+	sshServer := &SSHServer{}
 90+	s, err := wish.NewServer(
 91+		wish.WithAddress(fmt.Sprintf("%s:%s", host, port)),
 92+		wish.WithHostKeyPath("ssh_data/term_info_ed25519"),
 93+		wish.WithPublicKeyAuth(sshServer.authHandler),
 94+		withProxy(
 95+			handler,
 96+			promwish.Middleware(fmt.Sprintf("%s:%s", host, promPort), "prose-ssh"),
 97+		),
 98+	)
 99+	if err != nil {
100+		logger.Fatal(err)
101+	}
102+
103+	done := make(chan os.Signal, 1)
104+	signal.Notify(done, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
105+	logger.Infof("Starting SSH server on %s:%s", host, port)
106+	go func() {
107+		if err = s.ListenAndServe(); err != nil {
108+			logger.Fatal(err)
109+		}
110+	}()
111+
112+	<-done
113+	logger.Info("Stopping SSH server")
114+	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
115+	defer func() { cancel() }()
116+	if err := s.Shutdown(ctx); err != nil {
117+		logger.Fatal(err)
118+	}
119+}