Repository: supabase/cli
Pull request #1145 (2023-05-24 17:26:54)

fix: use db password everywhere
## What kind of change does this PR introduce?

Bug fix https://github.com/supabase/cli/issues/1141

## What is the new behavior?

Feel free to include screenshots if it includes visual changes.

## Additional context

Add any other context or screenshots.


coveralls: ## Pull Request Test Coverage Report for [Build 5071665064](https://coveralls.io/builds/60282881)

* **2** of **2**   **(100.0%)**  changed or added relevant lines in **2** files are covered.
* **7** unchanged lines in **1** file lost coverage.
* Overall coverage decreased (**-0.07%**) to **62.886%**

---


|  Files with Coverage Reduction | New Missed Lines | % |
| :-----|--------------|--: |
| [internal/gen/keys/keys.go](https://coveralls.io/builds/60282881/source?filename=internal%2Fgen%2Fkeys%2Fkeys.go#L94) | 7 | 7.94% |
<!-- | **Total:** | **7** |  | -->

|  Totals | [![Coverage Status](https://coveralls.io/builds/60282881/badge)](https://coveralls.io/builds/60282881) |
| :-- | --: |
| Change from base [Build 5071602015](https://coveralls.io/builds/60282696): |  -0.07% |
| Covered Lines: | 4497 |
| Relevant Lines: | 7151 |

---
##### 💛  - [Coveralls](https://coveralls.io)


Patch:
diff --git a/internal/db/branch/switch_/switch_.go b/internal/db/branch/switch_/switch_.go
index 02d54dfe..73e98022 100644
--- a/internal/db/branch/switch_/switch_.go
+++ b/internal/db/branch/switch_/switch_.go
@@ -7,6 +7,7 @@ import (
 	"os"
 	"path/filepath"
 
+	"github.com/jackc/pgconn"
 	"github.com/jackc/pgx/v4"
 	"github.com/spf13/afero"
 	"github.com/supabase/cli/internal/db/reset"
@@ -57,7 +58,7 @@ func Run(ctx context.Context, target string, fsys afero.Fs, options ...func(*pgx
 }
 
 func switchDatabase(ctx context.Context, source, target string, options ...func(*pgx.ConnConfig)) error {
-	conn, err := utils.ConnectLocalPostgres(ctx, "localhost", utils.Config.Db.Port, "template1", options...)
+	conn, err := utils.ConnectLocalPostgres(ctx, pgconn.Config{Database: "template1"}, options...)
 	if err != nil {
 		return err
 	}
diff --git a/internal/db/diff/migra.go b/internal/db/diff/migra.go
index 0aeb11f4..8fed56af 100644
--- a/internal/db/diff/migra.go
+++ b/internal/db/diff/migra.go
@@ -67,7 +67,7 @@ func RunMigra(ctx context.Context, schema []string, file string, config pgconn.C
 func loadSchema(ctx context.Context, config pgconn.Config, options ...func(*pgx.ConnConfig)) (schema []string, err error) {
 	var conn *pgx.Conn
 	if config.Host == "localhost" && config.Port == uint16(utils.Config.Db.Port) {
-		conn, err = utils.ConnectLocalPostgres(ctx, config.Host, uint(config.Port), config.Database, options...)
+		conn, err = utils.ConnectLocalPostgres(ctx, config, options...)
 	} else {
 		conn, err = utils.ConnectRemotePostgres(ctx, config, options...)
 	}
@@ -113,7 +113,7 @@ func connectShadowDatabase(ctx context.Context, timeout time.Duration, options .
 	defer ticker.Stop()
 	// Retry until connected, cancelled, or timeout
 	for t := now; t.Before(expiry); t = <-ticker.C {
-		conn, err = utils.ConnectLocalPostgres(ctx, "localhost", utils.Config.Db.ShadowPort, "postgres", options...)
+		conn, err = utils.ConnectLocalPostgres(ctx, pgconn.Config{Port: uint16(utils.Config.Db.ShadowPort)}, options...)
 		if err == nil || errors.Is(ctx.Err(), context.Canceled) {
 			break
 		}
diff --git a/internal/db/lint/lint.go b/internal/db/lint/lint.go
index 80440b6c..a09fb6ac 100644
--- a/internal/db/lint/lint.go
+++ b/internal/db/lint/lint.go
@@ -69,7 +69,7 @@ func connect(ctx context.Context, config pgconn.Config, fsys afero.Fs, options .
 	if err := utils.AssertSupabaseDbIsRunning(); err != nil {
 		return nil, err
 	}
-	return utils.ConnectLocalPostgres(ctx, "localhost", utils.Config.Db.Port, "postgres", options...)
+	return utils.ConnectLocalPostgres(ctx, pgconn.Config{}, options...)
 }
 
 func filterResult(result []Result, minLevel LintLevel) (filtered []Result) {
diff --git a/internal/db/start/start.go b/internal/db/start/start.go
index cfd87707..967ecff0 100644
--- a/internal/db/start/start.go
+++ b/internal/db/start/start.go
@@ -48,7 +48,7 @@ func NewContainerConfig() container.Config {
 	config := container.Config{
 		Image: utils.DbImage,
 		Env: []string{
-			"POSTGRES_PASSWORD=postgres",
+			"POSTGRES_PASSWORD=" + utils.Config.Db.Password,
 			"POSTGRES_HOST=/var/run/postgresql",
 			"POSTGRES_INITDB_ARGS=--lc-ctype=C.UTF-8",
 		},
@@ -136,7 +136,7 @@ func initCurrentBranch(fsys afero.Fs) error {
 
 func initDatabase(ctx context.Context, w io.Writer, options ...func(*pgx.ConnConfig)) error {
 	// Initialise globals
-	conn, err := utils.ConnectLocalPostgres(ctx, "localhost", utils.Config.Db.Port, "postgres", options...)
+	conn, err := utils.ConnectLocalPostgres(ctx, pgconn.Config{}, options...)
 	if err != nil {
 		return err
 	}
@@ -155,7 +155,7 @@ func SetupDatabase(ctx context.Context, dbConfig pgconn.Config, fsys afero.Fs, w
 	if dbConfig.Host != utils.DbId {
 		return nil
 	}
-	conn, err := utils.ConnectLocalPostgres(ctx, "localhost", utils.Config.Db.Port, "postgres", options...)
+	conn, err := utils.ConnectLocalPostgres(ctx, pgconn.Config{}, options...)
 	if err != nil {
 		return err
 	}
diff --git a/internal/migration/up/up.go b/internal/migration/up/up.go
index 2399cfbf..f2fadada 100644
--- a/internal/migration/up/up.go
+++ b/internal/migration/up/up.go
@@ -5,6 +5,7 @@ import (
 	"errors"
 	"fmt"
 
+	"github.com/jackc/pgconn"
 	"github.com/jackc/pgx/v4"
 	"github.com/spf13/afero"
 	"github.com/supabase/cli/internal/migration/apply"
@@ -18,7 +19,7 @@ func Run(ctx context.Context, fsys afero.Fs, options ...func(*pgx.ConnConfig)) e
 	if err := utils.LoadConfigFS(fsys); err != nil {
 		return err
 	}
-	conn, err := utils.ConnectLocalPostgres(ctx, "localhost", utils.Config.Db.Port, "postgres", options...)
+	conn, err := utils.ConnectLocalPostgres(ctx, pgconn.Config{}, options...)
 	if err != nil {
 		return err
 	}
diff --git a/internal/start/start.go b/internal/start/start.go
index 7c2ce84a..b6b85eba 100644
--- a/internal/start/start.go
+++ b/internal/start/start.go
@@ -615,7 +615,7 @@ EOF
 				Image: utils.StudioImage,
 				Env: []string{
 					"STUDIO_PG_META_URL=http://" + utils.PgmetaId + ":8080",
-					"POSTGRES_PASSWORD=postgres",
+					"POSTGRES_PASSWORD=" + dbConfig.Password,
 					"SUPABASE_URL=http://" + utils.KongId + ":8000",
 					fmt.Sprintf("SUPABASE_REST_URL=http://localhost:%v/rest/v1/", utils.Config.Api.Port),
 					fmt.Sprintf("SUPABASE_PUBLIC_URL=http://localhost:%v/", utils.Config.Api.Port),
diff --git a/internal/status/status.go b/internal/status/status.go
index 94b76161..922a8075 100644
--- a/internal/status/status.go
+++ b/internal/status/status.go
@@ -26,7 +26,7 @@ type CustomName struct {
 
 func (c *CustomName) toValues(exclude ...string) map[string]string {
 	values := map[string]string{
-		c.DbURL: fmt.Sprintf("postgresql://postgres:postgres@localhost:%d/postgres", utils.Config.Db.Port),
+		c.DbURL: fmt.Sprintf("postgresql://postgres:%s@localhost:%d/postgres", utils.Config.Db.Password, utils.Config.Db.Port),
 	}
 	if !sliceContains(exclude, utils.RestId) && !sliceContains(exclude, utils.ShortContainerImageName(utils.PostgrestImage)) {
 		values[c.ApiURL] = fmt.Sprintf("http://localhost:%d", utils.Config.Api.Port)
diff --git a/internal/utils/config.go b/internal/utils/config.go
index 5c11e3e1..8be6892b 100644
--- a/internal/utils/config.go
+++ b/internal/utils/config.go
@@ -109,7 +109,7 @@ type (
 		Port         uint   `toml:"port"`
 		ShadowPort   uint   `toml:"shadow_port"`
 		MajorVersion uint   `toml:"major_version"`
-		Password     string `toml:"-" mapstructure:"password"`
+		Password     string `toml:"-"`
 	}
 
 	studio struct {
diff --git a/internal/utils/connect.go b/internal/utils/connect.go
index f61cccee..94ceb37d 100644
--- a/internal/utils/connect.go
+++ b/internal/utils/connect.go
@@ -7,6 +7,7 @@ import (
 	"net"
 	"net/url"
 	"os"
+	"time"
 
 	"github.com/jackc/pgconn"
 	"github.com/jackc/pgx/v4"
@@ -65,9 +66,26 @@ func ConnectRemotePostgres(ctx context.Context, config pgconn.Config, options ..
 }
 
 // Connnect to local Postgres with optimised settings. The caller is responsible for closing the connection returned.
-func ConnectLocalPostgres(ctx context.Context, host string, port uint, database string, options ...func(*pgx.ConnConfig)) (*pgx.Conn, error) {
-	url := fmt.Sprintf("postgresql://postgres:postgres@%s:%d/%s?connect_timeout=2", host, port, database)
-	return ConnectByUrl(ctx, url, options...)
+func ConnectLocalPostgres(ctx context.Context, config pgconn.Config, options ...func(*pgx.ConnConfig)) (*pgx.Conn, error) {
+	if len(config.Host) == 0 {
+		config.Host = "localhost"
+	}
+	if config.Port == 0 {
+		config.Port = uint16(Config.Db.Port)
+	}
+	if len(config.User) == 0 {
+		config.User = "postgres"
+	}
+	if len(config.Password) == 0 {
+		config.Password = Config.Db.Password
+	}
+	if len(config.Database) == 0 {
+		config.Database = "postgres"
+	}
+	if config.ConnectTimeout == 0 {
+		config.ConnectTimeout = 2 * time.Second
+	}
+	return ConnectByUrl(ctx, ToPostgresURL(config), options...)
 }
 
 func ConnectByUrl(ctx context.Context, url string, options ...func(*pgx.ConnConfig)) (*pgx.Conn, error) {


Test patch:
diff --git a/internal/db/lint/lint_test.go b/internal/db/lint/lint_test.go
index 9747b820..48b728a8 100644
--- a/internal/db/lint/lint_test.go
+++ b/internal/db/lint/lint_test.go
@@ -121,7 +121,7 @@ func TestLintDatabase(t *testing.T) {
 			Query("rollback").Reply("ROLLBACK")
 		// Connect to mock
 		ctx := context.Background()
-		mock, err := utils.ConnectLocalPostgres(ctx, "localhost", 5432, "postgres", conn.Intercept)
+		mock, err := utils.ConnectLocalPostgres(ctx, pgconn.Config{Port: 5432}, conn.Intercept)
 		require.NoError(t, err)
 		defer mock.Close(ctx)
 		// Run test
@@ -167,7 +167,7 @@ func TestLintDatabase(t *testing.T) {
 			Query("rollback").Reply("ROLLBACK")
 		// Connect to mock
 		ctx := context.Background()
-		mock, err := utils.ConnectLocalPostgres(ctx, "localhost", 5432, "postgres", conn.Intercept)
+		mock, err := utils.ConnectLocalPostgres(ctx, pgconn.Config{Port: 5432}, conn.Intercept)
 		require.NoError(t, err)
 		defer mock.Close(ctx)
 		// Run test
@@ -187,7 +187,7 @@ func TestLintDatabase(t *testing.T) {
 			Query("rollback").Reply("ROLLBACK")
 		// Connect to mock
 		ctx := context.Background()
-		mock, err := utils.ConnectLocalPostgres(ctx, "localhost", 5432, "postgres", conn.Intercept)
+		mock, err := utils.ConnectLocalPostgres(ctx, pgconn.Config{Port: 5432}, conn.Intercept)
 		require.NoError(t, err)
 		defer mock.Close(ctx)
 		// Run test
@@ -207,7 +207,7 @@ func TestLintDatabase(t *testing.T) {
 			Query("rollback").Reply("ROLLBACK")
 		// Connect to mock
 		ctx := context.Background()
-		mock, err := utils.ConnectLocalPostgres(ctx, "localhost", 5432, "postgres", conn.Intercept)
+		mock, err := utils.ConnectLocalPostgres(ctx, pgconn.Config{Port: 5432}, conn.Intercept)
 		require.NoError(t, err)
 		defer mock.Close(ctx)
 		// Run test
diff --git a/internal/db/reset/reset_test.go b/internal/db/reset/reset_test.go
index b3d0862b..d155435e 100644
--- a/internal/db/reset/reset_test.go
+++ b/internal/db/reset/reset_test.go
@@ -167,7 +167,7 @@ func TestSeedDatabase(t *testing.T) {
 			Reply("INSERT 0 1")
 		// Connect to mock
 		ctx := context.Background()
-		mock, err := utils.ConnectLocalPostgres(ctx, "localhost", 54322, "postgres", conn.Intercept)
+		mock, err := utils.ConnectLocalPostgres(ctx, pgconn.Config{Port: 5432}, conn.Intercept)
 		require.NoError(t, err)
 		defer mock.Close(ctx)
 		// Run test
@@ -200,7 +200,7 @@ func TestSeedDatabase(t *testing.T) {
 			ReplyError(pgerrcode.NotNullViolation, `null value in column "age" of relation "employees"`)
 		// Connect to mock
 		ctx := context.Background()
-		mock, err := utils.ConnectLocalPostgres(ctx, "localhost", 54322, "postgres", conn.Intercept)
+		mock, err := utils.ConnectLocalPostgres(ctx, pgconn.Config{Port: 5432}, conn.Intercept)
 		require.NoError(t, err)
 		defer mock.Close(ctx)
 		// Run test
diff --git a/internal/migration/apply/apply_test.go b/internal/migration/apply/apply_test.go
index ca3fe8d8..c29ab4a7 100644
--- a/internal/migration/apply/apply_test.go
+++ b/internal/migration/apply/apply_test.go
@@ -8,6 +8,7 @@ import (
 	"strings"
 	"testing"
 
+	"github.com/jackc/pgconn"
 	"github.com/jackc/pgerrcode"
 	"github.com/spf13/afero"
 	"github.com/spf13/viper"
@@ -39,7 +40,7 @@ func TestMigrateDatabase(t *testing.T) {
 			Reply("INSERT 1")
 		// Connect to mock
 		ctx := context.Background()
-		mock, err := utils.ConnectLocalPostgres(ctx, "localhost", 5432, "postgres", conn.Intercept)
+		mock, err := utils.ConnectLocalPostgres(ctx, pgconn.Config{Port: 5432}, conn.Intercept)
 		require.NoError(t, err)
 		defer mock.Close(ctx)
 		// Run test
@@ -76,7 +77,7 @@ func TestMigrateUp(t *testing.T) {
 			ReplyError(pgerrcode.InsufficientPrivilege, "permission denied for relation supabase_migrations")
 		// Connect to mock
 		ctx := context.Background()
-		mock, err := utils.ConnectLocalPostgres(ctx, "localhost", 5432, "postgres", conn.Intercept)
+		mock, err := utils.ConnectLocalPostgres(ctx, pgconn.Config{Port: 5432}, conn.Intercept)
 		require.NoError(t, err)
 		defer mock.Close(ctx)
 		// Run test
@@ -97,7 +98,7 @@ func TestMigrateUp(t *testing.T) {
 			Reply("CREATE TABLE")
 		// Connect to mock
 		ctx := context.Background()
-		mock, err := utils.ConnectLocalPostgres(ctx, "localhost", 5432, "postgres", conn.Intercept)
+		mock, err := utils.ConnectLocalPostgres(ctx, pgconn.Config{Port: 5432}, conn.Intercept)
 		require.NoError(t, err)
 		defer mock.Close(ctx)
 		// Run test
@@ -149,7 +150,7 @@ func TestMigrationFile(t *testing.T) {
 			Query(repair.INSERT_MIGRATION_VERSION, "0")
 		// Connect to mock
 		ctx := context.Background()
-		mock, err := utils.ConnectLocalPostgres(ctx, "localhost", 5432, "postgres", conn.Intercept)
+		mock, err := utils.ConnectLocalPostgres(ctx, pgconn.Config{Port: 5432}, conn.Intercept)
 		require.NoError(t, err)
 		defer mock.Close(ctx)
 		// Run test
diff --git a/internal/migration/up/up_test.go b/internal/migration/up/up_test.go
index 40d9b6f3..1d9761b5 100644
--- a/internal/migration/up/up_test.go
+++ b/internal/migration/up/up_test.go
@@ -5,6 +5,7 @@ import (
 	"path/filepath"
 	"testing"
 
+	"github.com/jackc/pgconn"
 	"github.com/spf13/afero"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
@@ -34,7 +35,7 @@ func TestPendingMigrations(t *testing.T) {
 			Reply("SELECT 2", []interface{}{"20221201000000"}, []interface{}{"20221201000001"})
 		// Connect to mock
 		ctx := context.Background()
-		mock, err := utils.ConnectLocalPostgres(ctx, "localhost", 5432, "postgres", conn.Intercept)
+		mock, err := utils.ConnectLocalPostgres(ctx, pgconn.Config{Port: 5432}, conn.Intercept)
 		require.NoError(t, err)
 		defer mock.Close(ctx)
 		// Run test
@@ -54,7 +55,7 @@ func TestPendingMigrations(t *testing.T) {
 			Reply("SELECT 0")
 		// Connect to mock
 		ctx := context.Background()
-		mock, err := utils.ConnectLocalPostgres(ctx, "localhost", 5432, "postgres", conn.Intercept)
+		mock, err := utils.ConnectLocalPostgres(ctx, pgconn.Config{Port: 5432}, conn.Intercept)
 		require.NoError(t, err)
 		defer mock.Close(ctx)
 		// Run test
@@ -73,7 +74,7 @@ func TestPendingMigrations(t *testing.T) {
 			Reply("SELECT 1", []interface{}{"0"})
 		// Connect to mock
 		ctx := context.Background()
-		mock, err := utils.ConnectLocalPostgres(ctx, "localhost", 5432, "postgres", conn.Intercept)
+		mock, err := utils.ConnectLocalPostgres(ctx, pgconn.Config{Port: 5432}, conn.Intercept)
 		require.NoError(t, err)
 		defer mock.Close(ctx)
 		// Run test
@@ -94,7 +95,7 @@ func TestPendingMigrations(t *testing.T) {
 			Reply("SELECT 1", []interface{}{"0"})
 		// Connect to mock
 		ctx := context.Background()
-		mock, err := utils.ConnectLocalPostgres(ctx, "localhost", 5432, "postgres", conn.Intercept)
+		mock, err := utils.ConnectLocalPostgres(ctx, pgconn.Config{Port: 5432}, conn.Intercept)
 		require.NoError(t, err)
 		defer mock.Close(ctx)
 		// Run test
diff --git a/internal/utils/connect_test.go b/internal/utils/connect_test.go
index b4c185e2..74cd0559 100644
--- a/internal/utils/connect_test.go
+++ b/internal/utils/connect_test.go
@@ -99,14 +99,7 @@ func TestConnectRemotePostgres(t *testing.T) {
 func TestConnectLocal(t *testing.T) {
 	t.Run("connects with debug log", func(t *testing.T) {
 		viper.Set("DEBUG", true)
-		_, err := ConnectLocalPostgres(context.Background(), "0", 5432, "postgres")
+		_, err := ConnectLocalPostgres(context.Background(), pgconn.Config{Host: "0"})
 		assert.ErrorContains(t, err, "connect: connection refused")
 	})
-
-	t.Run("throws error on invalid port", func(t *testing.T) {
-		_, err := ConnectLocalPostgres(context.Background(), "localhost", 0, "postgres")
-		assert.ErrorContains(t, err, "invalid port (outside range)")
-		_, err = ConnectLocalPostgres(context.Background(), "localhost", 65536, "postgres")
-		assert.ErrorContains(t, err, `invalid port (strconv.ParseUint: parsing "65536": value out of range)`)
-	})
 }