github.com/mad-app/mattermost-server@v5.11.1+incompatible/api4/config_test.go (about)

     1  package api4
     2  
     3  import (
     4  	"net/http"
     5  	"os"
     6  	"strings"
     7  	"testing"
     8  
     9  	"github.com/mattermost/mattermost-server/model"
    10  	"github.com/stretchr/testify/assert"
    11  	"github.com/stretchr/testify/require"
    12  )
    13  
    14  func TestGetConfig(t *testing.T) {
    15  	th := Setup().InitBasic()
    16  	defer th.TearDown()
    17  	Client := th.Client
    18  
    19  	_, resp := Client.GetConfig()
    20  	CheckForbiddenStatus(t, resp)
    21  
    22  	cfg, resp := th.SystemAdminClient.GetConfig()
    23  	CheckNoError(t, resp)
    24  
    25  	require.NotEqual(t, "", cfg.TeamSettings.SiteName)
    26  
    27  	if *cfg.LdapSettings.BindPassword != model.FAKE_SETTING && len(*cfg.LdapSettings.BindPassword) != 0 {
    28  		t.Fatal("did not sanitize properly")
    29  	}
    30  	if *cfg.FileSettings.PublicLinkSalt != model.FAKE_SETTING {
    31  		t.Fatal("did not sanitize properly")
    32  	}
    33  	if *cfg.FileSettings.AmazonS3SecretAccessKey != model.FAKE_SETTING && len(*cfg.FileSettings.AmazonS3SecretAccessKey) != 0 {
    34  		t.Fatal("did not sanitize properly")
    35  	}
    36  	if *cfg.EmailSettings.SMTPPassword != model.FAKE_SETTING && len(*cfg.EmailSettings.SMTPPassword) != 0 {
    37  		t.Fatal("did not sanitize properly")
    38  	}
    39  	if *cfg.GitLabSettings.Secret != model.FAKE_SETTING && len(*cfg.GitLabSettings.Secret) != 0 {
    40  		t.Fatal("did not sanitize properly")
    41  	}
    42  	if *cfg.SqlSettings.DataSource != model.FAKE_SETTING {
    43  		t.Fatal("did not sanitize properly")
    44  	}
    45  	if *cfg.SqlSettings.AtRestEncryptKey != model.FAKE_SETTING {
    46  		t.Fatal("did not sanitize properly")
    47  	}
    48  	if !strings.Contains(strings.Join(cfg.SqlSettings.DataSourceReplicas, " "), model.FAKE_SETTING) && len(cfg.SqlSettings.DataSourceReplicas) != 0 {
    49  		t.Fatal("did not sanitize properly")
    50  	}
    51  	if !strings.Contains(strings.Join(cfg.SqlSettings.DataSourceSearchReplicas, " "), model.FAKE_SETTING) && len(cfg.SqlSettings.DataSourceSearchReplicas) != 0 {
    52  		t.Fatal("did not sanitize properly")
    53  	}
    54  }
    55  
    56  func TestReloadConfig(t *testing.T) {
    57  	th := Setup().InitBasic()
    58  	defer th.TearDown()
    59  	Client := th.Client
    60  
    61  	t.Run("as system user", func(t *testing.T) {
    62  		ok, resp := Client.ReloadConfig()
    63  		CheckForbiddenStatus(t, resp)
    64  		if ok {
    65  			t.Fatal("should not Reload the config due no permission.")
    66  		}
    67  	})
    68  
    69  	t.Run("as system admin", func(t *testing.T) {
    70  		ok, resp := th.SystemAdminClient.ReloadConfig()
    71  		CheckNoError(t, resp)
    72  		if !ok {
    73  			t.Fatal("should Reload the config")
    74  		}
    75  	})
    76  
    77  	t.Run("as restricted system admin", func(t *testing.T) {
    78  		th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ExperimentalSettings.RestrictSystemAdmin = true })
    79  
    80  		ok, resp := Client.ReloadConfig()
    81  		CheckForbiddenStatus(t, resp)
    82  		if ok {
    83  			t.Fatal("should not Reload the config due no permission.")
    84  		}
    85  	})
    86  }
    87  
    88  func TestUpdateConfig(t *testing.T) {
    89  	th := Setup().InitBasic()
    90  	defer th.TearDown()
    91  	Client := th.Client
    92  
    93  	cfg, resp := th.SystemAdminClient.GetConfig()
    94  	CheckNoError(t, resp)
    95  
    96  	_, resp = Client.UpdateConfig(cfg)
    97  	CheckForbiddenStatus(t, resp)
    98  
    99  	SiteName := th.App.Config().TeamSettings.SiteName
   100  
   101  	*cfg.TeamSettings.SiteName = "MyFancyName"
   102  	cfg, resp = th.SystemAdminClient.UpdateConfig(cfg)
   103  	CheckNoError(t, resp)
   104  
   105  	require.Equal(t, "MyFancyName", *cfg.TeamSettings.SiteName, "It should update the SiteName")
   106  
   107  	//Revert the change
   108  	cfg.TeamSettings.SiteName = SiteName
   109  	cfg, resp = th.SystemAdminClient.UpdateConfig(cfg)
   110  	CheckNoError(t, resp)
   111  
   112  	require.Equal(t, SiteName, cfg.TeamSettings.SiteName, "It should update the SiteName")
   113  
   114  	t.Run("Should fail with validation error if invalid config setting is passed", func(t *testing.T) {
   115  		//Revert the change
   116  		badcfg := cfg.Clone()
   117  		badcfg.PasswordSettings.MinimumLength = model.NewInt(4)
   118  		badcfg.PasswordSettings.MinimumLength = model.NewInt(4)
   119  		_, resp = th.SystemAdminClient.UpdateConfig(badcfg)
   120  		CheckBadRequestStatus(t, resp)
   121  		CheckErrorMessage(t, resp, "model.config.is_valid.password_length.app_error")
   122  	})
   123  
   124  	t.Run("Should not be able to modify PluginSettings.EnableUploads", func(t *testing.T) {
   125  		oldEnableUploads := *th.App.Config().PluginSettings.EnableUploads
   126  		*cfg.PluginSettings.EnableUploads = !oldEnableUploads
   127  
   128  		cfg, resp = th.SystemAdminClient.UpdateConfig(cfg)
   129  		CheckNoError(t, resp)
   130  		assert.Equal(t, oldEnableUploads, *cfg.PluginSettings.EnableUploads)
   131  		assert.Equal(t, oldEnableUploads, *th.App.Config().PluginSettings.EnableUploads)
   132  
   133  		cfg.PluginSettings.EnableUploads = nil
   134  		cfg, resp = th.SystemAdminClient.UpdateConfig(cfg)
   135  		CheckNoError(t, resp)
   136  		assert.Equal(t, oldEnableUploads, *cfg.PluginSettings.EnableUploads)
   137  		assert.Equal(t, oldEnableUploads, *th.App.Config().PluginSettings.EnableUploads)
   138  	})
   139  }
   140  
   141  func TestUpdateConfigMessageExportSpecialHandling(t *testing.T) {
   142  	th := Setup().InitBasic()
   143  	defer th.TearDown()
   144  
   145  	messageExportEnabled := *th.App.Config().MessageExportSettings.EnableExport
   146  	messageExportTimestamp := *th.App.Config().MessageExportSettings.ExportFromTimestamp
   147  
   148  	defer th.App.UpdateConfig(func(cfg *model.Config) {
   149  		*cfg.MessageExportSettings.EnableExport = messageExportEnabled
   150  		*cfg.MessageExportSettings.ExportFromTimestamp = messageExportTimestamp
   151  	})
   152  
   153  	th.App.UpdateConfig(func(cfg *model.Config) {
   154  		*cfg.MessageExportSettings.EnableExport = false
   155  		*cfg.MessageExportSettings.ExportFromTimestamp = int64(0)
   156  	})
   157  
   158  	// Turn it on, timestamp should be updated.
   159  	cfg, resp := th.SystemAdminClient.GetConfig()
   160  	CheckNoError(t, resp)
   161  
   162  	*cfg.MessageExportSettings.EnableExport = true
   163  	cfg, resp = th.SystemAdminClient.UpdateConfig(cfg)
   164  	CheckNoError(t, resp)
   165  
   166  	assert.True(t, *th.App.Config().MessageExportSettings.EnableExport)
   167  	assert.NotEqual(t, int64(0), *th.App.Config().MessageExportSettings.ExportFromTimestamp)
   168  
   169  	// Turn it off, timestamp should be cleared.
   170  	cfg, resp = th.SystemAdminClient.GetConfig()
   171  	CheckNoError(t, resp)
   172  
   173  	*cfg.MessageExportSettings.EnableExport = false
   174  	cfg, resp = th.SystemAdminClient.UpdateConfig(cfg)
   175  	CheckNoError(t, resp)
   176  
   177  	assert.False(t, *th.App.Config().MessageExportSettings.EnableExport)
   178  	assert.Equal(t, int64(0), *th.App.Config().MessageExportSettings.ExportFromTimestamp)
   179  
   180  	// Set a value from the config file.
   181  	th.App.UpdateConfig(func(cfg *model.Config) {
   182  		*cfg.MessageExportSettings.EnableExport = false
   183  		*cfg.MessageExportSettings.ExportFromTimestamp = int64(12345)
   184  	})
   185  
   186  	// Turn it on, timestamp should *not* be updated.
   187  	cfg, resp = th.SystemAdminClient.GetConfig()
   188  	CheckNoError(t, resp)
   189  
   190  	*cfg.MessageExportSettings.EnableExport = true
   191  	cfg, resp = th.SystemAdminClient.UpdateConfig(cfg)
   192  	CheckNoError(t, resp)
   193  
   194  	assert.True(t, *th.App.Config().MessageExportSettings.EnableExport)
   195  	assert.Equal(t, int64(12345), *th.App.Config().MessageExportSettings.ExportFromTimestamp)
   196  
   197  	// Turn it off, timestamp should be cleared.
   198  	cfg, resp = th.SystemAdminClient.GetConfig()
   199  	CheckNoError(t, resp)
   200  
   201  	*cfg.MessageExportSettings.EnableExport = false
   202  	cfg, resp = th.SystemAdminClient.UpdateConfig(cfg)
   203  	CheckNoError(t, resp)
   204  
   205  	assert.False(t, *th.App.Config().MessageExportSettings.EnableExport)
   206  	assert.Equal(t, int64(0), *th.App.Config().MessageExportSettings.ExportFromTimestamp)
   207  }
   208  
   209  func TestUpdateConfigRestrictSystemAdmin(t *testing.T) {
   210  	th := Setup().InitBasic()
   211  	defer th.TearDown()
   212  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ExperimentalSettings.RestrictSystemAdmin = true })
   213  
   214  	originalCfg, resp := th.SystemAdminClient.GetConfig()
   215  	CheckNoError(t, resp)
   216  
   217  	cfg := originalCfg.Clone()
   218  	*cfg.TeamSettings.SiteName = "MyFancyName"          // Allowed
   219  	*cfg.ServiceSettings.SiteURL = "http://example.com" // Ignored
   220  
   221  	returnedCfg, resp := th.SystemAdminClient.UpdateConfig(cfg)
   222  	CheckNoError(t, resp)
   223  
   224  	require.Equal(t, "MyFancyName", *returnedCfg.TeamSettings.SiteName)
   225  	require.Equal(t, *originalCfg.ServiceSettings.SiteURL, *returnedCfg.ServiceSettings.SiteURL)
   226  
   227  	actualCfg, resp := th.SystemAdminClient.GetConfig()
   228  	CheckNoError(t, resp)
   229  
   230  	require.Equal(t, returnedCfg, actualCfg)
   231  }
   232  
   233  func TestGetEnvironmentConfig(t *testing.T) {
   234  	os.Setenv("MM_SERVICESETTINGS_SITEURL", "http://example.mattermost.com")
   235  	os.Setenv("MM_SERVICESETTINGS_ENABLECUSTOMEMOJI", "true")
   236  	defer os.Unsetenv("MM_SERVICESETTINGS_SITEURL")
   237  
   238  	th := Setup().InitBasic()
   239  	defer th.TearDown()
   240  
   241  	t.Run("as system admin", func(t *testing.T) {
   242  		SystemAdminClient := th.SystemAdminClient
   243  
   244  		envConfig, resp := SystemAdminClient.GetEnvironmentConfig()
   245  		CheckNoError(t, resp)
   246  
   247  		if serviceSettings, ok := envConfig["ServiceSettings"]; !ok {
   248  			t.Fatal("should've returned ServiceSettings")
   249  		} else if serviceSettingsAsMap, ok := serviceSettings.(map[string]interface{}); !ok {
   250  			t.Fatal("should've returned ServiceSettings as a map")
   251  		} else {
   252  			if siteURL, ok := serviceSettingsAsMap["SiteURL"]; !ok {
   253  				t.Fatal("should've returned ServiceSettings.SiteURL")
   254  			} else if siteURLAsBool, ok := siteURL.(bool); !ok {
   255  				t.Fatal("should've returned ServiceSettings.SiteURL as a boolean")
   256  			} else if !siteURLAsBool {
   257  				t.Fatal("should've returned ServiceSettings.SiteURL as true")
   258  			}
   259  
   260  			if enableCustomEmoji, ok := serviceSettingsAsMap["EnableCustomEmoji"]; !ok {
   261  				t.Fatal("should've returned ServiceSettings.EnableCustomEmoji")
   262  			} else if enableCustomEmojiAsBool, ok := enableCustomEmoji.(bool); !ok {
   263  				t.Fatal("should've returned ServiceSettings.EnableCustomEmoji as a boolean")
   264  			} else if !enableCustomEmojiAsBool {
   265  				t.Fatal("should've returned ServiceSettings.EnableCustomEmoji as true")
   266  			}
   267  		}
   268  
   269  		if _, ok := envConfig["TeamSettings"]; ok {
   270  			t.Fatal("should not have returned TeamSettings")
   271  		}
   272  	})
   273  
   274  	t.Run("as team admin", func(t *testing.T) {
   275  		TeamAdminClient := th.CreateClient()
   276  		th.LoginTeamAdminWithClient(TeamAdminClient)
   277  
   278  		_, resp := TeamAdminClient.GetEnvironmentConfig()
   279  		CheckForbiddenStatus(t, resp)
   280  	})
   281  
   282  	t.Run("as regular user", func(t *testing.T) {
   283  		Client := th.Client
   284  
   285  		_, resp := Client.GetEnvironmentConfig()
   286  		CheckForbiddenStatus(t, resp)
   287  	})
   288  
   289  	t.Run("as not-regular user", func(t *testing.T) {
   290  		Client := th.CreateClient()
   291  
   292  		_, resp := Client.GetEnvironmentConfig()
   293  		CheckUnauthorizedStatus(t, resp)
   294  	})
   295  }
   296  
   297  func TestGetOldClientConfig(t *testing.T) {
   298  	th := Setup().InitBasic()
   299  	defer th.TearDown()
   300  
   301  	testKey := "supersecretkey"
   302  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.GoogleDeveloperKey = testKey })
   303  
   304  	t.Run("with session", func(t *testing.T) {
   305  		th.App.UpdateConfig(func(cfg *model.Config) {
   306  			*cfg.ServiceSettings.GoogleDeveloperKey = testKey
   307  		})
   308  
   309  		Client := th.Client
   310  
   311  		config, resp := Client.GetOldClientConfig("")
   312  		CheckNoError(t, resp)
   313  
   314  		if len(config["Version"]) == 0 {
   315  			t.Fatal("config not returned correctly")
   316  		}
   317  
   318  		if config["GoogleDeveloperKey"] != testKey {
   319  			t.Fatal("config missing developer key")
   320  		}
   321  	})
   322  
   323  	t.Run("without session", func(t *testing.T) {
   324  		th.App.UpdateConfig(func(cfg *model.Config) {
   325  			*cfg.ServiceSettings.GoogleDeveloperKey = testKey
   326  		})
   327  
   328  		Client := th.CreateClient()
   329  
   330  		config, resp := Client.GetOldClientConfig("")
   331  		CheckNoError(t, resp)
   332  
   333  		if len(config["Version"]) == 0 {
   334  			t.Fatal("config not returned correctly")
   335  		}
   336  
   337  		if _, ok := config["GoogleDeveloperKey"]; ok {
   338  			t.Fatal("config should be missing developer key")
   339  		}
   340  	})
   341  
   342  	t.Run("missing format", func(t *testing.T) {
   343  		Client := th.Client
   344  
   345  		if _, err := Client.DoApiGet("/config/client", ""); err == nil || err.StatusCode != http.StatusNotImplemented {
   346  			t.Fatal("should have errored with 501")
   347  		}
   348  	})
   349  
   350  	t.Run("invalid format", func(t *testing.T) {
   351  		Client := th.Client
   352  
   353  		if _, err := Client.DoApiGet("/config/client?format=junk", ""); err == nil || err.StatusCode != http.StatusBadRequest {
   354  			t.Fatal("should have errored with 400")
   355  		}
   356  	})
   357  }