Skip to content

Commit 91a696e

Browse files
committed
fix: handle new tenant api key
1 parent 8f8ddb2 commit 91a696e

File tree

5 files changed

+86
-53
lines changed

5 files changed

+86
-53
lines changed

internal/status/status.go

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -176,16 +176,11 @@ var (
176176

177177
func checkHTTPHead(ctx context.Context, path string) error {
178178
healthOnce.Do(func() {
179-
server := utils.Config.Api.ExternalUrl
180-
header := func(req *http.Request) {
181-
req.Header.Add("apikey", utils.Config.Auth.AnonKey.Value)
182-
}
183-
client := NewKongClient()
184-
healthClient = fetcher.NewFetcher(
185-
server,
186-
fetcher.WithHTTPClient(client),
187-
fetcher.WithRequestEditor(header),
188-
fetcher.WithExpectedStatus(http.StatusOK),
179+
healthClient = fetcher.NewServiceGateway(
180+
utils.Config.Api.ExternalUrl,
181+
utils.Config.Auth.AnonKey.Value,
182+
fetcher.WithHTTPClient(NewKongClient()),
183+
fetcher.WithUserAgent("SupabaseCLI/"+utils.Version),
189184
)
190185
})
191186
// HEAD method does not return response body

internal/storage/client/api.go

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,21 +28,19 @@ func NewStorageAPI(ctx context.Context, projectRef string) (storage.StorageAPI,
2828
}
2929

3030
func newLocalClient() *fetcher.Fetcher {
31-
client := status.NewKongClient()
32-
return fetcher.NewFetcher(
31+
return fetcher.NewServiceGateway(
3332
utils.Config.Api.ExternalUrl,
34-
fetcher.WithHTTPClient(client),
35-
fetcher.WithBearerToken(utils.Config.Auth.ServiceRoleKey.Value),
33+
utils.Config.Auth.ServiceRoleKey.Value,
34+
fetcher.WithHTTPClient(status.NewKongClient()),
3635
fetcher.WithUserAgent("SupabaseCLI/"+utils.Version),
37-
fetcher.WithExpectedStatus(http.StatusOK),
3836
)
3937
}
4038

4139
func newRemoteClient(projectRef, token string) *fetcher.Fetcher {
42-
return fetcher.NewFetcher(
40+
return fetcher.NewServiceGateway(
4341
"https://"+utils.GetSupabaseHost(projectRef),
44-
fetcher.WithBearerToken(token),
42+
token,
43+
fetcher.WithHTTPClient(http.DefaultClient),
4544
fetcher.WithUserAgent("SupabaseCLI/"+utils.Version),
46-
fetcher.WithExpectedStatus(http.StatusOK),
4745
)
4846
}

internal/utils/tenant/client.go

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@ package tenant
22

33
import (
44
"context"
5-
"net/http"
6-
"time"
5+
"strings"
76

87
"github.com/go-errors/errors"
98
"github.com/supabase/cli/internal/utils"
@@ -32,16 +31,42 @@ func NewApiKey(resp []api.ApiKeyResponse) ApiKey {
3231
if err != nil {
3332
continue
3433
}
35-
switch key.Name {
36-
case "anon":
34+
t, err := key.Type.Get()
35+
if err != nil {
36+
continue
37+
}
38+
switch t {
39+
case api.ApiKeyResponseTypePublishable:
3740
result.Anon = value
38-
case "service_role":
39-
result.ServiceRole = value
41+
case api.ApiKeyResponseTypeSecret:
42+
if isServiceRole(key) {
43+
result.ServiceRole = value
44+
}
45+
case api.ApiKeyResponseTypeLegacy:
46+
switch key.Name {
47+
case "anon":
48+
if len(result.Anon) == 0 {
49+
result.Anon = value
50+
}
51+
case "service_role":
52+
if len(result.ServiceRole) == 0 {
53+
result.ServiceRole = value
54+
}
55+
}
4056
}
4157
}
4258
return result
4359
}
4460

61+
func isServiceRole(key api.ApiKeyResponse) bool {
62+
if tmpl, err := key.SecretJwtTemplate.Get(); err == nil {
63+
if role, ok := tmpl["role"].(string); ok {
64+
return strings.EqualFold(role, "service_role")
65+
}
66+
}
67+
return false
68+
}
69+
4570
func GetApiKeys(ctx context.Context, projectRef string) (ApiKey, error) {
4671
resp, err := utils.GetSupabase().V1GetProjectApiKeysWithResponse(ctx, projectRef, &api.V1GetProjectApiKeysParams{})
4772
if err != nil {
@@ -62,19 +87,9 @@ type TenantAPI struct {
6287
}
6388

6489
func NewTenantAPI(ctx context.Context, projectRef, anonKey string) TenantAPI {
65-
server := "https://" + utils.GetSupabaseHost(projectRef)
66-
client := &http.Client{
67-
Timeout: 10 * time.Second,
68-
}
69-
header := func(req *http.Request) {
70-
req.Header.Add("apikey", anonKey)
71-
}
72-
api := TenantAPI{Fetcher: fetcher.NewFetcher(
73-
server,
74-
fetcher.WithHTTPClient(client),
75-
fetcher.WithRequestEditor(header),
90+
return TenantAPI{Fetcher: fetcher.NewServiceGateway(
91+
"https://"+utils.GetSupabaseHost(projectRef),
92+
anonKey,
7693
fetcher.WithUserAgent("SupabaseCLI/"+utils.Version),
77-
fetcher.WithExpectedStatus(http.StatusOK),
7894
)}
79-
return api
8095
}

internal/utils/tenant/client_test.go

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -131,24 +131,21 @@ func TestGetApiKeys(t *testing.T) {
131131
}
132132

133133
func TestNewTenantAPI(t *testing.T) {
134-
t.Run("creates tenant api client", func(t *testing.T) {
135-
projectRef := apitest.RandomProjectRef()
136-
anonKey := "test-key"
137-
138-
api := NewTenantAPI(context.Background(), projectRef, anonKey)
134+
projectRef := apitest.RandomProjectRef()
135+
anonKey := "test-key"
139136

140-
assert.NotNil(t, api.Fetcher)
137+
api := NewTenantAPI(context.Background(), projectRef, anonKey)
138+
assert.NotNil(t, api.Fetcher)
141139

142-
defer gock.OffAll()
143-
gock.New("https://"+utils.GetSupabaseHost(projectRef)).
144-
Get("/test").
145-
MatchHeader("apikey", anonKey).
146-
MatchHeader("User-Agent", "SupabaseCLI/"+utils.Version).
147-
Reply(http.StatusOK)
140+
defer gock.OffAll()
141+
gock.New("https://"+utils.GetSupabaseHost(projectRef)).
142+
Get("/test").
143+
MatchHeader("Authorization", "Bearer "+anonKey).
144+
MatchHeader("User-Agent", "SupabaseCLI/"+utils.Version).
145+
Reply(http.StatusOK)
148146

149-
_, err := api.Send(context.Background(), http.MethodGet, "/test", nil)
147+
_, err := api.Send(context.Background(), http.MethodGet, "/test", nil)
150148

151-
assert.NoError(t, err)
152-
assert.Empty(t, apitest.ListUnmatchedRequests())
153-
})
149+
assert.NoError(t, err)
150+
assert.Empty(t, apitest.ListUnmatchedRequests())
154151
}

pkg/fetcher/gateway.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package fetcher
2+
3+
import (
4+
"net/http"
5+
"strings"
6+
"time"
7+
)
8+
9+
func NewServiceGateway(server, token string, overrides ...FetcherOption) *Fetcher {
10+
opts := append([]FetcherOption{
11+
WithHTTPClient(&http.Client{
12+
Timeout: 10 * time.Second,
13+
}),
14+
withAuthToken(token),
15+
WithExpectedStatus(http.StatusOK),
16+
}, overrides...)
17+
return NewFetcher(server, opts...)
18+
}
19+
20+
func withAuthToken(token string) FetcherOption {
21+
if strings.HasPrefix(token, "sb_") {
22+
header := func(req *http.Request) {
23+
req.Header.Add("apikey", token)
24+
}
25+
return WithRequestEditor(header)
26+
}
27+
return WithBearerToken(token)
28+
}

0 commit comments

Comments
 (0)