123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230 |
- // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
- // See LICENSE.txt for license information.
- package api4
- import (
- "net/http"
- "reflect"
- "github.com/mattermost/mattermost-server/v5/audit"
- "github.com/mattermost/mattermost-server/v5/config"
- "github.com/mattermost/mattermost-server/v5/model"
- "github.com/mattermost/mattermost-server/v5/utils"
- )
- func (api *API) InitConfig() {
- api.BaseRoutes.ApiRoot.Handle("/config", api.ApiSessionRequired(getConfig)).Methods("GET")
- api.BaseRoutes.ApiRoot.Handle("/config", api.ApiSessionRequired(updateConfig)).Methods("PUT")
- api.BaseRoutes.ApiRoot.Handle("/config/patch", api.ApiSessionRequired(patchConfig)).Methods("PUT")
- api.BaseRoutes.ApiRoot.Handle("/config/reload", api.ApiSessionRequired(configReload)).Methods("POST")
- api.BaseRoutes.ApiRoot.Handle("/config/client", api.ApiHandler(getClientConfig)).Methods("GET")
- api.BaseRoutes.ApiRoot.Handle("/config/environment", api.ApiSessionRequired(getEnvironmentConfig)).Methods("GET")
- }
- func getConfig(c *Context, w http.ResponseWriter, r *http.Request) {
- if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_MANAGE_SYSTEM) {
- c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
- return
- }
- auditRec := c.MakeAuditRecord("getConfig", audit.Fail)
- defer c.LogAuditRec(auditRec)
- cfg := c.App.GetSanitizedConfig()
- auditRec.Success()
- w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
- w.Write([]byte(cfg.ToJson()))
- }
- func configReload(c *Context, w http.ResponseWriter, r *http.Request) {
- auditRec := c.MakeAuditRecord("configReload", audit.Fail)
- defer c.LogAuditRec(auditRec)
- if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_MANAGE_SYSTEM) {
- c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
- return
- }
- if *c.App.Config().ExperimentalSettings.RestrictSystemAdmin {
- c.Err = model.NewAppError("configReload", "api.restricted_system_admin", nil, "", http.StatusBadRequest)
- return
- }
- c.App.ReloadConfig()
- auditRec.Success()
- w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
- ReturnStatusOK(w)
- }
- func updateConfig(c *Context, w http.ResponseWriter, r *http.Request) {
- cfg := model.ConfigFromJson(r.Body)
- if cfg == nil {
- c.SetInvalidParam("config")
- return
- }
- auditRec := c.MakeAuditRecord("updateConfig", audit.Fail)
- defer c.LogAuditRec(auditRec)
- cfg.SetDefaults()
- if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_MANAGE_SYSTEM) {
- c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
- return
- }
- appCfg := c.App.Config()
- if *appCfg.ServiceSettings.SiteURL != "" && *cfg.ServiceSettings.SiteURL == "" {
- c.Err = model.NewAppError("updateConfig", "api.config.update_config.clear_siteurl.app_error", nil, "", http.StatusBadRequest)
- return
- }
- if *c.App.Config().ExperimentalSettings.RestrictSystemAdmin {
- // Start with the current configuration, and only merge values not marked as being
- // restricted.
- var err error
- cfg, err = config.Merge(appCfg, cfg, &utils.MergeConfig{
- StructFieldFilter: func(structField reflect.StructField, base, patch reflect.Value) bool {
- restricted := structField.Tag.Get("restricted") == "true"
- return !restricted
- },
- })
- if err != nil {
- c.Err = model.NewAppError("updateConfig", "api.config.update_config.restricted_merge.app_error", nil, err.Error(), http.StatusInternalServerError)
- }
- }
- // Do not allow plugin uploads to be toggled through the API
- cfg.PluginSettings.EnableUploads = appCfg.PluginSettings.EnableUploads
- // Do not allow certificates to be changed through the API
- cfg.PluginSettings.SignaturePublicKeyFiles = appCfg.PluginSettings.SignaturePublicKeyFiles
- c.App.HandleMessageExportConfig(cfg, appCfg)
- err := cfg.IsValid()
- if err != nil {
- c.Err = err
- return
- }
- err = c.App.SaveConfig(cfg, true)
- if err != nil {
- c.Err = err
- return
- }
- cfg = c.App.GetSanitizedConfig()
- auditRec.Success()
- c.LogAudit("updateConfig")
- w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
- w.Write([]byte(cfg.ToJson()))
- }
- func getClientConfig(c *Context, w http.ResponseWriter, r *http.Request) {
- format := r.URL.Query().Get("format")
- if format == "" {
- c.Err = model.NewAppError("getClientConfig", "api.config.client.old_format.app_error", nil, "", http.StatusNotImplemented)
- return
- }
- if format != "old" {
- c.SetInvalidParam("format")
- return
- }
- var config map[string]string
- if len(c.App.Session().UserId) == 0 {
- config = c.App.LimitedClientConfigWithComputed()
- } else {
- config = c.App.ClientConfigWithComputed()
- }
- w.Write([]byte(model.MapToJson(config)))
- }
- func getEnvironmentConfig(c *Context, w http.ResponseWriter, r *http.Request) {
- if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_MANAGE_SYSTEM) {
- c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
- return
- }
- envConfig := c.App.GetEnvironmentConfig()
- w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
- w.Write([]byte(model.StringInterfaceToJson(envConfig)))
- }
- func patchConfig(c *Context, w http.ResponseWriter, r *http.Request) {
- cfg := model.ConfigFromJson(r.Body)
- if cfg == nil {
- c.SetInvalidParam("config")
- return
- }
- auditRec := c.MakeAuditRecord("patchConfig", audit.Fail)
- defer c.LogAuditRec(auditRec)
- if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_MANAGE_SYSTEM) {
- c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
- return
- }
- appCfg := c.App.Config()
- if *appCfg.ServiceSettings.SiteURL != "" && *cfg.ServiceSettings.SiteURL == "" {
- c.Err = model.NewAppError("patchConfig", "api.config.update_config.clear_siteurl.app_error", nil, "", http.StatusBadRequest)
- return
- }
- var filterFn utils.StructFieldFilter
- if *appCfg.ExperimentalSettings.RestrictSystemAdmin {
- filterFn = func(structField reflect.StructField, base, patch reflect.Value) bool {
- return !(structField.Tag.Get("restricted") == "true")
- }
- } else {
- filterFn = func(structField reflect.StructField, base, patch reflect.Value) bool {
- return true
- }
- }
- // Do not allow plugin uploads to be toggled through the API
- cfg.PluginSettings.EnableUploads = appCfg.PluginSettings.EnableUploads
- if cfg.MessageExportSettings.EnableExport != nil {
- c.App.HandleMessageExportConfig(cfg, appCfg)
- }
- updatedCfg, mergeErr := config.Merge(appCfg, cfg, &utils.MergeConfig{
- StructFieldFilter: filterFn,
- })
- if mergeErr != nil {
- c.Err = model.NewAppError("patchConfig", "api.config.update_config.restricted_merge.app_error", nil, mergeErr.Error(), http.StatusInternalServerError)
- return
- }
- err := updatedCfg.IsValid()
- if err != nil {
- c.Err = err
- return
- }
- err = c.App.SaveConfig(updatedCfg, true)
- if err != nil {
- c.Err = err
- return
- }
- auditRec.Success()
- w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
- w.Write([]byte(c.App.GetSanitizedConfig().ToJson()))
- }
|