fix(19.3-06): refuse protected uploads into a public_url bucket (WR-07)

- attach.Store returns attach.ErrProtectedNeedsPrivateBucket for an
  is_public false upload while storage.uploads.public_url is set, before
  any blob is written
- OpenBucket's public_url line becomes a warning naming the refusal
This commit is contained in:
Jakub Zych
2026-10-15 22:30:00 +02:00
parent f705343904
commit caa5b5d8ff
5 changed files with 46 additions and 6 deletions

View File

@@ -3,6 +3,7 @@ package attach
import (
"bytes"
"encoding/binary"
"errors"
"fmt"
"hash/crc32"
"image"
@@ -19,6 +20,7 @@ import (
"git.golem15.com/golem15/summercms/modules/compass"
"gocloud.dev/blob"
"gocloud.dev/blob/memblob"
"gorm.io/gorm"
)
// winterLayoutBucket opens a mem:// bucket with the WinterCMS public prefix
@@ -466,3 +468,26 @@ func TestPublicURLValidation(t *testing.T) {
}
}
}
func TestStoreProtectedNeedsPrivateBucket(t *testing.T) {
// Not parallel: the public URL base is package state.
t.Cleanup(func() { setPublicURLBase("") })
bucket := memblob.OpenBucket(nil)
t.Cleanup(func() { _ = bucket.Close() })
db := &gorm.DB{}
setPublicURLBase("https://cdn.example.com/uploads/")
_, err := Store(t.Context(), db, bucket, Upload{FileName: "notes.txt", Body: bytes.NewReader([]byte("secret"))}, Limits{})
if !errors.Is(err, ErrProtectedNeedsPrivateBucket) {
t.Fatalf("protected upload with public_url: error = %v, want ErrProtectedNeedsPrivateBucket", err)
}
for _, want := range []string{"storage.uploads.public_url", "private bucket"} {
if !strings.Contains(err.Error(), want) {
t.Errorf("error %q lacks %q", err, want)
}
}
iter := bucket.List(nil)
if obj, err := iter.Next(t.Context()); err == nil {
t.Fatalf("a blob was written: %s", obj.Key)
}
}