From a21e1eaa3dd0c23e886b95dd243b752812ba7f07 Mon Sep 17 00:00:00 2001 From: Matias <83959431+mativm02@users.noreply.github.com> Date: Tue, 18 Jul 2023 12:20:26 -0300 Subject: [PATCH 1/5] reverting URL encoding changes --- persistent/internal/driver/mgo/life_cycle.go | 2 - .../internal/driver/mongo/life_cycle.go | 2 - persistent/internal/helper/functions.go | 68 -------------- persistent/internal/helper/functions_test.go | 91 ------------------- 4 files changed, 163 deletions(-) diff --git a/persistent/internal/driver/mgo/life_cycle.go b/persistent/internal/driver/mgo/life_cycle.go index f5765213..5849a5a5 100644 --- a/persistent/internal/driver/mgo/life_cycle.go +++ b/persistent/internal/driver/mgo/life_cycle.go @@ -24,8 +24,6 @@ type lifeCycle struct { // Connect connects to the mongo database given the ClientOpts. func (lc *lifeCycle) Connect(opts *types.ClientOpts) error { - opts.ConnectionString = helper.EncodeConnectionString(opts.ConnectionString) - dialInfo, err := mgo.ParseURL(opts.ConnectionString) if err != nil { return err diff --git a/persistent/internal/driver/mongo/life_cycle.go b/persistent/internal/driver/mongo/life_cycle.go index 84f9085b..c10eda3b 100644 --- a/persistent/internal/driver/mongo/life_cycle.go +++ b/persistent/internal/driver/mongo/life_cycle.go @@ -31,8 +31,6 @@ func (lc *lifeCycle) Connect(opts *types.ClientOpts) error { var err error var client *mongo.Client - opts.ConnectionString = helper.EncodeConnectionString(opts.ConnectionString) - // we check if the connection string is valid before building the connOpts. cs, err := connstring.ParseAndValidate(opts.ConnectionString) if err != nil { diff --git a/persistent/internal/helper/functions.go b/persistent/internal/helper/functions.go index 74d509ad..0a353f64 100644 --- a/persistent/internal/helper/functions.go +++ b/persistent/internal/helper/functions.go @@ -1,9 +1,7 @@ package helper import ( - "fmt" "log" - "net/url" "reflect" "strings" ) @@ -26,69 +24,3 @@ func IsCosmosDB(connectionString string) bool { strings.Contains(connectionString, "AccountEndpoint=") || strings.Contains(connectionString, "AccountKey=") } - -// EncodeConnectionString URL encodes the password and the username from the connection string. -// It's useful when they contains special characters. -// Example: mongodb://user:p@ssword@localhost:27017/db -> mongodb://user:p%40word@40localhost:27017/db -// If there's any conflict, the function returns the original connection string. -func EncodeConnectionString(connectionString string) string { - // Find the last '@' before the last ':' (the delimiter between credentials and host) - // we use ':' since the URL can contain '@' characters after the port number - at := findLastAtBeforeLastColon(connectionString) - if at == -1 { - // If there's no ':' in the connection string, we use the last '@' as delimiter - at = findLastAt(connectionString) - // If there's no '@' in the connection string, we return the original connection string - if at == -1 { - return connectionString - } - } - - credentialsAndScheme := connectionString[:at] - hostAndDB := connectionString[at+1:] - - // Split the credentials and scheme - credentialsAndSchemeParts := strings.SplitN(credentialsAndScheme, "://", 2) - if len(credentialsAndSchemeParts) != 2 { - return connectionString - } - - scheme := credentialsAndSchemeParts[0] // here we extract the scheme - credentials := credentialsAndSchemeParts[1] - - // Split the username and password - credentialsParts := strings.Split(credentials, ":") - if len(credentialsParts) < 2 { - return connectionString - } - - username := credentialsParts[0] - password := strings.Join(credentialsParts[1:], ":") - - // URL encode the password - encodedPassword := url.QueryEscape(password) - - encodedUsername := url.QueryEscape(username) - - // Construct the new connection string - newConnectionString := fmt.Sprintf("%s://%s:%s@%s", scheme, encodedUsername, encodedPassword, hostAndDB) - - return newConnectionString -} - -func findLastAtBeforeLastColon(str string) int { - lastColon := strings.LastIndex(str, ":") - if lastColon == -1 { - return -1 - } - - subStr := str[:lastColon] - - lastAt := strings.LastIndex(subStr, "@") - - return lastAt -} - -func findLastAt(str string) int { - return strings.LastIndex(str, "@") -} diff --git a/persistent/internal/helper/functions_test.go b/persistent/internal/helper/functions_test.go index 9ae5c503..96db214e 100644 --- a/persistent/internal/helper/functions_test.go +++ b/persistent/internal/helper/functions_test.go @@ -61,94 +61,3 @@ func TestIsCosmosDB(t *testing.T) { } } } - -func TestEncodeConnectionString(t *testing.T) { - tests := []struct { - name string - originalConnString string - expectedConnString string - }{ - { - name: "valid connection string", - originalConnString: "mongodb://user:password@localhost:27017/test", - expectedConnString: "mongodb://user:password@localhost:27017/test", - }, - { - name: "valid connection string with @", - originalConnString: "mongodb://user:p@ssword@localhost:27017", - expectedConnString: "mongodb://user:p%40ssword@localhost:27017", - }, - { - name: "valid connection string with @ and /", - originalConnString: "mongodb://u=s@r:p@sswor/d@localhost:27017/test", - expectedConnString: "mongodb://u%3Ds%40r:p%40sswor%2Fd@localhost:27017/test", - }, - { - name: "valid connection string with @ and / and '?' outside of the credentials part", - originalConnString: "mongodb://user:p@sswor/d@localhost:27017/test?authSource=admin", - expectedConnString: "mongodb://user:p%40sswor%2Fd@localhost:27017/test?authSource=admin", - }, - { - name: "special characters and multiple hosts", - originalConnString: "mongodb://user:p@sswor/d@localhost:27017,localhost:27018/test?authSource=admin", - expectedConnString: "mongodb://user:p%40sswor%2Fd@localhost:27017,localhost:27018/test?authSource=admin", - }, - { - name: "url without credentials", - originalConnString: "mongodb://localhost:27017/test?authSource=admin", - expectedConnString: "mongodb://localhost:27017/test?authSource=admin", - }, - { - name: "invalid connection string", - originalConnString: "test", - expectedConnString: "test", - }, - { - name: "connection string full of special characters", - originalConnString: "mongodb://user:p@ss:/?#[]wor/d@localhost:27017,localhost:27018", - expectedConnString: "mongodb://user:p%40ss%3A%2F%3F%23%5B%5Dwor%2Fd@localhost:27017,localhost:27018", - }, - { - name: "srv connection string", - originalConnString: "mongodb+srv://tyk:tyk@clur0.zlgl.mongodb.net/tyk?w=majority", - expectedConnString: "mongodb+srv://tyk:tyk@clur0.zlgl.mongodb.net/tyk?w=majority", - }, - { - name: "srv connection string with special characters", - originalConnString: "mongodb+srv://tyk:p@ssword@clur0.zlgl.mongodb.net/tyk?w=majority", - expectedConnString: "mongodb+srv://tyk:p%40ssword@clur0.zlgl.mongodb.net/tyk?w=majority", - }, - { - name: "connection string without username", - originalConnString: "mongodb://:password@localhost:27017/test", - expectedConnString: "mongodb://:password@localhost:27017/test", - }, - { - name: "connection string without password", - originalConnString: "mongodb://user:@localhost:27017/test", - expectedConnString: "mongodb://user:@localhost:27017/test", - }, - { - name: "connection string without host", - originalConnString: "mongodb://user:password@/test", - expectedConnString: "mongodb://user:password@/test", - }, - { - name: "connection string without database", - originalConnString: "mongodb://user:password@localhost:27017", - expectedConnString: "mongodb://user:password@localhost:27017", - }, - { - name: "cosmosdb url", - originalConnString: "mongodb://4-0-qa:zFAQ==@4-0-qa.azure:10/a1?maxIdleTimeMS=120000&appName=@4-testing@", - expectedConnString: "mongodb://4-0-qa:zFAQ%3D%3D@4-0-qa.azure:10/a1?maxIdleTimeMS=120000&appName=@4-testing@", - }, - } - - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - connString := EncodeConnectionString(test.originalConnString) - assert.Equal(t, test.expectedConnString, connString) - }) - } -} From ce3b80b185db21baa17720dd874447396bc1a8f3 Mon Sep 17 00:00:00 2001 From: Matias <83959431+mativm02@users.noreply.github.com> Date: Tue, 18 Jul 2023 12:35:38 -0300 Subject: [PATCH 2/5] adding more info to error message --- persistent/internal/driver/mgo/life_cycle.go | 2 +- persistent/internal/driver/mongo/life_cycle.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/persistent/internal/driver/mgo/life_cycle.go b/persistent/internal/driver/mgo/life_cycle.go index 5849a5a5..1704bb3c 100644 --- a/persistent/internal/driver/mgo/life_cycle.go +++ b/persistent/internal/driver/mgo/life_cycle.go @@ -26,7 +26,7 @@ type lifeCycle struct { func (lc *lifeCycle) Connect(opts *types.ClientOpts) error { dialInfo, err := mgo.ParseURL(opts.ConnectionString) if err != nil { - return err + return errors.New("invalid connection string: " + err.Error()) } dialInfo.Timeout = types.DEFAULT_CONN_TIMEOUT diff --git a/persistent/internal/driver/mongo/life_cycle.go b/persistent/internal/driver/mongo/life_cycle.go index c10eda3b..76692f77 100644 --- a/persistent/internal/driver/mongo/life_cycle.go +++ b/persistent/internal/driver/mongo/life_cycle.go @@ -34,7 +34,7 @@ func (lc *lifeCycle) Connect(opts *types.ClientOpts) error { // we check if the connection string is valid before building the connOpts. cs, err := connstring.ParseAndValidate(opts.ConnectionString) if err != nil { - return errors.New("invalid connection string") + return errors.New("invalid connection string: " + err.Error()) } connOpts, err := mongoOptsBuilder(opts) From 360002309c6eb0f430255978d90002ef31c18b9d Mon Sep 17 00:00:00 2001 From: Matias <83959431+mativm02@users.noreply.github.com> Date: Wed, 19 Jul 2023 10:15:48 -0300 Subject: [PATCH 3/5] returnirning actual error --- persistent/internal/driver/mgo/life_cycle.go | 2 +- persistent/internal/driver/mongo/life_cycle.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/persistent/internal/driver/mgo/life_cycle.go b/persistent/internal/driver/mgo/life_cycle.go index 1704bb3c..5849a5a5 100644 --- a/persistent/internal/driver/mgo/life_cycle.go +++ b/persistent/internal/driver/mgo/life_cycle.go @@ -26,7 +26,7 @@ type lifeCycle struct { func (lc *lifeCycle) Connect(opts *types.ClientOpts) error { dialInfo, err := mgo.ParseURL(opts.ConnectionString) if err != nil { - return errors.New("invalid connection string: " + err.Error()) + return err } dialInfo.Timeout = types.DEFAULT_CONN_TIMEOUT diff --git a/persistent/internal/driver/mongo/life_cycle.go b/persistent/internal/driver/mongo/life_cycle.go index 76692f77..5700903f 100644 --- a/persistent/internal/driver/mongo/life_cycle.go +++ b/persistent/internal/driver/mongo/life_cycle.go @@ -34,7 +34,7 @@ func (lc *lifeCycle) Connect(opts *types.ClientOpts) error { // we check if the connection string is valid before building the connOpts. cs, err := connstring.ParseAndValidate(opts.ConnectionString) if err != nil { - return errors.New("invalid connection string: " + err.Error()) + return err } connOpts, err := mongoOptsBuilder(opts) From 52cabe82eafec16342792aa65277d48bf1b2ed5f Mon Sep 17 00:00:00 2001 From: Matias <83959431+mativm02@users.noreply.github.com> Date: Wed, 19 Jul 2023 10:19:32 -0300 Subject: [PATCH 4/5] reverting change --- persistent/internal/driver/mgo/life_cycle.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/persistent/internal/driver/mgo/life_cycle.go b/persistent/internal/driver/mgo/life_cycle.go index 5849a5a5..7c69c05a 100644 --- a/persistent/internal/driver/mgo/life_cycle.go +++ b/persistent/internal/driver/mgo/life_cycle.go @@ -26,7 +26,7 @@ type lifeCycle struct { func (lc *lifeCycle) Connect(opts *types.ClientOpts) error { dialInfo, err := mgo.ParseURL(opts.ConnectionString) if err != nil { - return err + return errors.New("invalid connection string") } dialInfo.Timeout = types.DEFAULT_CONN_TIMEOUT From 36dca787259c9a66061c0cf3f9913ee9d2476977 Mon Sep 17 00:00:00 2001 From: Matias <83959431+mativm02@users.noreply.github.com> Date: Wed, 19 Jul 2023 10:24:20 -0300 Subject: [PATCH 5/5] reverting change part 2 --- persistent/internal/driver/mgo/life_cycle.go | 2 +- persistent/internal/driver/mongo/life_cycle.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/persistent/internal/driver/mgo/life_cycle.go b/persistent/internal/driver/mgo/life_cycle.go index 7c69c05a..5849a5a5 100644 --- a/persistent/internal/driver/mgo/life_cycle.go +++ b/persistent/internal/driver/mgo/life_cycle.go @@ -26,7 +26,7 @@ type lifeCycle struct { func (lc *lifeCycle) Connect(opts *types.ClientOpts) error { dialInfo, err := mgo.ParseURL(opts.ConnectionString) if err != nil { - return errors.New("invalid connection string") + return err } dialInfo.Timeout = types.DEFAULT_CONN_TIMEOUT diff --git a/persistent/internal/driver/mongo/life_cycle.go b/persistent/internal/driver/mongo/life_cycle.go index 5700903f..c10eda3b 100644 --- a/persistent/internal/driver/mongo/life_cycle.go +++ b/persistent/internal/driver/mongo/life_cycle.go @@ -34,7 +34,7 @@ func (lc *lifeCycle) Connect(opts *types.ClientOpts) error { // we check if the connection string is valid before building the connOpts. cs, err := connstring.ParseAndValidate(opts.ConnectionString) if err != nil { - return err + return errors.New("invalid connection string") } connOpts, err := mongoOptsBuilder(opts)