1// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2// See LICENSE.txt for license information.
3
4package model
5
6import (
7	"crypto/tls"
8	"encoding/json"
9	"io"
10	"math"
11	"net"
12	"net/http"
13	"net/url"
14	"os"
15	"reflect"
16	"regexp"
17	"strconv"
18	"strings"
19	"time"
20
21	"github.com/mattermost/ldap"
22	"github.com/mattermost/mattermost-server/v5/mlog"
23)
24
25const (
26	CONN_SECURITY_NONE     = ""
27	CONN_SECURITY_PLAIN    = "PLAIN"
28	CONN_SECURITY_TLS      = "TLS"
29	CONN_SECURITY_STARTTLS = "STARTTLS"
30
31	IMAGE_DRIVER_LOCAL = "local"
32	IMAGE_DRIVER_S3    = "amazons3"
33
34	DATABASE_DRIVER_SQLITE   = "sqlite3"
35	DATABASE_DRIVER_MYSQL    = "mysql"
36	DATABASE_DRIVER_POSTGRES = "postgres"
37
38	MINIO_ACCESS_KEY = "minioaccesskey"
39	MINIO_SECRET_KEY = "miniosecretkey"
40	MINIO_BUCKET     = "mattermost-test"
41
42	PASSWORD_MAXIMUM_LENGTH = 64
43	PASSWORD_MINIMUM_LENGTH = 5
44
45	SERVICE_GITLAB    = "gitlab"
46	SERVICE_GOOGLE    = "google"
47	SERVICE_OFFICE365 = "office365"
48
49	GENERIC_NO_CHANNEL_NOTIFICATION = "generic_no_channel"
50	GENERIC_NOTIFICATION            = "generic"
51	GENERIC_NOTIFICATION_SERVER     = "https://push-test.mattermost.com"
52	MM_SUPPORT_ADDRESS              = "support@mattermost.com"
53	FULL_NOTIFICATION               = "full"
54	ID_LOADED_NOTIFICATION          = "id_loaded"
55
56	DIRECT_MESSAGE_ANY  = "any"
57	DIRECT_MESSAGE_TEAM = "team"
58
59	SHOW_USERNAME          = "username"
60	SHOW_NICKNAME_FULLNAME = "nickname_full_name"
61	SHOW_FULLNAME          = "full_name"
62
63	PERMISSIONS_ALL           = "all"
64	PERMISSIONS_CHANNEL_ADMIN = "channel_admin"
65	PERMISSIONS_TEAM_ADMIN    = "team_admin"
66	PERMISSIONS_SYSTEM_ADMIN  = "system_admin"
67
68	FAKE_SETTING = "********************************"
69
70	RESTRICT_EMOJI_CREATION_ALL          = "all"
71	RESTRICT_EMOJI_CREATION_ADMIN        = "admin"
72	RESTRICT_EMOJI_CREATION_SYSTEM_ADMIN = "system_admin"
73
74	PERMISSIONS_DELETE_POST_ALL          = "all"
75	PERMISSIONS_DELETE_POST_TEAM_ADMIN   = "team_admin"
76	PERMISSIONS_DELETE_POST_SYSTEM_ADMIN = "system_admin"
77
78	ALLOW_EDIT_POST_ALWAYS     = "always"
79	ALLOW_EDIT_POST_NEVER      = "never"
80	ALLOW_EDIT_POST_TIME_LIMIT = "time_limit"
81
82	GROUP_UNREAD_CHANNELS_DISABLED    = "disabled"
83	GROUP_UNREAD_CHANNELS_DEFAULT_ON  = "default_on"
84	GROUP_UNREAD_CHANNELS_DEFAULT_OFF = "default_off"
85
86	EMAIL_BATCHING_BUFFER_SIZE = 256
87	EMAIL_BATCHING_INTERVAL    = 30
88
89	EMAIL_NOTIFICATION_CONTENTS_FULL    = "full"
90	EMAIL_NOTIFICATION_CONTENTS_GENERIC = "generic"
91
92	SITENAME_MAX_LENGTH = 30
93
94	SERVICE_SETTINGS_DEFAULT_SITE_URL           = "http://localhost:8065"
95	SERVICE_SETTINGS_DEFAULT_TLS_CERT_FILE      = ""
96	SERVICE_SETTINGS_DEFAULT_TLS_KEY_FILE       = ""
97	SERVICE_SETTINGS_DEFAULT_READ_TIMEOUT       = 300
98	SERVICE_SETTINGS_DEFAULT_WRITE_TIMEOUT      = 300
99	SERVICE_SETTINGS_DEFAULT_IDLE_TIMEOUT       = 60
100	SERVICE_SETTINGS_DEFAULT_MAX_LOGIN_ATTEMPTS = 10
101	SERVICE_SETTINGS_DEFAULT_ALLOW_CORS_FROM    = ""
102	SERVICE_SETTINGS_DEFAULT_LISTEN_AND_ADDRESS = ":8065"
103	SERVICE_SETTINGS_DEFAULT_GFYCAT_API_KEY     = "2_KtH_W5"
104	SERVICE_SETTINGS_DEFAULT_GFYCAT_API_SECRET  = "3wLVZPiswc3DnaiaFoLkDvB4X0IV6CpMkj4tf2inJRsBY6-FnkT08zGmppWFgeof"
105
106	TEAM_SETTINGS_DEFAULT_SITE_NAME                = "Mattermost"
107	TEAM_SETTINGS_DEFAULT_MAX_USERS_PER_TEAM       = 50
108	TEAM_SETTINGS_DEFAULT_CUSTOM_BRAND_TEXT        = ""
109	TEAM_SETTINGS_DEFAULT_CUSTOM_DESCRIPTION_TEXT  = ""
110	TEAM_SETTINGS_DEFAULT_USER_STATUS_AWAY_TIMEOUT = 300
111
112	SQL_SETTINGS_DEFAULT_DATA_SOURCE = "postgres://mmuser:mostest@localhost/mattermost_test?sslmode=disable&connect_timeout=10"
113
114	FILE_SETTINGS_DEFAULT_DIRECTORY = "./data/"
115
116	EMAIL_SETTINGS_DEFAULT_FEEDBACK_ORGANIZATION = ""
117
118	SUPPORT_SETTINGS_DEFAULT_TERMS_OF_SERVICE_LINK = "https://about.mattermost.com/default-terms/"
119	SUPPORT_SETTINGS_DEFAULT_PRIVACY_POLICY_LINK   = "https://about.mattermost.com/default-privacy-policy/"
120	SUPPORT_SETTINGS_DEFAULT_ABOUT_LINK            = "https://about.mattermost.com/default-about/"
121	SUPPORT_SETTINGS_DEFAULT_HELP_LINK             = "https://about.mattermost.com/default-help/"
122	SUPPORT_SETTINGS_DEFAULT_REPORT_A_PROBLEM_LINK = "https://about.mattermost.com/default-report-a-problem/"
123	SUPPORT_SETTINGS_DEFAULT_SUPPORT_EMAIL         = "feedback@mattermost.com"
124	SUPPORT_SETTINGS_DEFAULT_RE_ACCEPTANCE_PERIOD  = 365
125
126	LDAP_SETTINGS_DEFAULT_FIRST_NAME_ATTRIBUTE         = ""
127	LDAP_SETTINGS_DEFAULT_LAST_NAME_ATTRIBUTE          = ""
128	LDAP_SETTINGS_DEFAULT_EMAIL_ATTRIBUTE              = ""
129	LDAP_SETTINGS_DEFAULT_USERNAME_ATTRIBUTE           = ""
130	LDAP_SETTINGS_DEFAULT_NICKNAME_ATTRIBUTE           = ""
131	LDAP_SETTINGS_DEFAULT_ID_ATTRIBUTE                 = ""
132	LDAP_SETTINGS_DEFAULT_POSITION_ATTRIBUTE           = ""
133	LDAP_SETTINGS_DEFAULT_LOGIN_FIELD_NAME             = ""
134	LDAP_SETTINGS_DEFAULT_GROUP_DISPLAY_NAME_ATTRIBUTE = ""
135	LDAP_SETTINGS_DEFAULT_GROUP_ID_ATTRIBUTE           = ""
136	LDAP_SETTINGS_DEFAULT_PICTURE_ATTRIBUTE            = ""
137
138	SAML_SETTINGS_DEFAULT_ID_ATTRIBUTE         = ""
139	SAML_SETTINGS_DEFAULT_GUEST_ATTRIBUTE      = ""
140	SAML_SETTINGS_DEFAULT_ADMIN_ATTRIBUTE      = ""
141	SAML_SETTINGS_DEFAULT_FIRST_NAME_ATTRIBUTE = ""
142	SAML_SETTINGS_DEFAULT_LAST_NAME_ATTRIBUTE  = ""
143	SAML_SETTINGS_DEFAULT_EMAIL_ATTRIBUTE      = ""
144	SAML_SETTINGS_DEFAULT_USERNAME_ATTRIBUTE   = ""
145	SAML_SETTINGS_DEFAULT_NICKNAME_ATTRIBUTE   = ""
146	SAML_SETTINGS_DEFAULT_LOCALE_ATTRIBUTE     = ""
147	SAML_SETTINGS_DEFAULT_POSITION_ATTRIBUTE   = ""
148
149	SAML_SETTINGS_SIGNATURE_ALGORITHM_SHA1    = "RSAwithSHA1"
150	SAML_SETTINGS_SIGNATURE_ALGORITHM_SHA256  = "RSAwithSHA256"
151	SAML_SETTINGS_SIGNATURE_ALGORITHM_SHA512  = "RSAwithSHA512"
152	SAML_SETTINGS_DEFAULT_SIGNATURE_ALGORITHM = SAML_SETTINGS_SIGNATURE_ALGORITHM_SHA1
153
154	SAML_SETTINGS_CANONICAL_ALGORITHM_C14N    = "Canonical1.0"
155	SAML_SETTINGS_CANONICAL_ALGORITHM_C14N11  = "Canonical1.1"
156	SAML_SETTINGS_DEFAULT_CANONICAL_ALGORITHM = SAML_SETTINGS_CANONICAL_ALGORITHM_C14N
157
158	NATIVEAPP_SETTINGS_DEFAULT_APP_DOWNLOAD_LINK         = "https://mattermost.com/download/#mattermostApps"
159	NATIVEAPP_SETTINGS_DEFAULT_ANDROID_APP_DOWNLOAD_LINK = "https://about.mattermost.com/mattermost-android-app/"
160	NATIVEAPP_SETTINGS_DEFAULT_IOS_APP_DOWNLOAD_LINK     = "https://about.mattermost.com/mattermost-ios-app/"
161
162	EXPERIMENTAL_SETTINGS_DEFAULT_LINK_METADATA_TIMEOUT_MILLISECONDS = 5000
163
164	ANALYTICS_SETTINGS_DEFAULT_MAX_USERS_FOR_STATISTICS = 2500
165
166	ANNOUNCEMENT_SETTINGS_DEFAULT_BANNER_COLOR                    = "#f2a93b"
167	ANNOUNCEMENT_SETTINGS_DEFAULT_BANNER_TEXT_COLOR               = "#333333"
168	ANNOUNCEMENT_SETTINGS_DEFAULT_NOTICES_JSON_URL                = "https://notices.mattermost.com/"
169	ANNOUNCEMENT_SETTINGS_DEFAULT_NOTICES_FETCH_FREQUENCY_SECONDS = 3600
170
171	TEAM_SETTINGS_DEFAULT_TEAM_TEXT = "default"
172
173	ELASTICSEARCH_SETTINGS_DEFAULT_CONNECTION_URL                    = "http://localhost:9200"
174	ELASTICSEARCH_SETTINGS_DEFAULT_USERNAME                          = "elastic"
175	ELASTICSEARCH_SETTINGS_DEFAULT_PASSWORD                          = "changeme"
176	ELASTICSEARCH_SETTINGS_DEFAULT_POST_INDEX_REPLICAS               = 1
177	ELASTICSEARCH_SETTINGS_DEFAULT_POST_INDEX_SHARDS                 = 1
178	ELASTICSEARCH_SETTINGS_DEFAULT_CHANNEL_INDEX_REPLICAS            = 1
179	ELASTICSEARCH_SETTINGS_DEFAULT_CHANNEL_INDEX_SHARDS              = 1
180	ELASTICSEARCH_SETTINGS_DEFAULT_USER_INDEX_REPLICAS               = 1
181	ELASTICSEARCH_SETTINGS_DEFAULT_USER_INDEX_SHARDS                 = 1
182	ELASTICSEARCH_SETTINGS_DEFAULT_AGGREGATE_POSTS_AFTER_DAYS        = 365
183	ELASTICSEARCH_SETTINGS_DEFAULT_POSTS_AGGREGATOR_JOB_START_TIME   = "03:00"
184	ELASTICSEARCH_SETTINGS_DEFAULT_INDEX_PREFIX                      = ""
185	ELASTICSEARCH_SETTINGS_DEFAULT_LIVE_INDEXING_BATCH_SIZE          = 1
186	ELASTICSEARCH_SETTINGS_DEFAULT_BULK_INDEXING_TIME_WINDOW_SECONDS = 3600
187	ELASTICSEARCH_SETTINGS_DEFAULT_REQUEST_TIMEOUT_SECONDS           = 30
188
189	BLEVE_SETTINGS_DEFAULT_INDEX_DIR                         = ""
190	BLEVE_SETTINGS_DEFAULT_BULK_INDEXING_TIME_WINDOW_SECONDS = 3600
191
192	DATA_RETENTION_SETTINGS_DEFAULT_MESSAGE_RETENTION_DAYS  = 365
193	DATA_RETENTION_SETTINGS_DEFAULT_FILE_RETENTION_DAYS     = 365
194	DATA_RETENTION_SETTINGS_DEFAULT_DELETION_JOB_START_TIME = "02:00"
195
196	PLUGIN_SETTINGS_DEFAULT_DIRECTORY          = "./plugins"
197	PLUGIN_SETTINGS_DEFAULT_CLIENT_DIRECTORY   = "./client/plugins"
198	PLUGIN_SETTINGS_DEFAULT_ENABLE_MARKETPLACE = true
199	PLUGIN_SETTINGS_DEFAULT_MARKETPLACE_URL    = "https://api.integrations.mattermost.com"
200	PLUGIN_SETTINGS_OLD_MARKETPLACE_URL        = "https://marketplace.integrations.mattermost.com"
201
202	COMPLIANCE_EXPORT_TYPE_CSV             = "csv"
203	COMPLIANCE_EXPORT_TYPE_ACTIANCE        = "actiance"
204	COMPLIANCE_EXPORT_TYPE_GLOBALRELAY     = "globalrelay"
205	COMPLIANCE_EXPORT_TYPE_GLOBALRELAY_ZIP = "globalrelay-zip"
206	GLOBALRELAY_CUSTOMER_TYPE_A9           = "A9"
207	GLOBALRELAY_CUSTOMER_TYPE_A10          = "A10"
208
209	CLIENT_SIDE_CERT_CHECK_PRIMARY_AUTH   = "primary"
210	CLIENT_SIDE_CERT_CHECK_SECONDARY_AUTH = "secondary"
211
212	IMAGE_PROXY_TYPE_LOCAL      = "local"
213	IMAGE_PROXY_TYPE_ATMOS_CAMO = "atmos/camo"
214
215	GOOGLE_SETTINGS_DEFAULT_SCOPE             = "profile email"
216	GOOGLE_SETTINGS_DEFAULT_AUTH_ENDPOINT     = "https://accounts.google.com/o/oauth2/v2/auth"
217	GOOGLE_SETTINGS_DEFAULT_TOKEN_ENDPOINT    = "https://www.googleapis.com/oauth2/v4/token"
218	GOOGLE_SETTINGS_DEFAULT_USER_API_ENDPOINT = "https://people.googleapis.com/v1/people/me?personFields=names,emailAddresses,nicknames,metadata"
219
220	OFFICE365_SETTINGS_DEFAULT_SCOPE             = "User.Read"
221	OFFICE365_SETTINGS_DEFAULT_AUTH_ENDPOINT     = "https://login.microsoftonline.com/common/oauth2/v2.0/authorize"
222	OFFICE365_SETTINGS_DEFAULT_TOKEN_ENDPOINT    = "https://login.microsoftonline.com/common/oauth2/v2.0/token"
223	OFFICE365_SETTINGS_DEFAULT_USER_API_ENDPOINT = "https://graph.microsoft.com/v1.0/me"
224
225	CLOUD_SETTINGS_DEFAULT_CWS_URL = "https://customers.mattermost.com"
226
227	LOCAL_MODE_SOCKET_PATH = "/var/tmp/mattermost_local.socket"
228)
229
230var ServerTLSSupportedCiphers = map[string]uint16{
231	"TLS_RSA_WITH_RC4_128_SHA":                tls.TLS_RSA_WITH_RC4_128_SHA,
232	"TLS_RSA_WITH_3DES_EDE_CBC_SHA":           tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA,
233	"TLS_RSA_WITH_AES_128_CBC_SHA":            tls.TLS_RSA_WITH_AES_128_CBC_SHA,
234	"TLS_RSA_WITH_AES_256_CBC_SHA":            tls.TLS_RSA_WITH_AES_256_CBC_SHA,
235	"TLS_RSA_WITH_AES_128_CBC_SHA256":         tls.TLS_RSA_WITH_AES_128_CBC_SHA256,
236	"TLS_RSA_WITH_AES_128_GCM_SHA256":         tls.TLS_RSA_WITH_AES_128_GCM_SHA256,
237	"TLS_RSA_WITH_AES_256_GCM_SHA384":         tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
238	"TLS_ECDHE_ECDSA_WITH_RC4_128_SHA":        tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
239	"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA":    tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
240	"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA":    tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
241	"TLS_ECDHE_RSA_WITH_RC4_128_SHA":          tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA,
242	"TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA":     tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
243	"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA":      tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
244	"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA":      tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
245	"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256": tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
246	"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256":   tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
247	"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256":   tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
248	"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256": tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
249	"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384":   tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
250	"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384": tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
251	"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305":    tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
252	"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305":  tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
253}
254
255type ServiceSettings struct {
256	SiteURL                                           *string  `access:"environment,authentication,write_restrictable"`
257	WebsocketURL                                      *string  `access:"write_restrictable,cloud_restrictable"`
258	LicenseFileLocation                               *string  `access:"write_restrictable,cloud_restrictable"`
259	ListenAddress                                     *string  `access:"environment,write_restrictable,cloud_restrictable"`
260	ConnectionSecurity                                *string  `access:"environment,write_restrictable,cloud_restrictable"`
261	TLSCertFile                                       *string  `access:"environment,write_restrictable,cloud_restrictable"`
262	TLSKeyFile                                        *string  `access:"environment,write_restrictable,cloud_restrictable"`
263	TLSMinVer                                         *string  `access:"write_restrictable,cloud_restrictable"`
264	TLSStrictTransport                                *bool    `access:"write_restrictable,cloud_restrictable"`
265	TLSStrictTransportMaxAge                          *int64   `access:"write_restrictable,cloud_restrictable"`
266	TLSOverwriteCiphers                               []string `access:"write_restrictable,cloud_restrictable"`
267	UseLetsEncrypt                                    *bool    `access:"environment,write_restrictable,cloud_restrictable"`
268	LetsEncryptCertificateCacheFile                   *string  `access:"environment,write_restrictable,cloud_restrictable"`
269	Forward80To443                                    *bool    `access:"environment,write_restrictable,cloud_restrictable"`
270	TrustedProxyIPHeader                              []string `access:"write_restrictable,cloud_restrictable"`
271	ReadTimeout                                       *int     `access:"environment,write_restrictable,cloud_restrictable"`
272	WriteTimeout                                      *int     `access:"environment,write_restrictable,cloud_restrictable"`
273	IdleTimeout                                       *int     `access:"write_restrictable,cloud_restrictable"`
274	MaximumLoginAttempts                              *int     `access:"authentication,write_restrictable,cloud_restrictable"`
275	GoroutineHealthThreshold                          *int     `access:"write_restrictable,cloud_restrictable"`
276	GoogleDeveloperKey                                *string  `access:"site,write_restrictable,cloud_restrictable"`
277	EnableOAuthServiceProvider                        *bool    `access:"integrations"`
278	EnableIncomingWebhooks                            *bool    `access:"integrations"`
279	EnableOutgoingWebhooks                            *bool    `access:"integrations"`
280	EnableCommands                                    *bool    `access:"integrations"`
281	DEPRECATED_DO_NOT_USE_EnableOnlyAdminIntegrations *bool    `json:"EnableOnlyAdminIntegrations" mapstructure:"EnableOnlyAdminIntegrations"` // This field is deprecated and must not be used.
282	EnablePostUsernameOverride                        *bool    `access:"integrations"`
283	EnablePostIconOverride                            *bool    `access:"integrations"`
284	EnableLinkPreviews                                *bool    `access:"site"`
285	EnableTesting                                     *bool    `access:"environment,write_restrictable,cloud_restrictable"`
286	EnableDeveloper                                   *bool    `access:"environment,write_restrictable,cloud_restrictable"`
287	EnableOpenTracing                                 *bool    `access:"write_restrictable,cloud_restrictable"`
288	EnableSecurityFixAlert                            *bool    `access:"environment,write_restrictable,cloud_restrictable"`
289	EnableInsecureOutgoingConnections                 *bool    `access:"environment,write_restrictable,cloud_restrictable"`
290	AllowedUntrustedInternalConnections               *string  `access:"environment,write_restrictable,cloud_restrictable"`
291	EnableMultifactorAuthentication                   *bool    `access:"authentication"`
292	EnforceMultifactorAuthentication                  *bool    `access:"authentication"`
293	EnableUserAccessTokens                            *bool    `access:"integrations"`
294	AllowCorsFrom                                     *string  `access:"integrations,write_restrictable,cloud_restrictable"`
295	CorsExposedHeaders                                *string  `access:"integrations,write_restrictable,cloud_restrictable"`
296	CorsAllowCredentials                              *bool    `access:"integrations,write_restrictable,cloud_restrictable"`
297	CorsDebug                                         *bool    `access:"integrations,write_restrictable,cloud_restrictable"`
298	AllowCookiesForSubdomains                         *bool    `access:"write_restrictable,cloud_restrictable"`
299	ExtendSessionLengthWithActivity                   *bool    `access:"environment,write_restrictable,cloud_restrictable"`
300	SessionLengthWebInDays                            *int     `access:"environment,write_restrictable,cloud_restrictable"`
301	SessionLengthMobileInDays                         *int     `access:"environment,write_restrictable,cloud_restrictable"`
302	SessionLengthSSOInDays                            *int     `access:"environment,write_restrictable,cloud_restrictable"`
303	SessionCacheInMinutes                             *int     `access:"environment,write_restrictable,cloud_restrictable"`
304	SessionIdleTimeoutInMinutes                       *int     `access:"environment,write_restrictable,cloud_restrictable"`
305	WebsocketSecurePort                               *int     `access:"write_restrictable,cloud_restrictable"`
306	WebsocketPort                                     *int     `access:"write_restrictable,cloud_restrictable"`
307	WebserverMode                                     *string  `access:"environment,write_restrictable,cloud_restrictable"`
308	EnableCustomEmoji                                 *bool    `access:"site"`
309	EnableEmojiPicker                                 *bool    `access:"site"`
310	EnableGifPicker                                   *bool    `access:"integrations"`
311	GfycatApiKey                                      *string  `access:"integrations"`
312	GfycatApiSecret                                   *string  `access:"integrations"`
313	DEPRECATED_DO_NOT_USE_RestrictCustomEmojiCreation *string  `json:"RestrictCustomEmojiCreation" mapstructure:"RestrictCustomEmojiCreation"` // This field is deprecated and must not be used.
314	DEPRECATED_DO_NOT_USE_RestrictPostDelete          *string  `json:"RestrictPostDelete" mapstructure:"RestrictPostDelete"`                   // This field is deprecated and must not be used.
315	DEPRECATED_DO_NOT_USE_AllowEditPost               *string  `json:"AllowEditPost" mapstructure:"AllowEditPost"`                             // This field is deprecated and must not be used.
316	PostEditTimeLimit                                 *int     `access:"user_management_permissions"`
317	TimeBetweenUserTypingUpdatesMilliseconds          *int64   `access:"experimental,write_restrictable,cloud_restrictable"`
318	EnablePostSearch                                  *bool    `access:"write_restrictable,cloud_restrictable"`
319	MinimumHashtagLength                              *int     `access:"environment,write_restrictable,cloud_restrictable"`
320	EnableUserTypingMessages                          *bool    `access:"experimental,write_restrictable,cloud_restrictable"`
321	EnableChannelViewedMessages                       *bool    `access:"experimental,write_restrictable,cloud_restrictable"`
322	EnableUserStatuses                                *bool    `access:"write_restrictable,cloud_restrictable"`
323	ExperimentalEnableAuthenticationTransfer          *bool    `access:"experimental,write_restrictable,cloud_restrictable"`
324	ClusterLogTimeoutMilliseconds                     *int     `access:"write_restrictable,cloud_restrictable"`
325	CloseUnusedDirectMessages                         *bool    `access:"experimental"`
326	EnablePreviewFeatures                             *bool    `access:"experimental"`
327	EnableTutorial                                    *bool    `access:"experimental"`
328	ExperimentalEnableDefaultChannelLeaveJoinMessages *bool    `access:"experimental"`
329	ExperimentalGroupUnreadChannels                   *string  `access:"experimental"`
330	ExperimentalChannelOrganization                   *bool    `access:"experimental"`
331	ExperimentalChannelSidebarOrganization            *string  `access:"experimental"`
332	ExperimentalDataPrefetch                          *bool    `access:"experimental"`
333	DEPRECATED_DO_NOT_USE_ImageProxyType              *string  `json:"ImageProxyType" mapstructure:"ImageProxyType"`       // This field is deprecated and must not be used.
334	DEPRECATED_DO_NOT_USE_ImageProxyURL               *string  `json:"ImageProxyURL" mapstructure:"ImageProxyURL"`         // This field is deprecated and must not be used.
335	DEPRECATED_DO_NOT_USE_ImageProxyOptions           *string  `json:"ImageProxyOptions" mapstructure:"ImageProxyOptions"` // This field is deprecated and must not be used.
336	EnableAPITeamDeletion                             *bool
337	EnableAPIUserDeletion                             *bool
338	ExperimentalEnableHardenedMode                    *bool `access:"experimental"`
339	DisableLegacyMFA                                  *bool `access:"write_restrictable,cloud_restrictable"`
340	ExperimentalStrictCSRFEnforcement                 *bool `access:"experimental,write_restrictable,cloud_restrictable"`
341	EnableEmailInvitations                            *bool `access:"authentication"`
342	DisableBotsWhenOwnerIsDeactivated                 *bool `access:"integrations,write_restrictable,cloud_restrictable"`
343	EnableBotAccountCreation                          *bool `access:"integrations"`
344	EnableSVGs                                        *bool `access:"site"`
345	EnableLatex                                       *bool `access:"site"`
346	EnableAPIChannelDeletion                          *bool
347	EnableLocalMode                                   *bool
348	LocalModeSocketLocation                           *string
349	EnableAWSMetering                                 *bool
350	SplitKey                                          *string `access:"environment,write_restrictable"`
351	FeatureFlagSyncIntervalSeconds                    *int    `access:"environment,write_restrictable"`
352	DebugSplit                                        *bool   `access:"environment,write_restrictable"`
353	ThreadAutoFollow                                  *bool   `access:"experimental"`
354	ManagedResourcePaths                              *string `access:"environment,write_restrictable,cloud_restrictable"`
355}
356
357func (s *ServiceSettings) SetDefaults(isUpdate bool) {
358	if s.EnableEmailInvitations == nil {
359		// If the site URL is also not present then assume this is a clean install
360		if s.SiteURL == nil {
361			s.EnableEmailInvitations = NewBool(false)
362		} else {
363			s.EnableEmailInvitations = NewBool(true)
364		}
365	}
366
367	if s.SiteURL == nil {
368		if s.EnableDeveloper != nil && *s.EnableDeveloper {
369			s.SiteURL = NewString(SERVICE_SETTINGS_DEFAULT_SITE_URL)
370		} else {
371			s.SiteURL = NewString("")
372		}
373	}
374
375	if s.WebsocketURL == nil {
376		s.WebsocketURL = NewString("")
377	}
378
379	if s.LicenseFileLocation == nil {
380		s.LicenseFileLocation = NewString("")
381	}
382
383	if s.ListenAddress == nil {
384		s.ListenAddress = NewString(SERVICE_SETTINGS_DEFAULT_LISTEN_AND_ADDRESS)
385	}
386
387	if s.EnableLinkPreviews == nil {
388		s.EnableLinkPreviews = NewBool(true)
389	}
390
391	if s.EnableTesting == nil {
392		s.EnableTesting = NewBool(false)
393	}
394
395	if s.EnableDeveloper == nil {
396		s.EnableDeveloper = NewBool(false)
397	}
398
399	if s.EnableOpenTracing == nil {
400		s.EnableOpenTracing = NewBool(false)
401	}
402
403	if s.EnableSecurityFixAlert == nil {
404		s.EnableSecurityFixAlert = NewBool(true)
405	}
406
407	if s.EnableInsecureOutgoingConnections == nil {
408		s.EnableInsecureOutgoingConnections = NewBool(false)
409	}
410
411	if s.AllowedUntrustedInternalConnections == nil {
412		s.AllowedUntrustedInternalConnections = NewString("")
413	}
414
415	if s.EnableMultifactorAuthentication == nil {
416		s.EnableMultifactorAuthentication = NewBool(false)
417	}
418
419	if s.EnforceMultifactorAuthentication == nil {
420		s.EnforceMultifactorAuthentication = NewBool(false)
421	}
422
423	if s.EnableUserAccessTokens == nil {
424		s.EnableUserAccessTokens = NewBool(false)
425	}
426
427	if s.GoroutineHealthThreshold == nil {
428		s.GoroutineHealthThreshold = NewInt(-1)
429	}
430
431	if s.GoogleDeveloperKey == nil {
432		s.GoogleDeveloperKey = NewString("")
433	}
434
435	if s.EnableOAuthServiceProvider == nil {
436		s.EnableOAuthServiceProvider = NewBool(false)
437	}
438
439	if s.EnableIncomingWebhooks == nil {
440		s.EnableIncomingWebhooks = NewBool(true)
441	}
442
443	if s.EnableOutgoingWebhooks == nil {
444		s.EnableOutgoingWebhooks = NewBool(true)
445	}
446
447	if s.ConnectionSecurity == nil {
448		s.ConnectionSecurity = NewString("")
449	}
450
451	if s.TLSKeyFile == nil {
452		s.TLSKeyFile = NewString(SERVICE_SETTINGS_DEFAULT_TLS_KEY_FILE)
453	}
454
455	if s.TLSCertFile == nil {
456		s.TLSCertFile = NewString(SERVICE_SETTINGS_DEFAULT_TLS_CERT_FILE)
457	}
458
459	if s.TLSMinVer == nil {
460		s.TLSMinVer = NewString("1.2")
461	}
462
463	if s.TLSStrictTransport == nil {
464		s.TLSStrictTransport = NewBool(false)
465	}
466
467	if s.TLSStrictTransportMaxAge == nil {
468		s.TLSStrictTransportMaxAge = NewInt64(63072000)
469	}
470
471	if s.TLSOverwriteCiphers == nil {
472		s.TLSOverwriteCiphers = []string{}
473	}
474
475	if s.UseLetsEncrypt == nil {
476		s.UseLetsEncrypt = NewBool(false)
477	}
478
479	if s.LetsEncryptCertificateCacheFile == nil {
480		s.LetsEncryptCertificateCacheFile = NewString("./config/letsencrypt.cache")
481	}
482
483	if s.ReadTimeout == nil {
484		s.ReadTimeout = NewInt(SERVICE_SETTINGS_DEFAULT_READ_TIMEOUT)
485	}
486
487	if s.WriteTimeout == nil {
488		s.WriteTimeout = NewInt(SERVICE_SETTINGS_DEFAULT_WRITE_TIMEOUT)
489	}
490
491	if s.IdleTimeout == nil {
492		s.IdleTimeout = NewInt(SERVICE_SETTINGS_DEFAULT_IDLE_TIMEOUT)
493	}
494
495	if s.MaximumLoginAttempts == nil {
496		s.MaximumLoginAttempts = NewInt(SERVICE_SETTINGS_DEFAULT_MAX_LOGIN_ATTEMPTS)
497	}
498
499	if s.Forward80To443 == nil {
500		s.Forward80To443 = NewBool(false)
501	}
502
503	if isUpdate {
504		// When updating an existing configuration, ensure that defaults are set.
505		if s.TrustedProxyIPHeader == nil {
506			s.TrustedProxyIPHeader = []string{HEADER_FORWARDED, HEADER_REAL_IP}
507		}
508	} else {
509		// When generating a blank configuration, leave the list empty.
510		s.TrustedProxyIPHeader = []string{}
511	}
512
513	if s.TimeBetweenUserTypingUpdatesMilliseconds == nil {
514		s.TimeBetweenUserTypingUpdatesMilliseconds = NewInt64(5000)
515	}
516
517	if s.EnablePostSearch == nil {
518		s.EnablePostSearch = NewBool(true)
519	}
520
521	if s.MinimumHashtagLength == nil {
522		s.MinimumHashtagLength = NewInt(3)
523	}
524
525	if s.EnableUserTypingMessages == nil {
526		s.EnableUserTypingMessages = NewBool(true)
527	}
528
529	if s.EnableChannelViewedMessages == nil {
530		s.EnableChannelViewedMessages = NewBool(true)
531	}
532
533	if s.EnableUserStatuses == nil {
534		s.EnableUserStatuses = NewBool(true)
535	}
536
537	if s.ClusterLogTimeoutMilliseconds == nil {
538		s.ClusterLogTimeoutMilliseconds = NewInt(2000)
539	}
540
541	if s.CloseUnusedDirectMessages == nil {
542		s.CloseUnusedDirectMessages = NewBool(false)
543	}
544
545	if s.EnableTutorial == nil {
546		s.EnableTutorial = NewBool(true)
547	}
548
549	// Must be manually enabled for existing installations.
550	if s.ExtendSessionLengthWithActivity == nil {
551		s.ExtendSessionLengthWithActivity = NewBool(!isUpdate)
552	}
553
554	if s.SessionLengthWebInDays == nil {
555		if isUpdate {
556			s.SessionLengthWebInDays = NewInt(180)
557		} else {
558			s.SessionLengthWebInDays = NewInt(30)
559		}
560	}
561
562	if s.SessionLengthMobileInDays == nil {
563		if isUpdate {
564			s.SessionLengthMobileInDays = NewInt(180)
565		} else {
566			s.SessionLengthMobileInDays = NewInt(30)
567		}
568	}
569
570	if s.SessionLengthSSOInDays == nil {
571		s.SessionLengthSSOInDays = NewInt(30)
572	}
573
574	if s.SessionCacheInMinutes == nil {
575		s.SessionCacheInMinutes = NewInt(10)
576	}
577
578	if s.SessionIdleTimeoutInMinutes == nil {
579		s.SessionIdleTimeoutInMinutes = NewInt(43200)
580	}
581
582	if s.EnableCommands == nil {
583		s.EnableCommands = NewBool(true)
584	}
585
586	if s.DEPRECATED_DO_NOT_USE_EnableOnlyAdminIntegrations == nil {
587		s.DEPRECATED_DO_NOT_USE_EnableOnlyAdminIntegrations = NewBool(true)
588	}
589
590	if s.EnablePostUsernameOverride == nil {
591		s.EnablePostUsernameOverride = NewBool(false)
592	}
593
594	if s.EnablePostIconOverride == nil {
595		s.EnablePostIconOverride = NewBool(false)
596	}
597
598	if s.WebsocketPort == nil {
599		s.WebsocketPort = NewInt(80)
600	}
601
602	if s.WebsocketSecurePort == nil {
603		s.WebsocketSecurePort = NewInt(443)
604	}
605
606	if s.AllowCorsFrom == nil {
607		s.AllowCorsFrom = NewString(SERVICE_SETTINGS_DEFAULT_ALLOW_CORS_FROM)
608	}
609
610	if s.CorsExposedHeaders == nil {
611		s.CorsExposedHeaders = NewString("")
612	}
613
614	if s.CorsAllowCredentials == nil {
615		s.CorsAllowCredentials = NewBool(false)
616	}
617
618	if s.CorsDebug == nil {
619		s.CorsDebug = NewBool(false)
620	}
621
622	if s.AllowCookiesForSubdomains == nil {
623		s.AllowCookiesForSubdomains = NewBool(false)
624	}
625
626	if s.WebserverMode == nil {
627		s.WebserverMode = NewString("gzip")
628	} else if *s.WebserverMode == "regular" {
629		*s.WebserverMode = "gzip"
630	}
631
632	if s.EnableCustomEmoji == nil {
633		s.EnableCustomEmoji = NewBool(true)
634	}
635
636	if s.EnableEmojiPicker == nil {
637		s.EnableEmojiPicker = NewBool(true)
638	}
639
640	if s.EnableGifPicker == nil {
641		s.EnableGifPicker = NewBool(true)
642	}
643
644	if s.GfycatApiKey == nil || *s.GfycatApiKey == "" {
645		s.GfycatApiKey = NewString(SERVICE_SETTINGS_DEFAULT_GFYCAT_API_KEY)
646	}
647
648	if s.GfycatApiSecret == nil || *s.GfycatApiSecret == "" {
649		s.GfycatApiSecret = NewString(SERVICE_SETTINGS_DEFAULT_GFYCAT_API_SECRET)
650	}
651
652	if s.DEPRECATED_DO_NOT_USE_RestrictCustomEmojiCreation == nil {
653		s.DEPRECATED_DO_NOT_USE_RestrictCustomEmojiCreation = NewString(RESTRICT_EMOJI_CREATION_ALL)
654	}
655
656	if s.DEPRECATED_DO_NOT_USE_RestrictPostDelete == nil {
657		s.DEPRECATED_DO_NOT_USE_RestrictPostDelete = NewString(PERMISSIONS_DELETE_POST_ALL)
658	}
659
660	if s.DEPRECATED_DO_NOT_USE_AllowEditPost == nil {
661		s.DEPRECATED_DO_NOT_USE_AllowEditPost = NewString(ALLOW_EDIT_POST_ALWAYS)
662	}
663
664	if s.ExperimentalEnableAuthenticationTransfer == nil {
665		s.ExperimentalEnableAuthenticationTransfer = NewBool(true)
666	}
667
668	if s.PostEditTimeLimit == nil {
669		s.PostEditTimeLimit = NewInt(-1)
670	}
671
672	if s.EnablePreviewFeatures == nil {
673		s.EnablePreviewFeatures = NewBool(true)
674	}
675
676	if s.ExperimentalEnableDefaultChannelLeaveJoinMessages == nil {
677		s.ExperimentalEnableDefaultChannelLeaveJoinMessages = NewBool(true)
678	}
679
680	if s.ExperimentalGroupUnreadChannels == nil {
681		s.ExperimentalGroupUnreadChannels = NewString(GROUP_UNREAD_CHANNELS_DISABLED)
682	} else if *s.ExperimentalGroupUnreadChannels == "0" {
683		s.ExperimentalGroupUnreadChannels = NewString(GROUP_UNREAD_CHANNELS_DISABLED)
684	} else if *s.ExperimentalGroupUnreadChannels == "1" {
685		s.ExperimentalGroupUnreadChannels = NewString(GROUP_UNREAD_CHANNELS_DEFAULT_ON)
686	}
687
688	if s.ExperimentalChannelOrganization == nil {
689		experimentalUnreadEnabled := *s.ExperimentalGroupUnreadChannels != GROUP_UNREAD_CHANNELS_DISABLED
690		s.ExperimentalChannelOrganization = NewBool(experimentalUnreadEnabled)
691	}
692
693	if s.ExperimentalChannelSidebarOrganization == nil {
694		s.ExperimentalChannelSidebarOrganization = NewString("disabled")
695	}
696
697	if s.ExperimentalDataPrefetch == nil {
698		s.ExperimentalDataPrefetch = NewBool(true)
699	}
700
701	if s.DEPRECATED_DO_NOT_USE_ImageProxyType == nil {
702		s.DEPRECATED_DO_NOT_USE_ImageProxyType = NewString("")
703	}
704
705	if s.DEPRECATED_DO_NOT_USE_ImageProxyURL == nil {
706		s.DEPRECATED_DO_NOT_USE_ImageProxyURL = NewString("")
707	}
708
709	if s.DEPRECATED_DO_NOT_USE_ImageProxyOptions == nil {
710		s.DEPRECATED_DO_NOT_USE_ImageProxyOptions = NewString("")
711	}
712
713	if s.EnableAPITeamDeletion == nil {
714		s.EnableAPITeamDeletion = NewBool(false)
715	}
716
717	if s.EnableAPIUserDeletion == nil {
718		s.EnableAPIUserDeletion = NewBool(false)
719	}
720
721	if s.EnableAPIChannelDeletion == nil {
722		s.EnableAPIChannelDeletion = NewBool(false)
723	}
724
725	if s.ExperimentalEnableHardenedMode == nil {
726		s.ExperimentalEnableHardenedMode = NewBool(false)
727	}
728
729	if s.DisableLegacyMFA == nil {
730		s.DisableLegacyMFA = NewBool(!isUpdate)
731	}
732
733	if s.ExperimentalStrictCSRFEnforcement == nil {
734		s.ExperimentalStrictCSRFEnforcement = NewBool(false)
735	}
736
737	if s.DisableBotsWhenOwnerIsDeactivated == nil {
738		s.DisableBotsWhenOwnerIsDeactivated = NewBool(true)
739	}
740
741	if s.EnableBotAccountCreation == nil {
742		s.EnableBotAccountCreation = NewBool(false)
743	}
744
745	if s.EnableSVGs == nil {
746		if isUpdate {
747			s.EnableSVGs = NewBool(true)
748		} else {
749			s.EnableSVGs = NewBool(false)
750		}
751	}
752
753	if s.EnableLatex == nil {
754		if isUpdate {
755			s.EnableLatex = NewBool(true)
756		} else {
757			s.EnableLatex = NewBool(false)
758		}
759	}
760
761	if s.EnableLocalMode == nil {
762		s.EnableLocalMode = NewBool(false)
763	}
764
765	if s.LocalModeSocketLocation == nil {
766		s.LocalModeSocketLocation = NewString(LOCAL_MODE_SOCKET_PATH)
767	}
768
769	if s.EnableAWSMetering == nil {
770		s.EnableAWSMetering = NewBool(false)
771	}
772
773	if s.SplitKey == nil {
774		s.SplitKey = NewString("")
775	}
776
777	if s.FeatureFlagSyncIntervalSeconds == nil {
778		s.FeatureFlagSyncIntervalSeconds = NewInt(30)
779	}
780
781	if s.DebugSplit == nil {
782		s.DebugSplit = NewBool(false)
783	}
784
785	if s.ThreadAutoFollow == nil {
786		s.ThreadAutoFollow = NewBool(true)
787	}
788
789	if s.ManagedResourcePaths == nil {
790		s.ManagedResourcePaths = NewString("")
791	}
792}
793
794type ClusterSettings struct {
795	Enable                             *bool   `access:"environment,write_restrictable"`
796	ClusterName                        *string `access:"environment,write_restrictable,cloud_restrictable"`
797	OverrideHostname                   *string `access:"environment,write_restrictable,cloud_restrictable"`
798	NetworkInterface                   *string `access:"environment,write_restrictable,cloud_restrictable"`
799	BindAddress                        *string `access:"environment,write_restrictable,cloud_restrictable"`
800	AdvertiseAddress                   *string `access:"environment,write_restrictable,cloud_restrictable"`
801	UseIpAddress                       *bool   `access:"environment,write_restrictable,cloud_restrictable"`
802	UseExperimentalGossip              *bool   `access:"environment,write_restrictable,cloud_restrictable"`
803	EnableExperimentalGossipEncryption *bool   `access:"environment,write_restrictable,cloud_restrictable"`
804	ReadOnlyConfig                     *bool   `access:"environment,write_restrictable,cloud_restrictable"`
805	GossipPort                         *int    `access:"environment,write_restrictable,cloud_restrictable"`
806	StreamingPort                      *int    `access:"environment,write_restrictable,cloud_restrictable"`
807	MaxIdleConns                       *int    `access:"environment,write_restrictable,cloud_restrictable"`
808	MaxIdleConnsPerHost                *int    `access:"environment,write_restrictable,cloud_restrictable"`
809	IdleConnTimeoutMilliseconds        *int    `access:"environment,write_restrictable,cloud_restrictable"`
810}
811
812func (s *ClusterSettings) SetDefaults() {
813	if s.Enable == nil {
814		s.Enable = NewBool(false)
815	}
816
817	if s.ClusterName == nil {
818		s.ClusterName = NewString("")
819	}
820
821	if s.OverrideHostname == nil {
822		s.OverrideHostname = NewString("")
823	}
824
825	if s.NetworkInterface == nil {
826		s.NetworkInterface = NewString("")
827	}
828
829	if s.BindAddress == nil {
830		s.BindAddress = NewString("")
831	}
832
833	if s.AdvertiseAddress == nil {
834		s.AdvertiseAddress = NewString("")
835	}
836
837	if s.UseIpAddress == nil {
838		s.UseIpAddress = NewBool(true)
839	}
840
841	if s.UseExperimentalGossip == nil {
842		s.UseExperimentalGossip = NewBool(false)
843	}
844
845	if s.EnableExperimentalGossipEncryption == nil {
846		s.EnableExperimentalGossipEncryption = NewBool(false)
847	}
848
849	if s.ReadOnlyConfig == nil {
850		s.ReadOnlyConfig = NewBool(true)
851	}
852
853	if s.GossipPort == nil {
854		s.GossipPort = NewInt(8074)
855	}
856
857	if s.StreamingPort == nil {
858		s.StreamingPort = NewInt(8075)
859	}
860
861	if s.MaxIdleConns == nil {
862		s.MaxIdleConns = NewInt(100)
863	}
864
865	if s.MaxIdleConnsPerHost == nil {
866		s.MaxIdleConnsPerHost = NewInt(128)
867	}
868
869	if s.IdleConnTimeoutMilliseconds == nil {
870		s.IdleConnTimeoutMilliseconds = NewInt(90000)
871	}
872}
873
874type MetricsSettings struct {
875	Enable           *bool   `access:"environment,write_restrictable,cloud_restrictable"`
876	BlockProfileRate *int    `access:"environment,write_restrictable,cloud_restrictable"`
877	ListenAddress    *string `access:"environment,write_restrictable,cloud_restrictable"`
878}
879
880func (s *MetricsSettings) SetDefaults() {
881	if s.ListenAddress == nil {
882		s.ListenAddress = NewString(":8067")
883	}
884
885	if s.Enable == nil {
886		s.Enable = NewBool(false)
887	}
888
889	if s.BlockProfileRate == nil {
890		s.BlockProfileRate = NewInt(0)
891	}
892}
893
894type ExperimentalSettings struct {
895	ClientSideCertEnable            *bool   `access:"experimental,cloud_restrictable"`
896	ClientSideCertCheck             *string `access:"experimental,cloud_restrictable"`
897	EnableClickToReply              *bool   `access:"experimental,write_restrictable,cloud_restrictable"`
898	LinkMetadataTimeoutMilliseconds *int64  `access:"experimental,write_restrictable,cloud_restrictable"`
899	RestrictSystemAdmin             *bool   `access:"experimental,write_restrictable"`
900	UseNewSAMLLibrary               *bool   `access:"experimental,cloud_restrictable"`
901	CloudUserLimit                  *int64  `access:"experimental,write_restrictable"`
902	CloudBilling                    *bool   `access:"experimental,write_restrictable"`
903	EnableSharedChannels            *bool   `access:"experimental"`
904}
905
906func (s *ExperimentalSettings) SetDefaults() {
907	if s.ClientSideCertEnable == nil {
908		s.ClientSideCertEnable = NewBool(false)
909	}
910
911	if s.ClientSideCertCheck == nil {
912		s.ClientSideCertCheck = NewString(CLIENT_SIDE_CERT_CHECK_SECONDARY_AUTH)
913	}
914
915	if s.EnableClickToReply == nil {
916		s.EnableClickToReply = NewBool(false)
917	}
918
919	if s.LinkMetadataTimeoutMilliseconds == nil {
920		s.LinkMetadataTimeoutMilliseconds = NewInt64(EXPERIMENTAL_SETTINGS_DEFAULT_LINK_METADATA_TIMEOUT_MILLISECONDS)
921	}
922
923	if s.RestrictSystemAdmin == nil {
924		s.RestrictSystemAdmin = NewBool(false)
925	}
926
927	if s.CloudUserLimit == nil {
928		// User limit 0 is treated as no limit
929		s.CloudUserLimit = NewInt64(0)
930	}
931
932	if s.CloudBilling == nil {
933		s.CloudBilling = NewBool(false)
934	}
935
936	if s.UseNewSAMLLibrary == nil {
937		s.UseNewSAMLLibrary = NewBool(false)
938	}
939
940	if s.EnableSharedChannels == nil {
941		s.EnableSharedChannels = NewBool(false)
942	}
943}
944
945type AnalyticsSettings struct {
946	MaxUsersForStatistics *int `access:"write_restrictable,cloud_restrictable"`
947}
948
949func (s *AnalyticsSettings) SetDefaults() {
950	if s.MaxUsersForStatistics == nil {
951		s.MaxUsersForStatistics = NewInt(ANALYTICS_SETTINGS_DEFAULT_MAX_USERS_FOR_STATISTICS)
952	}
953}
954
955type SSOSettings struct {
956	Enable          *bool   `access:"authentication"`
957	Secret          *string `access:"authentication"`
958	Id              *string `access:"authentication"`
959	Scope           *string `access:"authentication"`
960	AuthEndpoint    *string `access:"authentication"`
961	TokenEndpoint   *string `access:"authentication"`
962	UserApiEndpoint *string `access:"authentication"`
963}
964
965func (s *SSOSettings) setDefaults(scope, authEndpoint, tokenEndpoint, userApiEndpoint string) {
966	if s.Enable == nil {
967		s.Enable = NewBool(false)
968	}
969
970	if s.Secret == nil {
971		s.Secret = NewString("")
972	}
973
974	if s.Id == nil {
975		s.Id = NewString("")
976	}
977
978	if s.Scope == nil {
979		s.Scope = NewString(scope)
980	}
981
982	if s.AuthEndpoint == nil {
983		s.AuthEndpoint = NewString(authEndpoint)
984	}
985
986	if s.TokenEndpoint == nil {
987		s.TokenEndpoint = NewString(tokenEndpoint)
988	}
989
990	if s.UserApiEndpoint == nil {
991		s.UserApiEndpoint = NewString(userApiEndpoint)
992	}
993}
994
995type Office365Settings struct {
996	Enable          *bool   `access:"authentication"`
997	Secret          *string `access:"authentication"`
998	Id              *string `access:"authentication"`
999	Scope           *string `access:"authentication"`
1000	AuthEndpoint    *string `access:"authentication"`
1001	TokenEndpoint   *string `access:"authentication"`
1002	UserApiEndpoint *string `access:"authentication"`
1003	DirectoryId     *string `access:"authentication"`
1004}
1005
1006func (s *Office365Settings) setDefaults() {
1007	if s.Enable == nil {
1008		s.Enable = NewBool(false)
1009	}
1010
1011	if s.Id == nil {
1012		s.Id = NewString("")
1013	}
1014
1015	if s.Secret == nil {
1016		s.Secret = NewString("")
1017	}
1018
1019	if s.Scope == nil {
1020		s.Scope = NewString(OFFICE365_SETTINGS_DEFAULT_SCOPE)
1021	}
1022
1023	if s.AuthEndpoint == nil {
1024		s.AuthEndpoint = NewString(OFFICE365_SETTINGS_DEFAULT_AUTH_ENDPOINT)
1025	}
1026
1027	if s.TokenEndpoint == nil {
1028		s.TokenEndpoint = NewString(OFFICE365_SETTINGS_DEFAULT_TOKEN_ENDPOINT)
1029	}
1030
1031	if s.UserApiEndpoint == nil {
1032		s.UserApiEndpoint = NewString(OFFICE365_SETTINGS_DEFAULT_USER_API_ENDPOINT)
1033	}
1034
1035	if s.DirectoryId == nil {
1036		s.DirectoryId = NewString("")
1037	}
1038}
1039
1040func (s *Office365Settings) SSOSettings() *SSOSettings {
1041	ssoSettings := SSOSettings{}
1042	ssoSettings.Enable = s.Enable
1043	ssoSettings.Secret = s.Secret
1044	ssoSettings.Id = s.Id
1045	ssoSettings.Scope = s.Scope
1046	ssoSettings.AuthEndpoint = s.AuthEndpoint
1047	ssoSettings.TokenEndpoint = s.TokenEndpoint
1048	ssoSettings.UserApiEndpoint = s.UserApiEndpoint
1049	return &ssoSettings
1050}
1051
1052type SqlSettings struct {
1053	DriverName                  *string  `access:"environment,write_restrictable,cloud_restrictable"`
1054	DataSource                  *string  `access:"environment,write_restrictable,cloud_restrictable"`
1055	DataSourceReplicas          []string `access:"environment,write_restrictable,cloud_restrictable"`
1056	DataSourceSearchReplicas    []string `access:"environment,write_restrictable,cloud_restrictable"`
1057	MaxIdleConns                *int     `access:"environment,write_restrictable,cloud_restrictable"`
1058	ConnMaxLifetimeMilliseconds *int     `access:"environment,write_restrictable,cloud_restrictable"`
1059	MaxOpenConns                *int     `access:"environment,write_restrictable,cloud_restrictable"`
1060	Trace                       *bool    `access:"environment,write_restrictable,cloud_restrictable"`
1061	AtRestEncryptKey            *string  `access:"environment,write_restrictable,cloud_restrictable"`
1062	QueryTimeout                *int     `access:"environment,write_restrictable,cloud_restrictable"`
1063	DisableDatabaseSearch       *bool    `access:"environment,write_restrictable,cloud_restrictable"`
1064}
1065
1066func (s *SqlSettings) SetDefaults(isUpdate bool) {
1067	if s.DriverName == nil {
1068		s.DriverName = NewString(DATABASE_DRIVER_POSTGRES)
1069	}
1070
1071	if s.DataSource == nil {
1072		s.DataSource = NewString(SQL_SETTINGS_DEFAULT_DATA_SOURCE)
1073	}
1074
1075	if s.DataSourceReplicas == nil {
1076		s.DataSourceReplicas = []string{}
1077	}
1078
1079	if s.DataSourceSearchReplicas == nil {
1080		s.DataSourceSearchReplicas = []string{}
1081	}
1082
1083	if isUpdate {
1084		// When updating an existing configuration, ensure an encryption key has been specified.
1085		if s.AtRestEncryptKey == nil || len(*s.AtRestEncryptKey) == 0 {
1086			s.AtRestEncryptKey = NewString(NewRandomString(32))
1087		}
1088	} else {
1089		// When generating a blank configuration, leave this key empty to be generated on server start.
1090		s.AtRestEncryptKey = NewString("")
1091	}
1092
1093	if s.MaxIdleConns == nil {
1094		s.MaxIdleConns = NewInt(20)
1095	}
1096
1097	if s.MaxOpenConns == nil {
1098		s.MaxOpenConns = NewInt(300)
1099	}
1100
1101	if s.ConnMaxLifetimeMilliseconds == nil {
1102		s.ConnMaxLifetimeMilliseconds = NewInt(3600000)
1103	}
1104
1105	if s.Trace == nil {
1106		s.Trace = NewBool(false)
1107	}
1108
1109	if s.QueryTimeout == nil {
1110		s.QueryTimeout = NewInt(30)
1111	}
1112
1113	if s.DisableDatabaseSearch == nil {
1114		s.DisableDatabaseSearch = NewBool(false)
1115	}
1116}
1117
1118type LogSettings struct {
1119	EnableConsole          *bool   `access:"environment,write_restrictable,cloud_restrictable"`
1120	ConsoleLevel           *string `access:"environment,write_restrictable,cloud_restrictable"`
1121	ConsoleJson            *bool   `access:"environment,write_restrictable,cloud_restrictable"`
1122	EnableFile             *bool   `access:"environment,write_restrictable,cloud_restrictable"`
1123	FileLevel              *string `access:"environment,write_restrictable,cloud_restrictable"`
1124	FileJson               *bool   `access:"environment,write_restrictable,cloud_restrictable"`
1125	FileLocation           *string `access:"environment,write_restrictable,cloud_restrictable"`
1126	EnableWebhookDebugging *bool   `access:"environment,write_restrictable,cloud_restrictable"`
1127	EnableDiagnostics      *bool   `access:"environment,write_restrictable,cloud_restrictable"`
1128	EnableSentry           *bool   `access:"environment,write_restrictable,cloud_restrictable"`
1129	AdvancedLoggingConfig  *string `access:"environment,write_restrictable,cloud_restrictable"`
1130}
1131
1132func (s *LogSettings) SetDefaults() {
1133	if s.EnableConsole == nil {
1134		s.EnableConsole = NewBool(true)
1135	}
1136
1137	if s.ConsoleLevel == nil {
1138		s.ConsoleLevel = NewString("DEBUG")
1139	}
1140
1141	if s.EnableFile == nil {
1142		s.EnableFile = NewBool(true)
1143	}
1144
1145	if s.FileLevel == nil {
1146		s.FileLevel = NewString("INFO")
1147	}
1148
1149	if s.FileLocation == nil {
1150		s.FileLocation = NewString("")
1151	}
1152
1153	if s.EnableWebhookDebugging == nil {
1154		s.EnableWebhookDebugging = NewBool(true)
1155	}
1156
1157	if s.EnableDiagnostics == nil {
1158		s.EnableDiagnostics = NewBool(true)
1159	}
1160
1161	if s.EnableSentry == nil {
1162		s.EnableSentry = NewBool(*s.EnableDiagnostics)
1163	}
1164
1165	if s.ConsoleJson == nil {
1166		s.ConsoleJson = NewBool(true)
1167	}
1168
1169	if s.FileJson == nil {
1170		s.FileJson = NewBool(true)
1171	}
1172
1173	if s.AdvancedLoggingConfig == nil {
1174		s.AdvancedLoggingConfig = NewString("")
1175	}
1176}
1177
1178type ExperimentalAuditSettings struct {
1179	FileEnabled           *bool   `access:"experimental,write_restrictable,cloud_restrictable"`
1180	FileName              *string `access:"experimental,write_restrictable,cloud_restrictable"`
1181	FileMaxSizeMB         *int    `access:"experimental,write_restrictable,cloud_restrictable"`
1182	FileMaxAgeDays        *int    `access:"experimental,write_restrictable,cloud_restrictable"`
1183	FileMaxBackups        *int    `access:"experimental,write_restrictable,cloud_restrictable"`
1184	FileCompress          *bool   `access:"experimental,write_restrictable,cloud_restrictable"`
1185	FileMaxQueueSize      *int    `access:"experimental,write_restrictable,cloud_restrictable"`
1186	AdvancedLoggingConfig *string `access:"experimental,write_restrictable,cloud_restrictable"`
1187}
1188
1189func (s *ExperimentalAuditSettings) SetDefaults() {
1190	if s.FileEnabled == nil {
1191		s.FileEnabled = NewBool(false)
1192	}
1193
1194	if s.FileName == nil {
1195		s.FileName = NewString("")
1196	}
1197
1198	if s.FileMaxSizeMB == nil {
1199		s.FileMaxSizeMB = NewInt(100)
1200	}
1201
1202	if s.FileMaxAgeDays == nil {
1203		s.FileMaxAgeDays = NewInt(0) // no limit on age
1204	}
1205
1206	if s.FileMaxBackups == nil { // no limit on number of backups
1207		s.FileMaxBackups = NewInt(0)
1208	}
1209
1210	if s.FileCompress == nil {
1211		s.FileCompress = NewBool(false)
1212	}
1213
1214	if s.FileMaxQueueSize == nil {
1215		s.FileMaxQueueSize = NewInt(1000)
1216	}
1217
1218	if s.AdvancedLoggingConfig == nil {
1219		s.AdvancedLoggingConfig = NewString("")
1220	}
1221}
1222
1223type NotificationLogSettings struct {
1224	EnableConsole         *bool   `access:"write_restrictable,cloud_restrictable"`
1225	ConsoleLevel          *string `access:"write_restrictable,cloud_restrictable"`
1226	ConsoleJson           *bool   `access:"write_restrictable,cloud_restrictable"`
1227	EnableFile            *bool   `access:"write_restrictable,cloud_restrictable"`
1228	FileLevel             *string `access:"write_restrictable,cloud_restrictable"`
1229	FileJson              *bool   `access:"write_restrictable,cloud_restrictable"`
1230	FileLocation          *string `access:"write_restrictable,cloud_restrictable"`
1231	AdvancedLoggingConfig *string `access:"write_restrictable,cloud_restrictable"`
1232}
1233
1234func (s *NotificationLogSettings) SetDefaults() {
1235	if s.EnableConsole == nil {
1236		s.EnableConsole = NewBool(true)
1237	}
1238
1239	if s.ConsoleLevel == nil {
1240		s.ConsoleLevel = NewString("DEBUG")
1241	}
1242
1243	if s.EnableFile == nil {
1244		s.EnableFile = NewBool(true)
1245	}
1246
1247	if s.FileLevel == nil {
1248		s.FileLevel = NewString("INFO")
1249	}
1250
1251	if s.FileLocation == nil {
1252		s.FileLocation = NewString("")
1253	}
1254
1255	if s.ConsoleJson == nil {
1256		s.ConsoleJson = NewBool(true)
1257	}
1258
1259	if s.FileJson == nil {
1260		s.FileJson = NewBool(true)
1261	}
1262
1263	if s.AdvancedLoggingConfig == nil {
1264		s.AdvancedLoggingConfig = NewString("")
1265	}
1266}
1267
1268type PasswordSettings struct {
1269	MinimumLength *int  `access:"authentication"`
1270	Lowercase     *bool `access:"authentication"`
1271	Number        *bool `access:"authentication"`
1272	Uppercase     *bool `access:"authentication"`
1273	Symbol        *bool `access:"authentication"`
1274}
1275
1276func (s *PasswordSettings) SetDefaults() {
1277	if s.MinimumLength == nil {
1278		s.MinimumLength = NewInt(10)
1279	}
1280
1281	if s.Lowercase == nil {
1282		s.Lowercase = NewBool(true)
1283	}
1284
1285	if s.Number == nil {
1286		s.Number = NewBool(true)
1287	}
1288
1289	if s.Uppercase == nil {
1290		s.Uppercase = NewBool(true)
1291	}
1292
1293	if s.Symbol == nil {
1294		s.Symbol = NewBool(true)
1295	}
1296}
1297
1298type FileSettings struct {
1299	EnableFileAttachments   *bool   `access:"site,cloud_restrictable"`
1300	EnableMobileUpload      *bool   `access:"site,cloud_restrictable"`
1301	EnableMobileDownload    *bool   `access:"site,cloud_restrictable"`
1302	MaxFileSize             *int64  `access:"environment,cloud_restrictable"`
1303	DriverName              *string `access:"environment,write_restrictable,cloud_restrictable"`
1304	Directory               *string `access:"environment,write_restrictable,cloud_restrictable"`
1305	EnablePublicLink        *bool   `access:"site,cloud_restrictable"`
1306	PublicLinkSalt          *string `access:"site,cloud_restrictable"`
1307	InitialFont             *string `access:"environment,cloud_restrictable"`
1308	AmazonS3AccessKeyId     *string `access:"environment,write_restrictable,cloud_restrictable"`
1309	AmazonS3SecretAccessKey *string `access:"environment,write_restrictable,cloud_restrictable"`
1310	AmazonS3Bucket          *string `access:"environment,write_restrictable,cloud_restrictable"`
1311	AmazonS3PathPrefix      *string `access:"environment,write_restrictable,cloud_restrictable"`
1312	AmazonS3Region          *string `access:"environment,write_restrictable,cloud_restrictable"`
1313	AmazonS3Endpoint        *string `access:"environment,write_restrictable,cloud_restrictable"`
1314	AmazonS3SSL             *bool   `access:"environment,write_restrictable,cloud_restrictable"`
1315	AmazonS3SignV2          *bool   `access:"environment,write_restrictable,cloud_restrictable"`
1316	AmazonS3SSE             *bool   `access:"environment,write_restrictable,cloud_restrictable"`
1317	AmazonS3Trace           *bool   `access:"environment,write_restrictable,cloud_restrictable"`
1318}
1319
1320func (s *FileSettings) SetDefaults(isUpdate bool) {
1321	if s.EnableFileAttachments == nil {
1322		s.EnableFileAttachments = NewBool(true)
1323	}
1324
1325	if s.EnableMobileUpload == nil {
1326		s.EnableMobileUpload = NewBool(true)
1327	}
1328
1329	if s.EnableMobileDownload == nil {
1330		s.EnableMobileDownload = NewBool(true)
1331	}
1332
1333	if s.MaxFileSize == nil {
1334		s.MaxFileSize = NewInt64(52428800) // 50 MB
1335	}
1336
1337	if s.DriverName == nil {
1338		s.DriverName = NewString(IMAGE_DRIVER_LOCAL)
1339	}
1340
1341	if s.Directory == nil || *s.Directory == "" {
1342		s.Directory = NewString(FILE_SETTINGS_DEFAULT_DIRECTORY)
1343	}
1344
1345	if s.EnablePublicLink == nil {
1346		s.EnablePublicLink = NewBool(false)
1347	}
1348
1349	if isUpdate {
1350		// When updating an existing configuration, ensure link salt has been specified.
1351		if s.PublicLinkSalt == nil || len(*s.PublicLinkSalt) == 0 {
1352			s.PublicLinkSalt = NewString(NewRandomString(32))
1353		}
1354	} else {
1355		// When generating a blank configuration, leave link salt empty to be generated on server start.
1356		s.PublicLinkSalt = NewString("")
1357	}
1358
1359	if s.InitialFont == nil {
1360		// Defaults to "nunito-bold.ttf"
1361		s.InitialFont = NewString("nunito-bold.ttf")
1362	}
1363
1364	if s.AmazonS3AccessKeyId == nil {
1365		s.AmazonS3AccessKeyId = NewString("")
1366	}
1367
1368	if s.AmazonS3SecretAccessKey == nil {
1369		s.AmazonS3SecretAccessKey = NewString("")
1370	}
1371
1372	if s.AmazonS3Bucket == nil {
1373		s.AmazonS3Bucket = NewString("")
1374	}
1375
1376	if s.AmazonS3PathPrefix == nil {
1377		s.AmazonS3PathPrefix = NewString("")
1378	}
1379
1380	if s.AmazonS3Region == nil {
1381		s.AmazonS3Region = NewString("")
1382	}
1383
1384	if s.AmazonS3Endpoint == nil || len(*s.AmazonS3Endpoint) == 0 {
1385		// Defaults to "s3.amazonaws.com"
1386		s.AmazonS3Endpoint = NewString("s3.amazonaws.com")
1387	}
1388
1389	if s.AmazonS3SSL == nil {
1390		s.AmazonS3SSL = NewBool(true) // Secure by default.
1391	}
1392
1393	if s.AmazonS3SignV2 == nil {
1394		s.AmazonS3SignV2 = new(bool)
1395		// Signature v2 is not enabled by default.
1396	}
1397
1398	if s.AmazonS3SSE == nil {
1399		s.AmazonS3SSE = NewBool(false) // Not Encrypted by default.
1400	}
1401
1402	if s.AmazonS3Trace == nil {
1403		s.AmazonS3Trace = NewBool(false)
1404	}
1405}
1406
1407type EmailSettings struct {
1408	EnableSignUpWithEmail             *bool   `access:"authentication"`
1409	EnableSignInWithEmail             *bool   `access:"authentication"`
1410	EnableSignInWithUsername          *bool   `access:"authentication"`
1411	SendEmailNotifications            *bool   `access:"site"`
1412	UseChannelInEmailNotifications    *bool   `access:"experimental"`
1413	RequireEmailVerification          *bool   `access:"authentication"`
1414	FeedbackName                      *string `access:"site"`
1415	FeedbackEmail                     *string `access:"site,cloud_restrictable"`
1416	ReplyToAddress                    *string `access:"site,cloud_restrictable"`
1417	FeedbackOrganization              *string `access:"site"`
1418	EnableSMTPAuth                    *bool   `access:"environment,write_restrictable,cloud_restrictable"`
1419	SMTPUsername                      *string `access:"environment,write_restrictable,cloud_restrictable"`
1420	SMTPPassword                      *string `access:"environment,write_restrictable,cloud_restrictable"`
1421	SMTPServer                        *string `access:"environment,write_restrictable,cloud_restrictable"`
1422	SMTPPort                          *string `access:"environment,write_restrictable,cloud_restrictable"`
1423	SMTPServerTimeout                 *int    `access:"cloud_restrictable"`
1424	ConnectionSecurity                *string `access:"environment,write_restrictable,cloud_restrictable"`
1425	SendPushNotifications             *bool   `access:"environment"`
1426	PushNotificationServer            *string `access:"environment"`
1427	PushNotificationContents          *string `access:"site"`
1428	PushNotificationBuffer            *int
1429	EnableEmailBatching               *bool   `access:"site"`
1430	EmailBatchingBufferSize           *int    `access:"experimental"`
1431	EmailBatchingInterval             *int    `access:"experimental"`
1432	EnablePreviewModeBanner           *bool   `access:"site"`
1433	SkipServerCertificateVerification *bool   `access:"environment,write_restrictable,cloud_restrictable"`
1434	EmailNotificationContentsType     *string `access:"site"`
1435	LoginButtonColor                  *string `access:"experimental"`
1436	LoginButtonBorderColor            *string `access:"experimental"`
1437	LoginButtonTextColor              *string `access:"experimental"`
1438}
1439
1440func (s *EmailSettings) SetDefaults(isUpdate bool) {
1441	if s.EnableSignUpWithEmail == nil {
1442		s.EnableSignUpWithEmail = NewBool(true)
1443	}
1444
1445	if s.EnableSignInWithEmail == nil {
1446		s.EnableSignInWithEmail = NewBool(*s.EnableSignUpWithEmail)
1447	}
1448
1449	if s.EnableSignInWithUsername == nil {
1450		s.EnableSignInWithUsername = NewBool(true)
1451	}
1452
1453	if s.SendEmailNotifications == nil {
1454		s.SendEmailNotifications = NewBool(true)
1455	}
1456
1457	if s.UseChannelInEmailNotifications == nil {
1458		s.UseChannelInEmailNotifications = NewBool(false)
1459	}
1460
1461	if s.RequireEmailVerification == nil {
1462		s.RequireEmailVerification = NewBool(false)
1463	}
1464
1465	if s.FeedbackName == nil {
1466		s.FeedbackName = NewString("")
1467	}
1468
1469	if s.FeedbackEmail == nil {
1470		s.FeedbackEmail = NewString("test@example.com")
1471	}
1472
1473	if s.ReplyToAddress == nil {
1474		s.ReplyToAddress = NewString("test@example.com")
1475	}
1476
1477	if s.FeedbackOrganization == nil {
1478		s.FeedbackOrganization = NewString(EMAIL_SETTINGS_DEFAULT_FEEDBACK_ORGANIZATION)
1479	}
1480
1481	if s.EnableSMTPAuth == nil {
1482		if s.ConnectionSecurity == nil || *s.ConnectionSecurity == CONN_SECURITY_NONE {
1483			s.EnableSMTPAuth = NewBool(false)
1484		} else {
1485			s.EnableSMTPAuth = NewBool(true)
1486		}
1487	}
1488
1489	if s.SMTPUsername == nil {
1490		s.SMTPUsername = NewString("")
1491	}
1492
1493	if s.SMTPPassword == nil {
1494		s.SMTPPassword = NewString("")
1495	}
1496
1497	if s.SMTPServer == nil || len(*s.SMTPServer) == 0 {
1498		s.SMTPServer = NewString("localhost")
1499	}
1500
1501	if s.SMTPPort == nil || len(*s.SMTPPort) == 0 {
1502		s.SMTPPort = NewString("10025")
1503	}
1504
1505	if s.SMTPServerTimeout == nil || *s.SMTPServerTimeout == 0 {
1506		s.SMTPServerTimeout = NewInt(10)
1507	}
1508
1509	if s.ConnectionSecurity == nil || *s.ConnectionSecurity == CONN_SECURITY_PLAIN {
1510		s.ConnectionSecurity = NewString(CONN_SECURITY_NONE)
1511	}
1512
1513	if s.SendPushNotifications == nil {
1514		s.SendPushNotifications = NewBool(!isUpdate)
1515	}
1516
1517	if s.PushNotificationServer == nil {
1518		if isUpdate {
1519			s.PushNotificationServer = NewString("")
1520		} else {
1521			s.PushNotificationServer = NewString(GENERIC_NOTIFICATION_SERVER)
1522		}
1523	}
1524
1525	if s.PushNotificationContents == nil {
1526		s.PushNotificationContents = NewString(FULL_NOTIFICATION)
1527	}
1528
1529	if s.PushNotificationBuffer == nil {
1530		s.PushNotificationBuffer = NewInt(1000)
1531	}
1532
1533	if s.EnableEmailBatching == nil {
1534		s.EnableEmailBatching = NewBool(false)
1535	}
1536
1537	if s.EmailBatchingBufferSize == nil {
1538		s.EmailBatchingBufferSize = NewInt(EMAIL_BATCHING_BUFFER_SIZE)
1539	}
1540
1541	if s.EmailBatchingInterval == nil {
1542		s.EmailBatchingInterval = NewInt(EMAIL_BATCHING_INTERVAL)
1543	}
1544
1545	if s.EnablePreviewModeBanner == nil {
1546		s.EnablePreviewModeBanner = NewBool(true)
1547	}
1548
1549	if s.EnableSMTPAuth == nil {
1550		if *s.ConnectionSecurity == CONN_SECURITY_NONE {
1551			s.EnableSMTPAuth = NewBool(false)
1552		} else {
1553			s.EnableSMTPAuth = NewBool(true)
1554		}
1555	}
1556
1557	if *s.ConnectionSecurity == CONN_SECURITY_PLAIN {
1558		*s.ConnectionSecurity = CONN_SECURITY_NONE
1559	}
1560
1561	if s.SkipServerCertificateVerification == nil {
1562		s.SkipServerCertificateVerification = NewBool(false)
1563	}
1564
1565	if s.EmailNotificationContentsType == nil {
1566		s.EmailNotificationContentsType = NewString(EMAIL_NOTIFICATION_CONTENTS_FULL)
1567	}
1568
1569	if s.LoginButtonColor == nil {
1570		s.LoginButtonColor = NewString("#0000")
1571	}
1572
1573	if s.LoginButtonBorderColor == nil {
1574		s.LoginButtonBorderColor = NewString("#2389D7")
1575	}
1576
1577	if s.LoginButtonTextColor == nil {
1578		s.LoginButtonTextColor = NewString("#2389D7")
1579	}
1580}
1581
1582type RateLimitSettings struct {
1583	Enable           *bool  `access:"environment,write_restrictable,cloud_restrictable"`
1584	PerSec           *int   `access:"environment,write_restrictable,cloud_restrictable"`
1585	MaxBurst         *int   `access:"environment,write_restrictable,cloud_restrictable"`
1586	MemoryStoreSize  *int   `access:"environment,write_restrictable,cloud_restrictable"`
1587	VaryByRemoteAddr *bool  `access:"environment,write_restrictable,cloud_restrictable"`
1588	VaryByUser       *bool  `access:"environment,write_restrictable,cloud_restrictable"`
1589	VaryByHeader     string `access:"environment,write_restrictable,cloud_restrictable"`
1590}
1591
1592func (s *RateLimitSettings) SetDefaults() {
1593	if s.Enable == nil {
1594		s.Enable = NewBool(false)
1595	}
1596
1597	if s.PerSec == nil {
1598		s.PerSec = NewInt(10)
1599	}
1600
1601	if s.MaxBurst == nil {
1602		s.MaxBurst = NewInt(100)
1603	}
1604
1605	if s.MemoryStoreSize == nil {
1606		s.MemoryStoreSize = NewInt(10000)
1607	}
1608
1609	if s.VaryByRemoteAddr == nil {
1610		s.VaryByRemoteAddr = NewBool(true)
1611	}
1612
1613	if s.VaryByUser == nil {
1614		s.VaryByUser = NewBool(false)
1615	}
1616}
1617
1618type PrivacySettings struct {
1619	ShowEmailAddress *bool `access:"site"`
1620	ShowFullName     *bool `access:"site"`
1621}
1622
1623func (s *PrivacySettings) setDefaults() {
1624	if s.ShowEmailAddress == nil {
1625		s.ShowEmailAddress = NewBool(true)
1626	}
1627
1628	if s.ShowFullName == nil {
1629		s.ShowFullName = NewBool(true)
1630	}
1631}
1632
1633type SupportSettings struct {
1634	TermsOfServiceLink                     *string `access:"site,write_restrictable,cloud_restrictable"`
1635	PrivacyPolicyLink                      *string `access:"site,write_restrictable,cloud_restrictable"`
1636	AboutLink                              *string `access:"site,write_restrictable,cloud_restrictable"`
1637	HelpLink                               *string `access:"site,write_restrictable,cloud_restrictable"`
1638	ReportAProblemLink                     *string `access:"site,write_restrictable,cloud_restrictable"`
1639	SupportEmail                           *string `access:"site"`
1640	CustomTermsOfServiceEnabled            *bool   `access:"compliance"`
1641	CustomTermsOfServiceReAcceptancePeriod *int    `access:"compliance"`
1642	EnableAskCommunityLink                 *bool   `access:"site"`
1643}
1644
1645func (s *SupportSettings) SetDefaults() {
1646	if !IsSafeLink(s.TermsOfServiceLink) {
1647		*s.TermsOfServiceLink = SUPPORT_SETTINGS_DEFAULT_TERMS_OF_SERVICE_LINK
1648	}
1649
1650	if s.TermsOfServiceLink == nil {
1651		s.TermsOfServiceLink = NewString(SUPPORT_SETTINGS_DEFAULT_TERMS_OF_SERVICE_LINK)
1652	}
1653
1654	if !IsSafeLink(s.PrivacyPolicyLink) {
1655		*s.PrivacyPolicyLink = ""
1656	}
1657
1658	if s.PrivacyPolicyLink == nil {
1659		s.PrivacyPolicyLink = NewString(SUPPORT_SETTINGS_DEFAULT_PRIVACY_POLICY_LINK)
1660	}
1661
1662	if !IsSafeLink(s.AboutLink) {
1663		*s.AboutLink = ""
1664	}
1665
1666	if s.AboutLink == nil {
1667		s.AboutLink = NewString(SUPPORT_SETTINGS_DEFAULT_ABOUT_LINK)
1668	}
1669
1670	if !IsSafeLink(s.HelpLink) {
1671		*s.HelpLink = ""
1672	}
1673
1674	if s.HelpLink == nil {
1675		s.HelpLink = NewString(SUPPORT_SETTINGS_DEFAULT_HELP_LINK)
1676	}
1677
1678	if !IsSafeLink(s.ReportAProblemLink) {
1679		*s.ReportAProblemLink = ""
1680	}
1681
1682	if s.ReportAProblemLink == nil {
1683		s.ReportAProblemLink = NewString(SUPPORT_SETTINGS_DEFAULT_REPORT_A_PROBLEM_LINK)
1684	}
1685
1686	if s.SupportEmail == nil {
1687		s.SupportEmail = NewString(SUPPORT_SETTINGS_DEFAULT_SUPPORT_EMAIL)
1688	}
1689
1690	if s.CustomTermsOfServiceEnabled == nil {
1691		s.CustomTermsOfServiceEnabled = NewBool(false)
1692	}
1693
1694	if s.CustomTermsOfServiceReAcceptancePeriod == nil {
1695		s.CustomTermsOfServiceReAcceptancePeriod = NewInt(SUPPORT_SETTINGS_DEFAULT_RE_ACCEPTANCE_PERIOD)
1696	}
1697
1698	if s.EnableAskCommunityLink == nil {
1699		s.EnableAskCommunityLink = NewBool(true)
1700	}
1701}
1702
1703type AnnouncementSettings struct {
1704	EnableBanner          *bool   `access:"site"`
1705	BannerText            *string `access:"site"`
1706	BannerColor           *string `access:"site"`
1707	BannerTextColor       *string `access:"site"`
1708	AllowBannerDismissal  *bool   `access:"site"`
1709	AdminNoticesEnabled   *bool   `access:"site"`
1710	UserNoticesEnabled    *bool   `access:"site"`
1711	NoticesURL            *string `access:"site,write_restrictable"`
1712	NoticesFetchFrequency *int    `access:"site,write_restrictable"`
1713	NoticesSkipCache      *bool   `access:"site,write_restrictable"`
1714}
1715
1716func (s *AnnouncementSettings) SetDefaults() {
1717	if s.EnableBanner == nil {
1718		s.EnableBanner = NewBool(false)
1719	}
1720
1721	if s.BannerText == nil {
1722		s.BannerText = NewString("")
1723	}
1724
1725	if s.BannerColor == nil {
1726		s.BannerColor = NewString(ANNOUNCEMENT_SETTINGS_DEFAULT_BANNER_COLOR)
1727	}
1728
1729	if s.BannerTextColor == nil {
1730		s.BannerTextColor = NewString(ANNOUNCEMENT_SETTINGS_DEFAULT_BANNER_TEXT_COLOR)
1731	}
1732
1733	if s.AllowBannerDismissal == nil {
1734		s.AllowBannerDismissal = NewBool(true)
1735	}
1736
1737	if s.AdminNoticesEnabled == nil {
1738		s.AdminNoticesEnabled = NewBool(true)
1739	}
1740
1741	if s.UserNoticesEnabled == nil {
1742		s.UserNoticesEnabled = NewBool(true)
1743	}
1744	if s.NoticesURL == nil {
1745		s.NoticesURL = NewString(ANNOUNCEMENT_SETTINGS_DEFAULT_NOTICES_JSON_URL)
1746	}
1747	if s.NoticesSkipCache == nil {
1748		s.NoticesSkipCache = NewBool(false)
1749	}
1750	if s.NoticesFetchFrequency == nil {
1751		s.NoticesFetchFrequency = NewInt(ANNOUNCEMENT_SETTINGS_DEFAULT_NOTICES_FETCH_FREQUENCY_SECONDS)
1752	}
1753
1754}
1755
1756type ThemeSettings struct {
1757	EnableThemeSelection *bool   `access:"experimental"`
1758	DefaultTheme         *string `access:"experimental"`
1759	AllowCustomThemes    *bool   `access:"experimental"`
1760	AllowedThemes        []string
1761}
1762
1763func (s *ThemeSettings) SetDefaults() {
1764	if s.EnableThemeSelection == nil {
1765		s.EnableThemeSelection = NewBool(true)
1766	}
1767
1768	if s.DefaultTheme == nil {
1769		s.DefaultTheme = NewString(TEAM_SETTINGS_DEFAULT_TEAM_TEXT)
1770	}
1771
1772	if s.AllowCustomThemes == nil {
1773		s.AllowCustomThemes = NewBool(true)
1774	}
1775
1776	if s.AllowedThemes == nil {
1777		s.AllowedThemes = []string{}
1778	}
1779}
1780
1781type TeamSettings struct {
1782	SiteName                                                  *string  `access:"site"`
1783	MaxUsersPerTeam                                           *int     `access:"site"`
1784	DEPRECATED_DO_NOT_USE_EnableTeamCreation                  *bool    `json:"EnableTeamCreation" mapstructure:"EnableTeamCreation"` // This field is deprecated and must not be used.
1785	EnableUserCreation                                        *bool    `access:"authentication"`
1786	EnableOpenServer                                          *bool    `access:"authentication"`
1787	EnableUserDeactivation                                    *bool    `access:"experimental"`
1788	RestrictCreationToDomains                                 *string  `access:"authentication"`
1789	EnableCustomBrand                                         *bool    `access:"site"`
1790	CustomBrandText                                           *string  `access:"site"`
1791	CustomDescriptionText                                     *string  `access:"site"`
1792	RestrictDirectMessage                                     *string  `access:"site"`
1793	DEPRECATED_DO_NOT_USE_RestrictTeamInvite                  *string  `json:"RestrictTeamInvite" mapstructure:"RestrictTeamInvite"`                                   // This field is deprecated and must not be used.
1794	DEPRECATED_DO_NOT_USE_RestrictPublicChannelManagement     *string  `json:"RestrictPublicChannelManagement" mapstructure:"RestrictPublicChannelManagement"`         // This field is deprecated and must not be used.
1795	DEPRECATED_DO_NOT_USE_RestrictPrivateChannelManagement    *string  `json:"RestrictPrivateChannelManagement" mapstructure:"RestrictPrivateChannelManagement"`       // This field is deprecated and must not be used.
1796	DEPRECATED_DO_NOT_USE_RestrictPublicChannelCreation       *string  `json:"RestrictPublicChannelCreation" mapstructure:"RestrictPublicChannelCreation"`             // This field is deprecated and must not be used.
1797	DEPRECATED_DO_NOT_USE_RestrictPrivateChannelCreation      *string  `json:"RestrictPrivateChannelCreation" mapstructure:"RestrictPrivateChannelCreation"`           // This field is deprecated and must not be used.
1798	DEPRECATED_DO_NOT_USE_RestrictPublicChannelDeletion       *string  `json:"RestrictPublicChannelDeletion" mapstructure:"RestrictPublicChannelDeletion"`             // This field is deprecated and must not be used.
1799	DEPRECATED_DO_NOT_USE_RestrictPrivateChannelDeletion      *string  `json:"RestrictPrivateChannelDeletion" mapstructure:"RestrictPrivateChannelDeletion"`           // This field is deprecated and must not be used.
1800	DEPRECATED_DO_NOT_USE_RestrictPrivateChannelManageMembers *string  `json:"RestrictPrivateChannelManageMembers" mapstructure:"RestrictPrivateChannelManageMembers"` // This field is deprecated and must not be used.
1801	EnableXToLeaveChannelsFromLHS                             *bool    `access:"experimental"`
1802	UserStatusAwayTimeout                                     *int64   `access:"experimental"`
1803	MaxChannelsPerTeam                                        *int64   `access:"site"`
1804	MaxNotificationsPerChannel                                *int64   `access:"environment"`
1805	EnableConfirmNotificationsToChannel                       *bool    `access:"site"`
1806	TeammateNameDisplay                                       *string  `access:"site"`
1807	ExperimentalViewArchivedChannels                          *bool    `access:"experimental,site"`
1808	ExperimentalEnableAutomaticReplies                        *bool    `access:"experimental"`
1809	ExperimentalHideTownSquareinLHS                           *bool    `access:"experimental"`
1810	ExperimentalTownSquareIsReadOnly                          *bool    `access:"experimental"`
1811	LockTeammateNameDisplay                                   *bool    `access:"site"`
1812	ExperimentalPrimaryTeam                                   *string  `access:"experimental"`
1813	ExperimentalDefaultChannels                               []string `access:"experimental"`
1814}
1815
1816func (s *TeamSettings) SetDefaults() {
1817
1818	if s.SiteName == nil || *s.SiteName == "" {
1819		s.SiteName = NewString(TEAM_SETTINGS_DEFAULT_SITE_NAME)
1820	}
1821
1822	if s.MaxUsersPerTeam == nil {
1823		s.MaxUsersPerTeam = NewInt(TEAM_SETTINGS_DEFAULT_MAX_USERS_PER_TEAM)
1824	}
1825
1826	if s.DEPRECATED_DO_NOT_USE_EnableTeamCreation == nil {
1827		s.DEPRECATED_DO_NOT_USE_EnableTeamCreation = NewBool(true)
1828	}
1829
1830	if s.EnableUserCreation == nil {
1831		s.EnableUserCreation = NewBool(true)
1832	}
1833
1834	if s.EnableOpenServer == nil {
1835		s.EnableOpenServer = NewBool(false)
1836	}
1837
1838	if s.RestrictCreationToDomains == nil {
1839		s.RestrictCreationToDomains = NewString("")
1840	}
1841
1842	if s.EnableCustomBrand == nil {
1843		s.EnableCustomBrand = NewBool(false)
1844	}
1845
1846	if s.EnableUserDeactivation == nil {
1847		s.EnableUserDeactivation = NewBool(false)
1848	}
1849
1850	if s.CustomBrandText == nil {
1851		s.CustomBrandText = NewString(TEAM_SETTINGS_DEFAULT_CUSTOM_BRAND_TEXT)
1852	}
1853
1854	if s.CustomDescriptionText == nil {
1855		s.CustomDescriptionText = NewString(TEAM_SETTINGS_DEFAULT_CUSTOM_DESCRIPTION_TEXT)
1856	}
1857
1858	if s.RestrictDirectMessage == nil {
1859		s.RestrictDirectMessage = NewString(DIRECT_MESSAGE_ANY)
1860	}
1861
1862	if s.DEPRECATED_DO_NOT_USE_RestrictTeamInvite == nil {
1863		s.DEPRECATED_DO_NOT_USE_RestrictTeamInvite = NewString(PERMISSIONS_ALL)
1864	}
1865
1866	if s.DEPRECATED_DO_NOT_USE_RestrictPublicChannelManagement == nil {
1867		s.DEPRECATED_DO_NOT_USE_RestrictPublicChannelManagement = NewString(PERMISSIONS_ALL)
1868	}
1869
1870	if s.DEPRECATED_DO_NOT_USE_RestrictPrivateChannelManagement == nil {
1871		s.DEPRECATED_DO_NOT_USE_RestrictPrivateChannelManagement = NewString(PERMISSIONS_ALL)
1872	}
1873
1874	if s.DEPRECATED_DO_NOT_USE_RestrictPublicChannelCreation == nil {
1875		s.DEPRECATED_DO_NOT_USE_RestrictPublicChannelCreation = new(string)
1876		// If this setting does not exist, assume migration from <3.6, so use management setting as default.
1877		if *s.DEPRECATED_DO_NOT_USE_RestrictPublicChannelManagement == PERMISSIONS_CHANNEL_ADMIN {
1878			*s.DEPRECATED_DO_NOT_USE_RestrictPublicChannelCreation = PERMISSIONS_TEAM_ADMIN
1879		} else {
1880			*s.DEPRECATED_DO_NOT_USE_RestrictPublicChannelCreation = *s.DEPRECATED_DO_NOT_USE_RestrictPublicChannelManagement
1881		}
1882	}
1883
1884	if s.DEPRECATED_DO_NOT_USE_RestrictPrivateChannelCreation == nil {
1885		// If this setting does not exist, assume migration from <3.6, so use management setting as default.
1886		if *s.DEPRECATED_DO_NOT_USE_RestrictPrivateChannelManagement == PERMISSIONS_CHANNEL_ADMIN {
1887			s.DEPRECATED_DO_NOT_USE_RestrictPrivateChannelCreation = NewString(PERMISSIONS_TEAM_ADMIN)
1888		} else {
1889			s.DEPRECATED_DO_NOT_USE_RestrictPrivateChannelCreation = NewString(*s.DEPRECATED_DO_NOT_USE_RestrictPrivateChannelManagement)
1890		}
1891	}
1892
1893	if s.DEPRECATED_DO_NOT_USE_RestrictPublicChannelDeletion == nil {
1894		// If this setting does not exist, assume migration from <3.6, so use management setting as default.
1895		s.DEPRECATED_DO_NOT_USE_RestrictPublicChannelDeletion = NewString(*s.DEPRECATED_DO_NOT_USE_RestrictPublicChannelManagement)
1896	}
1897
1898	if s.DEPRECATED_DO_NOT_USE_RestrictPrivateChannelDeletion == nil {
1899		// If this setting does not exist, assume migration from <3.6, so use management setting as default.
1900		s.DEPRECATED_DO_NOT_USE_RestrictPrivateChannelDeletion = NewString(*s.DEPRECATED_DO_NOT_USE_RestrictPrivateChannelManagement)
1901	}
1902
1903	if s.DEPRECATED_DO_NOT_USE_RestrictPrivateChannelManageMembers == nil {
1904		s.DEPRECATED_DO_NOT_USE_RestrictPrivateChannelManageMembers = NewString(PERMISSIONS_ALL)
1905	}
1906
1907	if s.EnableXToLeaveChannelsFromLHS == nil {
1908		s.EnableXToLeaveChannelsFromLHS = NewBool(false)
1909	}
1910
1911	if s.UserStatusAwayTimeout == nil {
1912		s.UserStatusAwayTimeout = NewInt64(TEAM_SETTINGS_DEFAULT_USER_STATUS_AWAY_TIMEOUT)
1913	}
1914
1915	if s.MaxChannelsPerTeam == nil {
1916		s.MaxChannelsPerTeam = NewInt64(2000)
1917	}
1918
1919	if s.MaxNotificationsPerChannel == nil {
1920		s.MaxNotificationsPerChannel = NewInt64(1000)
1921	}
1922
1923	if s.EnableConfirmNotificationsToChannel == nil {
1924		s.EnableConfirmNotificationsToChannel = NewBool(true)
1925	}
1926
1927	if s.ExperimentalEnableAutomaticReplies == nil {
1928		s.ExperimentalEnableAutomaticReplies = NewBool(false)
1929	}
1930
1931	if s.ExperimentalHideTownSquareinLHS == nil {
1932		s.ExperimentalHideTownSquareinLHS = NewBool(false)
1933	}
1934
1935	if s.ExperimentalTownSquareIsReadOnly == nil {
1936		s.ExperimentalTownSquareIsReadOnly = NewBool(false)
1937	}
1938
1939	if s.ExperimentalPrimaryTeam == nil {
1940		s.ExperimentalPrimaryTeam = NewString("")
1941	}
1942
1943	if s.ExperimentalDefaultChannels == nil {
1944		s.ExperimentalDefaultChannels = []string{}
1945	}
1946
1947	if s.DEPRECATED_DO_NOT_USE_EnableTeamCreation == nil {
1948		s.DEPRECATED_DO_NOT_USE_EnableTeamCreation = NewBool(true)
1949	}
1950
1951	if s.EnableUserCreation == nil {
1952		s.EnableUserCreation = NewBool(true)
1953	}
1954
1955	if s.ExperimentalViewArchivedChannels == nil {
1956		s.ExperimentalViewArchivedChannels = NewBool(true)
1957	}
1958
1959	if s.LockTeammateNameDisplay == nil {
1960		s.LockTeammateNameDisplay = NewBool(false)
1961	}
1962}
1963
1964type ClientRequirements struct {
1965	AndroidLatestVersion string `access:"write_restrictable,cloud_restrictable"`
1966	AndroidMinVersion    string `access:"write_restrictable,cloud_restrictable"`
1967	DesktopLatestVersion string `access:"write_restrictable,cloud_restrictable"`
1968	DesktopMinVersion    string `access:"write_restrictable,cloud_restrictable"`
1969	IosLatestVersion     string `access:"write_restrictable,cloud_restrictable"`
1970	IosMinVersion        string `access:"write_restrictable,cloud_restrictable"`
1971}
1972
1973type LdapSettings struct {
1974	// Basic
1975	Enable             *bool   `access:"authentication"`
1976	EnableSync         *bool   `access:"authentication"`
1977	LdapServer         *string `access:"authentication"`
1978	LdapPort           *int    `access:"authentication"`
1979	ConnectionSecurity *string `access:"authentication"`
1980	BaseDN             *string `access:"authentication"`
1981	BindUsername       *string `access:"authentication"`
1982	BindPassword       *string `access:"authentication"`
1983
1984	// Filtering
1985	UserFilter        *string `access:"authentication"`
1986	GroupFilter       *string `access:"authentication"`
1987	GuestFilter       *string `access:"authentication"`
1988	EnableAdminFilter *bool
1989	AdminFilter       *string
1990
1991	// Group Mapping
1992	GroupDisplayNameAttribute *string `access:"authentication"`
1993	GroupIdAttribute          *string `access:"authentication"`
1994
1995	// User Mapping
1996	FirstNameAttribute *string `access:"authentication"`
1997	LastNameAttribute  *string `access:"authentication"`
1998	EmailAttribute     *string `access:"authentication"`
1999	UsernameAttribute  *string `access:"authentication"`
2000	NicknameAttribute  *string `access:"authentication"`
2001	IdAttribute        *string `access:"authentication"`
2002	PositionAttribute  *string `access:"authentication"`
2003	LoginIdAttribute   *string `access:"authentication"`
2004	PictureAttribute   *string `access:"authentication"`
2005
2006	// Synchronization
2007	SyncIntervalMinutes *int `access:"authentication"`
2008
2009	// Advanced
2010	SkipCertificateVerification *bool   `access:"authentication"`
2011	PublicCertificateFile       *string `access:"authentication"`
2012	PrivateKeyFile              *string `access:"authentication"`
2013	QueryTimeout                *int    `access:"authentication"`
2014	MaxPageSize                 *int    `access:"authentication"`
2015
2016	// Customization
2017	LoginFieldName *string `access:"authentication"`
2018
2019	LoginButtonColor       *string `access:"authentication"`
2020	LoginButtonBorderColor *string `access:"authentication"`
2021	LoginButtonTextColor   *string `access:"authentication"`
2022
2023	Trace *bool `access:"authentication"`
2024}
2025
2026func (s *LdapSettings) SetDefaults() {
2027	if s.Enable == nil {
2028		s.Enable = NewBool(false)
2029	}
2030
2031	// When unset should default to LDAP Enabled
2032	if s.EnableSync == nil {
2033		s.EnableSync = NewBool(*s.Enable)
2034	}
2035
2036	if s.EnableAdminFilter == nil {
2037		s.EnableAdminFilter = NewBool(false)
2038	}
2039
2040	if s.LdapServer == nil {
2041		s.LdapServer = NewString("")
2042	}
2043
2044	if s.LdapPort == nil {
2045		s.LdapPort = NewInt(389)
2046	}
2047
2048	if s.ConnectionSecurity == nil {
2049		s.ConnectionSecurity = NewString("")
2050	}
2051
2052	if s.PublicCertificateFile == nil {
2053		s.PublicCertificateFile = NewString("")
2054	}
2055
2056	if s.PrivateKeyFile == nil {
2057		s.PrivateKeyFile = NewString("")
2058	}
2059
2060	if s.BaseDN == nil {
2061		s.BaseDN = NewString("")
2062	}
2063
2064	if s.BindUsername == nil {
2065		s.BindUsername = NewString("")
2066	}
2067
2068	if s.BindPassword == nil {
2069		s.BindPassword = NewString("")
2070	}
2071
2072	if s.UserFilter == nil {
2073		s.UserFilter = NewString("")
2074	}
2075
2076	if s.GuestFilter == nil {
2077		s.GuestFilter = NewString("")
2078	}
2079
2080	if s.AdminFilter == nil {
2081		s.AdminFilter = NewString("")
2082	}
2083
2084	if s.GroupFilter == nil {
2085		s.GroupFilter = NewString("")
2086	}
2087
2088	if s.GroupDisplayNameAttribute == nil {
2089		s.GroupDisplayNameAttribute = NewString(LDAP_SETTINGS_DEFAULT_GROUP_DISPLAY_NAME_ATTRIBUTE)
2090	}
2091
2092	if s.GroupIdAttribute == nil {
2093		s.GroupIdAttribute = NewString(LDAP_SETTINGS_DEFAULT_GROUP_ID_ATTRIBUTE)
2094	}
2095
2096	if s.FirstNameAttribute == nil {
2097		s.FirstNameAttribute = NewString(LDAP_SETTINGS_DEFAULT_FIRST_NAME_ATTRIBUTE)
2098	}
2099
2100	if s.LastNameAttribute == nil {
2101		s.LastNameAttribute = NewString(LDAP_SETTINGS_DEFAULT_LAST_NAME_ATTRIBUTE)
2102	}
2103
2104	if s.EmailAttribute == nil {
2105		s.EmailAttribute = NewString(LDAP_SETTINGS_DEFAULT_EMAIL_ATTRIBUTE)
2106	}
2107
2108	if s.UsernameAttribute == nil {
2109		s.UsernameAttribute = NewString(LDAP_SETTINGS_DEFAULT_USERNAME_ATTRIBUTE)
2110	}
2111
2112	if s.NicknameAttribute == nil {
2113		s.NicknameAttribute = NewString(LDAP_SETTINGS_DEFAULT_NICKNAME_ATTRIBUTE)
2114	}
2115
2116	if s.IdAttribute == nil {
2117		s.IdAttribute = NewString(LDAP_SETTINGS_DEFAULT_ID_ATTRIBUTE)
2118	}
2119
2120	if s.PositionAttribute == nil {
2121		s.PositionAttribute = NewString(LDAP_SETTINGS_DEFAULT_POSITION_ATTRIBUTE)
2122	}
2123
2124	if s.PictureAttribute == nil {
2125		s.PictureAttribute = NewString(LDAP_SETTINGS_DEFAULT_PICTURE_ATTRIBUTE)
2126	}
2127
2128	// For those upgrading to the version when LoginIdAttribute was added
2129	// they need IdAttribute == LoginIdAttribute not to break
2130	if s.LoginIdAttribute == nil {
2131		s.LoginIdAttribute = s.IdAttribute
2132	}
2133
2134	if s.SyncIntervalMinutes == nil {
2135		s.SyncIntervalMinutes = NewInt(60)
2136	}
2137
2138	if s.SkipCertificateVerification == nil {
2139		s.SkipCertificateVerification = NewBool(false)
2140	}
2141
2142	if s.QueryTimeout == nil {
2143		s.QueryTimeout = NewInt(60)
2144	}
2145
2146	if s.MaxPageSize == nil {
2147		s.MaxPageSize = NewInt(0)
2148	}
2149
2150	if s.LoginFieldName == nil {
2151		s.LoginFieldName = NewString(LDAP_SETTINGS_DEFAULT_LOGIN_FIELD_NAME)
2152	}
2153
2154	if s.LoginButtonColor == nil {
2155		s.LoginButtonColor = NewString("#0000")
2156	}
2157
2158	if s.LoginButtonBorderColor == nil {
2159		s.LoginButtonBorderColor = NewString("#2389D7")
2160	}
2161
2162	if s.LoginButtonTextColor == nil {
2163		s.LoginButtonTextColor = NewString("#2389D7")
2164	}
2165
2166	if s.Trace == nil {
2167		s.Trace = NewBool(false)
2168	}
2169}
2170
2171type ComplianceSettings struct {
2172	Enable      *bool   `access:"compliance"`
2173	Directory   *string `access:"compliance"`
2174	EnableDaily *bool   `access:"compliance"`
2175}
2176
2177func (s *ComplianceSettings) SetDefaults() {
2178	if s.Enable == nil {
2179		s.Enable = NewBool(false)
2180	}
2181
2182	if s.Directory == nil {
2183		s.Directory = NewString("./data/")
2184	}
2185
2186	if s.EnableDaily == nil {
2187		s.EnableDaily = NewBool(false)
2188	}
2189}
2190
2191type LocalizationSettings struct {
2192	DefaultServerLocale *string `access:"site"`
2193	DefaultClientLocale *string `access:"site"`
2194	AvailableLocales    *string `access:"site"`
2195}
2196
2197func (s *LocalizationSettings) SetDefaults() {
2198	if s.DefaultServerLocale == nil {
2199		s.DefaultServerLocale = NewString(DEFAULT_LOCALE)
2200	}
2201
2202	if s.DefaultClientLocale == nil {
2203		s.DefaultClientLocale = NewString(DEFAULT_LOCALE)
2204	}
2205
2206	if s.AvailableLocales == nil {
2207		s.AvailableLocales = NewString("")
2208	}
2209}
2210
2211type SamlSettings struct {
2212	// Basic
2213	Enable                        *bool `access:"authentication"`
2214	EnableSyncWithLdap            *bool `access:"authentication"`
2215	EnableSyncWithLdapIncludeAuth *bool `access:"authentication"`
2216	IgnoreGuestsLdapSync          *bool `access:"authentication"`
2217
2218	Verify      *bool `access:"authentication"`
2219	Encrypt     *bool `access:"authentication"`
2220	SignRequest *bool `access:"authentication"`
2221
2222	IdpUrl                      *string `access:"authentication"`
2223	IdpDescriptorUrl            *string `access:"authentication"`
2224	IdpMetadataUrl              *string `access:"authentication"`
2225	ServiceProviderIdentifier   *string `access:"authentication"`
2226	AssertionConsumerServiceURL *string `access:"authentication"`
2227
2228	SignatureAlgorithm *string `access:"authentication"`
2229	CanonicalAlgorithm *string `access:"authentication"`
2230
2231	ScopingIDPProviderId *string `access:"authentication"`
2232	ScopingIDPName       *string `access:"authentication"`
2233
2234	IdpCertificateFile    *string `access:"authentication"`
2235	PublicCertificateFile *string `access:"authentication"`
2236	PrivateKeyFile        *string `access:"authentication"`
2237
2238	// User Mapping
2239	IdAttribute          *string `access:"authentication"`
2240	GuestAttribute       *string `access:"authentication"`
2241	EnableAdminAttribute *bool
2242	AdminAttribute       *string
2243	FirstNameAttribute   *string `access:"authentication"`
2244	LastNameAttribute    *string `access:"authentication"`
2245	EmailAttribute       *string `access:"authentication"`
2246	UsernameAttribute    *string `access:"authentication"`
2247	NicknameAttribute    *string `access:"authentication"`
2248	LocaleAttribute      *string `access:"authentication"`
2249	PositionAttribute    *string `access:"authentication"`
2250
2251	LoginButtonText *string `access:"authentication"`
2252
2253	LoginButtonColor       *string `access:"authentication"`
2254	LoginButtonBorderColor *string `access:"authentication"`
2255	LoginButtonTextColor   *string `access:"authentication"`
2256}
2257
2258func (s *SamlSettings) SetDefaults() {
2259	if s.Enable == nil {
2260		s.Enable = NewBool(false)
2261	}
2262
2263	if s.EnableSyncWithLdap == nil {
2264		s.EnableSyncWithLdap = NewBool(false)
2265	}
2266
2267	if s.EnableSyncWithLdapIncludeAuth == nil {
2268		s.EnableSyncWithLdapIncludeAuth = NewBool(false)
2269	}
2270
2271	if s.IgnoreGuestsLdapSync == nil {
2272		s.IgnoreGuestsLdapSync = NewBool(false)
2273	}
2274
2275	if s.EnableAdminAttribute == nil {
2276		s.EnableAdminAttribute = NewBool(false)
2277	}
2278
2279	if s.Verify == nil {
2280		s.Verify = NewBool(true)
2281	}
2282
2283	if s.Encrypt == nil {
2284		s.Encrypt = NewBool(true)
2285	}
2286
2287	if s.SignRequest == nil {
2288		s.SignRequest = NewBool(false)
2289	}
2290
2291	if s.SignatureAlgorithm == nil {
2292		s.SignatureAlgorithm = NewString(SAML_SETTINGS_DEFAULT_SIGNATURE_ALGORITHM)
2293	}
2294
2295	if s.CanonicalAlgorithm == nil {
2296		s.CanonicalAlgorithm = NewString(SAML_SETTINGS_DEFAULT_CANONICAL_ALGORITHM)
2297	}
2298
2299	if s.IdpUrl == nil {
2300		s.IdpUrl = NewString("")
2301	}
2302
2303	if s.IdpDescriptorUrl == nil {
2304		s.IdpDescriptorUrl = NewString("")
2305	}
2306
2307	if s.ServiceProviderIdentifier == nil {
2308		if s.IdpDescriptorUrl != nil {
2309			s.ServiceProviderIdentifier = NewString(*s.IdpDescriptorUrl)
2310		} else {
2311			s.ServiceProviderIdentifier = NewString("")
2312		}
2313	}
2314
2315	if s.IdpMetadataUrl == nil {
2316		s.IdpMetadataUrl = NewString("")
2317	}
2318
2319	if s.IdpCertificateFile == nil {
2320		s.IdpCertificateFile = NewString("")
2321	}
2322
2323	if s.PublicCertificateFile == nil {
2324		s.PublicCertificateFile = NewString("")
2325	}
2326
2327	if s.PrivateKeyFile == nil {
2328		s.PrivateKeyFile = NewString("")
2329	}
2330
2331	if s.AssertionConsumerServiceURL == nil {
2332		s.AssertionConsumerServiceURL = NewString("")
2333	}
2334
2335	if s.ScopingIDPProviderId == nil {
2336		s.ScopingIDPProviderId = NewString("")
2337	}
2338
2339	if s.ScopingIDPName == nil {
2340		s.ScopingIDPName = NewString("")
2341	}
2342
2343	if s.LoginButtonText == nil || *s.LoginButtonText == "" {
2344		s.LoginButtonText = NewString(USER_AUTH_SERVICE_SAML_TEXT)
2345	}
2346
2347	if s.IdAttribute == nil {
2348		s.IdAttribute = NewString(SAML_SETTINGS_DEFAULT_ID_ATTRIBUTE)
2349	}
2350
2351	if s.GuestAttribute == nil {
2352		s.GuestAttribute = NewString(SAML_SETTINGS_DEFAULT_GUEST_ATTRIBUTE)
2353	}
2354	if s.AdminAttribute == nil {
2355		s.AdminAttribute = NewString(SAML_SETTINGS_DEFAULT_ADMIN_ATTRIBUTE)
2356	}
2357	if s.FirstNameAttribute == nil {
2358		s.FirstNameAttribute = NewString(SAML_SETTINGS_DEFAULT_FIRST_NAME_ATTRIBUTE)
2359	}
2360
2361	if s.LastNameAttribute == nil {
2362		s.LastNameAttribute = NewString(SAML_SETTINGS_DEFAULT_LAST_NAME_ATTRIBUTE)
2363	}
2364
2365	if s.EmailAttribute == nil {
2366		s.EmailAttribute = NewString(SAML_SETTINGS_DEFAULT_EMAIL_ATTRIBUTE)
2367	}
2368
2369	if s.UsernameAttribute == nil {
2370		s.UsernameAttribute = NewString(SAML_SETTINGS_DEFAULT_USERNAME_ATTRIBUTE)
2371	}
2372
2373	if s.NicknameAttribute == nil {
2374		s.NicknameAttribute = NewString(SAML_SETTINGS_DEFAULT_NICKNAME_ATTRIBUTE)
2375	}
2376
2377	if s.PositionAttribute == nil {
2378		s.PositionAttribute = NewString(SAML_SETTINGS_DEFAULT_POSITION_ATTRIBUTE)
2379	}
2380
2381	if s.LocaleAttribute == nil {
2382		s.LocaleAttribute = NewString(SAML_SETTINGS_DEFAULT_LOCALE_ATTRIBUTE)
2383	}
2384
2385	if s.LoginButtonColor == nil {
2386		s.LoginButtonColor = NewString("#34a28b")
2387	}
2388
2389	if s.LoginButtonBorderColor == nil {
2390		s.LoginButtonBorderColor = NewString("#2389D7")
2391	}
2392
2393	if s.LoginButtonTextColor == nil {
2394		s.LoginButtonTextColor = NewString("#ffffff")
2395	}
2396}
2397
2398type NativeAppSettings struct {
2399	AppDownloadLink        *string `access:"site,write_restrictable,cloud_restrictable"`
2400	AndroidAppDownloadLink *string `access:"site,write_restrictable,cloud_restrictable"`
2401	IosAppDownloadLink     *string `access:"site,write_restrictable,cloud_restrictable"`
2402}
2403
2404func (s *NativeAppSettings) SetDefaults() {
2405	if s.AppDownloadLink == nil {
2406		s.AppDownloadLink = NewString(NATIVEAPP_SETTINGS_DEFAULT_APP_DOWNLOAD_LINK)
2407	}
2408
2409	if s.AndroidAppDownloadLink == nil {
2410		s.AndroidAppDownloadLink = NewString(NATIVEAPP_SETTINGS_DEFAULT_ANDROID_APP_DOWNLOAD_LINK)
2411	}
2412
2413	if s.IosAppDownloadLink == nil {
2414		s.IosAppDownloadLink = NewString(NATIVEAPP_SETTINGS_DEFAULT_IOS_APP_DOWNLOAD_LINK)
2415	}
2416}
2417
2418type ElasticsearchSettings struct {
2419	ConnectionUrl                 *string `access:"environment,write_restrictable,cloud_restrictable"`
2420	Username                      *string `access:"environment,write_restrictable,cloud_restrictable"`
2421	Password                      *string `access:"environment,write_restrictable,cloud_restrictable"`
2422	EnableIndexing                *bool   `access:"environment,write_restrictable,cloud_restrictable"`
2423	EnableSearching               *bool   `access:"environment,write_restrictable,cloud_restrictable"`
2424	EnableAutocomplete            *bool   `access:"environment,write_restrictable,cloud_restrictable"`
2425	Sniff                         *bool   `access:"environment,write_restrictable,cloud_restrictable"`
2426	PostIndexReplicas             *int    `access:"environment,write_restrictable,cloud_restrictable"`
2427	PostIndexShards               *int    `access:"environment,write_restrictable,cloud_restrictable"`
2428	ChannelIndexReplicas          *int    `access:"environment,write_restrictable,cloud_restrictable"`
2429	ChannelIndexShards            *int    `access:"environment,write_restrictable,cloud_restrictable"`
2430	UserIndexReplicas             *int    `access:"environment,write_restrictable,cloud_restrictable"`
2431	UserIndexShards               *int    `access:"environment,write_restrictable,cloud_restrictable"`
2432	AggregatePostsAfterDays       *int    `access:"environment,write_restrictable,cloud_restrictable"`
2433	PostsAggregatorJobStartTime   *string `access:"environment,write_restrictable,cloud_restrictable"`
2434	IndexPrefix                   *string `access:"environment,write_restrictable,cloud_restrictable"`
2435	LiveIndexingBatchSize         *int    `access:"environment,write_restrictable,cloud_restrictable"`
2436	BulkIndexingTimeWindowSeconds *int    `access:"environment,write_restrictable,cloud_restrictable"`
2437	RequestTimeoutSeconds         *int    `access:"environment,write_restrictable,cloud_restrictable"`
2438	SkipTLSVerification           *bool   `access:"environment,write_restrictable,cloud_restrictable"`
2439	Trace                         *string `access:"environment,write_restrictable,cloud_restrictable"`
2440}
2441
2442func (s *ElasticsearchSettings) SetDefaults() {
2443	if s.ConnectionUrl == nil {
2444		s.ConnectionUrl = NewString(ELASTICSEARCH_SETTINGS_DEFAULT_CONNECTION_URL)
2445	}
2446
2447	if s.Username == nil {
2448		s.Username = NewString(ELASTICSEARCH_SETTINGS_DEFAULT_USERNAME)
2449	}
2450
2451	if s.Password == nil {
2452		s.Password = NewString(ELASTICSEARCH_SETTINGS_DEFAULT_PASSWORD)
2453	}
2454
2455	if s.EnableIndexing == nil {
2456		s.EnableIndexing = NewBool(false)
2457	}
2458
2459	if s.EnableSearching == nil {
2460		s.EnableSearching = NewBool(false)
2461	}
2462
2463	if s.EnableAutocomplete == nil {
2464		s.EnableAutocomplete = NewBool(false)
2465	}
2466
2467	if s.Sniff == nil {
2468		s.Sniff = NewBool(true)
2469	}
2470
2471	if s.PostIndexReplicas == nil {
2472		s.PostIndexReplicas = NewInt(ELASTICSEARCH_SETTINGS_DEFAULT_POST_INDEX_REPLICAS)
2473	}
2474
2475	if s.PostIndexShards == nil {
2476		s.PostIndexShards = NewInt(ELASTICSEARCH_SETTINGS_DEFAULT_POST_INDEX_SHARDS)
2477	}
2478
2479	if s.ChannelIndexReplicas == nil {
2480		s.ChannelIndexReplicas = NewInt(ELASTICSEARCH_SETTINGS_DEFAULT_CHANNEL_INDEX_REPLICAS)
2481	}
2482
2483	if s.ChannelIndexShards == nil {
2484		s.ChannelIndexShards = NewInt(ELASTICSEARCH_SETTINGS_DEFAULT_CHANNEL_INDEX_SHARDS)
2485	}
2486
2487	if s.UserIndexReplicas == nil {
2488		s.UserIndexReplicas = NewInt(ELASTICSEARCH_SETTINGS_DEFAULT_USER_INDEX_REPLICAS)
2489	}
2490
2491	if s.UserIndexShards == nil {
2492		s.UserIndexShards = NewInt(ELASTICSEARCH_SETTINGS_DEFAULT_USER_INDEX_SHARDS)
2493	}
2494
2495	if s.AggregatePostsAfterDays == nil {
2496		s.AggregatePostsAfterDays = NewInt(ELASTICSEARCH_SETTINGS_DEFAULT_AGGREGATE_POSTS_AFTER_DAYS)
2497	}
2498
2499	if s.PostsAggregatorJobStartTime == nil {
2500		s.PostsAggregatorJobStartTime = NewString(ELASTICSEARCH_SETTINGS_DEFAULT_POSTS_AGGREGATOR_JOB_START_TIME)
2501	}
2502
2503	if s.IndexPrefix == nil {
2504		s.IndexPrefix = NewString(ELASTICSEARCH_SETTINGS_DEFAULT_INDEX_PREFIX)
2505	}
2506
2507	if s.LiveIndexingBatchSize == nil {
2508		s.LiveIndexingBatchSize = NewInt(ELASTICSEARCH_SETTINGS_DEFAULT_LIVE_INDEXING_BATCH_SIZE)
2509	}
2510
2511	if s.BulkIndexingTimeWindowSeconds == nil {
2512		s.BulkIndexingTimeWindowSeconds = NewInt(ELASTICSEARCH_SETTINGS_DEFAULT_BULK_INDEXING_TIME_WINDOW_SECONDS)
2513	}
2514
2515	if s.RequestTimeoutSeconds == nil {
2516		s.RequestTimeoutSeconds = NewInt(ELASTICSEARCH_SETTINGS_DEFAULT_REQUEST_TIMEOUT_SECONDS)
2517	}
2518
2519	if s.SkipTLSVerification == nil {
2520		s.SkipTLSVerification = NewBool(false)
2521	}
2522
2523	if s.Trace == nil {
2524		s.Trace = NewString("")
2525	}
2526}
2527
2528type BleveSettings struct {
2529	IndexDir                      *string `access:"experimental"`
2530	EnableIndexing                *bool   `access:"experimental"`
2531	EnableSearching               *bool   `access:"experimental"`
2532	EnableAutocomplete            *bool   `access:"experimental"`
2533	BulkIndexingTimeWindowSeconds *int    `access:"experimental"`
2534}
2535
2536func (bs *BleveSettings) SetDefaults() {
2537	if bs.IndexDir == nil {
2538		bs.IndexDir = NewString(BLEVE_SETTINGS_DEFAULT_INDEX_DIR)
2539	}
2540
2541	if bs.EnableIndexing == nil {
2542		bs.EnableIndexing = NewBool(false)
2543	}
2544
2545	if bs.EnableSearching == nil {
2546		bs.EnableSearching = NewBool(false)
2547	}
2548
2549	if bs.EnableAutocomplete == nil {
2550		bs.EnableAutocomplete = NewBool(false)
2551	}
2552
2553	if bs.BulkIndexingTimeWindowSeconds == nil {
2554		bs.BulkIndexingTimeWindowSeconds = NewInt(BLEVE_SETTINGS_DEFAULT_BULK_INDEXING_TIME_WINDOW_SECONDS)
2555	}
2556}
2557
2558type DataRetentionSettings struct {
2559	EnableMessageDeletion *bool   `access:"compliance"`
2560	EnableFileDeletion    *bool   `access:"compliance"`
2561	MessageRetentionDays  *int    `access:"compliance"`
2562	FileRetentionDays     *int    `access:"compliance"`
2563	DeletionJobStartTime  *string `access:"compliance"`
2564}
2565
2566func (s *DataRetentionSettings) SetDefaults() {
2567	if s.EnableMessageDeletion == nil {
2568		s.EnableMessageDeletion = NewBool(false)
2569	}
2570
2571	if s.EnableFileDeletion == nil {
2572		s.EnableFileDeletion = NewBool(false)
2573	}
2574
2575	if s.MessageRetentionDays == nil {
2576		s.MessageRetentionDays = NewInt(DATA_RETENTION_SETTINGS_DEFAULT_MESSAGE_RETENTION_DAYS)
2577	}
2578
2579	if s.FileRetentionDays == nil {
2580		s.FileRetentionDays = NewInt(DATA_RETENTION_SETTINGS_DEFAULT_FILE_RETENTION_DAYS)
2581	}
2582
2583	if s.DeletionJobStartTime == nil {
2584		s.DeletionJobStartTime = NewString(DATA_RETENTION_SETTINGS_DEFAULT_DELETION_JOB_START_TIME)
2585	}
2586}
2587
2588type JobSettings struct {
2589	RunJobs      *bool `access:"write_restrictable,cloud_restrictable"`
2590	RunScheduler *bool `access:"write_restrictable,cloud_restrictable"`
2591}
2592
2593func (s *JobSettings) SetDefaults() {
2594	if s.RunJobs == nil {
2595		s.RunJobs = NewBool(true)
2596	}
2597
2598	if s.RunScheduler == nil {
2599		s.RunScheduler = NewBool(true)
2600	}
2601}
2602
2603type CloudSettings struct {
2604	CWSUrl *string `access:"environment,write_restrictable"`
2605}
2606
2607func (s *CloudSettings) SetDefaults() {
2608	if s.CWSUrl == nil {
2609		s.CWSUrl = NewString(CLOUD_SETTINGS_DEFAULT_CWS_URL)
2610	}
2611}
2612
2613type PluginState struct {
2614	Enable bool
2615}
2616
2617type PluginSettings struct {
2618	Enable                      *bool                             `access:"plugins,write_restrictable"`
2619	EnableUploads               *bool                             `access:"plugins,write_restrictable,cloud_restrictable"`
2620	AllowInsecureDownloadUrl    *bool                             `access:"plugins,write_restrictable,cloud_restrictable"`
2621	EnableHealthCheck           *bool                             `access:"plugins,write_restrictable,cloud_restrictable"`
2622	Directory                   *string                           `access:"plugins,write_restrictable,cloud_restrictable"`
2623	ClientDirectory             *string                           `access:"plugins,write_restrictable,cloud_restrictable"`
2624	Plugins                     map[string]map[string]interface{} `access:"plugins"`
2625	PluginStates                map[string]*PluginState           `access:"plugins"`
2626	EnableMarketplace           *bool                             `access:"plugins,write_restrictable,cloud_restrictable"`
2627	EnableRemoteMarketplace     *bool                             `access:"plugins,write_restrictable,cloud_restrictable"`
2628	AutomaticPrepackagedPlugins *bool                             `access:"plugins,write_restrictable,cloud_restrictable"`
2629	RequirePluginSignature      *bool                             `access:"plugins,write_restrictable,cloud_restrictable"`
2630	MarketplaceUrl              *string                           `access:"plugins,write_restrictable,cloud_restrictable"`
2631	SignaturePublicKeyFiles     []string                          `access:"plugins,write_restrictable,cloud_restrictable"`
2632}
2633
2634func (s *PluginSettings) SetDefaults(ls LogSettings) {
2635	if s.Enable == nil {
2636		s.Enable = NewBool(true)
2637	}
2638
2639	if s.EnableUploads == nil {
2640		s.EnableUploads = NewBool(false)
2641	}
2642
2643	if s.AllowInsecureDownloadUrl == nil {
2644		s.AllowInsecureDownloadUrl = NewBool(false)
2645	}
2646
2647	if s.EnableHealthCheck == nil {
2648		s.EnableHealthCheck = NewBool(true)
2649	}
2650
2651	if s.Directory == nil || *s.Directory == "" {
2652		s.Directory = NewString(PLUGIN_SETTINGS_DEFAULT_DIRECTORY)
2653	}
2654
2655	if s.ClientDirectory == nil || *s.ClientDirectory == "" {
2656		s.ClientDirectory = NewString(PLUGIN_SETTINGS_DEFAULT_CLIENT_DIRECTORY)
2657	}
2658
2659	if s.Plugins == nil {
2660		s.Plugins = make(map[string]map[string]interface{})
2661	}
2662
2663	if s.PluginStates == nil {
2664		s.PluginStates = make(map[string]*PluginState)
2665	}
2666
2667	if s.PluginStates["com.mattermost.nps"] == nil {
2668		// Enable the NPS plugin by default if diagnostics are enabled
2669		s.PluginStates["com.mattermost.nps"] = &PluginState{Enable: ls.EnableDiagnostics == nil || *ls.EnableDiagnostics}
2670	}
2671
2672	if s.PluginStates["com.mattermost.plugin-incident-management"] == nil && BuildEnterpriseReady == "true" {
2673		// Enable the incident management plugin by default
2674		s.PluginStates["com.mattermost.plugin-incident-management"] = &PluginState{Enable: true}
2675	}
2676
2677	if s.PluginStates["com.mattermost.plugin-channel-export"] == nil && BuildEnterpriseReady == "true" {
2678		// Enable the channel export plugin by default
2679		s.PluginStates["com.mattermost.plugin-channel-export"] = &PluginState{Enable: true}
2680	}
2681
2682	if s.EnableMarketplace == nil {
2683		s.EnableMarketplace = NewBool(PLUGIN_SETTINGS_DEFAULT_ENABLE_MARKETPLACE)
2684	}
2685
2686	if s.EnableRemoteMarketplace == nil {
2687		s.EnableRemoteMarketplace = NewBool(true)
2688	}
2689
2690	if s.AutomaticPrepackagedPlugins == nil {
2691		s.AutomaticPrepackagedPlugins = NewBool(true)
2692	}
2693
2694	if s.MarketplaceUrl == nil || *s.MarketplaceUrl == "" || *s.MarketplaceUrl == PLUGIN_SETTINGS_OLD_MARKETPLACE_URL {
2695		s.MarketplaceUrl = NewString(PLUGIN_SETTINGS_DEFAULT_MARKETPLACE_URL)
2696	}
2697
2698	if s.RequirePluginSignature == nil {
2699		s.RequirePluginSignature = NewBool(false)
2700	}
2701
2702	if s.SignaturePublicKeyFiles == nil {
2703		s.SignaturePublicKeyFiles = []string{}
2704	}
2705}
2706
2707type GlobalRelayMessageExportSettings struct {
2708	CustomerType      *string `access:"compliance"` // must be either A9 or A10, dictates SMTP server url
2709	SmtpUsername      *string `access:"compliance"`
2710	SmtpPassword      *string `access:"compliance"`
2711	EmailAddress      *string `access:"compliance"` // the address to send messages to
2712	SMTPServerTimeout *int    `access:"compliance"`
2713}
2714
2715func (s *GlobalRelayMessageExportSettings) SetDefaults() {
2716	if s.CustomerType == nil {
2717		s.CustomerType = NewString(GLOBALRELAY_CUSTOMER_TYPE_A9)
2718	}
2719	if s.SmtpUsername == nil {
2720		s.SmtpUsername = NewString("")
2721	}
2722	if s.SmtpPassword == nil {
2723		s.SmtpPassword = NewString("")
2724	}
2725	if s.EmailAddress == nil {
2726		s.EmailAddress = NewString("")
2727	}
2728	if s.SMTPServerTimeout == nil || *s.SMTPServerTimeout == 0 {
2729		s.SMTPServerTimeout = NewInt(1800)
2730	}
2731}
2732
2733type MessageExportSettings struct {
2734	EnableExport          *bool   `access:"compliance"`
2735	ExportFormat          *string `access:"compliance"`
2736	DailyRunTime          *string `access:"compliance"`
2737	ExportFromTimestamp   *int64  `access:"compliance"`
2738	BatchSize             *int    `access:"compliance"`
2739	DownloadExportResults *bool   `access:"compliance"`
2740
2741	// formatter-specific settings - these are only expected to be non-nil if ExportFormat is set to the associated format
2742	GlobalRelaySettings *GlobalRelayMessageExportSettings
2743}
2744
2745func (s *MessageExportSettings) SetDefaults() {
2746	if s.EnableExport == nil {
2747		s.EnableExport = NewBool(false)
2748	}
2749
2750	if s.DownloadExportResults == nil {
2751		s.DownloadExportResults = NewBool(false)
2752	}
2753
2754	if s.ExportFormat == nil {
2755		s.ExportFormat = NewString(COMPLIANCE_EXPORT_TYPE_ACTIANCE)
2756	}
2757
2758	if s.DailyRunTime == nil {
2759		s.DailyRunTime = NewString("01:00")
2760	}
2761
2762	if s.ExportFromTimestamp == nil {
2763		s.ExportFromTimestamp = NewInt64(0)
2764	}
2765
2766	if s.BatchSize == nil {
2767		s.BatchSize = NewInt(10000)
2768	}
2769
2770	if s.GlobalRelaySettings == nil {
2771		s.GlobalRelaySettings = &GlobalRelayMessageExportSettings{}
2772	}
2773	s.GlobalRelaySettings.SetDefaults()
2774}
2775
2776type DisplaySettings struct {
2777	CustomUrlSchemes     []string `access:"site"`
2778	ExperimentalTimezone *bool    `access:"experimental"`
2779}
2780
2781func (s *DisplaySettings) SetDefaults() {
2782	if s.CustomUrlSchemes == nil {
2783		customUrlSchemes := []string{}
2784		s.CustomUrlSchemes = customUrlSchemes
2785	}
2786
2787	if s.ExperimentalTimezone == nil {
2788		s.ExperimentalTimezone = NewBool(true)
2789	}
2790}
2791
2792type GuestAccountsSettings struct {
2793	Enable                           *bool   `access:"authentication"`
2794	AllowEmailAccounts               *bool   `access:"authentication"`
2795	EnforceMultifactorAuthentication *bool   `access:"authentication"`
2796	RestrictCreationToDomains        *string `access:"authentication"`
2797}
2798
2799func (s *GuestAccountsSettings) SetDefaults() {
2800	if s.Enable == nil {
2801		s.Enable = NewBool(false)
2802	}
2803
2804	if s.AllowEmailAccounts == nil {
2805		s.AllowEmailAccounts = NewBool(true)
2806	}
2807
2808	if s.EnforceMultifactorAuthentication == nil {
2809		s.EnforceMultifactorAuthentication = NewBool(false)
2810	}
2811
2812	if s.RestrictCreationToDomains == nil {
2813		s.RestrictCreationToDomains = NewString("")
2814	}
2815}
2816
2817type ImageProxySettings struct {
2818	Enable                  *bool   `access:"environment"`
2819	ImageProxyType          *string `access:"environment"`
2820	RemoteImageProxyURL     *string `access:"environment"`
2821	RemoteImageProxyOptions *string `access:"environment"`
2822}
2823
2824func (s *ImageProxySettings) SetDefaults(ss ServiceSettings) {
2825	if s.Enable == nil {
2826		if ss.DEPRECATED_DO_NOT_USE_ImageProxyType == nil || *ss.DEPRECATED_DO_NOT_USE_ImageProxyType == "" {
2827			s.Enable = NewBool(false)
2828		} else {
2829			s.Enable = NewBool(true)
2830		}
2831	}
2832
2833	if s.ImageProxyType == nil {
2834		if ss.DEPRECATED_DO_NOT_USE_ImageProxyType == nil || *ss.DEPRECATED_DO_NOT_USE_ImageProxyType == "" {
2835			s.ImageProxyType = NewString(IMAGE_PROXY_TYPE_LOCAL)
2836		} else {
2837			s.ImageProxyType = ss.DEPRECATED_DO_NOT_USE_ImageProxyType
2838		}
2839	}
2840
2841	if s.RemoteImageProxyURL == nil {
2842		if ss.DEPRECATED_DO_NOT_USE_ImageProxyURL == nil {
2843			s.RemoteImageProxyURL = NewString("")
2844		} else {
2845			s.RemoteImageProxyURL = ss.DEPRECATED_DO_NOT_USE_ImageProxyURL
2846		}
2847	}
2848
2849	if s.RemoteImageProxyOptions == nil {
2850		if ss.DEPRECATED_DO_NOT_USE_ImageProxyOptions == nil {
2851			s.RemoteImageProxyOptions = NewString("")
2852		} else {
2853			s.RemoteImageProxyOptions = ss.DEPRECATED_DO_NOT_USE_ImageProxyOptions
2854		}
2855	}
2856}
2857
2858type ConfigFunc func() *Config
2859
2860const ConfigAccessTagType = "access"
2861const ConfigAccessTagWriteRestrictable = "write_restrictable"
2862const ConfigAccessTagCloudRestrictable = "cloud_restrictable"
2863
2864// Config fields support the 'access' tag with the following values corresponding to the suffix of the associated
2865// PERMISSION_SYSCONSOLE_*_* permission Id: 'about', 'reporting', 'user_management_users',
2866// 'user_management_groups', 'user_management_teams', 'user_management_channels',
2867// 'user_management_permissions', 'environment', 'site', 'authentication', 'plugins',
2868// 'integrations', 'compliance', 'plugins', and 'experimental'. They grant read and/or write access to the config field
2869// to roles without PERMISSION_MANAGE_SYSTEM.
2870//
2871// By default config values can be written with PERMISSION_MANAGE_SYSTEM, but if ExperimentalSettings.RestrictSystemAdmin is true
2872// and the access tag contains the value 'write_restrictable', then even PERMISSION_MANAGE_SYSTEM does not grant write access.
2873//
2874// PERMISSION_MANAGE_SYSTEM always grants read access.
2875//
2876// Config values with the access tag 'cloud_restrictable' mean that are marked to be filtered when it's used in a cloud licensed
2877// environment with ExperimentalSettings.RestrictedSystemAdmin set to true.
2878//
2879// Example:
2880//  type HairSettings struct {
2881//      // Colour is writeable with either PERMISSION_SYSCONSOLE_WRITE_REPORTING or PERMISSION_SYSCONSOLE_WRITE_USER_MANAGEMENT_GROUPS.
2882//      // It is readable by PERMISSION_SYSCONSOLE_READ_REPORTING and PERMISSION_SYSCONSOLE_READ_USER_MANAGEMENT_GROUPS permissions.
2883//      // PERMISSION_MANAGE_SYSTEM grants read and write access.
2884//      Colour string `access:"reporting,user_management_groups"`
2885//
2886//
2887//      // Length is only readable and writable via PERMISSION_MANAGE_SYSTEM.
2888//      Length string
2889//
2890//      // Product is only writeable by PERMISSION_MANAGE_SYSTEM if ExperimentalSettings.RestrictSystemAdmin is false.
2891//      // PERMISSION_MANAGE_SYSTEM can always read the value.
2892//      Product bool `access:write_restrictable`
2893//  }
2894type Config struct {
2895	ServiceSettings           ServiceSettings
2896	TeamSettings              TeamSettings
2897	ClientRequirements        ClientRequirements
2898	SqlSettings               SqlSettings
2899	LogSettings               LogSettings
2900	ExperimentalAuditSettings ExperimentalAuditSettings
2901	NotificationLogSettings   NotificationLogSettings
2902	PasswordSettings          PasswordSettings
2903	FileSettings              FileSettings
2904	EmailSettings             EmailSettings
2905	RateLimitSettings         RateLimitSettings
2906	PrivacySettings           PrivacySettings
2907	SupportSettings           SupportSettings
2908	AnnouncementSettings      AnnouncementSettings
2909	ThemeSettings             ThemeSettings
2910	GitLabSettings            SSOSettings
2911	GoogleSettings            SSOSettings
2912	Office365Settings         Office365Settings
2913	LdapSettings              LdapSettings
2914	ComplianceSettings        ComplianceSettings
2915	LocalizationSettings      LocalizationSettings
2916	SamlSettings              SamlSettings
2917	NativeAppSettings         NativeAppSettings
2918	ClusterSettings           ClusterSettings
2919	MetricsSettings           MetricsSettings
2920	ExperimentalSettings      ExperimentalSettings
2921	AnalyticsSettings         AnalyticsSettings
2922	ElasticsearchSettings     ElasticsearchSettings
2923	BleveSettings             BleveSettings
2924	DataRetentionSettings     DataRetentionSettings
2925	MessageExportSettings     MessageExportSettings
2926	JobSettings               JobSettings
2927	PluginSettings            PluginSettings
2928	DisplaySettings           DisplaySettings
2929	GuestAccountsSettings     GuestAccountsSettings
2930	ImageProxySettings        ImageProxySettings
2931	CloudSettings             CloudSettings
2932	FeatureFlags              *FeatureFlags `json:",omitempty"`
2933}
2934
2935func (o *Config) Clone() *Config {
2936	var ret Config
2937	if err := json.Unmarshal([]byte(o.ToJson()), &ret); err != nil {
2938		panic(err)
2939	}
2940	return &ret
2941}
2942
2943func (o *Config) ToJson() string {
2944	b, _ := json.Marshal(o)
2945	return string(b)
2946}
2947
2948func (o *Config) ToJsonFiltered(tagType, tagValue string) string {
2949	filteredConfigMap := structToMapFilteredByTag(*o, tagType, tagValue)
2950	for key, value := range filteredConfigMap {
2951		v, ok := value.(map[string]interface{})
2952		if ok && len(v) == 0 {
2953			delete(filteredConfigMap, key)
2954		}
2955	}
2956	b, _ := json.Marshal(filteredConfigMap)
2957	return string(b)
2958}
2959
2960func (o *Config) GetSSOService(service string) *SSOSettings {
2961	switch service {
2962	case SERVICE_GITLAB:
2963		return &o.GitLabSettings
2964	case SERVICE_GOOGLE:
2965		return &o.GoogleSettings
2966	case SERVICE_OFFICE365:
2967		return o.Office365Settings.SSOSettings()
2968	}
2969
2970	return nil
2971}
2972
2973func ConfigFromJson(data io.Reader) *Config {
2974	var o *Config
2975	json.NewDecoder(data).Decode(&o)
2976	return o
2977}
2978
2979// isUpdate detects a pre-existing config based on whether SiteURL has been changed
2980func (o *Config) isUpdate() bool {
2981	return o.ServiceSettings.SiteURL != nil
2982}
2983
2984func (o *Config) SetDefaults() {
2985	isUpdate := o.isUpdate()
2986
2987	o.LdapSettings.SetDefaults()
2988	o.SamlSettings.SetDefaults()
2989
2990	if o.TeamSettings.TeammateNameDisplay == nil {
2991		o.TeamSettings.TeammateNameDisplay = NewString(SHOW_USERNAME)
2992
2993		if *o.SamlSettings.Enable || *o.LdapSettings.Enable {
2994			*o.TeamSettings.TeammateNameDisplay = SHOW_FULLNAME
2995		}
2996	}
2997
2998	o.SqlSettings.SetDefaults(isUpdate)
2999	o.FileSettings.SetDefaults(isUpdate)
3000	o.EmailSettings.SetDefaults(isUpdate)
3001	o.PrivacySettings.setDefaults()
3002	o.Office365Settings.setDefaults()
3003	o.GitLabSettings.setDefaults("", "", "", "")
3004	o.GoogleSettings.setDefaults(GOOGLE_SETTINGS_DEFAULT_SCOPE, GOOGLE_SETTINGS_DEFAULT_AUTH_ENDPOINT, GOOGLE_SETTINGS_DEFAULT_TOKEN_ENDPOINT, GOOGLE_SETTINGS_DEFAULT_USER_API_ENDPOINT)
3005	o.ServiceSettings.SetDefaults(isUpdate)
3006	o.PasswordSettings.SetDefaults()
3007	o.TeamSettings.SetDefaults()
3008	o.MetricsSettings.SetDefaults()
3009	o.ExperimentalSettings.SetDefaults()
3010	o.SupportSettings.SetDefaults()
3011	o.AnnouncementSettings.SetDefaults()
3012	o.ThemeSettings.SetDefaults()
3013	o.ClusterSettings.SetDefaults()
3014	o.PluginSettings.SetDefaults(o.LogSettings)
3015	o.AnalyticsSettings.SetDefaults()
3016	o.ComplianceSettings.SetDefaults()
3017	o.LocalizationSettings.SetDefaults()
3018	o.ElasticsearchSettings.SetDefaults()
3019	o.BleveSettings.SetDefaults()
3020	o.NativeAppSettings.SetDefaults()
3021	o.DataRetentionSettings.SetDefaults()
3022	o.RateLimitSettings.SetDefaults()
3023	o.LogSettings.SetDefaults()
3024	o.ExperimentalAuditSettings.SetDefaults()
3025	o.NotificationLogSettings.SetDefaults()
3026	o.JobSettings.SetDefaults()
3027	o.MessageExportSettings.SetDefaults()
3028	o.DisplaySettings.SetDefaults()
3029	o.GuestAccountsSettings.SetDefaults()
3030	o.ImageProxySettings.SetDefaults(o.ServiceSettings)
3031	o.CloudSettings.SetDefaults()
3032	if o.FeatureFlags == nil {
3033		o.FeatureFlags = &FeatureFlags{}
3034		o.FeatureFlags.SetDefaults()
3035	}
3036}
3037
3038func (o *Config) IsValid() *AppError {
3039	if len(*o.ServiceSettings.SiteURL) == 0 && *o.EmailSettings.EnableEmailBatching {
3040		return NewAppError("Config.IsValid", "model.config.is_valid.site_url_email_batching.app_error", nil, "", http.StatusBadRequest)
3041	}
3042
3043	if *o.ClusterSettings.Enable && *o.EmailSettings.EnableEmailBatching {
3044		return NewAppError("Config.IsValid", "model.config.is_valid.cluster_email_batching.app_error", nil, "", http.StatusBadRequest)
3045	}
3046
3047	if len(*o.ServiceSettings.SiteURL) == 0 && *o.ServiceSettings.AllowCookiesForSubdomains {
3048		return NewAppError("Config.IsValid", "model.config.is_valid.allow_cookies_for_subdomains.app_error", nil, "", http.StatusBadRequest)
3049	}
3050
3051	if err := o.TeamSettings.isValid(); err != nil {
3052		return err
3053	}
3054
3055	if err := o.SqlSettings.isValid(); err != nil {
3056		return err
3057	}
3058
3059	if err := o.FileSettings.isValid(); err != nil {
3060		return err
3061	}
3062
3063	if err := o.EmailSettings.isValid(); err != nil {
3064		return err
3065	}
3066
3067	if err := o.LdapSettings.isValid(); err != nil {
3068		return err
3069	}
3070
3071	if err := o.SamlSettings.isValid(); err != nil {
3072		return err
3073	}
3074
3075	if *o.PasswordSettings.MinimumLength < PASSWORD_MINIMUM_LENGTH || *o.PasswordSettings.MinimumLength > PASSWORD_MAXIMUM_LENGTH {
3076		return NewAppError("Config.IsValid", "model.config.is_valid.password_length.app_error", map[string]interface{}{"MinLength": PASSWORD_MINIMUM_LENGTH, "MaxLength": PASSWORD_MAXIMUM_LENGTH}, "", http.StatusBadRequest)
3077	}
3078
3079	if err := o.RateLimitSettings.isValid(); err != nil {
3080		return err
3081	}
3082
3083	if err := o.ServiceSettings.isValid(); err != nil {
3084		return err
3085	}
3086
3087	if err := o.ElasticsearchSettings.isValid(); err != nil {
3088		return err
3089	}
3090
3091	if err := o.BleveSettings.isValid(); err != nil {
3092		return err
3093	}
3094
3095	if err := o.DataRetentionSettings.isValid(); err != nil {
3096		return err
3097	}
3098
3099	if err := o.LocalizationSettings.isValid(); err != nil {
3100		return err
3101	}
3102
3103	if err := o.MessageExportSettings.isValid(o.FileSettings); err != nil {
3104		return err
3105	}
3106
3107	if err := o.DisplaySettings.isValid(); err != nil {
3108		return err
3109	}
3110
3111	if err := o.ImageProxySettings.isValid(); err != nil {
3112		return err
3113	}
3114	return nil
3115}
3116
3117func (s *TeamSettings) isValid() *AppError {
3118	if *s.MaxUsersPerTeam <= 0 {
3119		return NewAppError("Config.IsValid", "model.config.is_valid.max_users.app_error", nil, "", http.StatusBadRequest)
3120	}
3121
3122	if *s.MaxChannelsPerTeam <= 0 {
3123		return NewAppError("Config.IsValid", "model.config.is_valid.max_channels.app_error", nil, "", http.StatusBadRequest)
3124	}
3125
3126	if *s.MaxNotificationsPerChannel <= 0 {
3127		return NewAppError("Config.IsValid", "model.config.is_valid.max_notify_per_channel.app_error", nil, "", http.StatusBadRequest)
3128	}
3129
3130	if !(*s.RestrictDirectMessage == DIRECT_MESSAGE_ANY || *s.RestrictDirectMessage == DIRECT_MESSAGE_TEAM) {
3131		return NewAppError("Config.IsValid", "model.config.is_valid.restrict_direct_message.app_error", nil, "", http.StatusBadRequest)
3132	}
3133
3134	if !(*s.TeammateNameDisplay == SHOW_FULLNAME || *s.TeammateNameDisplay == SHOW_NICKNAME_FULLNAME || *s.TeammateNameDisplay == SHOW_USERNAME) {
3135		return NewAppError("Config.IsValid", "model.config.is_valid.teammate_name_display.app_error", nil, "", http.StatusBadRequest)
3136	}
3137
3138	if len(*s.SiteName) > SITENAME_MAX_LENGTH {
3139		return NewAppError("Config.IsValid", "model.config.is_valid.sitename_length.app_error", map[string]interface{}{"MaxLength": SITENAME_MAX_LENGTH}, "", http.StatusBadRequest)
3140	}
3141
3142	return nil
3143}
3144
3145func (s *SqlSettings) isValid() *AppError {
3146	if *s.AtRestEncryptKey != "" && len(*s.AtRestEncryptKey) < 32 {
3147		return NewAppError("Config.IsValid", "model.config.is_valid.encrypt_sql.app_error", nil, "", http.StatusBadRequest)
3148	}
3149
3150	if !(*s.DriverName == DATABASE_DRIVER_MYSQL || *s.DriverName == DATABASE_DRIVER_POSTGRES) {
3151		return NewAppError("Config.IsValid", "model.config.is_valid.sql_driver.app_error", nil, "", http.StatusBadRequest)
3152	}
3153
3154	if *s.MaxIdleConns <= 0 {
3155		return NewAppError("Config.IsValid", "model.config.is_valid.sql_idle.app_error", nil, "", http.StatusBadRequest)
3156	}
3157
3158	if *s.ConnMaxLifetimeMilliseconds < 0 {
3159		return NewAppError("Config.IsValid", "model.config.is_valid.sql_conn_max_lifetime_milliseconds.app_error", nil, "", http.StatusBadRequest)
3160	}
3161
3162	if *s.QueryTimeout <= 0 {
3163		return NewAppError("Config.IsValid", "model.config.is_valid.sql_query_timeout.app_error", nil, "", http.StatusBadRequest)
3164	}
3165
3166	if len(*s.DataSource) == 0 {
3167		return NewAppError("Config.IsValid", "model.config.is_valid.sql_data_src.app_error", nil, "", http.StatusBadRequest)
3168	}
3169
3170	if *s.MaxOpenConns <= 0 {
3171		return NewAppError("Config.IsValid", "model.config.is_valid.sql_max_conn.app_error", nil, "", http.StatusBadRequest)
3172	}
3173
3174	return nil
3175}
3176
3177func (s *FileSettings) isValid() *AppError {
3178	if *s.MaxFileSize <= 0 {
3179		return NewAppError("Config.IsValid", "model.config.is_valid.max_file_size.app_error", nil, "", http.StatusBadRequest)
3180	}
3181
3182	if !(*s.DriverName == IMAGE_DRIVER_LOCAL || *s.DriverName == IMAGE_DRIVER_S3) {
3183		return NewAppError("Config.IsValid", "model.config.is_valid.file_driver.app_error", nil, "", http.StatusBadRequest)
3184	}
3185
3186	if *s.PublicLinkSalt != "" && len(*s.PublicLinkSalt) < 32 {
3187		return NewAppError("Config.IsValid", "model.config.is_valid.file_salt.app_error", nil, "", http.StatusBadRequest)
3188	}
3189
3190	if *s.Directory == "" {
3191		return NewAppError("Config.IsValid", "model.config.is_valid.directory.app_error", nil, "", http.StatusBadRequest)
3192	}
3193
3194	return nil
3195}
3196
3197func (s *EmailSettings) isValid() *AppError {
3198	if !(*s.ConnectionSecurity == CONN_SECURITY_NONE || *s.ConnectionSecurity == CONN_SECURITY_TLS || *s.ConnectionSecurity == CONN_SECURITY_STARTTLS || *s.ConnectionSecurity == CONN_SECURITY_PLAIN) {
3199		return NewAppError("Config.IsValid", "model.config.is_valid.email_security.app_error", nil, "", http.StatusBadRequest)
3200	}
3201
3202	if *s.EmailBatchingBufferSize <= 0 {
3203		return NewAppError("Config.IsValid", "model.config.is_valid.email_batching_buffer_size.app_error", nil, "", http.StatusBadRequest)
3204	}
3205
3206	if *s.EmailBatchingInterval < 30 {
3207		return NewAppError("Config.IsValid", "model.config.is_valid.email_batching_interval.app_error", nil, "", http.StatusBadRequest)
3208	}
3209
3210	if !(*s.EmailNotificationContentsType == EMAIL_NOTIFICATION_CONTENTS_FULL || *s.EmailNotificationContentsType == EMAIL_NOTIFICATION_CONTENTS_GENERIC) {
3211		return NewAppError("Config.IsValid", "model.config.is_valid.email_notification_contents_type.app_error", nil, "", http.StatusBadRequest)
3212	}
3213
3214	return nil
3215}
3216
3217func (s *RateLimitSettings) isValid() *AppError {
3218	if *s.MemoryStoreSize <= 0 {
3219		return NewAppError("Config.IsValid", "model.config.is_valid.rate_mem.app_error", nil, "", http.StatusBadRequest)
3220	}
3221
3222	if *s.PerSec <= 0 {
3223		return NewAppError("Config.IsValid", "model.config.is_valid.rate_sec.app_error", nil, "", http.StatusBadRequest)
3224	}
3225
3226	if *s.MaxBurst <= 0 {
3227		return NewAppError("Config.IsValid", "model.config.is_valid.max_burst.app_error", nil, "", http.StatusBadRequest)
3228	}
3229
3230	return nil
3231}
3232
3233func (s *LdapSettings) isValid() *AppError {
3234	if !(*s.ConnectionSecurity == CONN_SECURITY_NONE || *s.ConnectionSecurity == CONN_SECURITY_TLS || *s.ConnectionSecurity == CONN_SECURITY_STARTTLS) {
3235		return NewAppError("Config.IsValid", "model.config.is_valid.ldap_security.app_error", nil, "", http.StatusBadRequest)
3236	}
3237
3238	if *s.SyncIntervalMinutes <= 0 {
3239		return NewAppError("Config.IsValid", "model.config.is_valid.ldap_sync_interval.app_error", nil, "", http.StatusBadRequest)
3240	}
3241
3242	if *s.MaxPageSize < 0 {
3243		return NewAppError("Config.IsValid", "model.config.is_valid.ldap_max_page_size.app_error", nil, "", http.StatusBadRequest)
3244	}
3245
3246	if *s.Enable {
3247		if *s.LdapServer == "" {
3248			return NewAppError("Config.IsValid", "model.config.is_valid.ldap_server", nil, "", http.StatusBadRequest)
3249		}
3250
3251		if *s.BaseDN == "" {
3252			return NewAppError("Config.IsValid", "model.config.is_valid.ldap_basedn", nil, "", http.StatusBadRequest)
3253		}
3254
3255		if *s.EmailAttribute == "" {
3256			return NewAppError("Config.IsValid", "model.config.is_valid.ldap_email", nil, "", http.StatusBadRequest)
3257		}
3258
3259		if *s.UsernameAttribute == "" {
3260			return NewAppError("Config.IsValid", "model.config.is_valid.ldap_username", nil, "", http.StatusBadRequest)
3261		}
3262
3263		if *s.IdAttribute == "" {
3264			return NewAppError("Config.IsValid", "model.config.is_valid.ldap_id", nil, "", http.StatusBadRequest)
3265		}
3266
3267		if *s.LoginIdAttribute == "" {
3268			return NewAppError("Config.IsValid", "model.config.is_valid.ldap_login_id", nil, "", http.StatusBadRequest)
3269		}
3270
3271		if *s.UserFilter != "" {
3272			if _, err := ldap.CompileFilter(*s.UserFilter); err != nil {
3273				return NewAppError("ValidateFilter", "ent.ldap.validate_filter.app_error", nil, err.Error(), http.StatusBadRequest)
3274			}
3275		}
3276
3277		if *s.GuestFilter != "" {
3278			if _, err := ldap.CompileFilter(*s.GuestFilter); err != nil {
3279				return NewAppError("LdapSettings.isValid", "ent.ldap.validate_guest_filter.app_error", nil, err.Error(), http.StatusBadRequest)
3280			}
3281		}
3282
3283		if *s.AdminFilter != "" {
3284			if _, err := ldap.CompileFilter(*s.AdminFilter); err != nil {
3285				return NewAppError("LdapSettings.isValid", "ent.ldap.validate_admin_filter.app_error", nil, err.Error(), http.StatusBadRequest)
3286			}
3287		}
3288	}
3289
3290	return nil
3291}
3292
3293func (s *SamlSettings) isValid() *AppError {
3294	if *s.Enable {
3295		if len(*s.IdpUrl) == 0 || !IsValidHttpUrl(*s.IdpUrl) {
3296			return NewAppError("Config.IsValid", "model.config.is_valid.saml_idp_url.app_error", nil, "", http.StatusBadRequest)
3297		}
3298
3299		if len(*s.IdpDescriptorUrl) == 0 || !IsValidHttpUrl(*s.IdpDescriptorUrl) {
3300			return NewAppError("Config.IsValid", "model.config.is_valid.saml_idp_descriptor_url.app_error", nil, "", http.StatusBadRequest)
3301		}
3302
3303		if len(*s.IdpCertificateFile) == 0 {
3304			return NewAppError("Config.IsValid", "model.config.is_valid.saml_idp_cert.app_error", nil, "", http.StatusBadRequest)
3305		}
3306
3307		if len(*s.EmailAttribute) == 0 {
3308			return NewAppError("Config.IsValid", "model.config.is_valid.saml_email_attribute.app_error", nil, "", http.StatusBadRequest)
3309		}
3310
3311		if len(*s.UsernameAttribute) == 0 {
3312			return NewAppError("Config.IsValid", "model.config.is_valid.saml_username_attribute.app_error", nil, "", http.StatusBadRequest)
3313		}
3314
3315		if len(*s.ServiceProviderIdentifier) == 0 {
3316			return NewAppError("Config.IsValid", "model.config.is_valid.saml_spidentifier_attribute.app_error", nil, "", http.StatusBadRequest)
3317		}
3318
3319		if *s.Verify {
3320			if len(*s.AssertionConsumerServiceURL) == 0 || !IsValidHttpUrl(*s.AssertionConsumerServiceURL) {
3321				return NewAppError("Config.IsValid", "model.config.is_valid.saml_assertion_consumer_service_url.app_error", nil, "", http.StatusBadRequest)
3322			}
3323		}
3324
3325		if *s.Encrypt {
3326			if len(*s.PrivateKeyFile) == 0 {
3327				return NewAppError("Config.IsValid", "model.config.is_valid.saml_private_key.app_error", nil, "", http.StatusBadRequest)
3328			}
3329
3330			if len(*s.PublicCertificateFile) == 0 {
3331				return NewAppError("Config.IsValid", "model.config.is_valid.saml_public_cert.app_error", nil, "", http.StatusBadRequest)
3332			}
3333		}
3334
3335		if len(*s.EmailAttribute) == 0 {
3336			return NewAppError("Config.IsValid", "model.config.is_valid.saml_email_attribute.app_error", nil, "", http.StatusBadRequest)
3337		}
3338
3339		if !(*s.SignatureAlgorithm == SAML_SETTINGS_SIGNATURE_ALGORITHM_SHA1 || *s.SignatureAlgorithm == SAML_SETTINGS_SIGNATURE_ALGORITHM_SHA256 || *s.SignatureAlgorithm == SAML_SETTINGS_SIGNATURE_ALGORITHM_SHA512) {
3340			return NewAppError("Config.IsValid", "model.config.is_valid.saml_signature_algorithm.app_error", nil, "", http.StatusBadRequest)
3341		}
3342		if !(*s.CanonicalAlgorithm == SAML_SETTINGS_CANONICAL_ALGORITHM_C14N || *s.CanonicalAlgorithm == SAML_SETTINGS_CANONICAL_ALGORITHM_C14N11) {
3343			return NewAppError("Config.IsValid", "model.config.is_valid.saml_canonical_algorithm.app_error", nil, "", http.StatusBadRequest)
3344		}
3345
3346		if len(*s.GuestAttribute) > 0 {
3347			if !(strings.Contains(*s.GuestAttribute, "=")) {
3348				return NewAppError("Config.IsValid", "model.config.is_valid.saml_guest_attribute.app_error", nil, "", http.StatusBadRequest)
3349			}
3350			if len(strings.Split(*s.GuestAttribute, "=")) != 2 {
3351				return NewAppError("Config.IsValid", "model.config.is_valid.saml_guest_attribute.app_error", nil, "", http.StatusBadRequest)
3352			}
3353		}
3354
3355		if len(*s.AdminAttribute) > 0 {
3356			if !(strings.Contains(*s.AdminAttribute, "=")) {
3357				return NewAppError("Config.IsValid", "model.config.is_valid.saml_admin_attribute.app_error", nil, "", http.StatusBadRequest)
3358			}
3359			if len(strings.Split(*s.AdminAttribute, "=")) != 2 {
3360				return NewAppError("Config.IsValid", "model.config.is_valid.saml_admin_attribute.app_error", nil, "", http.StatusBadRequest)
3361			}
3362		}
3363	}
3364
3365	return nil
3366}
3367
3368func (s *ServiceSettings) isValid() *AppError {
3369	if !(*s.ConnectionSecurity == CONN_SECURITY_NONE || *s.ConnectionSecurity == CONN_SECURITY_TLS) {
3370		return NewAppError("Config.IsValid", "model.config.is_valid.webserver_security.app_error", nil, "", http.StatusBadRequest)
3371	}
3372
3373	if *s.ConnectionSecurity == CONN_SECURITY_TLS && !*s.UseLetsEncrypt {
3374		appErr := NewAppError("Config.IsValid", "model.config.is_valid.tls_cert_file.app_error", nil, "", http.StatusBadRequest)
3375
3376		if *s.TLSCertFile == "" {
3377			return appErr
3378		} else if _, err := os.Stat(*s.TLSCertFile); os.IsNotExist(err) {
3379			return appErr
3380		}
3381
3382		appErr = NewAppError("Config.IsValid", "model.config.is_valid.tls_key_file.app_error", nil, "", http.StatusBadRequest)
3383
3384		if *s.TLSKeyFile == "" {
3385			return appErr
3386		} else if _, err := os.Stat(*s.TLSKeyFile); os.IsNotExist(err) {
3387			return appErr
3388		}
3389	}
3390
3391	if len(s.TLSOverwriteCiphers) > 0 {
3392		for _, cipher := range s.TLSOverwriteCiphers {
3393			if _, ok := ServerTLSSupportedCiphers[cipher]; !ok {
3394				return NewAppError("Config.IsValid", "model.config.is_valid.tls_overwrite_cipher.app_error", map[string]interface{}{"name": cipher}, "", http.StatusBadRequest)
3395			}
3396		}
3397	}
3398
3399	if *s.ReadTimeout <= 0 {
3400		return NewAppError("Config.IsValid", "model.config.is_valid.read_timeout.app_error", nil, "", http.StatusBadRequest)
3401	}
3402
3403	if *s.WriteTimeout <= 0 {
3404		return NewAppError("Config.IsValid", "model.config.is_valid.write_timeout.app_error", nil, "", http.StatusBadRequest)
3405	}
3406
3407	if *s.TimeBetweenUserTypingUpdatesMilliseconds < 1000 {
3408		return NewAppError("Config.IsValid", "model.config.is_valid.time_between_user_typing.app_error", nil, "", http.StatusBadRequest)
3409	}
3410
3411	if *s.MaximumLoginAttempts <= 0 {
3412		return NewAppError("Config.IsValid", "model.config.is_valid.login_attempts.app_error", nil, "", http.StatusBadRequest)
3413	}
3414
3415	if len(*s.SiteURL) != 0 {
3416		if _, err := url.ParseRequestURI(*s.SiteURL); err != nil {
3417			return NewAppError("Config.IsValid", "model.config.is_valid.site_url.app_error", nil, "", http.StatusBadRequest)
3418		}
3419	}
3420
3421	if len(*s.WebsocketURL) != 0 {
3422		if _, err := url.ParseRequestURI(*s.WebsocketURL); err != nil {
3423			return NewAppError("Config.IsValid", "model.config.is_valid.websocket_url.app_error", nil, "", http.StatusBadRequest)
3424		}
3425	}
3426
3427	host, port, _ := net.SplitHostPort(*s.ListenAddress)
3428	var isValidHost bool
3429	if host == "" {
3430		isValidHost = true
3431	} else {
3432		isValidHost = (net.ParseIP(host) != nil) || IsDomainName(host)
3433	}
3434	portInt, err := strconv.Atoi(port)
3435	if err != nil || !isValidHost || portInt < 0 || portInt > math.MaxUint16 {
3436		return NewAppError("Config.IsValid", "model.config.is_valid.listen_address.app_error", nil, "", http.StatusBadRequest)
3437	}
3438
3439	if *s.ExperimentalGroupUnreadChannels != GROUP_UNREAD_CHANNELS_DISABLED &&
3440		*s.ExperimentalGroupUnreadChannels != GROUP_UNREAD_CHANNELS_DEFAULT_ON &&
3441		*s.ExperimentalGroupUnreadChannels != GROUP_UNREAD_CHANNELS_DEFAULT_OFF {
3442		return NewAppError("Config.IsValid", "model.config.is_valid.group_unread_channels.app_error", nil, "", http.StatusBadRequest)
3443	}
3444
3445	return nil
3446}
3447
3448func (s *ElasticsearchSettings) isValid() *AppError {
3449	if *s.EnableIndexing {
3450		if len(*s.ConnectionUrl) == 0 {
3451			return NewAppError("Config.IsValid", "model.config.is_valid.elastic_search.connection_url.app_error", nil, "", http.StatusBadRequest)
3452		}
3453	}
3454
3455	if *s.EnableSearching && !*s.EnableIndexing {
3456		return NewAppError("Config.IsValid", "model.config.is_valid.elastic_search.enable_searching.app_error", nil, "", http.StatusBadRequest)
3457	}
3458
3459	if *s.EnableAutocomplete && !*s.EnableIndexing {
3460		return NewAppError("Config.IsValid", "model.config.is_valid.elastic_search.enable_autocomplete.app_error", nil, "", http.StatusBadRequest)
3461	}
3462
3463	if *s.AggregatePostsAfterDays < 1 {
3464		return NewAppError("Config.IsValid", "model.config.is_valid.elastic_search.aggregate_posts_after_days.app_error", nil, "", http.StatusBadRequest)
3465	}
3466
3467	if _, err := time.Parse("15:04", *s.PostsAggregatorJobStartTime); err != nil {
3468		return NewAppError("Config.IsValid", "model.config.is_valid.elastic_search.posts_aggregator_job_start_time.app_error", nil, err.Error(), http.StatusBadRequest)
3469	}
3470
3471	if *s.LiveIndexingBatchSize < 1 {
3472		return NewAppError("Config.IsValid", "model.config.is_valid.elastic_search.live_indexing_batch_size.app_error", nil, "", http.StatusBadRequest)
3473	}
3474
3475	if *s.BulkIndexingTimeWindowSeconds < 1 {
3476		return NewAppError("Config.IsValid", "model.config.is_valid.elastic_search.bulk_indexing_time_window_seconds.app_error", nil, "", http.StatusBadRequest)
3477	}
3478
3479	if *s.RequestTimeoutSeconds < 1 {
3480		return NewAppError("Config.IsValid", "model.config.is_valid.elastic_search.request_timeout_seconds.app_error", nil, "", http.StatusBadRequest)
3481	}
3482
3483	return nil
3484}
3485
3486func (bs *BleveSettings) isValid() *AppError {
3487	if *bs.EnableIndexing {
3488		if len(*bs.IndexDir) == 0 {
3489			return NewAppError("Config.IsValid", "model.config.is_valid.bleve_search.filename.app_error", nil, "", http.StatusBadRequest)
3490		}
3491	} else {
3492		if *bs.EnableSearching {
3493			return NewAppError("Config.IsValid", "model.config.is_valid.bleve_search.enable_searching.app_error", nil, "", http.StatusBadRequest)
3494		}
3495		if *bs.EnableAutocomplete {
3496			return NewAppError("Config.IsValid", "model.config.is_valid.bleve_search.enable_autocomplete.app_error", nil, "", http.StatusBadRequest)
3497		}
3498	}
3499	if *bs.BulkIndexingTimeWindowSeconds < 1 {
3500		return NewAppError("Config.IsValid", "model.config.is_valid.bleve_search.bulk_indexing_time_window_seconds.app_error", nil, "", http.StatusBadRequest)
3501	}
3502
3503	return nil
3504}
3505
3506func (s *DataRetentionSettings) isValid() *AppError {
3507	if *s.MessageRetentionDays <= 0 {
3508		return NewAppError("Config.IsValid", "model.config.is_valid.data_retention.message_retention_days_too_low.app_error", nil, "", http.StatusBadRequest)
3509	}
3510
3511	if *s.FileRetentionDays <= 0 {
3512		return NewAppError("Config.IsValid", "model.config.is_valid.data_retention.file_retention_days_too_low.app_error", nil, "", http.StatusBadRequest)
3513	}
3514
3515	if _, err := time.Parse("15:04", *s.DeletionJobStartTime); err != nil {
3516		return NewAppError("Config.IsValid", "model.config.is_valid.data_retention.deletion_job_start_time.app_error", nil, err.Error(), http.StatusBadRequest)
3517	}
3518
3519	return nil
3520}
3521
3522func (s *LocalizationSettings) isValid() *AppError {
3523	if len(*s.AvailableLocales) > 0 {
3524		if !strings.Contains(*s.AvailableLocales, *s.DefaultClientLocale) {
3525			return NewAppError("Config.IsValid", "model.config.is_valid.localization.available_locales.app_error", nil, "", http.StatusBadRequest)
3526		}
3527	}
3528
3529	return nil
3530}
3531
3532func (s *MessageExportSettings) isValid(fs FileSettings) *AppError {
3533	if s.EnableExport == nil {
3534		return NewAppError("Config.IsValid", "model.config.is_valid.message_export.enable.app_error", nil, "", http.StatusBadRequest)
3535	}
3536	if *s.EnableExport {
3537		if s.ExportFromTimestamp == nil || *s.ExportFromTimestamp < 0 || *s.ExportFromTimestamp > GetMillis() {
3538			return NewAppError("Config.IsValid", "model.config.is_valid.message_export.export_from.app_error", nil, "", http.StatusBadRequest)
3539		} else if s.DailyRunTime == nil {
3540			return NewAppError("Config.IsValid", "model.config.is_valid.message_export.daily_runtime.app_error", nil, "", http.StatusBadRequest)
3541		} else if _, err := time.Parse("15:04", *s.DailyRunTime); err != nil {
3542			return NewAppError("Config.IsValid", "model.config.is_valid.message_export.daily_runtime.app_error", nil, err.Error(), http.StatusBadRequest)
3543		} else if s.BatchSize == nil || *s.BatchSize < 0 {
3544			return NewAppError("Config.IsValid", "model.config.is_valid.message_export.batch_size.app_error", nil, "", http.StatusBadRequest)
3545		} else if s.ExportFormat == nil || (*s.ExportFormat != COMPLIANCE_EXPORT_TYPE_ACTIANCE && *s.ExportFormat != COMPLIANCE_EXPORT_TYPE_GLOBALRELAY && *s.ExportFormat != COMPLIANCE_EXPORT_TYPE_CSV) {
3546			return NewAppError("Config.IsValid", "model.config.is_valid.message_export.export_type.app_error", nil, "", http.StatusBadRequest)
3547		}
3548
3549		if *s.ExportFormat == COMPLIANCE_EXPORT_TYPE_GLOBALRELAY {
3550			if s.GlobalRelaySettings == nil {
3551				return NewAppError("Config.IsValid", "model.config.is_valid.message_export.global_relay.config_missing.app_error", nil, "", http.StatusBadRequest)
3552			} else if s.GlobalRelaySettings.CustomerType == nil || (*s.GlobalRelaySettings.CustomerType != GLOBALRELAY_CUSTOMER_TYPE_A9 && *s.GlobalRelaySettings.CustomerType != GLOBALRELAY_CUSTOMER_TYPE_A10) {
3553				return NewAppError("Config.IsValid", "model.config.is_valid.message_export.global_relay.customer_type.app_error", nil, "", http.StatusBadRequest)
3554			} else if s.GlobalRelaySettings.EmailAddress == nil || !strings.Contains(*s.GlobalRelaySettings.EmailAddress, "@") {
3555				// validating email addresses is hard - just make sure it contains an '@' sign
3556				// see https://stackoverflow.com/questions/201323/using-a-regular-expression-to-validate-an-email-address
3557				return NewAppError("Config.IsValid", "model.config.is_valid.message_export.global_relay.email_address.app_error", nil, "", http.StatusBadRequest)
3558			} else if s.GlobalRelaySettings.SmtpUsername == nil || *s.GlobalRelaySettings.SmtpUsername == "" {
3559				return NewAppError("Config.IsValid", "model.config.is_valid.message_export.global_relay.smtp_username.app_error", nil, "", http.StatusBadRequest)
3560			} else if s.GlobalRelaySettings.SmtpPassword == nil || *s.GlobalRelaySettings.SmtpPassword == "" {
3561				return NewAppError("Config.IsValid", "model.config.is_valid.message_export.global_relay.smtp_password.app_error", nil, "", http.StatusBadRequest)
3562			}
3563		}
3564	}
3565	return nil
3566}
3567
3568func (s *DisplaySettings) isValid() *AppError {
3569	if len(s.CustomUrlSchemes) != 0 {
3570		validProtocolPattern := regexp.MustCompile(`(?i)^\s*[A-Za-z][A-Za-z0-9.+-]*\s*$`)
3571
3572		for _, scheme := range s.CustomUrlSchemes {
3573			if !validProtocolPattern.MatchString(scheme) {
3574				return NewAppError(
3575					"Config.IsValid",
3576					"model.config.is_valid.display.custom_url_schemes.app_error",
3577					map[string]interface{}{"Scheme": scheme},
3578					"",
3579					http.StatusBadRequest,
3580				)
3581			}
3582		}
3583	}
3584
3585	return nil
3586}
3587
3588func (s *ImageProxySettings) isValid() *AppError {
3589	if *s.Enable {
3590		switch *s.ImageProxyType {
3591		case IMAGE_PROXY_TYPE_LOCAL:
3592			// No other settings to validate
3593		case IMAGE_PROXY_TYPE_ATMOS_CAMO:
3594			if *s.RemoteImageProxyURL == "" {
3595				return NewAppError("Config.IsValid", "model.config.is_valid.atmos_camo_image_proxy_url.app_error", nil, "", http.StatusBadRequest)
3596			}
3597
3598			if *s.RemoteImageProxyOptions == "" {
3599				return NewAppError("Config.IsValid", "model.config.is_valid.atmos_camo_image_proxy_options.app_error", nil, "", http.StatusBadRequest)
3600			}
3601		default:
3602			return NewAppError("Config.IsValid", "model.config.is_valid.image_proxy_type.app_error", nil, "", http.StatusBadRequest)
3603		}
3604	}
3605
3606	return nil
3607}
3608
3609func (o *Config) GetSanitizeOptions() map[string]bool {
3610	options := map[string]bool{}
3611	options["fullname"] = *o.PrivacySettings.ShowFullName
3612	options["email"] = *o.PrivacySettings.ShowEmailAddress
3613
3614	return options
3615}
3616
3617func (o *Config) Sanitize() {
3618	if o.LdapSettings.BindPassword != nil && len(*o.LdapSettings.BindPassword) > 0 {
3619		*o.LdapSettings.BindPassword = FAKE_SETTING
3620	}
3621
3622	*o.FileSettings.PublicLinkSalt = FAKE_SETTING
3623
3624	if len(*o.FileSettings.AmazonS3SecretAccessKey) > 0 {
3625		*o.FileSettings.AmazonS3SecretAccessKey = FAKE_SETTING
3626	}
3627
3628	if o.EmailSettings.SMTPPassword != nil && len(*o.EmailSettings.SMTPPassword) > 0 {
3629		*o.EmailSettings.SMTPPassword = FAKE_SETTING
3630	}
3631
3632	if len(*o.GitLabSettings.Secret) > 0 {
3633		*o.GitLabSettings.Secret = FAKE_SETTING
3634	}
3635
3636	if o.GoogleSettings.Secret != nil && len(*o.GoogleSettings.Secret) > 0 {
3637		*o.GoogleSettings.Secret = FAKE_SETTING
3638	}
3639
3640	if o.Office365Settings.Secret != nil && len(*o.Office365Settings.Secret) > 0 {
3641		*o.Office365Settings.Secret = FAKE_SETTING
3642	}
3643
3644	*o.SqlSettings.DataSource = FAKE_SETTING
3645	*o.SqlSettings.AtRestEncryptKey = FAKE_SETTING
3646
3647	*o.ElasticsearchSettings.Password = FAKE_SETTING
3648
3649	for i := range o.SqlSettings.DataSourceReplicas {
3650		o.SqlSettings.DataSourceReplicas[i] = FAKE_SETTING
3651	}
3652
3653	for i := range o.SqlSettings.DataSourceSearchReplicas {
3654		o.SqlSettings.DataSourceSearchReplicas[i] = FAKE_SETTING
3655	}
3656
3657	if o.MessageExportSettings.GlobalRelaySettings.SmtpPassword != nil && len(*o.MessageExportSettings.GlobalRelaySettings.SmtpPassword) > 0 {
3658		*o.MessageExportSettings.GlobalRelaySettings.SmtpPassword = FAKE_SETTING
3659	}
3660
3661	if o.ServiceSettings.GfycatApiSecret != nil && len(*o.ServiceSettings.GfycatApiSecret) > 0 {
3662		*o.ServiceSettings.GfycatApiSecret = FAKE_SETTING
3663	}
3664
3665	*o.ServiceSettings.SplitKey = FAKE_SETTING
3666}
3667
3668// structToMapFilteredByTag converts a struct into a map removing those fields that has the tag passed
3669// as argument
3670func structToMapFilteredByTag(t interface{}, typeOfTag, filterTag string) map[string]interface{} {
3671	defer func() {
3672		if r := recover(); r != nil {
3673			mlog.Error("Panicked in structToMapFilteredByTag. This should never happen.", mlog.Any("recover", r))
3674		}
3675	}()
3676
3677	val := reflect.ValueOf(t)
3678	elemField := reflect.TypeOf(t)
3679
3680	if val.Kind() != reflect.Struct {
3681		return nil
3682	}
3683
3684	out := map[string]interface{}{}
3685
3686	for i := 0; i < val.NumField(); i++ {
3687		field := val.Field(i)
3688
3689		structField := elemField.Field(i)
3690		tagPermissions := strings.Split(structField.Tag.Get(typeOfTag), ",")
3691		if isTagPresent(filterTag, tagPermissions) {
3692			continue
3693		}
3694
3695		var value interface{}
3696
3697		switch field.Kind() {
3698		case reflect.Struct:
3699			value = structToMapFilteredByTag(field.Interface(), typeOfTag, filterTag)
3700		case reflect.Ptr:
3701			indirectType := field.Elem()
3702			if indirectType.Kind() == reflect.Struct {
3703				value = structToMapFilteredByTag(indirectType.Interface(), typeOfTag, filterTag)
3704			} else if indirectType.Kind() != reflect.Invalid {
3705				value = indirectType.Interface()
3706			}
3707		default:
3708			value = field.Interface()
3709		}
3710
3711		out[val.Type().Field(i).Name] = value
3712	}
3713
3714	return out
3715}
3716
3717func isTagPresent(tag string, tags []string) bool {
3718	for _, val := range tags {
3719		tagValue := strings.TrimSpace(val)
3720		if tagValue != "" && tagValue == tag {
3721			return true
3722		}
3723	}
3724
3725	return false
3726}
3727