From da19bb039a5a26dae8c903953d93f97ec4004bfd Mon Sep 17 00:00:00 2001 From: Qiao Han Date: Sun, 25 Feb 2024 16:05:46 +0800 Subject: [PATCH 1/2] fix: check sslmode before connecting --- cmd/gen.go | 7 ++++-- internal/gen/types/typescript/typescript.go | 26 ++++++++++++++++----- internal/utils/misc.go | 2 +- 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/cmd/gen.go b/cmd/gen.go index 98e859896..3bcbe226f 100644 --- a/cmd/gen.go +++ b/cmd/gen.go @@ -2,6 +2,8 @@ package cmd import ( "errors" + "os" + "os/signal" env "github.com/Netflix/go-env" "github.com/spf13/afero" @@ -14,7 +16,7 @@ import ( var ( genCmd = &cobra.Command{ - GroupID: groupManagementAPI, + GroupID: groupLocalDev, Use: "gen", Short: "Run code generation tools", } @@ -41,6 +43,7 @@ var ( if err := env.Unmarshal(es, &keyNames); err != nil { return err } + cmd.GroupID = groupManagementAPI return cmd.Root().PersistentPreRunE(cmd, args) }, RunE: func(cmd *cobra.Command, args []string) error { @@ -65,7 +68,7 @@ var ( return nil }, RunE: func(cmd *cobra.Command, args []string) error { - ctx := cmd.Context() + ctx, _ := signal.NotifyContext(cmd.Context(), os.Interrupt) if flags.DbConfig.Host == "" { // If no flag is specified, prompt for project id. if err := flags.ParseProjectRef(ctx, afero.NewMemMapFs()); errors.Is(err, utils.ErrNotLinked) { diff --git a/internal/gen/types/typescript/typescript.go b/internal/gen/types/typescript/typescript.go index 234f6da59..2ecbcd4db 100644 --- a/internal/gen/types/typescript/typescript.go +++ b/internal/gen/types/typescript/typescript.go @@ -10,6 +10,7 @@ import ( "github.com/docker/docker/api/types/network" "github.com/go-errors/errors" "github.com/jackc/pgconn" + "github.com/jackc/pgx/v4" "github.com/spf13/afero" "github.com/supabase/cli/internal/utils" "github.com/supabase/cli/pkg/api" @@ -46,12 +47,6 @@ func Run(ctx context.Context, projectId string, dbConfig pgconn.Config, schemas if strings.Contains(utils.Config.Api.Image, "v9") { postgrestV9Compat = true } - } else { - // Additional configs for pg-meta with enforce ssl - if dbConfig.RuntimeParams == nil { - dbConfig.RuntimeParams = make(map[string]string, 1) - } - dbConfig.RuntimeParams["sslmode"] = "prefer" } fmt.Fprintln(os.Stderr, "Connecting to", dbConfig.Host, dbConfig.Port) @@ -59,6 +54,13 @@ func Run(ctx context.Context, projectId string, dbConfig pgconn.Config, schemas dbConfig.Database = "postgres" } escaped := utils.ToPostgresURL(dbConfig) + if require, err := isRequireSSL(ctx, escaped); err != nil { + return err + } else if require { + // node-postgres does not support sslmode=prefer + escaped += "&sslmode=require" + } + return utils.DockerRunOnceWithConfig( ctx, container.Config{ @@ -80,3 +82,15 @@ func Run(ctx context.Context, projectId string, dbConfig pgconn.Config, schemas os.Stderr, ) } + +func isRequireSSL(ctx context.Context, dbUrl string, options ...func(*pgx.ConnConfig)) (bool, error) { + conn, err := utils.ConnectByUrl(ctx, dbUrl+"&sslmode=require") + if err != nil { + if strings.HasSuffix(err.Error(), "(server refused TLS connection)") { + return false, nil + } + return false, err + } + defer conn.Close(context.Background()) + return true, nil +} diff --git a/internal/utils/misc.go b/internal/utils/misc.go index 2362fc298..5df199027 100644 --- a/internal/utils/misc.go +++ b/internal/utils/misc.go @@ -31,7 +31,7 @@ const ( PostgrestImage = "postgrest/postgrest:v12.0.1" DifferImage = "supabase/pgadmin-schema-diff:cli-0.0.5" MigraImage = "supabase/migra:3.0.1663481299" - PgmetaImage = "supabase/postgres-meta:v0.78.2" + PgmetaImage = "supabase/postgres-meta:v0.79.0" StudioImage = "supabase/studio:20240205-b145c86" ImageProxyImage = "darthsim/imgproxy:v3.8.0" EdgeRuntimeImage = "supabase/edge-runtime:v1.36.7" From a99c56c2da39d64578f33e87bd809a57354d7eed Mon Sep 17 00:00:00 2001 From: Qiao Han Date: Mon, 26 Feb 2024 12:02:45 +0800 Subject: [PATCH 2/2] chore: fix unit tests --- internal/gen/types/typescript/typescript.go | 9 ++++----- internal/gen/types/typescript/typescript_test.go | 11 +++++++++-- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/internal/gen/types/typescript/typescript.go b/internal/gen/types/typescript/typescript.go index 2ecbcd4db..e2ab071cd 100644 --- a/internal/gen/types/typescript/typescript.go +++ b/internal/gen/types/typescript/typescript.go @@ -16,7 +16,7 @@ import ( "github.com/supabase/cli/pkg/api" ) -func Run(ctx context.Context, projectId string, dbConfig pgconn.Config, schemas []string, postgrestV9Compat bool, fsys afero.Fs) error { +func Run(ctx context.Context, projectId string, dbConfig pgconn.Config, schemas []string, postgrestV9Compat bool, fsys afero.Fs, options ...func(*pgx.ConnConfig)) error { // Add default schemas if --schema flag is not specified if len(schemas) == 0 { schemas = utils.RemoveDuplicates(append([]string{"public"}, utils.Config.Api.Schemas...)) @@ -54,7 +54,7 @@ func Run(ctx context.Context, projectId string, dbConfig pgconn.Config, schemas dbConfig.Database = "postgres" } escaped := utils.ToPostgresURL(dbConfig) - if require, err := isRequireSSL(ctx, escaped); err != nil { + if require, err := isRequireSSL(ctx, escaped, options...); err != nil { return err } else if require { // node-postgres does not support sslmode=prefer @@ -84,13 +84,12 @@ func Run(ctx context.Context, projectId string, dbConfig pgconn.Config, schemas } func isRequireSSL(ctx context.Context, dbUrl string, options ...func(*pgx.ConnConfig)) (bool, error) { - conn, err := utils.ConnectByUrl(ctx, dbUrl+"&sslmode=require") + conn, err := utils.ConnectByUrl(ctx, dbUrl+"&sslmode=require", options...) if err != nil { if strings.HasSuffix(err.Error(), "(server refused TLS connection)") { return false, nil } return false, err } - defer conn.Close(context.Background()) - return true, nil + return true, conn.Close(ctx) } diff --git a/internal/gen/types/typescript/typescript_test.go b/internal/gen/types/typescript/typescript_test.go index 78fd7542e..54c7d7b96 100644 --- a/internal/gen/types/typescript/typescript_test.go +++ b/internal/gen/types/typescript/typescript_test.go @@ -12,6 +12,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/supabase/cli/internal/testing/apitest" + "github.com/supabase/cli/internal/testing/pgtest" "github.com/supabase/cli/internal/utils" "github.com/supabase/cli/pkg/api" "gopkg.in/h2non/gock.v1" @@ -43,8 +44,11 @@ func TestGenLocalCommand(t *testing.T) { JSON(types.ContainerJSON{}) apitest.MockDockerStart(utils.Docker, imageUrl, containerId) require.NoError(t, apitest.MockDockerLogs(utils.Docker, containerId, "hello world")) + // Setup mock postgres + conn := pgtest.NewConn() + defer conn.Close(t) // Run test - assert.NoError(t, Run(context.Background(), "", dbConfig, []string{}, true, fsys)) + assert.NoError(t, Run(context.Background(), "", dbConfig, []string{}, true, fsys, conn.Intercept)) // Validate api assert.Empty(t, apitest.ListUnmatchedRequests()) }) @@ -153,8 +157,11 @@ func TestGenRemoteCommand(t *testing.T) { defer gock.OffAll() apitest.MockDockerStart(utils.Docker, imageUrl, containerId) require.NoError(t, apitest.MockDockerLogs(utils.Docker, containerId, "hello world")) + // Setup mock postgres + conn := pgtest.NewConn() + defer conn.Close(t) // Run test - assert.NoError(t, Run(context.Background(), "", dbConfig, []string{"public"}, true, afero.NewMemMapFs())) + assert.NoError(t, Run(context.Background(), "", dbConfig, []string{"public"}, true, afero.NewMemMapFs(), conn.Intercept)) // Validate api assert.Empty(t, apitest.ListUnmatchedRequests()) })