config_test.go 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554
  1. // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
  2. // See LICENSE.txt for license information.
  3. package api4
  4. import (
  5. "net/http"
  6. "os"
  7. "strings"
  8. "testing"
  9. "github.com/mattermost/mattermost-server/v5/model"
  10. "github.com/stretchr/testify/assert"
  11. "github.com/stretchr/testify/require"
  12. )
  13. func TestGetConfig(t *testing.T) {
  14. th := Setup(t)
  15. defer th.TearDown()
  16. Client := th.Client
  17. _, resp := Client.GetConfig()
  18. CheckForbiddenStatus(t, resp)
  19. th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
  20. cfg, resp := client.GetConfig()
  21. CheckNoError(t, resp)
  22. require.NotEqual(t, "", cfg.TeamSettings.SiteName)
  23. if *cfg.LdapSettings.BindPassword != model.FAKE_SETTING && len(*cfg.LdapSettings.BindPassword) != 0 {
  24. require.FailNow(t, "did not sanitize properly")
  25. }
  26. require.Equal(t, model.FAKE_SETTING, *cfg.FileSettings.PublicLinkSalt, "did not sanitize properly")
  27. if *cfg.FileSettings.AmazonS3SecretAccessKey != model.FAKE_SETTING && len(*cfg.FileSettings.AmazonS3SecretAccessKey) != 0 {
  28. require.FailNow(t, "did not sanitize properly")
  29. }
  30. if *cfg.EmailSettings.SMTPPassword != model.FAKE_SETTING && len(*cfg.EmailSettings.SMTPPassword) != 0 {
  31. require.FailNow(t, "did not sanitize properly")
  32. }
  33. if *cfg.GitLabSettings.Secret != model.FAKE_SETTING && len(*cfg.GitLabSettings.Secret) != 0 {
  34. require.FailNow(t, "did not sanitize properly")
  35. }
  36. require.Equal(t, model.FAKE_SETTING, *cfg.SqlSettings.DataSource, "did not sanitize properly")
  37. require.Equal(t, model.FAKE_SETTING, *cfg.SqlSettings.AtRestEncryptKey, "did not sanitize properly")
  38. if !strings.Contains(strings.Join(cfg.SqlSettings.DataSourceReplicas, " "), model.FAKE_SETTING) && len(cfg.SqlSettings.DataSourceReplicas) != 0 {
  39. require.FailNow(t, "did not sanitize properly")
  40. }
  41. if !strings.Contains(strings.Join(cfg.SqlSettings.DataSourceSearchReplicas, " "), model.FAKE_SETTING) && len(cfg.SqlSettings.DataSourceSearchReplicas) != 0 {
  42. require.FailNow(t, "did not sanitize properly")
  43. }
  44. })
  45. }
  46. func TestReloadConfig(t *testing.T) {
  47. th := Setup(t)
  48. defer th.TearDown()
  49. Client := th.Client
  50. t.Run("as system user", func(t *testing.T) {
  51. ok, resp := Client.ReloadConfig()
  52. CheckForbiddenStatus(t, resp)
  53. require.False(t, ok, "should not Reload the config due no permission.")
  54. })
  55. t.Run("as system admin", func(t *testing.T) {
  56. ok, resp := th.SystemAdminClient.ReloadConfig()
  57. CheckNoError(t, resp)
  58. require.True(t, ok, "should Reload the config")
  59. })
  60. t.Run("as restricted system admin", func(t *testing.T) {
  61. th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ExperimentalSettings.RestrictSystemAdmin = true })
  62. ok, resp := Client.ReloadConfig()
  63. CheckForbiddenStatus(t, resp)
  64. require.False(t, ok, "should not Reload the config due no permission.")
  65. })
  66. }
  67. func TestUpdateConfig(t *testing.T) {
  68. th := Setup(t)
  69. defer th.TearDown()
  70. Client := th.Client
  71. cfg, resp := th.SystemAdminClient.GetConfig()
  72. CheckNoError(t, resp)
  73. _, resp = Client.UpdateConfig(cfg)
  74. CheckForbiddenStatus(t, resp)
  75. th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
  76. SiteName := th.App.Config().TeamSettings.SiteName
  77. *cfg.TeamSettings.SiteName = "MyFancyName"
  78. cfg, resp = client.UpdateConfig(cfg)
  79. CheckNoError(t, resp)
  80. require.Equal(t, "MyFancyName", *cfg.TeamSettings.SiteName, "It should update the SiteName")
  81. //Revert the change
  82. cfg.TeamSettings.SiteName = SiteName
  83. cfg, resp = client.UpdateConfig(cfg)
  84. CheckNoError(t, resp)
  85. require.Equal(t, SiteName, cfg.TeamSettings.SiteName, "It should update the SiteName")
  86. t.Run("Should set defaults for missing fields", func(t *testing.T) {
  87. _, appErr := th.SystemAdminClient.DoApiPut(th.SystemAdminClient.GetConfigRoute(), `{"ServiceSettings":{}}`)
  88. require.Nil(t, appErr)
  89. })
  90. t.Run("Should fail with validation error if invalid config setting is passed", func(t *testing.T) {
  91. //Revert the change
  92. badcfg := cfg.Clone()
  93. badcfg.PasswordSettings.MinimumLength = model.NewInt(4)
  94. badcfg.PasswordSettings.MinimumLength = model.NewInt(4)
  95. _, resp = client.UpdateConfig(badcfg)
  96. CheckBadRequestStatus(t, resp)
  97. CheckErrorMessage(t, resp, "model.config.is_valid.password_length.app_error")
  98. })
  99. t.Run("Should not be able to modify PluginSettings.EnableUploads", func(t *testing.T) {
  100. oldEnableUploads := *th.App.Config().PluginSettings.EnableUploads
  101. *cfg.PluginSettings.EnableUploads = !oldEnableUploads
  102. cfg, resp = client.UpdateConfig(cfg)
  103. CheckNoError(t, resp)
  104. assert.Equal(t, oldEnableUploads, *cfg.PluginSettings.EnableUploads)
  105. assert.Equal(t, oldEnableUploads, *th.App.Config().PluginSettings.EnableUploads)
  106. cfg.PluginSettings.EnableUploads = nil
  107. cfg, resp = client.UpdateConfig(cfg)
  108. CheckNoError(t, resp)
  109. assert.Equal(t, oldEnableUploads, *cfg.PluginSettings.EnableUploads)
  110. assert.Equal(t, oldEnableUploads, *th.App.Config().PluginSettings.EnableUploads)
  111. })
  112. t.Run("Should not be able to modify PluginSettings.SignaturePublicKeyFiles", func(t *testing.T) {
  113. oldPublicKeys := th.App.Config().PluginSettings.SignaturePublicKeyFiles
  114. cfg.PluginSettings.SignaturePublicKeyFiles = append(cfg.PluginSettings.SignaturePublicKeyFiles, "new_signature")
  115. cfg, resp = client.UpdateConfig(cfg)
  116. CheckNoError(t, resp)
  117. assert.Equal(t, oldPublicKeys, cfg.PluginSettings.SignaturePublicKeyFiles)
  118. assert.Equal(t, oldPublicKeys, th.App.Config().PluginSettings.SignaturePublicKeyFiles)
  119. cfg.PluginSettings.SignaturePublicKeyFiles = nil
  120. cfg, resp = client.UpdateConfig(cfg)
  121. CheckNoError(t, resp)
  122. assert.Equal(t, oldPublicKeys, cfg.PluginSettings.SignaturePublicKeyFiles)
  123. assert.Equal(t, oldPublicKeys, th.App.Config().PluginSettings.SignaturePublicKeyFiles)
  124. })
  125. })
  126. t.Run("System Admin should not be able to clear Site URL", func(t *testing.T) {
  127. siteURL := cfg.ServiceSettings.SiteURL
  128. defer th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.SiteURL = siteURL })
  129. nonEmptyURL := "http://localhost"
  130. cfg.ServiceSettings.SiteURL = &nonEmptyURL
  131. // Set the SiteURL
  132. cfg, resp = th.SystemAdminClient.UpdateConfig(cfg)
  133. CheckNoError(t, resp)
  134. require.Equal(t, nonEmptyURL, *cfg.ServiceSettings.SiteURL)
  135. // Check that the Site URL can't be cleared
  136. cfg.ServiceSettings.SiteURL = sToP("")
  137. cfg, resp = th.SystemAdminClient.UpdateConfig(cfg)
  138. CheckBadRequestStatus(t, resp)
  139. CheckErrorMessage(t, resp, "api.config.update_config.clear_siteurl.app_error")
  140. // Check that the Site URL wasn't cleared
  141. cfg, resp = th.SystemAdminClient.GetConfig()
  142. CheckNoError(t, resp)
  143. require.Equal(t, nonEmptyURL, *cfg.ServiceSettings.SiteURL)
  144. })
  145. }
  146. func TestUpdateConfigMessageExportSpecialHandling(t *testing.T) {
  147. th := Setup(t)
  148. defer th.TearDown()
  149. messageExportEnabled := *th.App.Config().MessageExportSettings.EnableExport
  150. messageExportTimestamp := *th.App.Config().MessageExportSettings.ExportFromTimestamp
  151. defer th.App.UpdateConfig(func(cfg *model.Config) {
  152. *cfg.MessageExportSettings.EnableExport = messageExportEnabled
  153. *cfg.MessageExportSettings.ExportFromTimestamp = messageExportTimestamp
  154. })
  155. th.App.UpdateConfig(func(cfg *model.Config) {
  156. *cfg.MessageExportSettings.EnableExport = false
  157. *cfg.MessageExportSettings.ExportFromTimestamp = int64(0)
  158. })
  159. // Turn it on, timestamp should be updated.
  160. cfg, resp := th.SystemAdminClient.GetConfig()
  161. CheckNoError(t, resp)
  162. *cfg.MessageExportSettings.EnableExport = true
  163. cfg, resp = th.SystemAdminClient.UpdateConfig(cfg)
  164. CheckNoError(t, resp)
  165. assert.True(t, *th.App.Config().MessageExportSettings.EnableExport)
  166. assert.NotEqual(t, int64(0), *th.App.Config().MessageExportSettings.ExportFromTimestamp)
  167. // Turn it off, timestamp should be cleared.
  168. cfg, resp = th.SystemAdminClient.GetConfig()
  169. CheckNoError(t, resp)
  170. *cfg.MessageExportSettings.EnableExport = false
  171. cfg, resp = th.SystemAdminClient.UpdateConfig(cfg)
  172. CheckNoError(t, resp)
  173. assert.False(t, *th.App.Config().MessageExportSettings.EnableExport)
  174. assert.Equal(t, int64(0), *th.App.Config().MessageExportSettings.ExportFromTimestamp)
  175. // Set a value from the config file.
  176. th.App.UpdateConfig(func(cfg *model.Config) {
  177. *cfg.MessageExportSettings.EnableExport = false
  178. *cfg.MessageExportSettings.ExportFromTimestamp = int64(12345)
  179. })
  180. // Turn it on, timestamp should *not* be updated.
  181. cfg, resp = th.SystemAdminClient.GetConfig()
  182. CheckNoError(t, resp)
  183. *cfg.MessageExportSettings.EnableExport = true
  184. cfg, resp = th.SystemAdminClient.UpdateConfig(cfg)
  185. CheckNoError(t, resp)
  186. assert.True(t, *th.App.Config().MessageExportSettings.EnableExport)
  187. assert.Equal(t, int64(12345), *th.App.Config().MessageExportSettings.ExportFromTimestamp)
  188. // Turn it off, timestamp should be cleared.
  189. cfg, resp = th.SystemAdminClient.GetConfig()
  190. CheckNoError(t, resp)
  191. *cfg.MessageExportSettings.EnableExport = false
  192. cfg, resp = th.SystemAdminClient.UpdateConfig(cfg)
  193. CheckNoError(t, resp)
  194. assert.False(t, *th.App.Config().MessageExportSettings.EnableExport)
  195. assert.Equal(t, int64(0), *th.App.Config().MessageExportSettings.ExportFromTimestamp)
  196. }
  197. func TestUpdateConfigRestrictSystemAdmin(t *testing.T) {
  198. th := Setup(t)
  199. defer th.TearDown()
  200. th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ExperimentalSettings.RestrictSystemAdmin = true })
  201. t.Run("Restrict flag should be honored for sysadmin", func(t *testing.T) {
  202. originalCfg, resp := th.SystemAdminClient.GetConfig()
  203. CheckNoError(t, resp)
  204. cfg := originalCfg.Clone()
  205. *cfg.TeamSettings.SiteName = "MyFancyName" // Allowed
  206. *cfg.ServiceSettings.SiteURL = "http://example.com" // Ignored
  207. returnedCfg, resp := th.SystemAdminClient.UpdateConfig(cfg)
  208. CheckNoError(t, resp)
  209. require.Equal(t, "MyFancyName", *returnedCfg.TeamSettings.SiteName)
  210. require.Equal(t, *originalCfg.ServiceSettings.SiteURL, *returnedCfg.ServiceSettings.SiteURL)
  211. actualCfg, resp := th.SystemAdminClient.GetConfig()
  212. CheckNoError(t, resp)
  213. require.Equal(t, returnedCfg, actualCfg)
  214. })
  215. t.Run("Restrict flag should be ignored by local mode", func(t *testing.T) {
  216. originalCfg, resp := th.LocalClient.GetConfig()
  217. CheckNoError(t, resp)
  218. cfg := originalCfg.Clone()
  219. *cfg.TeamSettings.SiteName = "MyFancyName" // Allowed
  220. *cfg.ServiceSettings.SiteURL = "http://example.com" // Ignored
  221. returnedCfg, resp := th.LocalClient.UpdateConfig(cfg)
  222. CheckNoError(t, resp)
  223. require.Equal(t, "MyFancyName", *returnedCfg.TeamSettings.SiteName)
  224. require.Equal(t, "http://example.com", *returnedCfg.ServiceSettings.SiteURL)
  225. })
  226. }
  227. func TestGetEnvironmentConfig(t *testing.T) {
  228. os.Setenv("MM_SERVICESETTINGS_SITEURL", "http://example.mattermost.com")
  229. os.Setenv("MM_SERVICESETTINGS_ENABLECUSTOMEMOJI", "true")
  230. defer os.Unsetenv("MM_SERVICESETTINGS_SITEURL")
  231. defer os.Unsetenv("MM_SERVICESETTINGS_ENABLECUSTOMEMOJI")
  232. th := Setup(t)
  233. defer th.TearDown()
  234. t.Run("as system admin", func(t *testing.T) {
  235. SystemAdminClient := th.SystemAdminClient
  236. envConfig, resp := SystemAdminClient.GetEnvironmentConfig()
  237. CheckNoError(t, resp)
  238. serviceSettings, ok := envConfig["ServiceSettings"]
  239. require.True(t, ok, "should've returned ServiceSettings")
  240. serviceSettingsAsMap, ok := serviceSettings.(map[string]interface{})
  241. require.True(t, ok, "should've returned ServiceSettings as a map")
  242. siteURL, ok := serviceSettingsAsMap["SiteURL"]
  243. require.True(t, ok, "should've returned ServiceSettings.SiteURL")
  244. siteURLAsBool, ok := siteURL.(bool)
  245. require.True(t, ok, "should've returned ServiceSettings.SiteURL as a boolean")
  246. require.True(t, siteURLAsBool, "should've returned ServiceSettings.SiteURL as true")
  247. enableCustomEmoji, ok := serviceSettingsAsMap["EnableCustomEmoji"]
  248. require.True(t, ok, "should've returned ServiceSettings.EnableCustomEmoji")
  249. enableCustomEmojiAsBool, ok := enableCustomEmoji.(bool)
  250. require.True(t, ok, "should've returned ServiceSettings.EnableCustomEmoji as a boolean")
  251. require.True(t, enableCustomEmojiAsBool, "should've returned ServiceSettings.EnableCustomEmoji as true")
  252. _, ok = envConfig["TeamSettings"]
  253. require.False(t, ok, "should not have returned TeamSettings")
  254. })
  255. t.Run("as team admin", func(t *testing.T) {
  256. TeamAdminClient := th.CreateClient()
  257. th.LoginTeamAdminWithClient(TeamAdminClient)
  258. _, resp := TeamAdminClient.GetEnvironmentConfig()
  259. CheckForbiddenStatus(t, resp)
  260. })
  261. t.Run("as regular user", func(t *testing.T) {
  262. Client := th.Client
  263. _, resp := Client.GetEnvironmentConfig()
  264. CheckForbiddenStatus(t, resp)
  265. })
  266. t.Run("as not-regular user", func(t *testing.T) {
  267. Client := th.CreateClient()
  268. _, resp := Client.GetEnvironmentConfig()
  269. CheckUnauthorizedStatus(t, resp)
  270. })
  271. }
  272. func TestGetOldClientConfig(t *testing.T) {
  273. th := Setup(t)
  274. defer th.TearDown()
  275. testKey := "supersecretkey"
  276. th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.GoogleDeveloperKey = testKey })
  277. t.Run("with session", func(t *testing.T) {
  278. th.App.UpdateConfig(func(cfg *model.Config) {
  279. *cfg.ServiceSettings.GoogleDeveloperKey = testKey
  280. })
  281. Client := th.Client
  282. config, resp := Client.GetOldClientConfig("")
  283. CheckNoError(t, resp)
  284. require.NotEmpty(t, config["Version"], "config not returned correctly")
  285. require.Equal(t, testKey, config["GoogleDeveloperKey"])
  286. })
  287. t.Run("without session", func(t *testing.T) {
  288. th.App.UpdateConfig(func(cfg *model.Config) {
  289. *cfg.ServiceSettings.GoogleDeveloperKey = testKey
  290. })
  291. Client := th.CreateClient()
  292. config, resp := Client.GetOldClientConfig("")
  293. CheckNoError(t, resp)
  294. require.NotEmpty(t, config["Version"], "config not returned correctly")
  295. require.Empty(t, config["GoogleDeveloperKey"], "config should be missing developer key")
  296. })
  297. t.Run("missing format", func(t *testing.T) {
  298. Client := th.Client
  299. _, err := Client.DoApiGet("/config/client", "")
  300. require.NotNil(t, err)
  301. require.Equal(t, http.StatusNotImplemented, err.StatusCode)
  302. })
  303. t.Run("invalid format", func(t *testing.T) {
  304. Client := th.Client
  305. _, err := Client.DoApiGet("/config/client?format=junk", "")
  306. require.NotNil(t, err)
  307. require.Equal(t, http.StatusBadRequest, err.StatusCode)
  308. })
  309. }
  310. func TestPatchConfig(t *testing.T) {
  311. th := Setup(t)
  312. defer th.TearDown()
  313. t.Run("config is missing", func(t *testing.T) {
  314. _, response := th.Client.PatchConfig(nil)
  315. CheckBadRequestStatus(t, response)
  316. })
  317. t.Run("user is not system admin", func(t *testing.T) {
  318. _, response := th.Client.PatchConfig(&model.Config{})
  319. CheckForbiddenStatus(t, response)
  320. })
  321. t.Run("should not update the restricted fields when restrict toggle is on for sysadmin", func(t *testing.T) {
  322. *th.App.Config().ExperimentalSettings.RestrictSystemAdmin = true
  323. config := model.Config{LogSettings: model.LogSettings{
  324. ConsoleLevel: model.NewString("INFO"),
  325. }}
  326. updatedConfig, _ := th.SystemAdminClient.PatchConfig(&config)
  327. assert.Equal(t, "DEBUG", *updatedConfig.LogSettings.ConsoleLevel)
  328. })
  329. t.Run("should not bypass the restrict toggle if local client", func(t *testing.T) {
  330. *th.App.Config().ExperimentalSettings.RestrictSystemAdmin = true
  331. config := model.Config{LogSettings: model.LogSettings{
  332. ConsoleLevel: model.NewString("INFO"),
  333. }}
  334. oldConfig, _ := th.LocalClient.GetConfig()
  335. updatedConfig, _ := th.LocalClient.PatchConfig(&config)
  336. assert.Equal(t, "INFO", *updatedConfig.LogSettings.ConsoleLevel)
  337. // reset the config
  338. _, resp := th.LocalClient.UpdateConfig(oldConfig)
  339. CheckNoError(t, resp)
  340. })
  341. th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
  342. t.Run("check if config is valid", func(t *testing.T) {
  343. config := model.Config{PasswordSettings: model.PasswordSettings{
  344. MinimumLength: model.NewInt(4),
  345. }}
  346. _, response := client.PatchConfig(&config)
  347. assert.Equal(t, http.StatusBadRequest, response.StatusCode)
  348. assert.NotNil(t, response.Error)
  349. assert.Equal(t, "model.config.is_valid.password_length.app_error", response.Error.Id)
  350. })
  351. t.Run("should patch the config", func(t *testing.T) {
  352. *th.App.Config().ExperimentalSettings.RestrictSystemAdmin = false
  353. th.App.UpdateConfig(func(cfg *model.Config) { cfg.TeamSettings.ExperimentalDefaultChannels = []string{"some-channel"} })
  354. oldConfig, _ := client.GetConfig()
  355. assert.False(t, *oldConfig.PasswordSettings.Lowercase)
  356. assert.NotEqual(t, 15, *oldConfig.PasswordSettings.MinimumLength)
  357. assert.Equal(t, "DEBUG", *oldConfig.LogSettings.ConsoleLevel)
  358. assert.True(t, oldConfig.PluginSettings.PluginStates["com.mattermost.nps"].Enable)
  359. states := make(map[string]*model.PluginState)
  360. states["com.mattermost.nps"] = &model.PluginState{Enable: *model.NewBool(false)}
  361. config := model.Config{PasswordSettings: model.PasswordSettings{
  362. Lowercase: model.NewBool(true),
  363. MinimumLength: model.NewInt(15),
  364. }, LogSettings: model.LogSettings{
  365. ConsoleLevel: model.NewString("INFO"),
  366. },
  367. TeamSettings: model.TeamSettings{
  368. ExperimentalDefaultChannels: []string{"another-channel"},
  369. },
  370. PluginSettings: model.PluginSettings{
  371. PluginStates: states,
  372. },
  373. }
  374. _, response := client.PatchConfig(&config)
  375. updatedConfig, _ := client.GetConfig()
  376. assert.True(t, *updatedConfig.PasswordSettings.Lowercase)
  377. assert.Equal(t, "INFO", *updatedConfig.LogSettings.ConsoleLevel)
  378. assert.Equal(t, []string{"another-channel"}, updatedConfig.TeamSettings.ExperimentalDefaultChannels)
  379. assert.False(t, updatedConfig.PluginSettings.PluginStates["com.mattermost.nps"].Enable)
  380. assert.Equal(t, "no-cache, no-store, must-revalidate", response.Header.Get("Cache-Control"))
  381. // reset the config
  382. _, resp := client.UpdateConfig(oldConfig)
  383. CheckNoError(t, resp)
  384. })
  385. t.Run("should sanitize config", func(t *testing.T) {
  386. config := model.Config{PasswordSettings: model.PasswordSettings{
  387. Symbol: model.NewBool(true),
  388. }}
  389. updatedConfig, _ := client.PatchConfig(&config)
  390. assert.Equal(t, model.FAKE_SETTING, *updatedConfig.SqlSettings.DataSource)
  391. })
  392. t.Run("not allowing to toggle enable uploads for plugin via api", func(t *testing.T) {
  393. config := model.Config{PluginSettings: model.PluginSettings{
  394. EnableUploads: model.NewBool(true),
  395. }}
  396. updatedConfig, _ := client.PatchConfig(&config)
  397. assert.Equal(t, false, *updatedConfig.PluginSettings.EnableUploads)
  398. })
  399. })
  400. t.Run("System Admin should not be able to clear Site URL", func(t *testing.T) {
  401. cfg, resp := th.SystemAdminClient.GetConfig()
  402. CheckNoError(t, resp)
  403. siteURL := cfg.ServiceSettings.SiteURL
  404. defer th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.SiteURL = siteURL })
  405. // Set the SiteURL
  406. nonEmptyURL := "http://localhost"
  407. config := model.Config{
  408. ServiceSettings: model.ServiceSettings{
  409. SiteURL: model.NewString(nonEmptyURL),
  410. },
  411. }
  412. updatedConfig, resp := th.SystemAdminClient.PatchConfig(&config)
  413. CheckNoError(t, resp)
  414. require.Equal(t, nonEmptyURL, *updatedConfig.ServiceSettings.SiteURL)
  415. // Check that the Site URL can't be cleared
  416. config = model.Config{
  417. ServiceSettings: model.ServiceSettings{
  418. SiteURL: model.NewString(""),
  419. },
  420. }
  421. updatedConfig, resp = th.SystemAdminClient.PatchConfig(&config)
  422. CheckBadRequestStatus(t, resp)
  423. CheckErrorMessage(t, resp, "api.config.update_config.clear_siteurl.app_error")
  424. // Check that the Site URL wasn't cleared
  425. cfg, resp = th.SystemAdminClient.GetConfig()
  426. CheckNoError(t, resp)
  427. require.Equal(t, nonEmptyURL, *cfg.ServiceSettings.SiteURL)
  428. })
  429. }