mirror of
https://github.com/optim-enterprises-bv/vault.git
synced 2025-11-02 19:47:54 +00:00
Fix MySQL legacy username regression (#3141)
* Fix the mysql legacy username length * Remove boolean parameter * Add a MySQL 5.6 container to test the legacy MySQL plugin against * Add database plugins to the make file * Fix credsutil test
This commit is contained in:
@@ -5,19 +5,15 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/vault/builtin/logical/database/dbplugin"
|
||||
"github.com/hashicorp/vault/plugins/helper/database/connutil"
|
||||
"github.com/hashicorp/vault/plugins/helper/database/credsutil"
|
||||
dockertest "gopkg.in/ory-am/dockertest.v3"
|
||||
)
|
||||
|
||||
var (
|
||||
testMySQLImagePull sync.Once
|
||||
)
|
||||
|
||||
func prepareMySQLTestContainer(t *testing.T) (cleanup func(), retURL string) {
|
||||
if os.Getenv("MYSQL_URL") != "" {
|
||||
return func() {}, os.Getenv("MYSQL_URL")
|
||||
@@ -58,6 +54,47 @@ func prepareMySQLTestContainer(t *testing.T) (cleanup func(), retURL string) {
|
||||
return
|
||||
}
|
||||
|
||||
func prepareMySQLLegacyTestContainer(t *testing.T) (cleanup func(), retURL string) {
|
||||
if os.Getenv("MYSQL_URL") != "" {
|
||||
return func() {}, os.Getenv("MYSQL_URL")
|
||||
}
|
||||
|
||||
pool, err := dockertest.NewPool("")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to connect to docker: %s", err)
|
||||
}
|
||||
|
||||
// Mysql 5.6 is the last MySQL version to limit usernames to 16 characters.
|
||||
resource, err := pool.Run("mysql", "5.6", []string{"MYSQL_ROOT_PASSWORD=secret"})
|
||||
if err != nil {
|
||||
t.Fatalf("Could not start local MySQL docker container: %s", err)
|
||||
}
|
||||
|
||||
cleanup = func() {
|
||||
err := pool.Purge(resource)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to cleanup local container: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
retURL = fmt.Sprintf("root:secret@(localhost:%s)/mysql?parseTime=true", resource.GetPort("3306/tcp"))
|
||||
|
||||
// exponential backoff-retry
|
||||
if err = pool.Retry(func() error {
|
||||
var err error
|
||||
var db *sql.DB
|
||||
db, err = sql.Open("mysql", retURL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return db.Ping()
|
||||
}); err != nil {
|
||||
t.Fatalf("Could not connect to MySQL docker container: %s", err)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func TestMySQL_Initialize(t *testing.T) {
|
||||
cleanup, connURL := prepareMySQLTestContainer(t)
|
||||
defer cleanup()
|
||||
@@ -66,7 +103,7 @@ func TestMySQL_Initialize(t *testing.T) {
|
||||
"connection_url": connURL,
|
||||
}
|
||||
|
||||
f := New(MetadataLen, UsernameLen)
|
||||
f := New(MetadataLen, MetadataLen, UsernameLen)
|
||||
dbRaw, _ := f()
|
||||
db := dbRaw.(*MySQL)
|
||||
connProducer := db.ConnectionProducer.(*connutil.SQLConnectionProducer)
|
||||
@@ -105,7 +142,7 @@ func TestMySQL_CreateUser(t *testing.T) {
|
||||
"connection_url": connURL,
|
||||
}
|
||||
|
||||
f := New(MetadataLen, UsernameLen)
|
||||
f := New(MetadataLen, MetadataLen, UsernameLen)
|
||||
dbRaw, _ := f()
|
||||
db := dbRaw.(*MySQL)
|
||||
|
||||
@@ -115,8 +152,8 @@ func TestMySQL_CreateUser(t *testing.T) {
|
||||
}
|
||||
|
||||
usernameConfig := dbplugin.UsernameConfig{
|
||||
DisplayName: "test",
|
||||
RoleName: "test",
|
||||
DisplayName: "test-long-displayname",
|
||||
RoleName: "test-long-rolename",
|
||||
}
|
||||
|
||||
// Test with no configured Creation Statememt
|
||||
@@ -137,6 +174,68 @@ func TestMySQL_CreateUser(t *testing.T) {
|
||||
if err := testCredsExist(t, connURL, username, password); err != nil {
|
||||
t.Fatalf("Could not connect with new credentials: %s", err)
|
||||
}
|
||||
|
||||
// Test a second time to make sure usernames don't collide
|
||||
username, password, err = db.CreateUser(statements, usernameConfig, time.Now().Add(time.Minute))
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
if err := testCredsExist(t, connURL, username, password); err != nil {
|
||||
t.Fatalf("Could not connect with new credentials: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMySQL_CreateUser_Legacy(t *testing.T) {
|
||||
cleanup, connURL := prepareMySQLLegacyTestContainer(t)
|
||||
defer cleanup()
|
||||
|
||||
connectionDetails := map[string]interface{}{
|
||||
"connection_url": connURL,
|
||||
}
|
||||
|
||||
f := New(credsutil.NoneLength, LegacyMetadataLen, LegacyUsernameLen)
|
||||
dbRaw, _ := f()
|
||||
db := dbRaw.(*MySQL)
|
||||
|
||||
err := db.Initialize(connectionDetails, true)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
usernameConfig := dbplugin.UsernameConfig{
|
||||
DisplayName: "test-long-displayname",
|
||||
RoleName: "test-long-rolename",
|
||||
}
|
||||
|
||||
// Test with no configured Creation Statememt
|
||||
_, _, err = db.CreateUser(dbplugin.Statements{}, usernameConfig, time.Now().Add(time.Minute))
|
||||
if err == nil {
|
||||
t.Fatal("Expected error when no creation statement is provided")
|
||||
}
|
||||
|
||||
statements := dbplugin.Statements{
|
||||
CreationStatements: testMySQLRoleWildCard,
|
||||
}
|
||||
|
||||
username, password, err := db.CreateUser(statements, usernameConfig, time.Now().Add(time.Minute))
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
if err := testCredsExist(t, connURL, username, password); err != nil {
|
||||
t.Fatalf("Could not connect with new credentials: %s", err)
|
||||
}
|
||||
|
||||
// Test a second time to make sure usernames don't collide
|
||||
username, password, err = db.CreateUser(statements, usernameConfig, time.Now().Add(time.Minute))
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
if err := testCredsExist(t, connURL, username, password); err != nil {
|
||||
t.Fatalf("Could not connect with new credentials: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMySQL_RevokeUser(t *testing.T) {
|
||||
@@ -147,7 +246,7 @@ func TestMySQL_RevokeUser(t *testing.T) {
|
||||
"connection_url": connURL,
|
||||
}
|
||||
|
||||
f := New(MetadataLen, UsernameLen)
|
||||
f := New(MetadataLen, MetadataLen, UsernameLen)
|
||||
dbRaw, _ := f()
|
||||
db := dbRaw.(*MySQL)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user