repos / pico

pico services mono repo
git clone https://github.com/picosh/pico.git

commit
1a3b2c0
parent
6fbdd09
author
Antonio Mika
date
2025-02-27 00:12:34 -0500 EST
Logging improvements
19 files changed,  +273, -135
M go.mod
M go.sum
M feeds/cli.go
+7, -28
 1@@ -2,7 +2,6 @@ package feeds
 2 
 3 import (
 4 	"fmt"
 5-	"log/slog"
 6 	"text/tabwriter"
 7 	"time"
 8 
 9@@ -10,27 +9,9 @@ import (
10 	"github.com/charmbracelet/wish"
11 	"github.com/picosh/pico/db"
12 	"github.com/picosh/pico/shared"
13-	"github.com/picosh/utils"
14-)
15-
16-func getUser(s ssh.Session, dbpool db.DB) (*db.User, error) {
17-	if s.PublicKey() == nil {
18-		return nil, fmt.Errorf("key not found")
19-	}
20-
21-	key := utils.KeyForKeyText(s.PublicKey())
22-
23-	user, err := dbpool.FindUserByPubkey(key)
24-	if err != nil {
25-		return nil, err
26-	}
27 
28-	if user.Name == "" {
29-		return nil, fmt.Errorf("must have username set")
30-	}
31-
32-	return user, nil
33-}
34+	wsh "github.com/picosh/pico/wish"
35+)
36 
37 func WishMiddleware(dbpool db.DB, cfg *shared.ConfigSite) wish.Middleware {
38 	return func(next ssh.Handler) ssh.Handler {
39@@ -41,9 +22,11 @@ func WishMiddleware(dbpool db.DB, cfg *shared.ConfigSite) wish.Middleware {
40 				return
41 			}
42 
43-			user, err := getUser(sesh, dbpool)
44-			if err != nil {
45-				wish.Errorln(sesh, err)
46+			logger := wsh.GetLogger(sesh)
47+			user := wsh.GetUser(sesh)
48+
49+			if user == nil {
50+				wish.Errorln(sesh, fmt.Errorf("user not found"))
51 				return
52 			}
53 
54@@ -142,10 +125,6 @@ func WishMiddleware(dbpool db.DB, cfg *shared.ConfigSite) wish.Middleware {
55 				}
56 				wish.Printf(sesh, "running feed post: %s\n", filename)
57 				fetcher := NewFetcher(dbpool, cfg)
58-				logger := slog.New(
59-					slog.NewTextHandler(sesh, &slog.HandlerOptions{}),
60-				)
61-				logger = shared.LoggerWithUser(logger, user)
62 				err = fetcher.RunPost(logger, user, post, true)
63 				if err != nil {
64 					wish.Errorln(sesh, err)
M feeds/ssh.go
+11, -1
 1@@ -35,7 +35,7 @@ func createRouter(handler *filehandlers.FileHandlerRouter) proxy.Router {
 2 			auth.Middleware(handler),
 3 			wsh.PtyMdw(wsh.DeprecatedNotice()),
 4 			WishMiddleware(handler.DBPool, handler.Cfg),
 5-			wsh.LogMiddleware(handler.GetLogger()),
 6+			wsh.LogMiddleware(handler.GetLogger(s), handler.DBPool),
 7 		}
 8 	}
 9 }
10@@ -47,6 +47,16 @@ func withProxy(handler *filehandlers.FileHandlerRouter, otherMiddleware ...wish.
11 			return err
12 		}
13 
14+		newSubsystemHandlers := map[string]ssh.SubsystemHandler{}
15+
16+		for name, subsystemHandler := range server.SubsystemHandlers {
17+			newSubsystemHandlers[name] = func(s ssh.Session) {
18+				wsh.LogMiddleware(handler.GetLogger(s), handler.DBPool)(ssh.Handler(subsystemHandler))(s)
19+			}
20+		}
21+
22+		server.SubsystemHandlers = newSubsystemHandlers
23+
24 		return proxy.WithProxy(createRouter(handler), otherMiddleware...)(server)
25 	}
26 }
M filehandlers/imgs/handler.go
+28, -17
  1@@ -16,6 +16,7 @@ import (
  2 	"github.com/picosh/pico/db"
  3 	"github.com/picosh/pico/shared"
  4 	"github.com/picosh/pico/shared/storage"
  5+	"github.com/picosh/pico/wish"
  6 	"github.com/picosh/pobj"
  7 	sst "github.com/picosh/pobj/storage"
  8 	sendutils "github.com/picosh/send/utils"
  9@@ -55,8 +56,12 @@ func (h *UploadImgHandler) getObjectPath(fpath string) string {
 10 func (h *UploadImgHandler) List(s ssh.Session, fpath string, isDir bool, recursive bool) ([]os.FileInfo, error) {
 11 	var fileList []os.FileInfo
 12 
 13-	user, err := h.DBPool.FindUser(s.Permissions().Extensions["user_id"])
 14-	if err != nil {
 15+	logger := wish.GetLogger(s)
 16+	user := wish.GetUser(s)
 17+
 18+	if user == nil {
 19+		err := fmt.Errorf("could not get user from ctx")
 20+		logger.Error("error getting user from ctx", "err", err)
 21 		return fileList, err
 22 	}
 23 
 24@@ -98,8 +103,12 @@ func (h *UploadImgHandler) List(s ssh.Session, fpath string, isDir bool, recursi
 25 }
 26 
 27 func (h *UploadImgHandler) Read(s ssh.Session, entry *sendutils.FileEntry) (os.FileInfo, sendutils.ReadAndReaderAtCloser, error) {
 28-	user, err := h.DBPool.FindUser(s.Permissions().Extensions["user_id"])
 29-	if err != nil {
 30+	logger := wish.GetLogger(s)
 31+	user := wish.GetUser(s)
 32+
 33+	if user == nil {
 34+		err := fmt.Errorf("could not get user from ctx")
 35+		logger.Error("error getting user from ctx", "err", err)
 36 		return nil, nil, err
 37 	}
 38 
 39@@ -131,13 +140,14 @@ func (h *UploadImgHandler) Read(s ssh.Session, entry *sendutils.FileEntry) (os.F
 40 }
 41 
 42 func (h *UploadImgHandler) Write(s ssh.Session, entry *sendutils.FileEntry) (string, error) {
 43-	logger := h.Cfg.Logger
 44-	user, err := h.DBPool.FindUser(s.Permissions().Extensions["user_id"])
 45-	if err != nil {
 46-		logger.Error("could not get user from ctx", "err", err.Error())
 47+	logger := wish.GetLogger(s)
 48+	user := wish.GetUser(s)
 49+
 50+	if user == nil {
 51+		err := fmt.Errorf("could not get user from ctx")
 52+		logger.Error("error getting user from ctx", "err", err)
 53 		return "", err
 54 	}
 55-	logger = shared.LoggerWithUser(logger, user)
 56 
 57 	filename := filepath.Base(entry.Filepath)
 58 
 59@@ -189,7 +199,7 @@ func (h *UploadImgHandler) Write(s ssh.Session, entry *sendutils.FileEntry) (str
 60 		TotalFileSize: int(totalFileSize),
 61 	}
 62 
 63-	err = h.writeImg(&metadata)
 64+	err = h.writeImg(s, &metadata)
 65 	if err != nil {
 66 		logger.Error("could not write img", "err", err.Error())
 67 		return "", err
 68@@ -213,15 +223,17 @@ func (h *UploadImgHandler) Write(s ssh.Session, entry *sendutils.FileEntry) (str
 69 }
 70 
 71 func (h *UploadImgHandler) Delete(s ssh.Session, entry *sendutils.FileEntry) error {
 72-	user, err := h.DBPool.FindUser(s.Permissions().Extensions["user_id"])
 73-	if err != nil {
 74+	logger := wish.GetLogger(s)
 75+	user := wish.GetUser(s)
 76+
 77+	if user == nil {
 78+		err := fmt.Errorf("could not get user from ctx")
 79+		logger.Error("error getting user from ctx", "err", err)
 80 		return err
 81 	}
 82 
 83 	filename := filepath.Base(entry.Filepath)
 84 
 85-	logger := h.Cfg.Logger
 86-	logger = shared.LoggerWithUser(logger, user)
 87 	logger = logger.With(
 88 		"filename", filename,
 89 	)
 90@@ -297,14 +309,13 @@ func (h *UploadImgHandler) metaImg(data *PostMetaData) error {
 91 	return nil
 92 }
 93 
 94-func (h *UploadImgHandler) writeImg(data *PostMetaData) error {
 95+func (h *UploadImgHandler) writeImg(s ssh.Session, data *PostMetaData) error {
 96 	valid, err := h.validateImg(data)
 97 	if !valid {
 98 		return err
 99 	}
100 
101-	logger := h.Cfg.Logger
102-	logger = shared.LoggerWithUser(logger, data.User)
103+	logger := wish.GetLogger(s)
104 	logger = logger.With(
105 		"filename", data.Filename,
106 	)
M filehandlers/post_handler.go
+21, -12
 1@@ -13,6 +13,7 @@ import (
 2 	"github.com/charmbracelet/ssh"
 3 	"github.com/picosh/pico/db"
 4 	"github.com/picosh/pico/shared"
 5+	"github.com/picosh/pico/wish"
 6 	sendutils "github.com/picosh/send/utils"
 7 	"github.com/picosh/utils"
 8 )
 9@@ -50,10 +51,15 @@ func (r *ScpUploadHandler) List(s ssh.Session, fpath string, isDir bool, recursi
10 }
11 
12 func (h *ScpUploadHandler) Read(s ssh.Session, entry *sendutils.FileEntry) (os.FileInfo, sendutils.ReadAndReaderAtCloser, error) {
13-	user, err := h.DBPool.FindUser(s.Permissions().Extensions["user_id"])
14-	if err != nil {
15+	logger := wish.GetLogger(s)
16+	user := wish.GetUser(s)
17+
18+	if user == nil {
19+		err := fmt.Errorf("could not get user from ctx")
20+		logger.Error("error getting user from ctx", "err", err)
21 		return nil, nil, err
22 	}
23+
24 	cleanFilename := filepath.Base(entry.Filepath)
25 
26 	if cleanFilename == "" || cleanFilename == "." {
27@@ -78,16 +84,18 @@ func (h *ScpUploadHandler) Read(s ssh.Session, entry *sendutils.FileEntry) (os.F
28 }
29 
30 func (h *ScpUploadHandler) Write(s ssh.Session, entry *sendutils.FileEntry) (string, error) {
31-	logger := h.Cfg.Logger
32-	user, err := h.DBPool.FindUser(s.Permissions().Extensions["user_id"])
33-	if err != nil {
34-		logger.Error("error getting user from ctx", "err", err.Error())
35+	logger := wish.GetLogger(s)
36+	user := wish.GetUser(s)
37+
38+	if user == nil {
39+		err := fmt.Errorf("could not get user from ctx")
40+		logger.Error("error getting user from ctx", "err", err)
41 		return "", err
42 	}
43 
44 	userID := user.ID
45 	filename := filepath.Base(entry.Filepath)
46-	logger = shared.LoggerWithUser(logger, user)
47+
48 	logger = logger.With(
49 		"filename", filename,
50 	)
51@@ -264,16 +272,17 @@ func (h *ScpUploadHandler) Write(s ssh.Session, entry *sendutils.FileEntry) (str
52 }
53 
54 func (h *ScpUploadHandler) Delete(s ssh.Session, entry *sendutils.FileEntry) error {
55-	logger := h.Cfg.Logger
56-	user, err := h.DBPool.FindUser(s.Permissions().Extensions["user_id"])
57-	if err != nil {
58-		logger.Error("could not get user from ctx", "err", err.Error())
59+	logger := wish.GetLogger(s)
60+	user := wish.GetUser(s)
61+
62+	if user == nil {
63+		err := fmt.Errorf("could not get user from ctx")
64+		logger.Error("error getting user from ctx", "err", err)
65 		return err
66 	}
67 
68 	userID := user.ID
69 	filename := filepath.Base(entry.Filepath)
70-	logger = shared.LoggerWithUser(logger, user)
71 	logger = logger.With(
72 		"filename", filename,
73 	)
M filehandlers/router_handler.go
+20, -8
 1@@ -11,6 +11,7 @@ import (
 2 	"github.com/charmbracelet/ssh"
 3 	"github.com/picosh/pico/db"
 4 	"github.com/picosh/pico/shared"
 5+	"github.com/picosh/pico/wish"
 6 	"github.com/picosh/send/utils"
 7 )
 8 
 9@@ -91,7 +92,7 @@ func (r *FileHandlerRouter) List(s ssh.Session, fpath string, isDir bool, recurs
10 
11 		ff, err := handler.List(s, fpath, isDir, recursive)
12 		if err != nil {
13-			r.GetLogger().Error("handler list", "err", err)
14+			r.GetLogger(s).Error("handler list", "err", err)
15 			continue
16 		}
17 		files = append(files, ff...)
18@@ -99,17 +100,21 @@ func (r *FileHandlerRouter) List(s ssh.Session, fpath string, isDir bool, recurs
19 	return files, nil
20 }
21 
22-func (r *FileHandlerRouter) GetLogger() *slog.Logger {
23-	return r.Cfg.Logger
24+func (r *FileHandlerRouter) GetLogger(s ssh.Session) *slog.Logger {
25+	return wish.GetLogger(s)
26 }
27 
28 func (r *FileHandlerRouter) Validate(s ssh.Session) error {
29-	user, err := r.DBPool.FindUser(s.Permissions().Extensions["user_id"])
30-	if err != nil {
31+	logger := wish.GetLogger(s)
32+	user := wish.GetUser(s)
33+
34+	if user == nil {
35+		err := fmt.Errorf("could not get user from ctx")
36+		logger.Error("error getting user from ctx", "err", err)
37 		return err
38 	}
39 
40-	r.Cfg.Logger.Info(
41+	logger.Info(
42 		"attempting to upload files",
43 		"user", user.Name,
44 		"space", r.Cfg.Space,
45@@ -119,10 +124,17 @@ func (r *FileHandlerRouter) Validate(s ssh.Session) error {
46 
47 func BaseList(s ssh.Session, fpath string, isDir bool, recursive bool, spaces []string, dbpool db.DB) ([]os.FileInfo, error) {
48 	var fileList []os.FileInfo
49-	user, err := dbpool.FindUser(s.Permissions().Extensions["user_id"])
50-	if err != nil {
51+	logger := wish.GetLogger(s)
52+	user := wish.GetUser(s)
53+
54+	var err error
55+
56+	if user == nil {
57+		err = fmt.Errorf("could not get user from ctx")
58+		logger.Error("error getting user from ctx", "err", err)
59 		return fileList, err
60 	}
61+
62 	cleanFilename := filepath.Base(fpath)
63 
64 	var post *db.Post
M go.mod
+3, -3
 1@@ -53,9 +53,9 @@ require (
 2 	github.com/muesli/reflow v0.3.0
 3 	github.com/muesli/termenv v0.16.0
 4 	github.com/neurosnap/go-exif-remove v0.0.0-20221010134343-50d1e3c35577
 5-	github.com/picosh/pobj v0.0.0-20250226214525-3032185b0871
 6+	github.com/picosh/pobj v0.0.0-20250227050834-c7a07802fbf9
 7 	github.com/picosh/pubsub v0.0.0-20241114191831-ec8f16c0eb88
 8-	github.com/picosh/send v0.0.0-20250226204721-03aad51a1f7d
 9+	github.com/picosh/send v0.0.0-20250227050705-0c2cd3b14935
10 	github.com/picosh/tunkit v0.0.0-20240905223921-532404cef9d9
11 	github.com/picosh/utils v0.0.0-20241120033529-8ca070c09bf4
12 	github.com/pkg/sftp v1.13.7
13@@ -259,7 +259,7 @@ require (
14 	github.com/nutsdb/nutsdb v1.0.4 // indirect
15 	github.com/onsi/ginkgo/v2 v2.15.0 // indirect
16 	github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c // indirect
17-	github.com/picosh/go-rsync-receiver v0.0.0-20250226204508-de154908d143 // indirect
18+	github.com/picosh/go-rsync-receiver v0.0.0-20250227050534-f3af0a9d7aa6 // indirect
19 	github.com/pierrec/lz4/v4 v4.1.21 // indirect
20 	github.com/pkg/errors v0.9.1 // indirect
21 	github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
M go.sum
+6, -6
 1@@ -715,14 +715,14 @@ github.com/peterbourgon/diskv/v3 v3.0.1 h1:x06SQA46+PKIUftmEujdwSEpIx8kR+M9eLYsU
 2 github.com/peterbourgon/diskv/v3 v3.0.1/go.mod h1:kJ5Ny7vLdARGU3WUuy6uzO6T0nb/2gWcT1JiBvRmb5o=
 3 github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c h1:dAMKvw0MlJT1GshSTtih8C2gDs04w8dReiOGXrGLNoY=
 4 github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM=
 5-github.com/picosh/go-rsync-receiver v0.0.0-20250226204508-de154908d143 h1:kJQF0l6QZVc5k82GyvbV007nUb70i6jvq0xV7pu8vKE=
 6-github.com/picosh/go-rsync-receiver v0.0.0-20250226204508-de154908d143/go.mod h1:4ZICsr6bESoHP8He9DqROlZiMw4hHHjcbDzhtTTDQzA=
 7-github.com/picosh/pobj v0.0.0-20250226214525-3032185b0871 h1:rj6rKpa+UVow+VgV7+HhHQVS8+MWvHcugV4LjBmsRQU=
 8-github.com/picosh/pobj v0.0.0-20250226214525-3032185b0871/go.mod h1:opQ0Lp/suBL/wioQfVy3wd+mktpT2Rralq5LWP33jR4=
 9+github.com/picosh/go-rsync-receiver v0.0.0-20250227050534-f3af0a9d7aa6 h1:MCyv/ZwRrtTVLXh2fOTcii5FsPyisWKjcCpBi4FKWQs=
10+github.com/picosh/go-rsync-receiver v0.0.0-20250227050534-f3af0a9d7aa6/go.mod h1:4ZICsr6bESoHP8He9DqROlZiMw4hHHjcbDzhtTTDQzA=
11+github.com/picosh/pobj v0.0.0-20250227050834-c7a07802fbf9 h1:s4oBDJ3Hi8pQ/nHjrbGWATPXRAa6qegUUy8RN4ydzKg=
12+github.com/picosh/pobj v0.0.0-20250227050834-c7a07802fbf9/go.mod h1:pLksoFGKlfy31MVhKjkH3p/lfg7GgYjZqCmVKzWI9/0=
13 github.com/picosh/pubsub v0.0.0-20241114191831-ec8f16c0eb88 h1:hdxE6rquHHw1/eeqS1b+ojLaxGtN8zOiTUclPwaVbPg=
14 github.com/picosh/pubsub v0.0.0-20241114191831-ec8f16c0eb88/go.mod h1:+9hDKIDHQCvGFigCVlIl589BwpT9R4boKhUVc/OgRU4=
15-github.com/picosh/send v0.0.0-20250226204721-03aad51a1f7d h1:KTw+/3E4O+VZ0O6h+3u9v1q4PEVS7jadVS0OixpWQy4=
16-github.com/picosh/send v0.0.0-20250226204721-03aad51a1f7d/go.mod h1:KY80SSX4YcLira+7HRTGVLVHZTVc+emlO56wGzv+SnU=
17+github.com/picosh/send v0.0.0-20250227050705-0c2cd3b14935 h1:4LWBTIpez+fa7RGVsCov6N6BAqE+KO0iwW35/e3yEzg=
18+github.com/picosh/send v0.0.0-20250227050705-0c2cd3b14935/go.mod h1:ehht7ZCPfMc5ycCKlD/yNG0hj3sWWyO4dF3E8IWTQd0=
19 github.com/picosh/tunkit v0.0.0-20240905223921-532404cef9d9 h1:g5oZmnDFr11HarA8IAXcc4o9PBlolSM59QIATCSoato=
20 github.com/picosh/tunkit v0.0.0-20240905223921-532404cef9d9/go.mod h1:UrDH/VCIc1wg/L6iY2zSYt4TiGw+25GsKSnkVkU40Dw=
21 github.com/picosh/utils v0.0.0-20241120033529-8ca070c09bf4 h1:pwbgY9shKyMlpYvpUalTyV0ZVd5paj8pSEYT4OPOYTk=
M pastes/ssh.go
+9, -5
 1@@ -20,7 +20,6 @@ import (
 2 	"github.com/picosh/send/pipe"
 3 	wishrsync "github.com/picosh/send/protocols/rsync"
 4 	"github.com/picosh/send/protocols/scp"
 5-	"github.com/picosh/send/protocols/sftp"
 6 	"github.com/picosh/send/proxy"
 7 	"github.com/picosh/utils"
 8 )
 9@@ -34,18 +33,23 @@ func createRouter(handler *filehandlers.FileHandlerRouter) proxy.Router {
10 			wishrsync.Middleware(handler),
11 			auth.Middleware(handler),
12 			wsh.PtyMdw(wsh.DeprecatedNotice()),
13-			wsh.LogMiddleware(handler.GetLogger()),
14+			wsh.LogMiddleware(handler.GetLogger(s), handler.DBPool),
15 		}
16 	}
17 }
18 
19 func withProxy(handler *filehandlers.FileHandlerRouter, otherMiddleware ...wish.Middleware) ssh.Option {
20 	return func(server *ssh.Server) error {
21-		err := sftp.SSHOption(handler)(server)
22-		if err != nil {
23-			return err
24+		newSubsystemHandlers := map[string]ssh.SubsystemHandler{}
25+
26+		for name, subsystemHandlers := range server.SubsystemHandlers {
27+			newSubsystemHandlers[name] = func(s ssh.Session) {
28+				wsh.LogMiddleware(handler.GetLogger(s), handler.DBPool)(ssh.Handler(subsystemHandlers))
29+			}
30 		}
31 
32+		server.SubsystemHandlers = newSubsystemHandlers
33+
34 		return proxy.WithProxy(createRouter(handler), otherMiddleware...)(server)
35 	}
36 }
M pgs/ssh.go
+11, -1
 1@@ -34,7 +34,7 @@ func createRouter(handler *UploadAssetHandler) proxy.Router {
 2 			auth.Middleware(handler),
 3 			wsh.PtyMdw(wsh.DeprecatedNotice()),
 4 			WishMiddleware(handler),
 5-			wsh.LogMiddleware(handler.GetLogger()),
 6+			wsh.LogMiddleware(handler.GetLogger(s), handler.Cfg.DB),
 7 		}
 8 	}
 9 }
10@@ -46,6 +46,16 @@ func withProxy(handler *UploadAssetHandler, otherMiddleware ...wish.Middleware)
11 			return err
12 		}
13 
14+		newSubsystemHandlers := map[string]ssh.SubsystemHandler{}
15+
16+		for name, subsystemHandler := range server.SubsystemHandlers {
17+			newSubsystemHandlers[name] = func(s ssh.Session) {
18+				wsh.LogMiddleware(handler.GetLogger(s), handler.Cfg.DB)(ssh.Handler(subsystemHandler))(s)
19+			}
20+		}
21+
22+		server.SubsystemHandlers = newSubsystemHandlers
23+
24 		return proxy.WithProxy(createRouter(handler), otherMiddleware...)(server)
25 	}
26 }
M pgs/ssh_test.go
+4, -2
 1@@ -26,11 +26,12 @@ import (
 2 func TestSshServerSftp(t *testing.T) {
 3 	opts := &slog.HandlerOptions{
 4 		AddSource: true,
 5-		Level:     slog.LevelInfo,
 6+		Level:     slog.LevelDebug,
 7 	}
 8 	logger := slog.New(
 9 		slog.NewTextHandler(os.Stdout, opts),
10 	)
11+	slog.SetDefault(logger)
12 	dbpool := pgsdb.NewDBMemory(logger)
13 	// setup test data
14 	dbpool.SetupTestData()
15@@ -85,11 +86,12 @@ func TestSshServerSftp(t *testing.T) {
16 func TestSshServerRsync(t *testing.T) {
17 	opts := &slog.HandlerOptions{
18 		AddSource: true,
19-		Level:     slog.LevelInfo,
20+		Level:     slog.LevelDebug,
21 	}
22 	logger := slog.New(
23 		slog.NewTextHandler(os.Stdout, opts),
24 	)
25+	slog.SetDefault(logger)
26 	dbpool := pgsdb.NewDBMemory(logger)
27 	// setup test data
28 	dbpool.SetupTestData()
M pgs/uploader.go
+41, -22
  1@@ -20,6 +20,7 @@ import (
  2 	"github.com/picosh/pico/db"
  3 	pgsdb "github.com/picosh/pico/pgs/db"
  4 	"github.com/picosh/pico/shared"
  5+	wsh "github.com/picosh/pico/wish"
  6 	"github.com/picosh/pobj"
  7 	sst "github.com/picosh/pobj/storage"
  8 	sendutils "github.com/picosh/send/utils"
  9@@ -112,13 +113,17 @@ func NewUploadAssetHandler(cfg *PgsConfig, ch chan string, ctx context.Context)
 10 	}
 11 }
 12 
 13-func (h *UploadAssetHandler) GetLogger() *slog.Logger {
 14-	return h.Cfg.Logger
 15+func (h *UploadAssetHandler) GetLogger(s ssh.Session) *slog.Logger {
 16+	return wsh.GetLogger(s)
 17 }
 18 
 19 func (h *UploadAssetHandler) Read(s ssh.Session, entry *sendutils.FileEntry) (os.FileInfo, sendutils.ReadAndReaderAtCloser, error) {
 20-	user, err := h.Cfg.DB.FindUser(s.Permissions().Extensions["user_id"])
 21-	if err != nil {
 22+	logger := wsh.GetLogger(s)
 23+	user := wsh.GetUser(s)
 24+
 25+	if user == nil {
 26+		err := fmt.Errorf("could not get user from ctx")
 27+		logger.Error("error getting user from ctx", "err", err)
 28 		return nil, nil, err
 29 	}
 30 
 31@@ -151,8 +156,12 @@ func (h *UploadAssetHandler) Read(s ssh.Session, entry *sendutils.FileEntry) (os
 32 func (h *UploadAssetHandler) List(s ssh.Session, fpath string, isDir bool, recursive bool) ([]os.FileInfo, error) {
 33 	var fileList []os.FileInfo
 34 
 35-	user, err := h.Cfg.DB.FindUser(s.Permissions().Extensions["user_id"])
 36-	if err != nil {
 37+	logger := wsh.GetLogger(s)
 38+	user := wsh.GetUser(s)
 39+
 40+	if user == nil {
 41+		err := fmt.Errorf("could not get user from ctx")
 42+		logger.Error("error getting user from ctx", "err", err)
 43 		return fileList, err
 44 	}
 45 
 46@@ -193,8 +202,12 @@ func (h *UploadAssetHandler) List(s ssh.Session, fpath string, isDir bool, recur
 47 }
 48 
 49 func (h *UploadAssetHandler) Validate(s ssh.Session) error {
 50-	user, err := h.Cfg.DB.FindUser(s.Permissions().Extensions["user_id"])
 51-	if err != nil {
 52+	logger := wsh.GetLogger(s)
 53+	user := wsh.GetUser(s)
 54+
 55+	if user == nil {
 56+		err := fmt.Errorf("could not get user from ctx")
 57+		logger.Error("error getting user from ctx", "err", err)
 58 		return err
 59 	}
 60 
 61@@ -203,20 +216,23 @@ func (h *UploadAssetHandler) Validate(s ssh.Session) error {
 62 	if err != nil {
 63 		return err
 64 	}
 65+
 66 	s.Context().SetValue(ctxBucketKey{}, bucket)
 67 
 68 	totalStorageSize, err := h.Cfg.Storage.GetBucketQuota(bucket)
 69 	if err != nil {
 70 		return err
 71 	}
 72+
 73 	s.Context().SetValue(ctxStorageSizeKey{}, totalStorageSize)
 74-	h.Cfg.Logger.Info(
 75+
 76+	logger.Info(
 77 		"bucket size",
 78 		"user", user.Name,
 79 		"bytes", totalStorageSize,
 80 	)
 81 
 82-	h.Cfg.Logger.Info(
 83+	logger.Info(
 84 		"attempting to upload files",
 85 		"user", user.Name,
 86 		"txtPrefix", h.Cfg.TxtPrefix,
 87@@ -264,9 +280,12 @@ func findPlusFF(dbpool pgsdb.PgsDB, cfg *PgsConfig, userID string) *db.FeatureFl
 88 }
 89 
 90 func (h *UploadAssetHandler) Write(s ssh.Session, entry *sendutils.FileEntry) (string, error) {
 91-	user, err := h.Cfg.DB.FindUser(s.Permissions().Extensions["user_id"])
 92-	if user == nil || err != nil {
 93-		h.Cfg.Logger.Error("user not found in ctx", "err", err.Error())
 94+	logger := wsh.GetLogger(s)
 95+	user := wsh.GetUser(s)
 96+
 97+	if user == nil {
 98+		err := fmt.Errorf("could not get user from ctx")
 99+		logger.Error("error getting user from ctx", "err", err)
100 		return "", err
101 	}
102 
103@@ -274,8 +293,6 @@ func (h *UploadAssetHandler) Write(s ssh.Session, entry *sendutils.FileEntry) (s
104 		entry.Filepath = strings.TrimPrefix(entry.Filepath, "/")
105 	}
106 
107-	logger := h.GetLogger()
108-	logger = shared.LoggerWithUser(logger, user)
109 	logger = logger.With(
110 		"file", entry.Filepath,
111 		"size", entry.Size,
112@@ -379,6 +396,7 @@ func (h *UploadAssetHandler) Write(s ssh.Session, entry *sendutils.FileEntry) (s
113 	}
114 
115 	fsize, err := h.writeAsset(
116+		s,
117 		utils.NewMaxBytesReader(data.Reader, int64(sizeRemaining)),
118 		data,
119 	)
120@@ -425,9 +443,12 @@ func isSpecialFile(entry *sendutils.FileEntry) bool {
121 }
122 
123 func (h *UploadAssetHandler) Delete(s ssh.Session, entry *sendutils.FileEntry) error {
124-	user, err := h.Cfg.DB.FindUser(s.Permissions().Extensions["user_id"])
125-	if err != nil {
126-		h.Cfg.Logger.Error("user not found in ctx", "err", err.Error())
127+	logger := wsh.GetLogger(s)
128+	user := wsh.GetUser(s)
129+
130+	if user == nil {
131+		err := fmt.Errorf("could not get user from ctx")
132+		logger.Error("error getting user from ctx", "err", err)
133 		return err
134 	}
135 
136@@ -437,8 +458,6 @@ func (h *UploadAssetHandler) Delete(s ssh.Session, entry *sendutils.FileEntry) e
137 
138 	assetFilepath := shared.GetAssetFileName(entry)
139 
140-	logger := h.GetLogger()
141-	logger = shared.LoggerWithUser(logger, user)
142 	logger = logger.With(
143 		"file", assetFilepath,
144 	)
145@@ -518,10 +537,10 @@ func (h *UploadAssetHandler) validateAsset(data *FileData) (bool, error) {
146 	return true, nil
147 }
148 
149-func (h *UploadAssetHandler) writeAsset(reader io.Reader, data *FileData) (int64, error) {
150+func (h *UploadAssetHandler) writeAsset(s ssh.Session, reader io.Reader, data *FileData) (int64, error) {
151 	assetFilepath := shared.GetAssetFileName(data.FileEntry)
152 
153-	logger := shared.LoggerWithUser(h.Cfg.Logger, data.User)
154+	logger := h.GetLogger(s)
155 	logger.Info(
156 		"uploading file to bucket",
157 		"bucket", data.Bucket.Name,
M pico/file_handler.go
+24, -10
 1@@ -15,6 +15,7 @@ import (
 2 	"github.com/charmbracelet/wish"
 3 	"github.com/picosh/pico/db"
 4 	"github.com/picosh/pico/shared"
 5+	wsh "github.com/picosh/pico/wish"
 6 	sendutils "github.com/picosh/send/utils"
 7 	"github.com/picosh/utils"
 8 )
 9@@ -56,10 +57,15 @@ func (h *UploadHandler) Delete(s ssh.Session, entry *sendutils.FileEntry) error
10 }
11 
12 func (h *UploadHandler) Read(s ssh.Session, entry *sendutils.FileEntry) (os.FileInfo, sendutils.ReadAndReaderAtCloser, error) {
13-	user, err := h.DBPool.FindUser(s.Permissions().Extensions["user_id"])
14-	if err != nil {
15+	logger := wsh.GetLogger(s)
16+	user := wsh.GetUser(s)
17+
18+	if user == nil {
19+		err := fmt.Errorf("could not get user from ctx")
20+		logger.Error("error getting user from ctx", "err", err)
21 		return nil, nil, err
22 	}
23+
24 	cleanFilename := filepath.Base(entry.Filepath)
25 
26 	if cleanFilename == "" || cleanFilename == "." {
27@@ -80,10 +86,16 @@ func (h *UploadHandler) Read(s ssh.Session, entry *sendutils.FileEntry) (os.File
28 
29 func (h *UploadHandler) List(s ssh.Session, fpath string, isDir bool, recursive bool) ([]os.FileInfo, error) {
30 	var fileList []os.FileInfo
31-	user, err := h.DBPool.FindUser(s.Permissions().Extensions["user_id"])
32-	if err != nil {
33+
34+	logger := wsh.GetLogger(s)
35+	user := wsh.GetUser(s)
36+
37+	if user == nil {
38+		err := fmt.Errorf("could not get user from ctx")
39+		logger.Error("error getting user from ctx", "err", err)
40 		return fileList, err
41 	}
42+
43 	cleanFilename := filepath.Base(fpath)
44 
45 	if cleanFilename == "" || cleanFilename == "." || cleanFilename == "/" {
46@@ -115,8 +127,8 @@ func (h *UploadHandler) List(s ssh.Session, fpath string, isDir bool, recursive
47 	return fileList, nil
48 }
49 
50-func (h *UploadHandler) GetLogger() *slog.Logger {
51-	return h.Cfg.Logger
52+func (h *UploadHandler) GetLogger(s ssh.Session) *slog.Logger {
53+	return wsh.GetLogger(s)
54 }
55 
56 func (h *UploadHandler) Validate(s ssh.Session) error {
57@@ -275,10 +287,12 @@ func (h *UploadHandler) ProcessAuthorizedKeys(text []byte, logger *slog.Logger,
58 }
59 
60 func (h *UploadHandler) Write(s ssh.Session, entry *sendutils.FileEntry) (string, error) {
61-	logger := h.Cfg.Logger
62-	user, err := h.DBPool.FindUser(s.Permissions().Extensions["user_id"])
63-	if err != nil {
64-		logger.Error(err.Error())
65+	logger := wsh.GetLogger(s)
66+	user := wsh.GetUser(s)
67+
68+	if user == nil {
69+		err := fmt.Errorf("could not get user from ctx")
70+		logger.Error("error getting user from ctx", "err", err)
71 		return "", err
72 	}
73 
M pico/ssh.go
+11, -1
 1@@ -37,7 +37,7 @@ func createRouter(cfg *shared.ConfigSite, handler *UploadHandler, cliHandler *Cl
 2 			auth.Middleware(handler),
 3 			wsh.PtyMdw(bm.MiddlewareWithColorProfile(tui.CmsMiddleware(cfg), termenv.TrueColor)),
 4 			WishMiddleware(cliHandler),
 5-			wsh.LogMiddleware(handler.GetLogger()),
 6+			wsh.LogMiddleware(handler.GetLogger(s), handler.DBPool),
 7 		}
 8 	}
 9 }
10@@ -49,6 +49,16 @@ func withProxy(cfg *shared.ConfigSite, handler *UploadHandler, cliHandler *CliHa
11 			return err
12 		}
13 
14+		newSubsystemHandlers := map[string]ssh.SubsystemHandler{}
15+
16+		for name, subsystemHandler := range server.SubsystemHandlers {
17+			newSubsystemHandlers[name] = func(s ssh.Session) {
18+				wsh.LogMiddleware(handler.GetLogger(s), handler.DBPool)(ssh.Handler(subsystemHandler))(s)
19+			}
20+		}
21+
22+		server.SubsystemHandlers = newSubsystemHandlers
23+
24 		return proxy.WithProxy(createRouter(cfg, handler, cliHandler), otherMiddleware...)(server)
25 	}
26 }
M pipe/cli.go
+5, -12
 1@@ -18,8 +18,8 @@ import (
 2 	"github.com/google/uuid"
 3 	"github.com/picosh/pico/db"
 4 	"github.com/picosh/pico/shared"
 5+	wsh "github.com/picosh/pico/wish"
 6 	psub "github.com/picosh/pubsub"
 7-	"github.com/picosh/utils"
 8 	gossh "golang.org/x/crypto/ssh"
 9 )
10 
11@@ -139,18 +139,9 @@ func WishMiddleware(handler *CliHandler) wish.Middleware {
12 
13 	return func(next ssh.Handler) ssh.Handler {
14 		return func(sesh ssh.Session) {
15-			logger := handler.Logger
16 			ctx := sesh.Context()
17-
18-			pubkey := utils.KeyForKeyText(sesh.PublicKey())
19-			user, err := handler.DBPool.FindUserForKey(sesh.User(), pubkey)
20-			if err != nil {
21-				logger.Info("user not found", "err", err)
22-			}
23-
24-			if user != nil {
25-				logger = shared.LoggerWithUser(logger, user)
26-			}
27+			logger := wsh.GetLogger(sesh)
28+			user := wsh.GetUser(sesh)
29 
30 			args := sesh.Command()
31 
32@@ -303,6 +294,8 @@ func WishMiddleware(handler *CliHandler) wish.Middleware {
33 
34 			clientID := fmt.Sprintf("%s (%s%s@%s)", uuid.NewString(), userName, userNameAddition, sesh.RemoteAddr().String())
35 
36+			var err error
37+
38 			if cmd == "pub" {
39 				pubCmd := flagSet("pub", sesh)
40 				access := pubCmd.String("a", "", "Comma separated list of pico usernames or ssh-key fingerprints to allow access to a topic")
M pipe/ssh.go
+1, -1
1@@ -53,7 +53,7 @@ func StartSshServer() {
2 		wish.WithMiddleware(
3 			WishMiddleware(handler),
4 			promwish.Middleware(fmt.Sprintf("%s:%s", host, promPort), "pipe-ssh"),
5-			wsh.LogMiddleware(logger),
6+			wsh.LogMiddleware(logger, dbh),
7 		),
8 	)
9 	if err != nil {
M prose/ssh.go
+11, -1
 1@@ -36,7 +36,7 @@ func createRouter(handler *filehandlers.FileHandlerRouter) proxy.Router {
 2 			wishrsync.Middleware(handler),
 3 			auth.Middleware(handler),
 4 			wsh.PtyMdw(wsh.DeprecatedNotice()),
 5-			wsh.LogMiddleware(handler.GetLogger()),
 6+			wsh.LogMiddleware(handler.GetLogger(s), handler.DBPool),
 7 		}
 8 	}
 9 }
10@@ -48,6 +48,16 @@ func withProxy(handler *filehandlers.FileHandlerRouter, otherMiddleware ...wish.
11 			return err
12 		}
13 
14+		newSubsystemHandlers := map[string]ssh.SubsystemHandler{}
15+
16+		for name, subsystemHandler := range server.SubsystemHandlers {
17+			newSubsystemHandlers[name] = func(s ssh.Session) {
18+				wsh.LogMiddleware(handler.GetLogger(s), handler.DBPool)(ssh.Handler(subsystemHandler))(s)
19+			}
20+		}
21+
22+		server.SubsystemHandlers = newSubsystemHandlers
23+
24 		return proxy.WithProxy(createRouter(handler), otherMiddleware...)(server)
25 	}
26 }
M shared/config.go
+4, -1
 1@@ -288,7 +288,10 @@ func CreateLogger(space string) *slog.Logger {
 2 		newLogger = pipeLogger.RegisterReconnectLogger(context.Background(), log, conn, 100, 10*time.Millisecond)
 3 	}
 4 
 5-	return newLogger.With("service", space)
 6+	defaultLogger := newLogger.With("service", space)
 7+	slog.SetDefault(defaultLogger)
 8+
 9+	return defaultLogger
10 }
11 
12 func LoggerWithUser(logger *slog.Logger, user *db.User) *slog.Logger {
M wish/logger.go
+56, -4
 1@@ -6,18 +6,45 @@ import (
 2 
 3 	"github.com/charmbracelet/ssh"
 4 	"github.com/charmbracelet/wish"
 5+	"github.com/picosh/pico/db"
 6+	"github.com/picosh/pico/shared"
 7 )
 8 
 9-func LogMiddleware(logger *slog.Logger) wish.Middleware {
10+type ctxLoggerKey struct{}
11+type ctxUserKey struct{}
12+
13+type FindUserInterface interface {
14+	FindUser(string) (*db.User, error)
15+}
16+
17+func LogMiddleware(defaultLogger *slog.Logger, db FindUserInterface) wish.Middleware {
18 	return func(sh ssh.Handler) ssh.Handler {
19 		return func(s ssh.Session) {
20 			ct := time.Now()
21+
22+			logger := GetLogger(s)
23+			if logger == slog.Default() {
24+				logger = defaultLogger
25+
26+				user := GetUser(s)
27+				if user == nil {
28+					user, err := db.FindUser(s.Permissions().Extensions["user_id"])
29+					if err == nil && user != nil {
30+						logger = shared.LoggerWithUser(logger, user).With(
31+							"ip", s.RemoteAddr(),
32+						)
33+						s.Context().SetValue(ctxUserKey{}, user)
34+					}
35+				}
36+
37+				s.Context().SetValue(ctxLoggerKey{}, logger)
38+			}
39+
40 			pty, _, ok := s.Pty()
41 
42 			logger.Info(
43 				"connect",
44-				"user", s.User(),
45-				"ip", s.RemoteAddr().String(),
46+				"sshUser", s.User(),
47 				"pty", ok,
48 				"term", pty.Term,
49 				"windowWidth", pty.Window.Width,
50@@ -28,9 +55,34 @@ func LogMiddleware(logger *slog.Logger) wish.Middleware {
51 
52 			logger.Info(
53 				"disconnect",
54-				"ip", s.RemoteAddr().String(),
55+				"sshUser", s.User(),
56+				"pty", ok,
57+				"term", pty.Term,
58+				"windowWidth", pty.Window.Width,
59+				"windowHeight", pty.Window.Height,
60 				"duration", time.Since(ct),
61 			)
62 		}
63 	}
64 }
65+
66+func GetLogger(s ssh.Session) *slog.Logger {
67+	logger := slog.Default()
68+	if s == nil {
69+		return logger
70+	}
71+
72+	if v, ok := s.Context().Value(ctxLoggerKey{}).(*slog.Logger); ok {
73+		return v
74+	}
75+
76+	return logger
77+}
78+
79+func GetUser(s ssh.Session) *db.User {
80+	if v, ok := s.Context().Value(ctxUserKey{}).(*db.User); ok {
81+		return v
82+	}
83+
84+	return nil
85+}
R wish/mdw.go => wish/pty.go
+0, -0