repos / pico

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

commit
2527b65
parent
7405bc8
author
Eric Bower
date
2024-02-24 21:41:35 +0000 UTC
chore(pgs): acl for public sites
4 files changed,  +60, -29
M imgs/api.go
+5, -1
 1@@ -166,6 +166,10 @@ func ImgsRssHandler(w http.ResponseWriter, r *http.Request) {
 2 	}
 3 }
 4 
 5+func anyPerm(proj *db.Project) bool {
 6+	return true
 7+}
 8+
 9 func ImgRequest(w http.ResponseWriter, r *http.Request) {
10 	subdomain := shared.GetSubdomain(r)
11 	cfg := shared.GetCfg(r)
12@@ -230,7 +234,7 @@ func ImgRequest(w http.ResponseWriter, r *http.Request) {
13 	}
14 
15 	fname := post.Filename
16-	pgs.ServeAsset(fname, opts, true, w, r)
17+	pgs.ServeAsset(fname, opts, true, anyPerm, w, r)
18 }
19 
20 func FindImgPost(r *http.Request, user *db.User, slug string) (*db.Post, error) {
M pgs/api.go
+48, -27
  1@@ -313,7 +313,7 @@ func getProjectFromSubdomain(subdomain string) (*SubdomainProps, error) {
  2 	return props, nil
  3 }
  4 
  5-func ServeAsset(fname string, opts *storage.ImgProcessOpts, fromImgs bool, w http.ResponseWriter, r *http.Request) {
  6+func ServeAsset(fname string, opts *storage.ImgProcessOpts, fromImgs bool, hasPerm HasPerm, w http.ResponseWriter, r *http.Request) {
  7 	subdomain := shared.GetSubdomain(r)
  8 	cfg := shared.GetCfg(r)
  9 	dbpool := shared.GetDB(r)
 10@@ -344,10 +344,20 @@ func ServeAsset(fname string, opts *storage.ImgProcessOpts, fromImgs bool, w htt
 11 		bucket, err = st.GetBucket(shared.GetImgsBucketName(user.ID))
 12 	} else {
 13 		bucket, err = st.GetBucket(shared.GetAssetBucketName(user.ID))
 14-		projectDir = props.ProjectName
 15 		project, err := dbpool.FindProjectByName(user.ID, props.ProjectName)
 16-		if err == nil {
 17-			projectDir = project.ProjectDir
 18+		if err != nil {
 19+			logger.Info(
 20+				"project not found",
 21+				"projectName", props.ProjectName,
 22+			)
 23+			http.Error(w, "project not found", http.StatusNotFound)
 24+			return
 25+		}
 26+
 27+		projectDir = project.ProjectDir
 28+		if !hasPerm(project) {
 29+			http.Error(w, "You do not have access to this site", http.StatusUnauthorized)
 30+			return
 31 		}
 32 	}
 33 
 34@@ -375,28 +385,29 @@ func ServeAsset(fname string, opts *storage.ImgProcessOpts, fromImgs bool, w htt
 35 	asset.handle(w)
 36 }
 37 
 38-func ImgAssetRequest(w http.ResponseWriter, r *http.Request) {
 39-	logger := shared.GetLogger(r)
 40-	fname, _ := url.PathUnescape(shared.GetField(r, 0))
 41-	imgOpts, _ := url.PathUnescape(shared.GetField(r, 1))
 42-	opts, err := storage.UriToImgProcessOpts(imgOpts)
 43-	if err != nil {
 44-		errMsg := fmt.Sprintf("error processing img options: %s", err.Error())
 45-		logger.Info(errMsg)
 46-		http.Error(w, errMsg, http.StatusUnprocessableEntity)
 47-	}
 48+type HasPerm = func(proj *db.Project) bool
 49 
 50-	ServeAsset(fname, opts, false, w, r)
 51-}
 52+func ImgAssetRequest(hasPerm HasPerm) http.HandlerFunc {
 53+	return func(w http.ResponseWriter, r *http.Request) {
 54+		logger := shared.GetLogger(r)
 55+		fname, _ := url.PathUnescape(shared.GetField(r, 0))
 56+		imgOpts, _ := url.PathUnescape(shared.GetField(r, 1))
 57+		opts, err := storage.UriToImgProcessOpts(imgOpts)
 58+		if err != nil {
 59+			errMsg := fmt.Sprintf("error processing img options: %s", err.Error())
 60+			logger.Info(errMsg)
 61+			http.Error(w, errMsg, http.StatusUnprocessableEntity)
 62+		}
 63 
 64-func AssetRequest(w http.ResponseWriter, r *http.Request) {
 65-	fname, _ := url.PathUnescape(shared.GetField(r, 0))
 66-	ServeAsset(fname, nil, false, w, r)
 67+		ServeAsset(fname, opts, false, hasPerm, w, r)
 68+	}
 69 }
 70 
 71-func PrivateAssetRequest(w http.ResponseWriter, r *http.Request) {
 72-	fname, _ := url.PathUnescape(shared.GetField(r, 0))
 73-	ServeAsset(fname, nil, false, w, r)
 74+func AssetRequest(hasPerm HasPerm) http.HandlerFunc {
 75+	return func(w http.ResponseWriter, r *http.Request) {
 76+		fname, _ := url.PathUnescape(shared.GetField(r, 0))
 77+		ServeAsset(fname, nil, false, hasPerm, w, r)
 78+	}
 79 }
 80 
 81 var mainRoutes = []shared.Route{
 82@@ -412,10 +423,20 @@ var mainRoutes = []shared.Route{
 83 	shared.NewRoute("GET", "/rss", rssHandler),
 84 	shared.NewRoute("GET", "/(.+)", shared.CreatePageHandler("html/marketing.page.tmpl")),
 85 }
 86-var subdomainRoutes = []shared.Route{
 87-	shared.NewRoute("GET", "/", AssetRequest),
 88-	shared.NewRoute("GET", "(/.+.(?:jpg|jpeg|png|gif|webp|svg))(/.+)", ImgAssetRequest),
 89-	shared.NewRoute("GET", "/(.+)", AssetRequest),
 90+
 91+func createSubdomainRoutes(hasPerm HasPerm) []shared.Route {
 92+	assetRequest := AssetRequest(hasPerm)
 93+	imgRequest := ImgAssetRequest(hasPerm)
 94+
 95+	return []shared.Route{
 96+		shared.NewRoute("GET", "/", assetRequest),
 97+		shared.NewRoute("GET", "(/.+.(?:jpg|jpeg|png|gif|webp|svg))(/.+)", imgRequest),
 98+		shared.NewRoute("GET", "/(.+)", assetRequest),
 99+	}
100+}
101+
102+func publicPerm(proj *db.Project) bool {
103+	return proj.Acl.Type == "public"
104 }
105 
106 func StartApiServer() {
107@@ -443,7 +464,7 @@ func StartApiServer() {
108 		return
109 	}
110 
111-	handler := shared.CreateServe(mainRoutes, subdomainRoutes, cfg, db, st, logger, cache)
112+	handler := shared.CreateServe(mainRoutes, createSubdomainRoutes(publicPerm), cfg, db, st, logger, cache)
113 	router := http.HandlerFunc(handler)
114 
115 	portStr := fmt.Sprintf(":%s", cfg.Port)
M pgs/cms.go
+0, -1
1@@ -80,7 +80,6 @@ type GotDBMsg db.DB
2 
3 func CmsMiddleware(cfg *config.ConfigCms, urls config.ConfigURL) bm.Handler {
4 	return func(s ssh.Session) (tea.Model, []tea.ProgramOption) {
5-		fmt.Println("MADE IT HERE")
6 		logger := cfg.Logger
7 
8 		_, _, active := s.Pty()
M pgs/ssh.go
+7, -0
 1@@ -15,6 +15,7 @@ import (
 2 	"github.com/charmbracelet/wish"
 3 	bm "github.com/charmbracelet/wish/bubbletea"
 4 	gocache "github.com/patrickmn/go-cache"
 5+	"github.com/picosh/pico/db"
 6 	"github.com/picosh/pico/db/postgres"
 7 	uploadassets "github.com/picosh/pico/filehandlers/assets"
 8 	"github.com/picosh/pico/shared"
 9@@ -78,6 +79,10 @@ func unauthorizedHandler(w http.ResponseWriter, r *http.Request) {
10 	http.Error(w, "You do not have access to this site", http.StatusUnauthorized)
11 }
12 
13+func allowPerm(proj *db.Project) bool {
14+	return true
15+}
16+
17 type PicoApi struct {
18 	UserID    string `json:"user_id"`
19 	UserName  string `json:"username"`
20@@ -189,6 +194,8 @@ func StartSshServer() {
21 					}
22 				}),
23 			}
24+
25+			subdomainRoutes := createSubdomainRoutes(allowPerm)
26 			routes = append(routes, subdomainRoutes...)
27 			httpHandler := shared.CreateServeBasic(
28 				routes,