Skip to content

Commit c3358bc

Browse files
committed
test edge gateway single default bucket paths
1 parent ff4b81c commit c3358bc

1 file changed

Lines changed: 146 additions & 0 deletions

File tree

cmd/edge-gateway/main_test.go

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,22 @@ func signedDefaultBucketMultiURL(t *testing.T, method, server, bucket, key strin
135135
return signed
136136
}
137137

138+
func signedDefaultBucketSingleURL(t *testing.T, method, bucket, key string, now time.Time) string {
139+
t.Helper()
140+
signed, err := signing.SignURLForModeWithOptions(signing.SignInput{
141+
Method: method,
142+
BaseURL: "https://files.example",
143+
Bucket: bucket,
144+
Key: key,
145+
Expires: now.Add(time.Minute),
146+
Secret: "secret",
147+
}, publicpath.ModeSingle, signing.SignOptions{DefaultBucketPath: true})
148+
if err != nil {
149+
t.Fatalf("SignURLForModeWithOptions() error = %v", err)
150+
}
151+
return signed
152+
}
153+
138154
func testMultiEdge(pub *fakePublisher, cfg config.EdgeConfig, fetchers map[string]objectFetcher) (*edgeServer, *pending.Registry) {
139155
reg := pending.NewRegistry(pending.Options{})
140156
cfg.IngestURL = "https://edge.internal/_ingest"
@@ -620,6 +636,136 @@ func TestSingleServerPublishesDefaultSubjectAndEmptyServer(t *testing.T) {
620636
}
621637
}
622638

639+
func TestSingleServerDefaultBucketShortPathPublishesTicket(t *testing.T) {
640+
pub := &fakePublisher{err: errors.New("stop after publish")}
641+
reg := pending.NewRegistry(pending.Options{})
642+
edge := newEdgeServer(config.EdgeConfig{
643+
IngestURL: "https://edge.internal/_ingest",
644+
DefaultBucket: "demo",
645+
AllowedBuckets: []string{"demo"},
646+
NATS: config.NATSConfig{Subject: "air3.tickets"},
647+
Signing: config.SigningConfig{Disabled: true},
648+
Timeouts: config.TimeoutConfig{PendingRequestTTL: time.Second},
649+
}, reg, pub, nil)
650+
edge.newToken = func() (string, error) { return "single-default-token", nil }
651+
652+
resp := httptest.NewRecorder()
653+
edge.ServeHTTP(resp, httptest.NewRequest(http.MethodGet, "/file.txt", nil))
654+
655+
published := pub.snapshot()
656+
if len(published) != 1 {
657+
t.Fatalf("published tickets = %#v, want one", published)
658+
}
659+
if published[0].Server != "" || published[0].Bucket != "demo" || published[0].Key != "file.txt" {
660+
t.Fatalf("published ticket = %#v, want empty server bucket demo key file.txt", published[0])
661+
}
662+
}
663+
664+
func TestSingleServerDefaultBucketShortFormWinsOverBucketPrefix(t *testing.T) {
665+
pub := &fakePublisher{err: errors.New("stop after publish")}
666+
reg := pending.NewRegistry(pending.Options{})
667+
edge := newEdgeServer(config.EdgeConfig{
668+
IngestURL: "https://edge.internal/_ingest",
669+
DefaultBucket: "demo",
670+
AllowedBuckets: []string{"demo"},
671+
Signing: config.SigningConfig{Disabled: true},
672+
Timeouts: config.TimeoutConfig{PendingRequestTTL: time.Second},
673+
}, reg, pub, nil)
674+
edge.newToken = func() (string, error) { return "single-explicit-token", nil }
675+
676+
resp := httptest.NewRecorder()
677+
edge.ServeHTTP(resp, httptest.NewRequest(http.MethodGet, "/demo/file.txt", nil))
678+
679+
published := pub.snapshot()
680+
if len(published) != 1 {
681+
t.Fatalf("published tickets = %#v, want one", published)
682+
}
683+
if published[0].Server != "" || published[0].Bucket != "demo" || published[0].Key != "demo/file.txt" {
684+
t.Fatalf("published ticket = %#v, want empty server bucket demo key demo/file.txt", published[0])
685+
}
686+
}
687+
688+
func TestSingleServerDefaultBucketShortPathAllowlistUsesResolvedBucket(t *testing.T) {
689+
pub := &fakePublisher{}
690+
reg := pending.NewRegistry(pending.Options{})
691+
edge := newEdgeServer(config.EdgeConfig{
692+
IngestURL: "https://edge.internal/_ingest",
693+
DefaultBucket: "demo",
694+
AllowedBuckets: []string{"other"},
695+
Signing: config.SigningConfig{Disabled: true},
696+
Timeouts: config.TimeoutConfig{PendingRequestTTL: time.Second},
697+
}, reg, pub, nil)
698+
699+
resp := httptest.NewRecorder()
700+
edge.ServeHTTP(resp, httptest.NewRequest(http.MethodGet, "/file.txt", nil))
701+
if got := resp.Result().StatusCode; got != http.StatusForbidden {
702+
t.Fatalf("status = %d, want %d", got, http.StatusForbidden)
703+
}
704+
if pub.count() != 0 {
705+
t.Fatalf("published %d tickets, want 0", pub.count())
706+
}
707+
}
708+
709+
func TestSignedSingleServerDefaultBucketShortURLAcceptedAndTamperingRejected(t *testing.T) {
710+
now := time.Now()
711+
signed := signedDefaultBucketSingleURL(t, http.MethodGet, "demo", "file.txt", now)
712+
713+
t.Run("accepted", func(t *testing.T) {
714+
pub := &fakePublisher{err: errors.New("stop after publish")}
715+
reg := pending.NewRegistry(pending.Options{})
716+
edge := newEdgeServer(config.EdgeConfig{
717+
IngestURL: "https://edge.internal/_ingest",
718+
DefaultBucket: "demo",
719+
AllowedBuckets: []string{"demo"},
720+
Signing: config.SigningConfig{Secret: "secret"},
721+
Timeouts: config.TimeoutConfig{PendingRequestTTL: time.Second},
722+
}, reg, pub, nil)
723+
edge.now = func() time.Time { return now }
724+
edge.newToken = func() (string, error) { return "signed-single-default-token", nil }
725+
726+
resp := httptest.NewRecorder()
727+
edge.ServeHTTP(resp, httptest.NewRequest(http.MethodGet, signed, nil))
728+
729+
published := pub.snapshot()
730+
if len(published) != 1 {
731+
t.Fatalf("published tickets = %#v, want one", published)
732+
}
733+
if published[0].Server != "" || published[0].Bucket != "demo" || published[0].Key != "file.txt" {
734+
t.Fatalf("published ticket = %#v, want empty server bucket demo key file.txt", published[0])
735+
}
736+
})
737+
738+
for _, tt := range []struct {
739+
name string
740+
raw string
741+
}{
742+
{name: "path", raw: strings.Replace(signed, "/file.txt", "/other.txt", 1)},
743+
{name: "signature", raw: strings.Replace(signed, "sig=", "sig=bad", 1)},
744+
} {
745+
t.Run("tampered "+tt.name, func(t *testing.T) {
746+
pub := &fakePublisher{}
747+
reg := pending.NewRegistry(pending.Options{})
748+
edge := newEdgeServer(config.EdgeConfig{
749+
IngestURL: "https://edge.internal/_ingest",
750+
DefaultBucket: "demo",
751+
AllowedBuckets: []string{"demo"},
752+
Signing: config.SigningConfig{Secret: "secret"},
753+
Timeouts: config.TimeoutConfig{PendingRequestTTL: time.Second},
754+
}, reg, pub, nil)
755+
edge.now = func() time.Time { return now }
756+
757+
resp := httptest.NewRecorder()
758+
edge.ServeHTTP(resp, httptest.NewRequest(http.MethodGet, tt.raw, nil))
759+
if got := resp.Result().StatusCode; got != http.StatusForbidden {
760+
t.Fatalf("status = %d, want %d", got, http.StatusForbidden)
761+
}
762+
if pub.count() != 0 {
763+
t.Fatalf("published %d tickets, want 0", pub.count())
764+
}
765+
})
766+
}
767+
}
768+
623769
func TestMultiServerConnectorPublishesRoutedSubjectAndTicket(t *testing.T) {
624770
pub := &fakePublisher{err: errors.New("stop after publish")}
625771
edge, _ := testMultiEdge(pub, config.EdgeConfig{

0 commit comments

Comments
 (0)