- commit
- dcfb7ac
- parent
- fc16c4a
- author
- Eric Bower
- date
- 2024-12-11 18:38:58 +0000 UTC
fix: address CVE-2024-45337 Reference: https://github.com/golang/go/issues/70779
12 files changed,
+71,
-136
+4,
-7
1@@ -48,7 +48,7 @@ func NewUploadImgHandler(dbpool db.DB, cfg *shared.ConfigSite, storage storage.S
2 }
3
4 func (h *UploadImgHandler) Read(s ssh.Session, entry *sendutils.FileEntry) (os.FileInfo, sendutils.ReaderAtCloser, error) {
5- user, err := shared.GetUser(s.Context())
6+ user, err := h.DBPool.FindUser(s.Permissions().Extensions["user_id"])
7 if err != nil {
8 return nil, nil, err
9 }
10@@ -88,7 +88,7 @@ func (h *UploadImgHandler) Read(s ssh.Session, entry *sendutils.FileEntry) (os.F
11
12 func (h *UploadImgHandler) Write(s ssh.Session, entry *sendutils.FileEntry) (string, error) {
13 logger := h.Cfg.Logger
14- user, err := shared.GetUser(s.Context())
15+ user, err := h.DBPool.FindUser(s.Permissions().Extensions["user_id"])
16 if err != nil {
17 logger.Error("could not get user from ctx", "err", err.Error())
18 return "", err
19@@ -145,10 +145,7 @@ func (h *UploadImgHandler) Write(s ssh.Session, entry *sendutils.FileEntry) (str
20 logger.Info("unable to find image, continuing", "filename", nextPost.Filename, "err", err.Error())
21 }
22
23- featureFlag, err := shared.GetFeatureFlag(s.Context())
24- if err != nil {
25- return "", err
26- }
27+ featureFlag := shared.FindPlusFF(h.DBPool, h.Cfg, user.ID)
28 metadata := PostMetaData{
29 OrigText: text,
30 Post: &nextPost,
31@@ -192,7 +189,7 @@ func (h *UploadImgHandler) Write(s ssh.Session, entry *sendutils.FileEntry) (str
32 }
33
34 func (h *UploadImgHandler) Delete(s ssh.Session, entry *sendutils.FileEntry) error {
35- user, err := shared.GetUser(s.Context())
36+ user, err := h.DBPool.FindUser(s.Permissions().Extensions["user_id"])
37 if err != nil {
38 return err
39 }
+1,
-1
1@@ -80,7 +80,7 @@ func (h *UploadImgHandler) writeImg(s ssh.Session, data *PostMetaData) error {
2 if !valid {
3 return err
4 }
5- user, err := shared.GetUser(s.Context())
6+ user, err := h.DBPool.FindUser(s.Permissions().Extensions["user_id"])
7 if err != nil {
8 return err
9 }
+3,
-3
1@@ -47,7 +47,7 @@ func NewScpPostHandler(dbpool db.DB, cfg *shared.ConfigSite, hooks ScpFileHooks,
2 }
3
4 func (h *ScpUploadHandler) Read(s ssh.Session, entry *sendutils.FileEntry) (os.FileInfo, sendutils.ReaderAtCloser, error) {
5- user, err := shared.GetUser(s.Context())
6+ user, err := h.DBPool.FindUser(s.Permissions().Extensions["user_id"])
7 if err != nil {
8 return nil, nil, err
9 }
10@@ -76,7 +76,7 @@ func (h *ScpUploadHandler) Read(s ssh.Session, entry *sendutils.FileEntry) (os.F
11
12 func (h *ScpUploadHandler) Write(s ssh.Session, entry *sendutils.FileEntry) (string, error) {
13 logger := h.Cfg.Logger
14- user, err := shared.GetUser(s.Context())
15+ user, err := h.DBPool.FindUser(s.Permissions().Extensions["user_id"])
16 if err != nil {
17 logger.Error("error getting user from ctx", "err", err.Error())
18 return "", err
19@@ -263,7 +263,7 @@ func (h *ScpUploadHandler) Write(s ssh.Session, entry *sendutils.FileEntry) (str
20
21 func (h *ScpUploadHandler) Delete(s ssh.Session, entry *sendutils.FileEntry) error {
22 logger := h.Cfg.Logger
23- user, err := shared.GetUser(s.Context())
24+ user, err := h.DBPool.FindUser(s.Permissions().Extensions["user_id"])
25 if err != nil {
26 logger.Error("could not get user from ctx", "err", err.Error())
27 return err
+2,
-2
1@@ -82,7 +82,7 @@ func (r *FileHandlerRouter) Read(s ssh.Session, entry *utils.FileEntry) (os.File
2
3 func BaseList(s ssh.Session, fpath string, isDir bool, recursive bool, spaces []string, dbpool db.DB) ([]os.FileInfo, error) {
4 var fileList []os.FileInfo
5- user, err := shared.GetUser(s.Context())
6+ user, err := dbpool.FindUser(s.Permissions().Extensions["user_id"])
7 if err != nil {
8 return fileList, err
9 }
10@@ -153,7 +153,7 @@ func (r *FileHandlerRouter) GetLogger() *slog.Logger {
11 }
12
13 func (r *FileHandlerRouter) Validate(s ssh.Session) error {
14- user, err := shared.GetUser(s.Context())
15+ user, err := r.DBPool.FindUser(s.Permissions().Extensions["user_id"])
16 if err != nil {
17 return err
18 }
M
go.mod
+5,
-5
1@@ -53,7 +53,7 @@ require (
2 go.abhg.dev/goldmark/anchor v0.1.1
3 go.abhg.dev/goldmark/hashtag v0.3.1
4 go.abhg.dev/goldmark/toc v0.10.0
5- golang.org/x/crypto v0.29.0
6+ golang.org/x/crypto v0.31.0
7 gopkg.in/yaml.v2 v2.4.0
8 )
9
10@@ -179,10 +179,10 @@ require (
11 github.com/yusufpapurcu/wmi v1.2.4 // indirect
12 golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f // indirect
13 golang.org/x/net v0.31.0 // indirect
14- golang.org/x/sync v0.9.0 // indirect
15- golang.org/x/sys v0.27.0 // indirect
16- golang.org/x/term v0.26.0 // indirect
17- golang.org/x/text v0.20.0 // indirect
18+ golang.org/x/sync v0.10.0 // indirect
19+ golang.org/x/sys v0.28.0 // indirect
20+ golang.org/x/term v0.27.0 // indirect
21+ golang.org/x/text v0.21.0 // indirect
22 golang.org/x/time v0.8.0 // indirect
23 google.golang.org/protobuf v1.35.2 // indirect
24 mvdan.cc/xurls/v2 v2.5.0 // indirect
M
go.sum
+10,
-10
1@@ -391,8 +391,8 @@ golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPh
2 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
3 golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g=
4 golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
5-golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ=
6-golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg=
7+golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
8+golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
9 golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f h1:XdNn9LlyWAhLVp6P/i8QYBW+hlyhrhei9uErw2B5GJo=
10 golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f/go.mod h1:D5SMRVC3C2/4+F/DB1wZsLRnSNimn2Sp/NPsCrsv8ak=
11 golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
12@@ -417,8 +417,8 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJ
13 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
14 golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
15 golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
16-golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ=
17-golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
18+golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
19+golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
20 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
21 golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
22 golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
23@@ -438,8 +438,8 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
24 golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
25 golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
26 golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
27-golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
28-golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
29+golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
30+golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
31 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
32 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
33 golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
34@@ -447,16 +447,16 @@ golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
35 golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
36 golang.org/x/term v0.14.0/go.mod h1:TySc+nGkYR6qt8km8wUhuFRTVSMIX3XPR58y2lC8vww=
37 golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
38-golang.org/x/term v0.26.0 h1:WEQa6V3Gja/BhNxg540hBip/kkaYtRg3cxg4oXSw4AU=
39-golang.org/x/term v0.26.0/go.mod h1:Si5m1o57C5nBNQo5z1iq+XDijt21BDBDp2bK0QI8e3E=
40+golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q=
41+golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
42 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
43 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
44 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
45 golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
46 golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
47 golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
48-golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug=
49-golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4=
50+golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
51+golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
52 golang.org/x/time v0.4.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
53 golang.org/x/time v0.8.0 h1:9i3RxcPv3PZnitoVGMPDKZSq1xW1gK1Xy3ArNOGZfEg=
54 golang.org/x/time v0.8.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
+11,
-29
1@@ -7,7 +7,6 @@ import (
2 "github.com/charmbracelet/ssh"
3 "github.com/picosh/pico/db"
4 "github.com/picosh/pico/shared"
5- "github.com/picosh/utils"
6 )
7
8 type TunnelWebRouter struct {
9@@ -39,16 +38,14 @@ func createHttpHandler(apiConfig *shared.ApiConfig) CtxHttpBridge {
10 "impersonating", asUser,
11 )
12
13- pubkey, err := shared.GetPublicKey(ctx)
14- if err != nil {
15- log.Error(err.Error(), "subdomain", subdomain)
16+ pubkey := ctx.Permissions().Extensions["pubkey"]
17+ if pubkey == "" {
18+ log.Error("pubkey not found in extensions", "subdomain", subdomain)
19 return http.HandlerFunc(shared.UnauthorizedHandler)
20 }
21
22- pubkeyStr := utils.KeyForKeyText(pubkey)
23-
24 log = log.With(
25- "pubkey", pubkeyStr,
26+ "pubkey", pubkey,
27 )
28
29 props, err := shared.GetProjectFromSubdomain(subdomain)
30@@ -72,7 +69,7 @@ func createHttpHandler(apiConfig *shared.ApiConfig) CtxHttpBridge {
31 return http.HandlerFunc(shared.UnauthorizedHandler)
32 }
33
34- requester, _ := dbh.FindUserForKey("", pubkeyStr)
35+ requester, _ := dbh.FindUserForKey("", pubkey)
36 if requester != nil {
37 log = log.With(
38 "requester", requester.Name,
39@@ -89,33 +86,18 @@ func createHttpHandler(apiConfig *shared.ApiConfig) CtxHttpBridge {
40 requester, _ = dbh.FindUserForName(asUser)
41 }
42
43- shared.SetUser(ctx, requester)
44-
45- if !HasProjectAccess(project, owner, requester, pubkey) {
46+ ctx.Permissions().Extensions["user_id"] = requester.ID
47+ publicKey, err := ssh.ParsePublicKey([]byte(pubkey))
48+ if err != nil {
49+ return http.HandlerFunc(shared.UnauthorizedHandler)
50+ }
51+ if !HasProjectAccess(project, owner, requester, publicKey) {
52 log.Error("no access")
53 return http.HandlerFunc(shared.UnauthorizedHandler)
54 }
55
56 log.Info("user has access to site")
57
58- /* routes := []shared.Route{
59- // special API endpoint for tunnel users accessing site
60- shared.NewCorsRoute("GET", "/api/current_user", func(w http.ResponseWriter, r *http.Request) {
61- w.Header().Set("Content-Type", "application/json")
62- user, err := shared.GetUser(ctx)
63- if err != nil {
64- logger.Error("could not find user", "err", err.Error())
65- shared.JSONError(w, err.Error(), http.StatusNotFound)
66- return
67- }
68- pico := shared.NewUserApi(user, pubkey)
69- err = json.NewEncoder(w).Encode(pico)
70- if err != nil {
71- log.Error(err.Error())
72- }
73- }),
74- } */
75-
76 routes := NewWebRouter(
77 apiConfig.Cfg,
78 logger,
+6,
-10
1@@ -121,7 +121,7 @@ func (h *UploadAssetHandler) GetLogger() *slog.Logger {
2 }
3
4 func (h *UploadAssetHandler) Read(s ssh.Session, entry *sendutils.FileEntry) (os.FileInfo, sendutils.ReaderAtCloser, error) {
5- user, err := shared.GetUser(s.Context())
6+ user, err := h.DBPool.FindUser(s.Permissions().Extensions["user_id"])
7 if err != nil {
8 return nil, nil, err
9 }
10@@ -155,7 +155,7 @@ func (h *UploadAssetHandler) Read(s ssh.Session, entry *sendutils.FileEntry) (os
11 func (h *UploadAssetHandler) List(s ssh.Session, fpath string, isDir bool, recursive bool) ([]os.FileInfo, error) {
12 var fileList []os.FileInfo
13
14- user, err := shared.GetUser(s.Context())
15+ user, err := h.DBPool.FindUser(s.Permissions().Extensions["user_id"])
16 if err != nil {
17 return fileList, err
18 }
19@@ -197,7 +197,7 @@ func (h *UploadAssetHandler) List(s ssh.Session, fpath string, isDir bool, recur
20 }
21
22 func (h *UploadAssetHandler) Validate(s ssh.Session) error {
23- user, err := shared.GetUser(s.Context())
24+ user, err := h.DBPool.FindUser(s.Permissions().Extensions["user_id"])
25 if err != nil {
26 return err
27 }
28@@ -248,7 +248,7 @@ func (h *UploadAssetHandler) findDenylist(bucket sst.Bucket, project *db.Project
29 }
30
31 func (h *UploadAssetHandler) Write(s ssh.Session, entry *sendutils.FileEntry) (string, error) {
32- user, err := shared.GetUser(s.Context())
33+ user, err := h.DBPool.FindUser(s.Permissions().Extensions["user_id"])
34 if user == nil || err != nil {
35 h.Cfg.Logger.Error("user not found in ctx", "err", err.Error())
36 return "", err
37@@ -314,11 +314,7 @@ func (h *UploadAssetHandler) Write(s ssh.Session, entry *sendutils.FileEntry) (s
38 return "", err
39 }
40
41- featureFlag, err := shared.GetFeatureFlag(s.Context())
42- if err != nil {
43- return "", err
44- }
45-
46+ featureFlag := shared.FindPlusFF(h.DBPool, h.Cfg, user.ID)
47 // calculate the filsize difference between the same file already
48 // stored and the updated file being uploaded
49 assetFilename := shared.GetAssetFileName(entry)
50@@ -424,7 +420,7 @@ func isSpecialFile(entry *sendutils.FileEntry) bool {
51 }
52
53 func (h *UploadAssetHandler) Delete(s ssh.Session, entry *sendutils.FileEntry) error {
54- user, err := shared.GetUser(s.Context())
55+ user, err := h.DBPool.FindUser(s.Permissions().Extensions["user_id"])
56 if err != nil {
57 h.Cfg.Logger.Error("user not found in ctx", "err", err.Error())
58 return err
+4,
-4
1@@ -56,7 +56,7 @@ func (h *UploadHandler) Delete(s ssh.Session, entry *sendutils.FileEntry) error
2 }
3
4 func (h *UploadHandler) Read(s ssh.Session, entry *sendutils.FileEntry) (os.FileInfo, sendutils.ReaderAtCloser, error) {
5- user, err := shared.GetUser(s.Context())
6+ user, err := h.DBPool.FindUser(s.Permissions().Extensions["user_id"])
7 if err != nil {
8 return nil, nil, err
9 }
10@@ -80,7 +80,7 @@ func (h *UploadHandler) Read(s ssh.Session, entry *sendutils.FileEntry) (os.File
11
12 func (h *UploadHandler) List(s ssh.Session, fpath string, isDir bool, recursive bool) ([]os.FileInfo, error) {
13 var fileList []os.FileInfo
14- user, err := shared.GetUser(s.Context())
15+ user, err := h.DBPool.FindUser(s.Permissions().Extensions["user_id"])
16 if err != nil {
17 return fileList, err
18 }
19@@ -135,7 +135,7 @@ func (h *UploadHandler) Validate(s ssh.Session) error {
20 return fmt.Errorf("must have username set")
21 }
22
23- shared.SetUser(s.Context(), user)
24+ s.Permissions().Extensions["user_id"] = user.ID
25 return nil
26 }
27
28@@ -276,7 +276,7 @@ func (h *UploadHandler) ProcessAuthorizedKeys(text []byte, logger *slog.Logger,
29
30 func (h *UploadHandler) Write(s ssh.Session, entry *sendutils.FileEntry) (string, error) {
31 logger := h.Cfg.Logger
32- user, err := shared.GetUser(s.Context())
33+ user, err := h.DBPool.FindUser(s.Permissions().Extensions["user_id"])
34 if err != nil {
35 logger.Error(err.Error())
36 return "", err
+0,
-1
1@@ -28,7 +28,6 @@ import (
2 )
3
4 func authHandler(ctx ssh.Context, key ssh.PublicKey) bool {
5- shared.SetPublicKey(ctx, key)
6 return true
7 }
8
+1,
-1
1@@ -141,7 +141,7 @@ func WishMiddleware(handler *CliHandler) wish.Middleware {
2 logger := handler.Logger
3 ctx := sesh.Context()
4
5- user, err := shared.GetUser(ctx)
6+ user, err := handler.DBPool.FindUser(sesh.Permissions().Extensions["user_id"])
7 if err != nil {
8 logger.Info("user not found", "err", err)
9 }
1@@ -1,7 +1,6 @@
2 package shared
3
4 import (
5- "fmt"
6 "log/slog"
7
8 "github.com/charmbracelet/ssh"
9@@ -9,47 +8,6 @@ import (
10 "github.com/picosh/utils"
11 )
12
13-type ctxUserKey struct{}
14-type ctxFeatureFlagKey struct{}
15-
16-func GetUser(ctx ssh.Context) (*db.User, error) {
17- user, ok := ctx.Value(ctxUserKey{}).(*db.User)
18- if !ok {
19- return user, fmt.Errorf("user not set on `ssh.Context()` for connection")
20- }
21- return user, nil
22-}
23-
24-func SetUser(ctx ssh.Context, user *db.User) {
25- ctx.SetValue(ctxUserKey{}, user)
26-}
27-
28-func GetFeatureFlag(ctx ssh.Context) (*db.FeatureFlag, error) {
29- ff, ok := ctx.Value(ctxFeatureFlagKey{}).(*db.FeatureFlag)
30- if !ok || ff.Name == "" {
31- return ff, fmt.Errorf("feature flag not set on `ssh.Context()` for connection")
32- }
33- return ff, nil
34-}
35-
36-func SetFeatureFlag(ctx ssh.Context, ff *db.FeatureFlag) {
37- ctx.SetValue(ctxFeatureFlagKey{}, ff)
38-}
39-
40-type ctxPublicKey struct{}
41-
42-func GetPublicKey(ctx ssh.Context) (ssh.PublicKey, error) {
43- pk, ok := ctx.Value(ctxPublicKey{}).(ssh.PublicKey)
44- if !ok {
45- return nil, fmt.Errorf("public key not set on `ssh.Context()` for connection")
46- }
47- return pk, nil
48-}
49-
50-func SetPublicKey(ctx ssh.Context, pk ssh.PublicKey) {
51- ctx.SetValue(ctxPublicKey{}, pk)
52-}
53-
54 type SshAuthHandler struct {
55 DBPool db.DB
56 Logger *slog.Logger
57@@ -64,11 +22,28 @@ func NewSshAuthHandler(dbpool db.DB, logger *slog.Logger, cfg *ConfigSite) *SshA
58 }
59 }
60
61-func (r *SshAuthHandler) PubkeyAuthHandler(ctx ssh.Context, key ssh.PublicKey) bool {
62- SetPublicKey(ctx, key)
63+func FindPlusFF(dbpool db.DB, cfg *ConfigSite, userID string) *db.FeatureFlag {
64+ ff, _ := dbpool.FindFeatureForUser(userID, "plus")
65+ // we have free tiers so users might not have a feature flag
66+ // in which case we set sane defaults
67+ if ff == nil {
68+ ff = db.NewFeatureFlag(
69+ userID,
70+ "plus",
71+ cfg.MaxSize,
72+ cfg.MaxAssetSize,
73+ cfg.MaxSpecialFileSize,
74+ )
75+ }
76+ // this is jank
77+ ff.Data.StorageMax = ff.FindStorageMax(cfg.MaxSize)
78+ ff.Data.FileMax = ff.FindFileMax(cfg.MaxAssetSize)
79+ ff.Data.SpecialFileMax = ff.FindSpecialFileMax(cfg.MaxSpecialFileSize)
80+ return ff
81+}
82
83+func (r *SshAuthHandler) PubkeyAuthHandler(ctx ssh.Context, key ssh.PublicKey) bool {
84 pubkey := utils.KeyForKeyText(key)
85-
86 user, err := r.DBPool.FindUserForKey(ctx.User(), pubkey)
87 if err != nil {
88 r.Logger.Error(
89@@ -84,24 +59,10 @@ func (r *SshAuthHandler) PubkeyAuthHandler(ctx ssh.Context, key ssh.PublicKey) b
90 return false
91 }
92
93- ff, _ := r.DBPool.FindFeatureForUser(user.ID, "plus")
94- // we have free tiers so users might not have a feature flag
95- // in which case we set sane defaults
96- if ff == nil {
97- ff = db.NewFeatureFlag(
98- user.ID,
99- "plus",
100- r.Cfg.MaxSize,
101- r.Cfg.MaxAssetSize,
102- r.Cfg.MaxSpecialFileSize,
103- )
104+ if ctx.Permissions().Extensions == nil {
105+ ctx.Permissions().Extensions = map[string]string{}
106 }
107- // this is jank
108- ff.Data.StorageMax = ff.FindStorageMax(r.Cfg.MaxSize)
109- ff.Data.FileMax = ff.FindFileMax(r.Cfg.MaxAssetSize)
110- ff.Data.SpecialFileMax = ff.FindSpecialFileMax(r.Cfg.MaxSpecialFileSize)
111-
112- SetUser(ctx, user)
113- SetFeatureFlag(ctx, ff)
114+ ctx.Permissions().Extensions["user_id"] = user.ID
115+ ctx.Permissions().Extensions["pubkey"] = pubkey
116 return true
117 }