Skip to content

Commit f572ced

Browse files
authored
fix: skip cleanup for non-2xx status (#1877)
## What kind of change does this PR introduce? * Skip the cleanup function if the status returned from the `ResponseWriter` is a non-2xx code * Refactor the cleanup method to be passed as an interface into `databaseCleanup` to make it easier to test
1 parent a3eecd1 commit f572ced

File tree

3 files changed

+77
-4
lines changed

3 files changed

+77
-4
lines changed

internal/api/middleware.go

+8-4
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"sync"
1212
"time"
1313

14+
chimiddleware "github.com/go-chi/chi/v5/middleware"
1415
"github.com/sirupsen/logrus"
1516
"github.com/supabase/auth/internal/models"
1617
"github.com/supabase/auth/internal/observability"
@@ -245,15 +246,18 @@ func (a *API) requireManualLinkingEnabled(w http.ResponseWriter, req *http.Reque
245246
return ctx, nil
246247
}
247248

248-
func (a *API) databaseCleanup(cleanup *models.Cleanup) func(http.Handler) http.Handler {
249+
func (a *API) databaseCleanup(cleanup models.Cleaner) func(http.Handler) http.Handler {
249250
return func(next http.Handler) http.Handler {
250251
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
251-
next.ServeHTTP(w, r)
252-
252+
wrappedResp := chimiddleware.NewWrapResponseWriter(w, r.ProtoMajor)
253+
next.ServeHTTP(wrappedResp, r)
253254
switch r.Method {
254255
case http.MethodPost, http.MethodPut, http.MethodPatch, http.MethodDelete:
256+
if (wrappedResp.Status() / 100) != 2 {
257+
// don't do any cleanups for non-2xx responses
258+
return
259+
}
255260
// continue
256-
257261
default:
258262
return
259263
}

internal/api/middleware_test.go

+65
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@ import (
1414
"github.com/didip/tollbooth/v5/limiter"
1515
jwt "github.com/golang-jwt/jwt/v5"
1616
"github.com/stretchr/testify/assert"
17+
"github.com/stretchr/testify/mock"
1718
"github.com/stretchr/testify/require"
1819
"github.com/stretchr/testify/suite"
1920
"github.com/supabase/auth/internal/conf"
21+
"github.com/supabase/auth/internal/storage"
2022
)
2123

2224
const (
@@ -443,3 +445,66 @@ func (ts *MiddlewareTestSuite) TestLimitHandler() {
443445
ts.API.limitHandler(lmt).handler(okHandler).ServeHTTP(w, req)
444446
require.Equal(ts.T(), http.StatusTooManyRequests, w.Code)
445447
}
448+
449+
type MockCleanup struct {
450+
mock.Mock
451+
}
452+
453+
func (m *MockCleanup) Clean(db *storage.Connection) (int, error) {
454+
m.Called(db)
455+
return 0, nil
456+
}
457+
458+
func (ts *MiddlewareTestSuite) TestDatabaseCleanup() {
459+
testHandler := func(statusCode int) http.HandlerFunc {
460+
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
461+
w.WriteHeader(statusCode)
462+
b, _ := json.Marshal(map[string]interface{}{"message": "ok"})
463+
w.Write([]byte(b))
464+
})
465+
}
466+
467+
cases := []struct {
468+
desc string
469+
statusCode int
470+
method string
471+
}{
472+
{
473+
desc: "Run cleanup successfully",
474+
statusCode: http.StatusOK,
475+
method: http.MethodPost,
476+
},
477+
{
478+
desc: "Skip cleanup if GET",
479+
statusCode: http.StatusOK,
480+
method: http.MethodGet,
481+
},
482+
{
483+
desc: "Skip cleanup if 3xx",
484+
statusCode: http.StatusSeeOther,
485+
method: http.MethodPost,
486+
},
487+
{
488+
desc: "Skip cleanup if 4xx",
489+
statusCode: http.StatusBadRequest,
490+
method: http.MethodPost,
491+
},
492+
{
493+
desc: "Skip cleanup if 5xx",
494+
statusCode: http.StatusInternalServerError,
495+
method: http.MethodPost,
496+
},
497+
}
498+
499+
mockCleanup := new(MockCleanup)
500+
mockCleanup.On("Clean", mock.Anything).Return(0, nil)
501+
for _, c := range cases {
502+
ts.Run("DatabaseCleanup", func() {
503+
req := httptest.NewRequest(c.method, "http://localhost", nil)
504+
w := httptest.NewRecorder()
505+
ts.API.databaseCleanup(mockCleanup)(testHandler(c.statusCode)).ServeHTTP(w, req)
506+
require.Equal(ts.T(), c.statusCode, w.Code)
507+
})
508+
}
509+
mockCleanup.AssertNumberOfCalls(ts.T(), "Clean", 1)
510+
}

internal/models/cleanup.go

+4
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ import (
1616
"github.com/supabase/auth/internal/storage"
1717
)
1818

19+
type Cleaner interface {
20+
Clean(*storage.Connection) (int, error)
21+
}
22+
1923
type Cleanup struct {
2024
cleanupStatements []string
2125

0 commit comments

Comments
 (0)