- commit
- ea9df3f
- parent
- 45f05e7
- author
- Eric Bower
- date
- 2025-04-23 23:52:14 -0400 EDT
fix(pgs): private site access We were not correctly overriding the default WebRouter which meant it was always rejecting non-public ACLs for sites.
3 files changed,
+41,
-32
+4,
-4
1@@ -19,12 +19,12 @@ type TunnelWebRouter struct {
2
3 func (web *TunnelWebRouter) InitRouter() {
4 router := http.NewServeMux()
5- router.HandleFunc("GET /{fname...}", web.AssetRequest)
6- router.HandleFunc("GET /{$}", web.AssetRequest)
7+ router.HandleFunc("GET /{fname...}", web.AssetRequest(tunnelPerm))
8+ router.HandleFunc("GET /{$}", web.AssetRequest(tunnelPerm))
9 web.UserRouter = router
10 }
11
12-func (web *TunnelWebRouter) Perm(proj *db.Project) bool {
13+func tunnelPerm(proj *db.Project) bool {
14 return true
15 }
16
17@@ -128,7 +128,7 @@ func createHttpHandler(cfg *PgsConfig) CtxHttpBridge {
18
19 routes := NewWebRouter(cfg)
20 tunnelRouter := TunnelWebRouter{routes, subdomain}
21- tunnelRouter.initRouters()
22+ tunnelRouter.InitRouter()
23 return &tunnelRouter
24 }
25 }
+33,
-28
1@@ -143,8 +143,8 @@ func (web *WebRouter) initRouters() {
2
3 // subdomain or custom domains
4 userRouter := http.NewServeMux()
5- userRouter.HandleFunc("GET /{fname...}", web.AssetRequest)
6- userRouter.HandleFunc("GET /{$}", web.AssetRequest)
7+ userRouter.HandleFunc("GET /{fname...}", web.AssetRequest(WebPerm))
8+ userRouter.HandleFunc("GET /{$}", web.AssetRequest(WebPerm))
9 web.UserRouter = userRouter
10 }
11
12@@ -397,42 +397,46 @@ func (web *WebRouter) createRssHandler(by string) http.HandlerFunc {
13 }
14 }
15
16-func (web *WebRouter) Perm(proj *db.Project) bool {
17+func WebPerm(proj *db.Project) bool {
18 return proj.Acl.Type == "public" || proj.Acl.Type == ""
19 }
20
21 var imgRegex = regexp.MustCompile("(.+.(?:jpg|jpeg|png|gif|webp|svg))(/.+)")
22
23-func (web *WebRouter) AssetRequest(w http.ResponseWriter, r *http.Request) {
24- fname := r.PathValue("fname")
25- if imgRegex.MatchString(fname) {
26- web.ImageRequest(w, r)
27- return
28+func (web *WebRouter) AssetRequest(perm func(proj *db.Project) bool) http.HandlerFunc {
29+ return func(w http.ResponseWriter, r *http.Request) {
30+ fname := r.PathValue("fname")
31+ if imgRegex.MatchString(fname) {
32+ web.ImageRequest(perm)(w, r)
33+ return
34+ }
35+ web.ServeAsset(fname, nil, false, perm, w, r)
36 }
37- web.ServeAsset(fname, nil, false, web.Perm, w, r)
38 }
39
40-func (web *WebRouter) ImageRequest(w http.ResponseWriter, r *http.Request) {
41- rawname := r.PathValue("fname")
42- matches := imgRegex.FindStringSubmatch(rawname)
43- fname := rawname
44- imgOpts := ""
45- if len(matches) >= 2 {
46- fname = matches[1]
47- }
48- if len(matches) >= 3 {
49- imgOpts = matches[2]
50- }
51+func (web *WebRouter) ImageRequest(perm func(proj *db.Project) bool) http.HandlerFunc {
52+ return func(w http.ResponseWriter, r *http.Request) {
53+ rawname := r.PathValue("fname")
54+ matches := imgRegex.FindStringSubmatch(rawname)
55+ fname := rawname
56+ imgOpts := ""
57+ if len(matches) >= 2 {
58+ fname = matches[1]
59+ }
60+ if len(matches) >= 3 {
61+ imgOpts = matches[2]
62+ }
63
64- opts, err := storage.UriToImgProcessOpts(imgOpts)
65- if err != nil {
66- errMsg := fmt.Sprintf("error processing img options: %s", err.Error())
67- web.Cfg.Logger.Error("error processing img options", "err", errMsg)
68- http.Error(w, errMsg, http.StatusUnprocessableEntity)
69- return
70- }
71+ opts, err := storage.UriToImgProcessOpts(imgOpts)
72+ if err != nil {
73+ errMsg := fmt.Sprintf("error processing img options: %s", err.Error())
74+ web.Cfg.Logger.Error("error processing img options", "err", errMsg)
75+ http.Error(w, errMsg, http.StatusUnprocessableEntity)
76+ return
77+ }
78
79- web.ServeAsset(fname, opts, false, web.Perm, w, r)
80+ web.ServeAsset(fname, opts, false, perm, w, r)
81+ }
82 }
83
84 func (web *WebRouter) ServeAsset(fname string, opts *storage.ImgProcessOpts, fromImgs bool, hasPerm HasPerm, w http.ResponseWriter, r *http.Request) {
85@@ -502,6 +506,7 @@ func (web *WebRouter) ServeAsset(fname string, opts *storage.ImgProcessOpts, fro
86 projectID = project.ID
87 projectDir = project.ProjectDir
88 if !hasPerm(project) {
89+ logger.Error("You do not have access to this site")
90 http.Error(w, "You do not have access to this site", http.StatusUnauthorized)
91 return
92 }
+4,
-0
1@@ -1,6 +1,7 @@
2 package tunkit
3
4 import (
5+ "context"
6 "errors"
7 "io"
8 "log/slog"
9@@ -51,9 +52,12 @@ func LocalForwardHandler(handler Tunnel) pssh.SSHServerChannelMiddleware {
10 return err
11 }
12
13+ origCtx, cancel := context.WithCancel(context.Background())
14 ctx := &pssh.SSHServerConnSession{
15 Channel: ch,
16 SSHServerConn: sc,
17+ Ctx: origCtx,
18+ CancelFunc: cancel,
19 }
20
21 go ssh.DiscardRequests(reqs)