diff --git a/changelog/23240.txt b/changelog/23240.txt new file mode 100644 index 000000000..da202c7a9 --- /dev/null +++ b/changelog/23240.txt @@ -0,0 +1,3 @@ +```release-note:bug +mongo-db: allow non-admin database for root credential rotation +``` diff --git a/plugins/database/mongodb/mongodb.go b/plugins/database/mongodb/mongodb.go index 4026fbc69..a2911545c 100644 --- a/plugins/database/mongodb/mongodb.go +++ b/plugins/database/mongodb/mongodb.go @@ -176,7 +176,7 @@ func (m *MongoDB) changeUserPassword(ctx context.Context, username, password str } database := cs.Database - if username == m.Username || database == "" { + if database == "" { database = "admin" } diff --git a/plugins/database/mongodb/mongodb_test.go b/plugins/database/mongodb/mongodb_test.go index 4f36e3617..a0b513e6e 100644 --- a/plugins/database/mongodb/mongodb_test.go +++ b/plugins/database/mongodb/mongodb_test.go @@ -27,7 +27,10 @@ import ( "go.mongodb.org/mongo-driver/mongo/readpref" ) -const mongoAdminRole = `{ "db": "admin", "roles": [ { "role": "readWrite" } ] }` +const ( + mongoAdminRole = `{ "db": "admin", "roles": [ { "role": "readWrite" } ] }` + mongoTestDBAdminRole = `{ "db": "test", "roles": [ { "role": "readWrite" } ] }` +) func TestMongoDB_Initialize(t *testing.T) { cleanup, connURL := mongodb.PrepareTestContainer(t, "latest") @@ -119,6 +122,23 @@ func TestNewUser_usernameTemplate(t *testing.T) { expectedUsernameRegex: "^[A-Z0-9]{2}_[0-9]{10}_TESTROLENAMEWITHMANYCHARACTERS_TOKEN$", }, + "admin in test database username template": { + usernameTemplate: "", + + newUserReq: dbplugin.NewUserRequest{ + UsernameConfig: dbplugin.UsernameMetadata{ + DisplayName: "token", + RoleName: "testrolenamewithmanycharacters", + }, + Statements: dbplugin.Statements{ + Commands: []string{mongoTestDBAdminRole}, + }, + Password: "98yq3thgnakjsfhjkl", + Expiration: time.Now().Add(time.Minute), + }, + + expectedUsernameRegex: "^v-token-testrolenamewit-[a-zA-Z0-9]{20}-[0-9]{10}$", + }, } for name, test := range tests { @@ -126,6 +146,10 @@ func TestNewUser_usernameTemplate(t *testing.T) { cleanup, connURL := mongodb.PrepareTestContainer(t, "latest") defer cleanup() + if name == "admin in test database username template" { + connURL = connURL + "/test?authSource=test" + } + db := new() defer dbtesting.AssertClose(t, db) @@ -290,6 +314,39 @@ func TestMongoDB_UpdateUser_Password(t *testing.T) { assertCredsExist(t, dbUser, newPassword, connURL) } +func TestMongoDB_RotateRoot_NonAdminDB(t *testing.T) { + cleanup, connURL := mongodb.PrepareTestContainer(t, "latest") + defer cleanup() + + connURL = connURL + "/test?authSource=test" + db := new() + defer dbtesting.AssertClose(t, db) + + initReq := dbplugin.InitializeRequest{ + Config: map[string]interface{}{ + "connection_url": connURL, + }, + VerifyConnection: true, + } + dbtesting.AssertInitialize(t, db, initReq) + + dbUser := "testmongouser" + startingPassword := "password" + createDBUser(t, connURL, "test", dbUser, startingPassword) + + newPassword := "myreallysecurecredentials" + + updateReq := dbplugin.UpdateUserRequest{ + Username: dbUser, + Password: &dbplugin.ChangePassword{ + NewPassword: newPassword, + }, + } + dbtesting.AssertUpdateUser(t, db, updateReq) + + assertCredsExist(t, dbUser, newPassword, connURL) +} + func TestGetTLSAuth(t *testing.T) { ca := certhelpers.NewCert(t, certhelpers.CommonName("certificate authority"),