From e2edd275cc6ac9dd797e684abe100eec447f4e5f Mon Sep 17 00:00:00 2001 From: Will Baker Date: Fri, 20 Sep 2024 13:08:11 -0400 Subject: [PATCH] materialize-snowflake: percent encode username + password input The user/password encoding that `uri.User.String()` uses is actually slightly different than `url.QueryEscape()`, and the latter is what is needed to handle inputs with special characters to build a compatible Snowflake DSN. --- .../TestConfigURI-User_&_Password_Authentication | 1 + .../TestConfigURI-v1_User_&_Password_Authentication | 1 - .../TestConfigURI-v2_User_&_Password_Authentication | 1 - materialize-snowflake/config.go | 7 ++++--- materialize-snowflake/config_test.go | 4 ++-- 5 files changed, 7 insertions(+), 7 deletions(-) create mode 100644 materialize-snowflake/.snapshots/TestConfigURI-User_&_Password_Authentication delete mode 100644 materialize-snowflake/.snapshots/TestConfigURI-v1_User_&_Password_Authentication delete mode 100644 materialize-snowflake/.snapshots/TestConfigURI-v2_User_&_Password_Authentication diff --git a/materialize-snowflake/.snapshots/TestConfigURI-User_&_Password_Authentication b/materialize-snowflake/.snapshots/TestConfigURI-User_&_Password_Authentication new file mode 100644 index 0000000000..76e1cb0d11 --- /dev/null +++ b/materialize-snowflake/.snapshots/TestConfigURI-User_&_Password_Authentication @@ -0,0 +1 @@ +will:some%2Bcomplex%2Fpassword@orgname-accountname.snowflakecomputing.com:443?GO_QUERY_RESULT_FORMAT=json&MULTI_STATEMENT_COUNT=0&application=mytenant_EstuaryFlow&client_session_keep_alive=true&database=mydb&schema=myschema diff --git a/materialize-snowflake/.snapshots/TestConfigURI-v1_User_&_Password_Authentication b/materialize-snowflake/.snapshots/TestConfigURI-v1_User_&_Password_Authentication deleted file mode 100644 index 0a0f9d78df..0000000000 --- a/materialize-snowflake/.snapshots/TestConfigURI-v1_User_&_Password_Authentication +++ /dev/null @@ -1 +0,0 @@ -alex:mysecret@orgname-accountname.snowflakecomputing.com:443?GO_QUERY_RESULT_FORMAT=json&MULTI_STATEMENT_COUNT=0&application=mytenant_EstuaryFlow&client_session_keep_alive=true&database=mydb&schema=myschema diff --git a/materialize-snowflake/.snapshots/TestConfigURI-v2_User_&_Password_Authentication b/materialize-snowflake/.snapshots/TestConfigURI-v2_User_&_Password_Authentication deleted file mode 100644 index 9efe7d8bfd..0000000000 --- a/materialize-snowflake/.snapshots/TestConfigURI-v2_User_&_Password_Authentication +++ /dev/null @@ -1 +0,0 @@ -will:password@orgname-accountname.snowflakecomputing.com:443?GO_QUERY_RESULT_FORMAT=json&MULTI_STATEMENT_COUNT=0&application=mytenant_EstuaryFlow&client_session_keep_alive=true&database=mydb&schema=myschema diff --git a/materialize-snowflake/config.go b/materialize-snowflake/config.go index b2550e46a8..8884a7afa4 100644 --- a/materialize-snowflake/config.go +++ b/materialize-snowflake/config.go @@ -69,8 +69,9 @@ func (c *config) toURI(tenant string) (string, error) { } // Authentication + var user string if c.Credentials.AuthType == UserPass { - uri.User = url.UserPassword(c.Credentials.User, c.Credentials.Password) + user = url.QueryEscape(c.Credentials.User) + ":" + url.QueryEscape(c.Credentials.Password) } else if c.Credentials.AuthType == JWT { // We run this as part of validate to ensure that there is no error, so // this is not expected to error here. @@ -83,12 +84,12 @@ func (c *config) toURI(tenant string) (string, error) { queryParams.Add("privateKey", privateKeyString) queryParams.Add("authenticator", strings.ToLower(sf.AuthTypeJwt.String())) } - uri.User = url.User(c.Credentials.User) + user = url.QueryEscape(c.Credentials.User) } else { return "", fmt.Errorf("unknown auth type: %s", c.Credentials.AuthType) } - dsn := uri.User.String() + "@" + uri.Hostname() + ":" + uri.Port() + "?" + queryParams.Encode() + dsn := user + "@" + uri.Hostname() + ":" + uri.Port() + "?" + queryParams.Encode() return dsn, nil } diff --git a/materialize-snowflake/config_test.go b/materialize-snowflake/config_test.go index f6dc277e2f..04b5e84c92 100644 --- a/materialize-snowflake/config_test.go +++ b/materialize-snowflake/config_test.go @@ -9,14 +9,14 @@ import ( func TestConfigURI(t *testing.T) { for name, cfg := range map[string]config{ - "v2 User & Password Authentication": { + "User & Password Authentication": { Host: "orgname-accountname.snowflakecomputing.com", Database: "mydb", Schema: "myschema", Credentials: credentialConfig{ UserPass, "will", - "password", + "some+complex/password", "non-existant-jwt", }, },