Skip to content

AuthSource, Other Auth Info Ignored in URI Affecting v0.33.0 #534

@a-gavin

Description

@a-gavin

Describe the bug
When attempting to pass authSource in the MONGO_URI, either implicitly as defaultauthdb or explicitly as authSource in the connection string, the exporter is unable to log in and the following can be found in the MongoDB logs.

{"t":{"$date":"2022-07-26T21:39:12.182Z"},"s":"W", "c":"-", "id":23075, "ctx":"AuthorizationManager-0","msg":"DBException thrown","attr":{"error":{"code":11,"codeName":"UserNotFound","errmsg":"Could not find user \"REDACTED\" for db \"admin\""}}}

An example format of a breaking connection string is as follows:
mongodb://user:password@host:port/?authSource=authDbName

Using the same format connection string with v0.32.0 this error does not occur, thus appearing to be a regression affecting versions greater than v0.32.0. Having recompiled and stepped through the code with a debugger, it appears that this bug was introduced by the fix for PMM-9320. Specifically the bug is here where the client options are overwritten when username and password is used.

I'll have a PR up shortly to fix this.

To Reproduce
Apply the following patch to dsn_fix_test.go, checking that the authSource passed is the same:

diff --git a/exporter/dsn_fix/dsn_fix_test.go b/exporter/dsn_fix/dsn_fix_test.go
index 8ab175c..85efb50 100644
--- a/exporter/dsn_fix/dsn_fix_test.go
+++ b/exporter/dsn_fix/dsn_fix_test.go
@@ -29,6 +29,7 @@ func TestClientOptionsForDSN(t *testing.T) {
                dsn              string
                expectedUser     string
                expectedPassword string
+               expectedAuthSource  string
        }{
                {
                        name: "Escape username",
@@ -40,6 +41,7 @@ func TestClientOptionsForDSN(t *testing.T) {
                        }).String(),
                        expectedUser:     "user+",
                        expectedPassword: "pass",
+                       expectedAuthSource: "/db",
                },
                {
                        name: "Escape password",
@@ -51,6 +53,7 @@ func TestClientOptionsForDSN(t *testing.T) {
                        }).String(),
                        expectedUser:     "user",
                        expectedPassword: "pass+",
+                       expectedAuthSource: "/db",
                },
        }
        for _, tt := range tests {
@@ -59,6 +62,7 @@ func TestClientOptionsForDSN(t *testing.T) {
                        assert.Nil(t, err)
                        assert.Equal(t, got.Auth.Username, tt.expectedUser)
                        assert.Equal(t, got.Auth.Password, tt.expectedPassword)
+                       assert.Equal(t, got.Auth.AuthSource, tt.expectedAuthSource)
                })
        }
 }

Running go test -v, output looks like:

=== RUN   TestClientOptionsForDSN
=== RUN   TestClientOptionsForDSN/Escape_username
    dsn_fix_test.go:65: 
                Error Trace:    dsn_fix_test.go:65
                Error:          Not equal: 
                                expected: ""
                                actual  : "/db"
                            
                                Diff:
                                --- Expected
                                +++ Actual
                                @@ -1 +1 @@
                                -
                                +/db
                Test:           TestClientOptionsForDSN/Escape_username
=== RUN   TestClientOptionsForDSN/Escape_password
    dsn_fix_test.go:65: 
                Error Trace:    dsn_fix_test.go:65
                Error:          Not equal: 
                                expected: ""
                                actual  : "/db"
                            
                                Diff:
                                --- Expected
                                +++ Actual
                                @@ -1 +1 @@
                                -
                                +/db
                Test:           TestClientOptionsForDSN/Escape_password
--- FAIL: TestClientOptionsForDSN (0.00s)
    --- FAIL: TestClientOptionsForDSN/Escape_username (0.00s)
    --- FAIL: TestClientOptionsForDSN/Escape_password (0.00s)
FAIL
exit status 1
FAIL    github.com/percona/mongodb_exporter/exporter/dsn_fix    0.003s

Expected behavior
Passing authSource should result in the passed database being used to login when a username and password are specified.

Logs
See above

Environment

  • RHEL, Ubuntu
  • Bare metal
  • Not relevant

Additional context
See above

Edit: In implementing patch, realized that the true test should check for AuthSource "/db" and not "db". Updated w/ new patch and error output to reflect.

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions