Commit e5d5430
Eric Bower
·
2026-08-11 13:56:36 -0400 EDT
parent 06944c5
refactor(pgs): validate pico+ before uploading so we don't create empty projects
3 files changed,
+28,
-12
+1,
-0
| ... | ... | @@ -194,6 +194,7 @@ services: | |
| 194 | 194 | environment: | |
| 195 | 195 | APP_DOMAIN: ${PGS_DOMAIN:-pgs.sh} | |
| 196 | 196 | APP_EMAIL: ${PGS_EMAIL:-hello@pico.sh} | |
| 197 | + | DATABASE_URL: ${DATABASE_URL} | |
| 197 | 198 | volumes: | |
| 198 | 199 | - ${PGS_CADDYFILE}:/etc/caddy/Caddyfile | |
| 199 | 200 | - ./data/pgs-caddy/data:/data |
+24,
-10
| ... | ... | @@ -27,6 +27,7 @@ import ( | |
| 27 | 27 | type ctxBucketKey struct{} | |
| 28 | 28 | type ctxStorageSizeKey struct{} | |
| 29 | 29 | type ctxProjectKey struct{} | |
| 30 | + | type ctxFeatureFlagKey struct{} | |
| 30 | 31 | type ctxDenylistKey struct{} | |
| 31 | 32 | ||
| 32 | 33 | type DenyList struct { |
| ... | ... | @@ -59,6 +60,19 @@ func setProject(s *pssh.SSHServerConnSession, project *db.Project) { | |
| 59 | 60 | s.SetValue(ctxProjectKey{}, project) | |
| 60 | 61 | } | |
| 61 | 62 | ||
| 63 | + | func getFeatureFlag(s *pssh.SSHServerConnSession) *db.FeatureFlag { | |
| 64 | + | v := s.Context().Value(ctxFeatureFlagKey{}) | |
| 65 | + | if v == nil { | |
| 66 | + | return nil | |
| 67 | + | } | |
| 68 | + | ff := s.Context().Value(ctxFeatureFlagKey{}).(*db.FeatureFlag) | |
| 69 | + | return ff | |
| 70 | + | } | |
| 71 | + | ||
| 72 | + | func setFeatureFlag(s *pssh.SSHServerConnSession, ff *db.FeatureFlag) { | |
| 73 | + | s.SetValue(ctxFeatureFlagKey{}, ff) | |
| 74 | + | } | |
| 75 | + | ||
| 62 | 76 | func getBucket(s *pssh.SSHServerConnSession) (storage.Bucket, error) { | |
| 63 | 77 | bucket := s.Context().Value(ctxBucketKey{}).(storage.Bucket) | |
| 64 | 78 | if bucket.Name == "" { |
| ... | ... | @@ -205,19 +219,23 @@ func (h *UploadAssetHandler) Validate(s *pssh.SSHServerConnSession) error { | |
| 205 | 219 | return err | |
| 206 | 220 | } | |
| 207 | 221 | ||
| 222 | + | ff, err := findPlusFF(h.Cfg.DB, h.Cfg, user.ID) | |
| 223 | + | if err != nil { | |
| 224 | + | return err | |
| 225 | + | } | |
| 226 | + | setFeatureFlag(s, ff) | |
| 227 | + | ||
| 208 | 228 | assetBucket := shared.GetAssetBucketName(user.ID) | |
| 209 | 229 | bucket, err := h.Cfg.Storage.UpsertBucket(assetBucket) | |
| 210 | 230 | if err != nil { | |
| 211 | 231 | return err | |
| 212 | 232 | } | |
| 213 | - | ||
| 214 | 233 | s.SetValue(ctxBucketKey{}, bucket) | |
| 215 | 234 | ||
| 216 | 235 | totalStorageSize, err := h.Cfg.Storage.GetBucketQuota(bucket) | |
| 217 | 236 | if err != nil { | |
| 218 | 237 | return err | |
| 219 | 238 | } | |
| 220 | - | ||
| 221 | 239 | s.SetValue(ctxStorageSizeKey{}, totalStorageSize) | |
| 222 | 240 | ||
| 223 | 241 | logger.Info( |
| ... | ... | @@ -337,14 +355,6 @@ func (h *UploadAssetHandler) Write(s *pssh.SSHServerConnSession, entry *sendutil | |
| 337 | 355 | return "", err | |
| 338 | 356 | } | |
| 339 | 357 | ||
| 340 | - | featureFlag, err := findPlusFF(h.Cfg.DB, h.Cfg, user.ID) | |
| 341 | - | if err != nil { | |
| 342 | - | return "", err | |
| 343 | - | } | |
| 344 | - | if !featureFlag.IsValid() && pgsdb.IsProjectPrivate(projectName) { | |
| 345 | - | return "", fmt.Errorf("private projects are only allowed for pico+ users") | |
| 346 | - | } | |
| 347 | - | ||
| 348 | 358 | // calculate the filsize difference between the same file already | |
| 349 | 359 | // stored and the updated file being uploaded | |
| 350 | 360 | assetFilename := shared.GetAssetFileName(entry) |
| ... | ... | @@ -383,6 +393,10 @@ func (h *UploadAssetHandler) Write(s *pssh.SSHServerConnSession, entry *sendutil | |
| 383 | 393 | return "", err | |
| 384 | 394 | } | |
| 385 | 395 | ||
| 396 | + | featureFlag := getFeatureFlag(s) | |
| 397 | + | if featureFlag == nil { | |
| 398 | + | return "", fmt.Errorf("pico+ feature flag ctx not set") | |
| 399 | + | } | |
| 386 | 400 | // SFTP does not report file size so the more performant way to | |
| 387 | 401 | // check filesize constraints is to try and upload the file to s3 | |
| 388 | 402 | // with a specialized reader that raises an error if the filesize limit |
+3,
-2
| ... | ... | @@ -186,7 +186,6 @@ func (m *ServicesList) getServiceKv() []Kv { | |
| 186 | 186 | {"prose", "active"}, | |
| 187 | 187 | {"pipe", "active"}, | |
| 188 | 188 | {"pastes", "active"}, | |
| 189 | - | {"rss-to-email", "active"}, | |
| 190 | 189 | } | |
| 191 | 190 | ||
| 192 | 191 | if hasPlus { |
| ... | ... | @@ -195,13 +194,15 @@ func (m *ServicesList) getServiceKv() []Kv { | |
| 195 | 194 | []string{"pages", "active"}, | |
| 196 | 195 | []string{"tuns", "active"}, | |
| 197 | 196 | []string{"irc bouncer", "active"}, | |
| 197 | + | []string{"rss-to-email", "active"}, | |
| 198 | 198 | ) | |
| 199 | 199 | } else { | |
| 200 | 200 | data = append( | |
| 201 | 201 | data, | |
| 202 | - | []string{"pages", "free tier"}, | |
| 202 | + | []string{"pages", "pico+"}, | |
| 203 | 203 | []string{"tuns", "pico+"}, | |
| 204 | 204 | []string{"irc bouncer", "pico+"}, | |
| 205 | + | []string{"rss-to-email", "pico+"}, | |
| 205 | 206 | ) | |
| 206 | 207 | } | |
| 207 | 208 |