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 }