Combined Database backend: Add Static Account support to MongoDB (#7003)

* Implement SetCredentials for MongoDB, adding support for static accounts

* rework SetCredentials to split from CreateUser, and to parse the url for database

* Add integration test for mongodb static account rotation

* check the length of the password results to avoid out-of-bounds

* remove unused method

* use the pre-existing test helper for this. Add parse method to helper

* remove unused command
This commit is contained in:
Clint
2019-07-05 13:57:01 -05:00
committed by Chris Hoffman
parent 27e295ace8
commit 30de18eb23
7 changed files with 388 additions and 22 deletions

View File

@@ -155,6 +155,56 @@ func (m *MongoDB) CreateUser(ctx context.Context, statements dbplugin.Statements
return username, password, nil
}
// SetCredentials uses provided information to set/create a user in the
// database. Unlike CreateUser, this method requires a username be provided and
// uses the name given, instead of generating a name. This is used for creating
// and setting the password of static accounts, as well as rolling back
// passwords in the database in the event an updated database fails to save in
// Vault's storage.
func (m *MongoDB) SetCredentials(ctx context.Context, statements dbplugin.Statements, staticUser dbplugin.StaticUserConfig) (username, password string, err error) {
// Grab the lock
m.Lock()
defer m.Unlock()
session, err := m.getConnection(ctx)
if err != nil {
return "", "", err
}
username = staticUser.Username
password = staticUser.Password
dialInfo, err := parseMongoURL(m.ConnectionURL)
if err != nil {
return "", "", err
}
mongoUser := mgo.User{
Username: username,
Password: password,
}
err = session.DB(dialInfo.Database).UpsertUser(&mongoUser)
switch {
case err == nil:
case err == io.EOF, strings.Contains(err.Error(), "EOF"):
// Call getConnection to reset and retry query if we get an EOF error on first attempt.
session, err := m.getConnection(ctx)
if err != nil {
return "", "", err
}
err = session.DB(dialInfo.Database).UpsertUser(&mongoUser)
if err != nil {
return "", "", err
}
default:
return "", "", err
}
return username, password, nil
}
// RenewUser is not supported on MongoDB, so this is a no-op.
func (m *MongoDB) RenewUser(ctx context.Context, statements dbplugin.Statements, username string, expiration time.Time) error {
// NOOP