github.com/masterhung0112/hk_server/v5@v5.0.0-20220302090640-ec71aef15e1c/config/utils_test.go (about)

     1  // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
     2  // See LICENSE.txt for license information.
     3  
     4  package config
     5  
     6  import (
     7  	"testing"
     8  
     9  	"github.com/stretchr/testify/assert"
    10  	"github.com/stretchr/testify/require"
    11  
    12  	"github.com/masterhung0112/hk_server/v5/model"
    13  	"github.com/masterhung0112/hk_server/v5/utils"
    14  )
    15  
    16  func TestDesanitize(t *testing.T) {
    17  	actual := &model.Config{}
    18  	actual.SetDefaults()
    19  
    20  	// These setting should be ignored
    21  	actual.LdapSettings.Enable = model.NewBool(false)
    22  	actual.FileSettings.DriverName = model.NewString("s3")
    23  
    24  	// These settings should be desanitized into target.
    25  	actual.LdapSettings.BindPassword = model.NewString("bind_password")
    26  	actual.FileSettings.PublicLinkSalt = model.NewString("public_link_salt")
    27  	actual.FileSettings.AmazonS3SecretAccessKey = model.NewString("amazon_s3_secret_access_key")
    28  	actual.EmailSettings.SMTPPassword = model.NewString("smtp_password")
    29  	actual.GitLabSettings.Secret = model.NewString("secret")
    30  	actual.OpenIdSettings.Secret = model.NewString("secret")
    31  	actual.SqlSettings.DataSource = model.NewString("data_source")
    32  	actual.SqlSettings.AtRestEncryptKey = model.NewString("at_rest_encrypt_key")
    33  	actual.ElasticsearchSettings.Password = model.NewString("password")
    34  	actual.SqlSettings.DataSourceReplicas = append(actual.SqlSettings.DataSourceReplicas, "replica0")
    35  	actual.SqlSettings.DataSourceReplicas = append(actual.SqlSettings.DataSourceReplicas, "replica1")
    36  	actual.SqlSettings.DataSourceSearchReplicas = append(actual.SqlSettings.DataSourceSearchReplicas, "search_replica0")
    37  	actual.SqlSettings.DataSourceSearchReplicas = append(actual.SqlSettings.DataSourceSearchReplicas, "search_replica1")
    38  
    39  	target := &model.Config{}
    40  	target.SetDefaults()
    41  
    42  	// These setting should be ignored
    43  	target.LdapSettings.Enable = model.NewBool(true)
    44  	target.FileSettings.DriverName = model.NewString("file")
    45  
    46  	// These settings should be updated from actual
    47  	target.LdapSettings.BindPassword = model.NewString(model.FAKE_SETTING)
    48  	target.FileSettings.PublicLinkSalt = model.NewString(model.FAKE_SETTING)
    49  	target.FileSettings.AmazonS3SecretAccessKey = model.NewString(model.FAKE_SETTING)
    50  	target.EmailSettings.SMTPPassword = model.NewString(model.FAKE_SETTING)
    51  	target.GitLabSettings.Secret = model.NewString(model.FAKE_SETTING)
    52  	target.OpenIdSettings.Secret = model.NewString(model.FAKE_SETTING)
    53  	target.SqlSettings.DataSource = model.NewString(model.FAKE_SETTING)
    54  	target.SqlSettings.AtRestEncryptKey = model.NewString(model.FAKE_SETTING)
    55  	target.ElasticsearchSettings.Password = model.NewString(model.FAKE_SETTING)
    56  	target.SqlSettings.DataSourceReplicas = []string{model.FAKE_SETTING, model.FAKE_SETTING}
    57  	target.SqlSettings.DataSourceSearchReplicas = []string{model.FAKE_SETTING, model.FAKE_SETTING}
    58  
    59  	actualClone := actual.Clone()
    60  	desanitize(actual, target)
    61  	assert.Equal(t, actualClone, actual, "actual should not have been changed")
    62  
    63  	// Verify the settings that should have been left untouched in target
    64  	assert.True(t, *target.LdapSettings.Enable, "LdapSettings.Enable should not have changed")
    65  	assert.Equal(t, "file", *target.FileSettings.DriverName, "FileSettings.DriverName should not have been changed")
    66  
    67  	// Verify the settings that should have been desanitized into target
    68  	assert.Equal(t, *actual.LdapSettings.BindPassword, *target.LdapSettings.BindPassword)
    69  	assert.Equal(t, *actual.FileSettings.PublicLinkSalt, *target.FileSettings.PublicLinkSalt)
    70  	assert.Equal(t, *actual.FileSettings.AmazonS3SecretAccessKey, *target.FileSettings.AmazonS3SecretAccessKey)
    71  	assert.Equal(t, *actual.EmailSettings.SMTPPassword, *target.EmailSettings.SMTPPassword)
    72  	assert.Equal(t, *actual.GitLabSettings.Secret, *target.GitLabSettings.Secret)
    73  	assert.Equal(t, *actual.OpenIdSettings.Secret, *target.OpenIdSettings.Secret)
    74  	assert.Equal(t, *actual.SqlSettings.DataSource, *target.SqlSettings.DataSource)
    75  	assert.Equal(t, *actual.SqlSettings.AtRestEncryptKey, *target.SqlSettings.AtRestEncryptKey)
    76  	assert.Equal(t, *actual.ElasticsearchSettings.Password, *target.ElasticsearchSettings.Password)
    77  	assert.Equal(t, actual.SqlSettings.DataSourceReplicas, target.SqlSettings.DataSourceReplicas)
    78  	assert.Equal(t, actual.SqlSettings.DataSourceSearchReplicas, target.SqlSettings.DataSourceSearchReplicas)
    79  	assert.Equal(t, actual.ServiceSettings.SplitKey, target.ServiceSettings.SplitKey)
    80  }
    81  
    82  func TestFixInvalidLocales(t *testing.T) {
    83  	utils.TranslationsPreInit()
    84  
    85  	cfg := &model.Config{}
    86  	cfg.SetDefaults()
    87  
    88  	*cfg.LocalizationSettings.DefaultServerLocale = "en"
    89  	*cfg.LocalizationSettings.DefaultClientLocale = "en"
    90  	*cfg.LocalizationSettings.AvailableLocales = ""
    91  
    92  	changed := FixInvalidLocales(cfg)
    93  	assert.False(t, changed)
    94  
    95  	*cfg.LocalizationSettings.DefaultServerLocale = "junk"
    96  	changed = FixInvalidLocales(cfg)
    97  	assert.True(t, changed)
    98  	assert.Equal(t, "en", *cfg.LocalizationSettings.DefaultServerLocale)
    99  
   100  	*cfg.LocalizationSettings.DefaultServerLocale = ""
   101  	changed = FixInvalidLocales(cfg)
   102  	assert.True(t, changed)
   103  	assert.Equal(t, "en", *cfg.LocalizationSettings.DefaultServerLocale)
   104  
   105  	*cfg.LocalizationSettings.AvailableLocales = "en"
   106  	*cfg.LocalizationSettings.DefaultServerLocale = "de"
   107  	changed = FixInvalidLocales(cfg)
   108  	assert.False(t, changed)
   109  	assert.NotContains(t, *cfg.LocalizationSettings.AvailableLocales, *cfg.LocalizationSettings.DefaultServerLocale, "DefaultServerLocale should not be added to AvailableLocales")
   110  
   111  	*cfg.LocalizationSettings.AvailableLocales = ""
   112  	*cfg.LocalizationSettings.DefaultClientLocale = "junk"
   113  	changed = FixInvalidLocales(cfg)
   114  	assert.True(t, changed)
   115  	assert.Equal(t, "en", *cfg.LocalizationSettings.DefaultClientLocale)
   116  
   117  	*cfg.LocalizationSettings.DefaultClientLocale = ""
   118  	changed = FixInvalidLocales(cfg)
   119  	assert.True(t, changed)
   120  	assert.Equal(t, "en", *cfg.LocalizationSettings.DefaultClientLocale)
   121  
   122  	*cfg.LocalizationSettings.AvailableLocales = "en"
   123  	*cfg.LocalizationSettings.DefaultClientLocale = "de"
   124  	changed = FixInvalidLocales(cfg)
   125  	assert.True(t, changed)
   126  	assert.Contains(t, *cfg.LocalizationSettings.AvailableLocales, *cfg.LocalizationSettings.DefaultServerLocale, "DefaultClientLocale should have been added to AvailableLocales")
   127  
   128  	// validate AvailableLocales
   129  	*cfg.LocalizationSettings.DefaultServerLocale = "en"
   130  	*cfg.LocalizationSettings.DefaultClientLocale = "en"
   131  	*cfg.LocalizationSettings.AvailableLocales = "junk"
   132  	changed = FixInvalidLocales(cfg)
   133  	assert.True(t, changed)
   134  	assert.Equal(t, "", *cfg.LocalizationSettings.AvailableLocales)
   135  
   136  	*cfg.LocalizationSettings.AvailableLocales = "en,de,junk"
   137  	changed = FixInvalidLocales(cfg)
   138  	assert.True(t, changed)
   139  	assert.Equal(t, "", *cfg.LocalizationSettings.AvailableLocales)
   140  
   141  	*cfg.LocalizationSettings.DefaultServerLocale = "fr"
   142  	*cfg.LocalizationSettings.DefaultClientLocale = "de"
   143  	*cfg.LocalizationSettings.AvailableLocales = "en"
   144  	changed = FixInvalidLocales(cfg)
   145  	assert.True(t, changed)
   146  	assert.NotContains(t, *cfg.LocalizationSettings.AvailableLocales, *cfg.LocalizationSettings.DefaultServerLocale, "DefaultServerLocale should not be added to AvailableLocales")
   147  	assert.Contains(t, *cfg.LocalizationSettings.AvailableLocales, *cfg.LocalizationSettings.DefaultClientLocale, "DefaultClientLocale should have been added to AvailableLocales")
   148  }
   149  
   150  func TestIsDatabaseDSN(t *testing.T) {
   151  	testCases := []struct {
   152  		Name     string
   153  		DSN      string
   154  		Expected bool
   155  	}{
   156  		{
   157  			Name:     "Mysql DSN",
   158  			DSN:      "mysql://localhost",
   159  			Expected: true,
   160  		},
   161  		{
   162  			Name:     "Postgresql DSN",
   163  			DSN:      "postgres://localhost",
   164  			Expected: true,
   165  		},
   166  		{
   167  			Name:     "Empty DSN",
   168  			DSN:      "",
   169  			Expected: false,
   170  		},
   171  		{
   172  			Name:     "Default file DSN",
   173  			DSN:      "config.json",
   174  			Expected: false,
   175  		},
   176  		{
   177  			Name:     "Relative path DSN",
   178  			DSN:      "configuration/config.json",
   179  			Expected: false,
   180  		},
   181  		{
   182  			Name:     "Absolute path DSN",
   183  			DSN:      "/opt/mattermost/configuration/config.json",
   184  			Expected: false,
   185  		},
   186  	}
   187  
   188  	for _, tc := range testCases {
   189  		t.Run(tc.Name, func(t *testing.T) {
   190  			assert.Equal(t, tc.Expected, IsDatabaseDSN(tc.DSN))
   191  		})
   192  	}
   193  }
   194  
   195  func TestStripPassword(t *testing.T) {
   196  	for name, test := range map[string]struct {
   197  		DSN         string
   198  		Schema      string
   199  		ExpectedOut string
   200  	}{
   201  		"mysql": {
   202  			DSN:         "mysql://mmuser:password@tcp(localhost:3306)/mattermost?charset=utf8mb4,utf8&readTimeout=30s",
   203  			Schema:      "mysql",
   204  			ExpectedOut: "mysql://mmuser:@tcp(localhost:3306)/mattermost?charset=utf8mb4,utf8&readTimeout=30s",
   205  		},
   206  		"mysql idempotent": {
   207  			DSN:         "mysql://mmuser:@tcp(localhost:3306)/mattermost?charset=utf8mb4,utf8&readTimeout=30s",
   208  			Schema:      "mysql",
   209  			ExpectedOut: "mysql://mmuser:@tcp(localhost:3306)/mattermost?charset=utf8mb4,utf8&readTimeout=30s",
   210  		},
   211  		"mysql: password with : and @": {
   212  			DSN:         "mysql://mmuser:p:assw@ord@tcp(localhost:3306)/mattermost?charset=utf8mb4,utf8&readTimeout=30s",
   213  			Schema:      "mysql",
   214  			ExpectedOut: "mysql://mmuser:@tcp(localhost:3306)/mattermost?charset=utf8mb4,utf8&readTimeout=30s",
   215  		},
   216  		"mysql: password with @ and :": {
   217  			DSN:         "mysql://mmuser:pa@sswo:rd@tcp(localhost:3306)/mattermost?charset=utf8mb4,utf8&readTimeout=30s",
   218  			Schema:      "mysql",
   219  			ExpectedOut: "mysql://mmuser:@tcp(localhost:3306)/mattermost?charset=utf8mb4,utf8&readTimeout=30s",
   220  		},
   221  		"postgres": {
   222  			DSN:         "postgres://mmuser:password@localhost:5432/mattermost?sslmode=disable&connect_timeout=10",
   223  			Schema:      "postgres",
   224  			ExpectedOut: "postgres://mmuser:@localhost:5432/mattermost?sslmode=disable&connect_timeout=10",
   225  		},
   226  		"pipe": {
   227  			DSN:         "mysql://user@unix(/path/to/socket)/dbname",
   228  			Schema:      "mysql",
   229  			ExpectedOut: "mysql://user@unix(/path/to/socket)/dbname",
   230  		},
   231  		"malformed without :": {
   232  			DSN:         "postgres://mmuserpassword@localhost:5432/mattermost?sslmode=disable&connect_timeout=10",
   233  			Schema:      "postgres",
   234  			ExpectedOut: "postgres://mmuserpassword@localhost:5432/mattermost?sslmode=disable&connect_timeout=10",
   235  		},
   236  		"malformed without @": {
   237  			DSN:         "postgres://mmuser:passwordlocalhost:5432/mattermost?sslmode=disable&connect_timeout=10",
   238  			Schema:      "postgres",
   239  			ExpectedOut: "(omitted due to error parsing the DSN)",
   240  		},
   241  	} {
   242  		t.Run(name, func(t *testing.T) {
   243  			out := stripPassword(test.DSN, test.Schema)
   244  
   245  			assert.Equal(t, test.ExpectedOut, out)
   246  		})
   247  	}
   248  }
   249  
   250  func TestIsJSONMap(t *testing.T) {
   251  	tests := []struct {
   252  		name string
   253  		data string
   254  		want bool
   255  	}{
   256  		{name: "good json", data: `{"local_tcp": {
   257  			"Type": "tcp","Format": "json","Levels": [
   258  				{"ID": 5,"Name": "debug","Stacktrace": false}
   259  			],
   260  			"Options": {"ip": "localhost","port": 18065},
   261  			"MaxQueueSize": 1000}}
   262  			`, want: true,
   263  		},
   264  		{name: "empty json", data: "{}", want: true},
   265  		{name: "string json", data: `"test"`, want: false},
   266  		{name: "array json", data: `["test1", "test2"]`, want: false},
   267  		{name: "bad json", data: `{huh?}`, want: false},
   268  		{name: "filename", data: "/tmp/logger.conf", want: false},
   269  		{name: "mysql dsn", data: "mysql://mmuser:@tcp(localhost:3306)/mattermost?charset=utf8mb4,utf8&readTimeout=30s", want: false},
   270  		{name: "postgres dsn", data: "postgres://mmuser:passwordlocalhost:5432/mattermost?sslmode=disable&connect_timeout=10", want: false},
   271  	}
   272  	for _, tt := range tests {
   273  		t.Run(tt.name, func(t *testing.T) {
   274  			if got := isJSONMap(tt.data); got != tt.want {
   275  				t.Errorf("isJSONMap() = %v, want %v", got, tt.want)
   276  			}
   277  		})
   278  	}
   279  }
   280  
   281  func TestEqual(t *testing.T) {
   282  	t.Run("nil", func(t *testing.T) {
   283  		diff, err := equal(nil, nil)
   284  		require.NoError(t, err)
   285  		require.False(t, diff)
   286  	})
   287  
   288  	t.Run("no diff", func(t *testing.T) {
   289  		old := minimalConfig.Clone()
   290  		new := minimalConfig.Clone()
   291  		diff, err := equal(old, new)
   292  		require.NoError(t, err)
   293  		require.False(t, diff)
   294  	})
   295  
   296  	t.Run("diff", func(t *testing.T) {
   297  		old := minimalConfig.Clone()
   298  		new := minimalConfig.Clone()
   299  		new.SqlSettings = model.SqlSettings{}
   300  		diff, err := equal(old, new)
   301  		require.NoError(t, err)
   302  		require.True(t, diff)
   303  	})
   304  }