github.com/crspeller/mattermost-server@v0.0.0-20190328001957-a200beb3d111/config/utils.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  	"strings"
     8  
     9  	"github.com/crspeller/mattermost-server/mlog"
    10  	"github.com/crspeller/mattermost-server/model"
    11  	"github.com/crspeller/mattermost-server/utils"
    12  )
    13  
    14  // desanitize replaces fake settings with their actual values.
    15  func desanitize(actual, target *model.Config) {
    16  	if target.LdapSettings.BindPassword != nil && *target.LdapSettings.BindPassword == model.FAKE_SETTING {
    17  		*target.LdapSettings.BindPassword = *actual.LdapSettings.BindPassword
    18  	}
    19  
    20  	if *target.FileSettings.PublicLinkSalt == model.FAKE_SETTING {
    21  		*target.FileSettings.PublicLinkSalt = *actual.FileSettings.PublicLinkSalt
    22  	}
    23  	if *target.FileSettings.AmazonS3SecretAccessKey == model.FAKE_SETTING {
    24  		target.FileSettings.AmazonS3SecretAccessKey = actual.FileSettings.AmazonS3SecretAccessKey
    25  	}
    26  
    27  	if *target.EmailSettings.SMTPPassword == model.FAKE_SETTING {
    28  		target.EmailSettings.SMTPPassword = actual.EmailSettings.SMTPPassword
    29  	}
    30  
    31  	if *target.GitLabSettings.Secret == model.FAKE_SETTING {
    32  		target.GitLabSettings.Secret = actual.GitLabSettings.Secret
    33  	}
    34  
    35  	if *target.SqlSettings.DataSource == model.FAKE_SETTING {
    36  		*target.SqlSettings.DataSource = *actual.SqlSettings.DataSource
    37  	}
    38  	if *target.SqlSettings.AtRestEncryptKey == model.FAKE_SETTING {
    39  		target.SqlSettings.AtRestEncryptKey = actual.SqlSettings.AtRestEncryptKey
    40  	}
    41  
    42  	if *target.ElasticsearchSettings.Password == model.FAKE_SETTING {
    43  		*target.ElasticsearchSettings.Password = *actual.ElasticsearchSettings.Password
    44  	}
    45  
    46  	target.SqlSettings.DataSourceReplicas = make([]string, len(actual.SqlSettings.DataSourceReplicas))
    47  	for i := range target.SqlSettings.DataSourceReplicas {
    48  		target.SqlSettings.DataSourceReplicas[i] = actual.SqlSettings.DataSourceReplicas[i]
    49  	}
    50  
    51  	target.SqlSettings.DataSourceSearchReplicas = make([]string, len(actual.SqlSettings.DataSourceSearchReplicas))
    52  	for i := range target.SqlSettings.DataSourceSearchReplicas {
    53  		target.SqlSettings.DataSourceSearchReplicas[i] = actual.SqlSettings.DataSourceSearchReplicas[i]
    54  	}
    55  }
    56  
    57  // fixConfig patches invalid or missing data in the configuration, returning true if changed.
    58  func fixConfig(cfg *model.Config) bool {
    59  	changed := false
    60  
    61  	// Ensure SiteURL has no trailing slash.
    62  	if strings.HasSuffix(*cfg.ServiceSettings.SiteURL, "/") {
    63  		*cfg.ServiceSettings.SiteURL = strings.TrimRight(*cfg.ServiceSettings.SiteURL, "/")
    64  		changed = true
    65  	}
    66  
    67  	// Ensure the directory for a local file store has a trailing slash.
    68  	if *cfg.FileSettings.DriverName == model.IMAGE_DRIVER_LOCAL {
    69  		if !strings.HasSuffix(*cfg.FileSettings.Directory, "/") {
    70  			*cfg.FileSettings.Directory += "/"
    71  			changed = true
    72  		}
    73  	}
    74  
    75  	if FixInvalidLocales(cfg) {
    76  		changed = true
    77  	}
    78  
    79  	return changed
    80  }
    81  
    82  // FixInvalidLocales checks and corrects the given config for invalid locale-related settings.
    83  //
    84  // Ideally, this function would be completely internal, but it's currently exposed to allow the cli
    85  // to test the config change before allowing the save.
    86  func FixInvalidLocales(cfg *model.Config) bool {
    87  	var changed bool
    88  
    89  	locales := utils.GetSupportedLocales()
    90  	if _, ok := locales[*cfg.LocalizationSettings.DefaultServerLocale]; !ok {
    91  		*cfg.LocalizationSettings.DefaultServerLocale = model.DEFAULT_LOCALE
    92  		mlog.Warn("DefaultServerLocale must be one of the supported locales. Setting DefaultServerLocale to en as default value.")
    93  		changed = true
    94  	}
    95  
    96  	if _, ok := locales[*cfg.LocalizationSettings.DefaultClientLocale]; !ok {
    97  		*cfg.LocalizationSettings.DefaultClientLocale = model.DEFAULT_LOCALE
    98  		mlog.Warn("DefaultClientLocale must be one of the supported locales. Setting DefaultClientLocale to en as default value.")
    99  		changed = true
   100  	}
   101  
   102  	if len(*cfg.LocalizationSettings.AvailableLocales) > 0 {
   103  		isDefaultClientLocaleInAvailableLocales := false
   104  		for _, word := range strings.Split(*cfg.LocalizationSettings.AvailableLocales, ",") {
   105  			if _, ok := locales[word]; !ok {
   106  				*cfg.LocalizationSettings.AvailableLocales = ""
   107  				isDefaultClientLocaleInAvailableLocales = true
   108  				mlog.Warn("AvailableLocales must include DefaultClientLocale. Setting AvailableLocales to all locales as default value.")
   109  				changed = true
   110  				break
   111  			}
   112  
   113  			if word == *cfg.LocalizationSettings.DefaultClientLocale {
   114  				isDefaultClientLocaleInAvailableLocales = true
   115  			}
   116  		}
   117  
   118  		availableLocales := *cfg.LocalizationSettings.AvailableLocales
   119  
   120  		if !isDefaultClientLocaleInAvailableLocales {
   121  			availableLocales += "," + *cfg.LocalizationSettings.DefaultClientLocale
   122  			mlog.Warn("Adding DefaultClientLocale to AvailableLocales.")
   123  			changed = true
   124  		}
   125  
   126  		*cfg.LocalizationSettings.AvailableLocales = strings.Join(utils.RemoveDuplicatesFromStringArray(strings.Split(availableLocales, ",")), ",")
   127  	}
   128  
   129  	return changed
   130  }
   131  
   132  // Merge merges two configs together. The receiver's values are overwritten with the patch's
   133  // values except when the patch's values are nil.
   134  func Merge(cfg *model.Config, patch *model.Config, mergeConfig *utils.MergeConfig) (*model.Config, error) {
   135  	ret, err := utils.Merge(cfg, patch, mergeConfig)
   136  	if err != nil {
   137  		return nil, err
   138  	}
   139  
   140  	retCfg := ret.(model.Config)
   141  	return &retCfg, nil
   142  }