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