mirror of
https://github.com/mattermost/mattermost.git
synced 2025-02-25 18:55:24 -06:00
[MM-18625] Fix database source parsing on go 1.12.8 (#12250)
This commit is contained in:
@@ -8,6 +8,7 @@ import (
|
||||
"database/sql"
|
||||
"io/ioutil"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/jmoiron/sqlx"
|
||||
@@ -22,6 +23,8 @@ import (
|
||||
_ "github.com/lib/pq"
|
||||
)
|
||||
|
||||
var tcpStripper = regexp.MustCompile(`@tcp\((.*)\)`)
|
||||
|
||||
// DatabaseStore is a config store backed by a database.
|
||||
type DatabaseStore struct {
|
||||
commonStore
|
||||
@@ -101,23 +104,22 @@ func initializeConfigurationsTable(db *sqlx.DB) error {
|
||||
// By contrast, a Postgres DSN is returned unmodified.
|
||||
func parseDSN(dsn string) (string, string, error) {
|
||||
// Treat the DSN as the URL that it is.
|
||||
u, err := url.Parse(dsn)
|
||||
if err != nil {
|
||||
return "", "", errors.Wrap(err, "failed to parse DSN as URL")
|
||||
s := strings.SplitN(dsn, "://", 2)
|
||||
if len(s) != 2 {
|
||||
errors.New("failed to parse DSN as URL")
|
||||
}
|
||||
|
||||
scheme := u.Scheme
|
||||
scheme := s[0]
|
||||
switch scheme {
|
||||
case "mysql":
|
||||
// Strip off the mysql:// for the dsn with which to connect.
|
||||
u.Scheme = ""
|
||||
dsn = strings.TrimPrefix(u.String(), "//")
|
||||
dsn = s[1]
|
||||
|
||||
case "postgres":
|
||||
// No changes required
|
||||
|
||||
default:
|
||||
return "", "", errors.Wrapf(err, "unsupported scheme %s", scheme)
|
||||
return "", "", errors.Errorf("unsupported scheme %s", scheme)
|
||||
}
|
||||
|
||||
return scheme, dsn, nil
|
||||
@@ -293,7 +295,11 @@ func (ds *DatabaseStore) RemoveFile(name string) error {
|
||||
|
||||
// String returns the path to the database backing the config, masking the password.
|
||||
func (ds *DatabaseStore) String() string {
|
||||
u, _ := url.Parse(ds.originalDsn)
|
||||
// Remove @tcp and the parentheses from the host and parse the rest as a URL
|
||||
u, err := url.Parse(tcpStripper.ReplaceAllString(ds.originalDsn, `@$1`))
|
||||
if err != nil {
|
||||
return "(omitted due to error parsing the DSN)"
|
||||
}
|
||||
|
||||
// Strip out the password to avoid leaking in logs.
|
||||
u.User = url.User(u.User.Username())
|
||||
|
||||
@@ -6,7 +6,6 @@ package config_test
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
@@ -137,6 +136,11 @@ func TestDatabaseStoreNew(t *testing.T) {
|
||||
_, err := config.NewDatabaseStore("invalid")
|
||||
require.Error(t, err)
|
||||
})
|
||||
|
||||
t.Run("unsupported scheme with valid data source", func(t *testing.T) {
|
||||
_, err := config.NewDatabaseStore(fmt.Sprintf("invalid://%s", *sqlSettings.DataSource))
|
||||
require.Error(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDatabaseStoreGet(t *testing.T) {
|
||||
@@ -930,14 +934,11 @@ func TestDatabaseStoreString(t *testing.T) {
|
||||
sqlSettings := mainHelper.GetSqlSettings()
|
||||
ds, err := config.NewDatabaseStore(fmt.Sprintf("%s://%s", *sqlSettings.DriverName, *sqlSettings.DataSource))
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, ds)
|
||||
defer ds.Close()
|
||||
|
||||
actualStringURL, err := url.Parse(ds.String())
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, *sqlSettings.DriverName, actualStringURL.Scheme)
|
||||
actualUsername := actualStringURL.User.Username()
|
||||
actualPassword, _ := actualStringURL.User.Password()
|
||||
assert.NotEmpty(t, actualUsername)
|
||||
assert.Empty(t, actualPassword, "should mask password")
|
||||
maskedDSN := ds.String()
|
||||
assert.True(t, strings.HasPrefix(maskedDSN, "mysql://"))
|
||||
assert.True(t, strings.Contains(maskedDSN, "mmuser"))
|
||||
assert.False(t, strings.Contains(maskedDSN, "mostest"))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user