github.com/vnforks/kid/v5@v5.22.1-0.20200408055009-b89d99c65676/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/vnforks/kid/v5/mlog" 10 "github.com/vnforks/kid/v5/model" 11 "github.com/vnforks/kid/v5/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 } 143 144 // stripPassword remove the password from a given DSN 145 func stripPassword(dsn, schema string) string { 146 prefix := schema + "://" 147 dsn = strings.TrimPrefix(dsn, prefix) 148 149 i := strings.Index(dsn, ":") 150 j := strings.LastIndex(dsn, "@") 151 152 // Return error if no @ sign is found 153 if j < 0 { 154 return "(omitted due to error parsing the DSN)" 155 } 156 157 // Return back the input if no password is found 158 if i < 0 || i > j { 159 return prefix + dsn 160 } 161 162 return prefix + dsn[:i+1] + dsn[j:] 163 }