From 3e36894ac77b84190135a5c5de6cc8f6b7588067 Mon Sep 17 00:00:00 2001 From: Shivashis Padhi Date: Wed, 3 Aug 2022 15:43:09 +0530 Subject: [PATCH 01/10] Avoid joining with Posts table while getting top user reactions --- store/sqlstore/reaction_store.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/store/sqlstore/reaction_store.go b/store/sqlstore/reaction_store.go index 7651257ff5..d1a56b6e08 100644 --- a/store/sqlstore/reaction_store.go +++ b/store/sqlstore/reaction_store.go @@ -316,8 +316,7 @@ func (s *SqlReactionStore) GetTopForUserSince(userID string, teamID string, sinc count(EmojiName) AS Count FROM Reactions - INNER JOIN Posts ON Reactions.PostId = Posts.Id - INNER JOIN Channels ON Posts.ChannelId = Channels.Id + INNER JOIN Channels ON Channels.Id = Reactions.ChannelId WHERE Reactions.DeleteAt = 0 AND Reactions.UserId = ? From 236716f9c70c18c5fea8b775e088bc7a3eb46941 Mon Sep 17 00:00:00 2001 From: Mustafa Kara Date: Fri, 5 Aug 2022 12:49:45 +0300 Subject: [PATCH 02/10] Stop applying server lint rules to focalbard repo. (#20772) * Stop applying server lint rules to focalbard repo. * Remove board packages from the tests. Signed-off-by: Mustafa Kara Co-authored-by: Mattermod --- Makefile | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 8166fa88b6..d005e85722 100644 --- a/Makefile +++ b/Makefile @@ -184,7 +184,10 @@ endif # Prepare optional Boards build. BOARDS_PACKAGES=$(shell $(GO) list $(BUILD_BOARDS_DIR)/server/...) ifeq ($(BUILD_BOARDS),true) - ALL_PACKAGES += $(BOARDS_PACKAGES) +# We removed `ALL_PACKAGES += $(BOARDS_PACKAGES)` since board tests needs `-tag 'json1'` in the tests. +# Adding that flag to server breaks the build with unsupported flag error. +# PR: https://github.com/mattermost/mattermost-server/pull/20772 +# Ticket: https://mattermost.atlassian.net/browse/CLD-3800 IGNORE:=$(shell echo Boards build selected, preparing) IGNORE:=$(shell rm -f imports/boards_imports.go) IGNORE:=$(shell cp $(BUILD_BOARDS_DIR)/mattermost-plugin/product/imports/boards_imports.go imports/) @@ -317,7 +320,7 @@ ifeq ($(BUILD_ENTERPRISE_READY),true) endif ifeq ($(BUILD_BOARDS),true) ifneq ($(MM_NO_BOARDS_LINT),true) - $(GOBIN)/golangci-lint run $(BUILD_BOARDS_DIR)/server/... + cd $(BUILD_BOARDS_DIR); make server-lint endif endif From b8264217167ec559c3a2765529e0d42f2de6f673 Mon Sep 17 00:00:00 2001 From: Agniva De Sarker Date: Mon, 8 Aug 2022 14:14:18 +0530 Subject: [PATCH 03/10] MM-45534: Fix flaky TestCreateGroupChannel (#20781) The returned elements weren't in a specific order. Therefore, we need to perform an order insensitive match. https://mattermost.atlassian.net/browse/MM-45534 ```release-note NONE ``` --- api4/channel_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api4/channel_test.go b/api4/channel_test.go index a47a92b12b..216e54f082 100644 --- a/api4/channel_test.go +++ b/api4/channel_test.go @@ -569,7 +569,7 @@ func TestCreateGroupChannel(t *testing.T) { require.Equal(t, rgc.Id, rgc2.Id, "should have returned existing channel") m2, _ := th.App.GetChannelMembersPage(th.Context, rgc2.Id, 0, 10) - require.Equal(t, m, m2) + require.ElementsMatch(t, m, m2) _, resp, err = client.CreateGroupChannel([]string{user2.Id}) require.Error(t, err) From f0e4794cdac5ed8f0b4073dbe2f5688cffc35889 Mon Sep 17 00:00:00 2001 From: Ibrahim Serdar Acikgoz Date: Mon, 8 Aug 2022 16:52:31 +0300 Subject: [PATCH 04/10] Move config store into Platform Service (#20718) * update config methods --- app/admin.go | 8 +- app/app_iface.go | 3 +- app/audit.go | 6 +- app/channel_test.go | 2 +- app/channels.go | 16 +- app/cluster_discovery.go | 2 +- app/config.go | 128 ++-------------- app/config_test.go | 35 ----- app/download.go | 2 +- app/enterprise.go | 4 +- app/feature_flags.go | 118 --------------- app/ldap.go | 4 +- app/license.go | 35 +++-- app/migrations.go | 8 +- app/notification_push.go | 2 +- app/notification_push_test.go | 9 +- app/options.go | 34 ++++- app/platform/cluster.go | 12 ++ app/platform/config.go | 145 +++++++++++++++++- app/platform/config_test.go | 47 ++++++ app/platform/feature_flags.go | 118 +++++++++++++++ app/platform/helper_test.go | 87 +++++++++++ app/platform/main_test.go | 32 ++++ app/platform/server_license.go | 19 +++ app/platform/service.go | 28 ++++ app/plugin_signature.go | 6 +- app/post_metadata.go | 2 +- app/post_metadata_test.go | 2 +- app/post_test.go | 8 +- app/reaction_test.go | 8 +- app/saml.go | 12 +- app/security_update_check.go | 4 +- app/server.go | 236 ++++++++++++++---------------- app/server_inactivity.go | 8 +- app/server_license.go | 13 -- app/server_test.go | 45 ++++-- app/status_test.go | 2 +- app/team_test.go | 4 +- app/user_test.go | 10 +- app/web_hub_test.go | 2 +- cmd/mattermost/commands/init.go | 3 +- cmd/mattermost/commands/server.go | 3 +- web/web_test.go | 11 +- 43 files changed, 764 insertions(+), 519 deletions(-) delete mode 100644 app/feature_flags.go create mode 100644 app/platform/cluster.go create mode 100644 app/platform/config_test.go create mode 100644 app/platform/feature_flags.go create mode 100644 app/platform/helper_test.go create mode 100644 app/platform/main_test.go create mode 100644 app/platform/server_license.go delete mode 100644 app/server_license.go diff --git a/app/admin.go b/app/admin.go index 890a0d7d89..8b901b1b5d 100644 --- a/app/admin.go +++ b/app/admin.go @@ -29,7 +29,7 @@ func (s *Server) GetLogs(page, perPage int) ([]string, *model.AppError) { var lines []string license := s.License() - if license != nil && *license.Features.Cluster && s.Cluster != nil && *s.Config().ClusterSettings.Enable { + if license != nil && *license.Features.Cluster && s.Cluster != nil && *s.platform.Config().ClusterSettings.Enable { if info := s.Cluster.GetMyClusterInfo(); info != nil { lines = append(lines, "-----------------------------------------------------------------------------------------------------------") lines = append(lines, "-----------------------------------------------------------------------------------------------------------") @@ -48,7 +48,7 @@ func (s *Server) GetLogs(page, perPage int) ([]string, *model.AppError) { lines = append(lines, melines...) - if s.Cluster != nil && *s.Config().ClusterSettings.Enable { + if s.Cluster != nil && *s.platform.Config().ClusterSettings.Enable { clines, err := s.Cluster.GetLogs(page, perPage) if err != nil { return nil, err @@ -67,9 +67,9 @@ func (a *App) GetLogs(page, perPage int) ([]string, *model.AppError) { func (s *Server) GetLogsSkipSend(page, perPage int) ([]string, *model.AppError) { var lines []string - if *s.Config().LogSettings.EnableFile { + if *s.platform.Config().LogSettings.EnableFile { s.Log.Flush() - logFile := config.GetLogFileLocation(*s.Config().LogSettings.FileLocation) + logFile := config.GetLogFileLocation(*s.platform.Config().LogSettings.FileLocation) file, err := os.Open(logFile) if err != nil { return nil, model.NewAppError("getLogs", "api.admin.file_read_error", nil, err.Error(), http.StatusInternalServerError) diff --git a/app/app_iface.go b/app/app_iface.go index f2466ad4c2..7b54096e61 100644 --- a/app/app_iface.go +++ b/app/app_iface.go @@ -283,6 +283,8 @@ type AppIface interface { // PromoteGuestToUser Convert user's roles and all his membership's roles from // guest roles to regular user roles. PromoteGuestToUser(c *request.Context, user *model.User, requestorId string) *model.AppError + // Removes a listener function by the unique ID returned when AddConfigListener was called + RemoveConfigListener(id string) // RenameChannel is used to rename the channel Name and the DisplayName fields RenameChannel(c request.CTX, channel *model.Channel, newChannelName string, newDisplayName string) (*model.Channel, *model.AppError) // RenameTeam is used to rename the team Name and the DisplayName fields @@ -941,7 +943,6 @@ type AppIface interface { ReloadConfig() error RemoveAllDeactivatedMembersFromChannel(c request.CTX, channel *model.Channel) *model.AppError RemoveChannelsFromRetentionPolicy(policyID string, channelIDs []string) *model.AppError - RemoveConfigListener(id string) RemoveCustomStatus(c request.CTX, userID string) *model.AppError RemoveDirectory(path string) *model.AppError RemoveFile(path string) *model.AppError diff --git a/app/audit.go b/app/audit.go index 9f6e727235..7b250c769e 100644 --- a/app/audit.go +++ b/app/audit.go @@ -109,10 +109,10 @@ func (s *Server) configureAudit(adt *audit.Audit, bAllowAdvancedLogging bool) er adt.OnError = s.onAuditError var logConfigSrc config.LogConfigSrc - dsn := *s.Config().ExperimentalAuditSettings.AdvancedLoggingConfig + dsn := *s.platform.Config().ExperimentalAuditSettings.AdvancedLoggingConfig if bAllowAdvancedLogging && dsn != "" { var err error - logConfigSrc, err = config.NewLogConfigSrc(dsn, s.configStore.Store) + logConfigSrc, err = config.NewLogConfigSrc(dsn, s.platform.GetConfigStore()) if err != nil { return fmt.Errorf("invalid config source for audit, %w", err) } @@ -120,7 +120,7 @@ func (s *Server) configureAudit(adt *audit.Audit, bAllowAdvancedLogging bool) er } // ExperimentalAuditSettings provides basic file audit (E0, E10); logConfigSrc provides advanced config (E20). - cfg, err := config.MloggerConfigFromAuditConfig(s.Config().ExperimentalAuditSettings, logConfigSrc) + cfg, err := config.MloggerConfigFromAuditConfig(s.platform.Config().ExperimentalAuditSettings, logConfigSrc) if err != nil { return fmt.Errorf("invalid config for audit, %w", err) } diff --git a/app/channel_test.go b/app/channel_test.go index 459423ab29..72dc0db3e5 100644 --- a/app/channel_test.go +++ b/app/channel_test.go @@ -2056,7 +2056,7 @@ func TestMarkChannelsAsViewedPanic(t *testing.T) { UserStore: &mockUserStore, SessionStore: &mockSessionStore, OAuthStore: &mockOAuthStore, - ConfigFn: th.App.ch.srv.Config, + ConfigFn: th.App.ch.srv.platform.Config, LicenseFn: th.App.ch.srv.License, }) require.NoError(t, err) diff --git a/app/channels.go b/app/channels.go index 48aba3297c..ed3dea6c44 100644 --- a/app/channels.go +++ b/app/channels.go @@ -31,12 +31,6 @@ type licenseSvc interface { RequestTrialLicense(requesterID string, users int, termsAccepted bool, receiveEmailsAccepted bool) *model.AppError } -// namer is an interface which enforces that -// all services can return their names. -type namer interface { - Name() ServiceKey -} - // Channels contains all channels related state. type Channels struct { srv *Server @@ -107,7 +101,7 @@ func init() { func NewChannels(s *Server, services map[ServiceKey]any) (*Channels, error) { ch := &Channels{ srv: s, - imageProxy: imageproxy.MakeImageProxy(s, s.httpService, s.Log), + imageProxy: imageproxy.MakeImageProxy(s.platform, s.httpService, s.Log), uploadLockMap: map[string]bool{}, } @@ -133,10 +127,6 @@ func NewChannels(s *Server, services map[ServiceKey]any) (*Channels, error) { if !ok { return nil, errors.New("Config service did not satisfy ConfigSvc interface") } - _, ok = svc.(namer) - if !ok { - return nil, errors.New("Config service does not contain Name method") - } ch.cfgSvc = cfgSvc case FilestoreKey: filestore, ok := svc.(filestore.FileBackend) @@ -149,10 +139,6 @@ func NewChannels(s *Server, services map[ServiceKey]any) (*Channels, error) { if !ok { return nil, errors.New("License service did not satisfy licenseSvc interface") } - _, ok = svc.(namer) - if !ok { - return nil, errors.New("License service does not contain Name method") - } ch.licenseSvc = svc } } diff --git a/app/cluster_discovery.go b/app/cluster_discovery.go index 0a003e06a0..9ae26038d4 100644 --- a/app/cluster_discovery.go +++ b/app/cluster_discovery.go @@ -83,7 +83,7 @@ func (cds *ClusterDiscoveryService) Stop() { } func (s *Server) IsLeader() bool { - if s.License() != nil && *s.Config().ClusterSettings.Enable && s.Cluster != nil { + if s.License() != nil && *s.platform.Config().ClusterSettings.Enable && s.Cluster != nil { return s.Cluster.IsLeader() } return true diff --git a/app/config.go b/app/config.go index 6aacab9405..1c66654039 100644 --- a/app/config.go +++ b/app/config.go @@ -12,7 +12,6 @@ import ( "encoding/base64" "encoding/json" "fmt" - "net/http" "net/url" "reflect" "strconv" @@ -22,7 +21,6 @@ import ( "github.com/mattermost/mattermost-server/v6/config" "github.com/mattermost/mattermost-server/v6/model" - "github.com/mattermost/mattermost-server/v6/product" "github.com/mattermost/mattermost-server/v6/shared/mail" "github.com/mattermost/mattermost-server/v6/shared/mlog" "github.com/mattermost/mattermost-server/v6/utils" @@ -32,113 +30,24 @@ const ( ErrorTermsOfServiceNoRowsFound = "app.terms_of_service.get.no_rows.app_error" ) -// ensure the config wrapper implements `product.ConfigService` -var _ product.ConfigService = (*configWrapper)(nil) - -// configWrapper is an adapter struct that only exposes the -// config related functionality to be passed down to other products. -type configWrapper struct { - srv *Server - *config.Store -} - -func (w *configWrapper) Name() ServiceKey { - return ConfigKey -} - -func (w *configWrapper) Config() *model.Config { - return w.Store.Get() -} - -func (w *configWrapper) AddConfigListener(listener func(*model.Config, *model.Config)) string { - return w.Store.AddListener(listener) -} - -func (w *configWrapper) RemoveConfigListener(id string) { - w.Store.RemoveListener(id) -} - -func (w *configWrapper) UpdateConfig(f func(*model.Config)) { - if w.Store.IsReadOnly() { - return - } - old := w.Config() - updated := old.Clone() - f(updated) - if _, _, err := w.Store.Set(updated); err != nil { - mlog.Error("Failed to update config", mlog.Err(err)) - } -} - -func (w *configWrapper) SaveConfig(newCfg *model.Config, sendConfigChangeClusterMessage bool) (*model.Config, *model.Config, *model.AppError) { - oldCfg, newCfg, err := w.Store.Set(newCfg) - if errors.Cause(err) == config.ErrReadOnlyConfiguration { - return nil, nil, model.NewAppError("saveConfig", "ent.cluster.save_config.error", nil, err.Error(), http.StatusForbidden) - } else if err != nil { - return nil, nil, model.NewAppError("saveConfig", "app.save_config.app_error", nil, err.Error(), http.StatusInternalServerError) - } - - if w.srv.startMetrics && *w.Config().MetricsSettings.Enable { - if w.srv.GetMetrics() != nil { - w.srv.GetMetrics().Register() - } - w.srv.platform.RestartMetrics() // TODO: remove when this moved to the platform service - } else { - w.srv.platform.ShutdownMetrics() // TODO: remove when this moved to the platform service - } - - if w.srv.Cluster != nil { - err := w.srv.Cluster.ConfigChanged(w.Store.RemoveEnvironmentOverrides(oldCfg), - w.Store.RemoveEnvironmentOverrides(newCfg), sendConfigChangeClusterMessage) - if err != nil { - return nil, nil, err - } - } - - return oldCfg, newCfg, nil -} - -func (w *configWrapper) ReloadConfig() error { - if err := w.Store.Load(); err != nil { - return err - } - return nil -} - func (s *Server) Config() *model.Config { - return s.configStore.Config() -} - -func (s *Server) ConfigStore() *configWrapper { - return s.configStore + return s.platform.Config() } func (a *App) Config() *model.Config { return a.ch.cfgSvc.Config() } -func (s *Server) EnvironmentConfig(filter func(reflect.StructField) bool) map[string]any { - return s.configStore.GetEnvironmentOverridesWithFilter(filter) -} - func (a *App) EnvironmentConfig(filter func(reflect.StructField) bool) map[string]any { - return a.Srv().EnvironmentConfig(filter) -} - -func (s *Server) UpdateConfig(f func(*model.Config)) { - s.configStore.UpdateConfig(f) + return a.Srv().platform.GetEnvironmentOverridesWithFilter(filter) } func (a *App) UpdateConfig(f func(*model.Config)) { - a.Srv().UpdateConfig(f) -} - -func (s *Server) ReloadConfig() error { - return s.configStore.ReloadConfig() + a.Srv().platform.UpdateConfig(f) } func (a *App) ReloadConfig() error { - return a.Srv().ReloadConfig() + return a.Srv().platform.ReloadConfig() } func (a *App) ClientConfig() map[string]string { @@ -153,24 +62,13 @@ func (a *App) LimitedClientConfig() map[string]string { return a.ch.limitedClientConfig.Load().(map[string]string) } -// Registers a function with a given listener to be called when the config is reloaded and may have changed. The function -// will be called with two arguments: the old config and the new config. AddConfigListener returns a unique ID -// for the listener that can later be used to remove it. -func (s *Server) AddConfigListener(listener func(*model.Config, *model.Config)) string { - return s.configStore.AddConfigListener(listener) -} - func (a *App) AddConfigListener(listener func(*model.Config, *model.Config)) string { - return a.Srv().AddConfigListener(listener) + return a.Srv().platform.AddConfigListener(listener) } // Removes a listener function by the unique ID returned when AddConfigListener was called -func (s *Server) RemoveConfigListener(id string) { - s.configStore.RemoveConfigListener(id) -} - func (a *App) RemoveConfigListener(id string) { - a.Srv().RemoveConfigListener(id) + a.Srv().platform.RemoveConfigListener(id) } // ensurePostActionCookieSecret ensures that the key for encrypting PostActionCookie exists @@ -449,7 +347,7 @@ func (a *App) LimitedClientConfigWithComputed() map[string]string { // GetConfigFile proxies access to the given configuration file to the underlying config store. func (a *App) GetConfigFile(name string) ([]byte, error) { - data, err := a.Srv().configStore.GetFile(name) + data, err := a.Srv().platform.GetConfigFile(name) if err != nil { return nil, errors.Wrapf(err, "failed to get config file %s", name) } @@ -471,15 +369,9 @@ func (a *App) GetEnvironmentConfig(filter func(reflect.StructField) bool) map[st return a.EnvironmentConfig(filter) } -// SaveConfig replaces the active configuration, optionally notifying cluster peers. -// It returns both the previous and current configs. -func (s *Server) SaveConfig(newCfg *model.Config, sendConfigChangeClusterMessage bool) (*model.Config, *model.Config, *model.AppError) { - return s.configStore.SaveConfig(newCfg, sendConfigChangeClusterMessage) -} - // SaveConfig replaces the active configuration, optionally notifying cluster peers. func (a *App) SaveConfig(newCfg *model.Config, sendConfigChangeClusterMessage bool) (*model.Config, *model.Config, *model.AppError) { - return a.Srv().SaveConfig(newCfg, sendConfigChangeClusterMessage) + return a.Srv().platform.SaveConfig(newCfg, sendConfigChangeClusterMessage) } func (a *App) HandleMessageExportConfig(cfg *model.Config, appCfg *model.Config) { @@ -499,8 +391,8 @@ func (a *App) HandleMessageExportConfig(cfg *model.Config, appCfg *model.Config) } func (s *Server) MailServiceConfig() *mail.SMTPConfig { - emailSettings := s.Config().EmailSettings - hostname := utils.GetHostnameFromSiteURL(*s.Config().ServiceSettings.SiteURL) + emailSettings := s.platform.Config().EmailSettings + hostname := utils.GetHostnameFromSiteURL(*s.platform.Config().ServiceSettings.SiteURL) cfg := mail.SMTPConfig{ Hostname: hostname, ConnectionSecurity: *emailSettings.ConnectionSecurity, diff --git a/app/config_test.go b/app/config_test.go index fcca2889a4..aa019e4281 100644 --- a/app/config_test.go +++ b/app/config_test.go @@ -16,41 +16,6 @@ import ( "github.com/mattermost/mattermost-server/v6/utils" ) -func TestConfigListener(t *testing.T) { - th := Setup(t) - defer th.TearDown() - - originalSiteName := th.App.Config().TeamSettings.SiteName - - listenerCalled := false - listener := func(oldConfig *model.Config, newConfig *model.Config) { - assert.False(t, listenerCalled, "listener called twice") - - assert.Equal(t, *originalSiteName, *oldConfig.TeamSettings.SiteName, "old config contains incorrect site name") - assert.Equal(t, "test123", *newConfig.TeamSettings.SiteName, "new config contains incorrect site name") - - listenerCalled = true - } - listenerId := th.App.AddConfigListener(listener) - defer th.App.RemoveConfigListener(listenerId) - - listener2Called := false - listener2 := func(oldConfig *model.Config, newConfig *model.Config) { - assert.False(t, listener2Called, "listener2 called twice") - - listener2Called = true - } - listener2Id := th.App.AddConfigListener(listener2) - defer th.App.RemoveConfigListener(listener2Id) - - th.App.UpdateConfig(func(cfg *model.Config) { - *cfg.TeamSettings.SiteName = "test123" - }) - - assert.True(t, listenerCalled, "listener should've been called") - assert.True(t, listener2Called, "listener 2 should've been called") -} - func TestAsymmetricSigningKey(t *testing.T) { th := SetupWithStoreMock(t) defer th.TearDown() diff --git a/app/download.go b/app/download.go index ac9ac68466..d83299d483 100644 --- a/app/download.go +++ b/app/download.go @@ -35,7 +35,7 @@ func (s *Server) downloadFromURL(downloadURL string) ([]byte, error) { if err != nil { return nil, errors.Errorf("failed to parse url %s", downloadURL) } - if !*s.Config().PluginSettings.AllowInsecureDownloadURL && u.Scheme != "https" { + if !*s.platform.Config().PluginSettings.AllowInsecureDownloadURL && u.Scheme != "https" { return nil, errors.Errorf("insecure url not allowed %s", downloadURL) } diff --git a/app/enterprise.go b/app/enterprise.go index bb34bb1d8e..db826a873f 100644 --- a/app/enterprise.go +++ b/app/enterprise.go @@ -87,9 +87,9 @@ func RegisterCloudInterface(f func(*Server) einterfaces.CloudInterface) { cloudInterface = f } -var metricsInterface func(*Server) einterfaces.MetricsInterface +var metricsInterface func(*Server, string, string) einterfaces.MetricsInterface -func RegisterMetricsInterface(f func(*Server) einterfaces.MetricsInterface) { +func RegisterMetricsInterface(f func(*Server, string, string) einterfaces.MetricsInterface) { metricsInterface = f } diff --git a/app/feature_flags.go b/app/feature_flags.go deleted file mode 100644 index efb517eca3..0000000000 --- a/app/feature_flags.go +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. -// See LICENSE.txt for license information. - -package app - -import ( - "encoding/json" - "os" - "time" - - "github.com/mattermost/mattermost-server/v6/app/featureflag" - "github.com/mattermost/mattermost-server/v6/shared/mlog" -) - -// setupFeatureFlags called on startup and when the cluster leader changes. -// Starts or stops the synchronization of feature flags from upstream management. -func (s *Server) setupFeatureFlags() { - s.featureFlagSynchronizerMutex.Lock() - defer s.featureFlagSynchronizerMutex.Unlock() - splitKey := *s.Config().ServiceSettings.SplitKey - splitConfigured := splitKey != "" - syncFeatureFlags := splitConfigured && s.IsLeader() - - s.configStore.SetReadOnlyFF(!splitConfigured) - - if syncFeatureFlags { - if err := s.startFeatureFlagUpdateJob(); err != nil { - s.Log.Warn("Unable to setup synchronization with feature flag management. Will fallback to cache.", mlog.Err(err)) - } - } else { - s.stopFeatureFlagUpdateJob() - } - - if err := s.configStore.Load(); err != nil { - s.Log.Warn("Unable to load config store after feature flag setup.", mlog.Err(err)) - } -} - -func (s *Server) updateFeatureFlagValuesFromManagement() { - newCfg := s.configStore.GetNoEnv().Clone() - oldFlags := *newCfg.FeatureFlags - newFlags := s.featureFlagSynchronizer.UpdateFeatureFlagValues(oldFlags) - oldFlagsBytes, _ := json.Marshal(oldFlags) - newFlagsBytes, _ := json.Marshal(newFlags) - s.Log.Debug("Checking feature flags from management service", mlog.String("old_flags", string(oldFlagsBytes)), mlog.String("new_flags", string(newFlagsBytes))) - if oldFlags != newFlags { - s.Log.Debug("Feature flag change detected, updating config") - *newCfg.FeatureFlags = newFlags - s.SaveConfig(newCfg, true) - } -} - -func (s *Server) startFeatureFlagUpdateJob() error { - // Can be run multiple times - if s.featureFlagSynchronizer != nil { - return nil - } - - var log *mlog.Logger - if *s.Config().ServiceSettings.DebugSplit { - log = s.Log - } - - attributes := map[string]any{} - - // if we are part of a cloud installation, add its installation and group id - if installationId := os.Getenv("MM_CLOUD_INSTALLATION_ID"); installationId != "" { - attributes["installation_id"] = installationId - } - if groupId := os.Getenv("MM_CLOUD_GROUP_ID"); groupId != "" { - attributes["group_id"] = groupId - } - - synchronizer, err := featureflag.NewSynchronizer(featureflag.SyncParams{ - ServerID: s.TelemetryId(), - SplitKey: *s.Config().ServiceSettings.SplitKey, - Log: log, - Attributes: attributes, - }) - if err != nil { - return err - } - - s.featureFlagStop = make(chan struct{}) - s.featureFlagStopped = make(chan struct{}) - s.featureFlagSynchronizer = synchronizer - syncInterval := *s.Config().ServiceSettings.FeatureFlagSyncIntervalSeconds - - go func() { - ticker := time.NewTicker(time.Duration(syncInterval) * time.Second) - defer ticker.Stop() - defer close(s.featureFlagStopped) - if err := synchronizer.EnsureReady(); err != nil { - s.Log.Warn("Problem connecting to feature flag management. Will fallback to cloud cache.", mlog.Err(err)) - return - } - s.updateFeatureFlagValuesFromManagement() - for { - select { - case <-s.featureFlagStop: - return - case <-ticker.C: - s.updateFeatureFlagValuesFromManagement() - } - } - }() - - return nil -} - -func (s *Server) stopFeatureFlagUpdateJob() { - if s.featureFlagSynchronizer != nil { - close(s.featureFlagStop) - <-s.featureFlagStopped - s.featureFlagSynchronizer.Close() - s.featureFlagSynchronizer = nil - } -} diff --git a/app/ldap.go b/app/ldap.go index 20f4fdf752..40399f50f4 100644 --- a/app/ldap.go +++ b/app/ldap.go @@ -191,7 +191,7 @@ func (a *App) writeLdapFile(filename string, fileData *multipart.FileHeader) *mo return model.NewAppError("AddLdapCertificate", "api.admin.add_certificate.saving.app_error", nil, err.Error(), http.StatusInternalServerError) } - err = a.Srv().configStore.SetFile(filename, data) + err = a.Srv().platform.SetConfigFile(filename, data) if err != nil { return model.NewAppError("AddLdapCertificate", "api.admin.add_certificate.saving.app_error", nil, err.Error(), http.StatusInternalServerError) } @@ -234,7 +234,7 @@ func (a *App) AddLdapPrivateCertificate(fileData *multipart.FileHeader) *model.A } func (a *App) removeLdapFile(filename string) *model.AppError { - if err := a.Srv().configStore.RemoveFile(filename); err != nil { + if err := a.Srv().platform.RemoveConfigFile(filename); err != nil { return model.NewAppError("RemoveLdapFile", "api.admin.remove_certificate.delete.app_error", map[string]any{"Filename": filename}, err.Error(), http.StatusInternalServerError) } return nil diff --git a/app/license.go b/app/license.go index c6617bd76f..ff6b2dff9a 100644 --- a/app/license.go +++ b/app/license.go @@ -48,7 +48,7 @@ func (w *licenseWrapper) GetLicense() *model.License { } func (w *licenseWrapper) RequestTrialLicense(requesterID string, users int, termsAccepted bool, receiveEmailsAccepted bool) *model.AppError { - if *w.srv.Config().ExperimentalSettings.RestrictSystemAdmin { + if *w.srv.platform.Config().ExperimentalSettings.RestrictSystemAdmin { return model.NewAppError("RequestTrialLicense", "api.restricted_system_admin", nil, "", http.StatusForbidden) } @@ -75,8 +75,8 @@ func (w *licenseWrapper) RequestTrialLicense(requesterID string, users int, term ServerID: w.srv.TelemetryId(), Name: requester.GetDisplayName(model.ShowFullName), Email: requester.Email, - SiteName: *w.srv.Config().TeamSettings.SiteName, - SiteURL: *w.srv.Config().ServiceSettings.SiteURL, + SiteName: *w.srv.platform.Config().TeamSettings.SiteName, + SiteURL: *w.srv.platform.Config().ServiceSettings.SiteURL, Users: users, TermsAccepted: termsAccepted, ReceiveEmailsAccepted: receiveEmailsAccepted, @@ -93,6 +93,11 @@ type JWTClaims struct { jwt.StandardClaims } +func (s *Server) License() *model.License { + license, _ := s.licenseValue.Load().(*model.License) + return license +} + func (s *Server) LoadLicense() { // ENV var overrides all other sources of license. licenseStr := os.Getenv(LicenseEnv) @@ -131,7 +136,7 @@ func (s *Server) LoadLicense() { if !model.IsValidId(licenseId) { // Lets attempt to load the file from disk since it was missing from the DB - license, licenseBytes := utils.GetAndValidateLicenseFileFromDisk(*s.Config().ServiceSettings.LicenseFileLocation) + license, licenseBytes := utils.GetAndValidateLicenseFileFromDisk(*s.platform.Config().ServiceSettings.LicenseFileLocation) if license != nil { if _, err := s.SaveLicense(licenseBytes); err != nil { @@ -177,13 +182,13 @@ func (s *Server) SaveLicense(licenseBytes []byte) (*model.License, *model.AppErr return nil, model.NewAppError("addLicense", model.ExpiredLicenseError, nil, "", http.StatusBadRequest) } - if *s.Config().JobSettings.RunJobs && s.Jobs != nil { + if *s.platform.Config().JobSettings.RunJobs && s.Jobs != nil { if err := s.Jobs.StopWorkers(); err != nil && !errors.Is(err, jobs.ErrWorkersNotRunning) { mlog.Warn("Stopping job server workers failed", mlog.Err(err)) } } - if *s.Config().JobSettings.RunScheduler && s.Jobs != nil { + if *s.platform.Config().JobSettings.RunScheduler && s.Jobs != nil { if err := s.Jobs.StopSchedulers(); err != nil && !errors.Is(err, jobs.ErrSchedulersNotRunning) { mlog.Error("Stopping job server schedulers failed", mlog.Err(err)) } @@ -193,12 +198,12 @@ func (s *Server) SaveLicense(licenseBytes []byte) (*model.License, *model.AppErr // restart job server workers - this handles the edge case where a license file is uploaded, but the job server // doesn't start until the server is restarted, which prevents the 'run job now' buttons in system console from // functioning as expected - if *s.Config().JobSettings.RunJobs && s.Jobs != nil { + if *s.platform.Config().JobSettings.RunJobs && s.Jobs != nil { if err := s.Jobs.StartWorkers(); err != nil { mlog.Error("Starting job server workers failed", mlog.Err(err)) } } - if *s.Config().JobSettings.RunScheduler && s.Jobs != nil { + if *s.platform.Config().JobSettings.RunScheduler && s.Jobs != nil { if err := s.Jobs.StartSchedulers(); err != nil && !errors.Is(err, jobs.ErrSchedulersRunning) { mlog.Error("Starting job server schedulers failed", mlog.Err(err)) } @@ -233,7 +238,7 @@ func (s *Server) SaveLicense(licenseBytes []byte) (*model.License, *model.AppErr return nil, model.NewAppError("addLicense", "api.license.add_license.save_active.app_error", nil, "", http.StatusInternalServerError) } - s.ReloadConfig() + s.platform.ReloadConfig() s.InvalidateAllCaches() return &license, nil @@ -256,12 +261,20 @@ func (s *Server) SetLicense(license *model.License) bool { license.Features.SetDefaults() s.licenseValue.Store(license) + if s.platform != nil { + s.platform.SetLicense(license) + } + s.clientLicenseValue.Store(utils.GetClientLicense(license)) return true } s.licenseValue.Store((*model.License)(nil)) s.clientLicenseValue.Store(map[string]string(nil)) + if s.platform != nil { + s.platform.SetLicense((*model.License)(nil)) + } + return false } @@ -307,7 +320,7 @@ func (s *Server) RemoveLicense() *model.AppError { } s.SetLicense(nil) - s.ReloadConfig() + s.platform.ReloadConfig() s.InvalidateAllCaches() return nil @@ -360,7 +373,7 @@ func (s *Server) RequestTrialLicense(trialRequest *model.TrialLicenseRequest) *m return err } - s.ReloadConfig() + s.platform.ReloadConfig() s.InvalidateAllCaches() return nil diff --git a/app/migrations.go b/app/migrations.go index aba545c443..36d12302c1 100644 --- a/app/migrations.go +++ b/app/migrations.go @@ -69,9 +69,9 @@ func (s *Server) doAdvancedPermissionsMigration() { return } - config := s.Config() + config := s.platform.Config() *config.ServiceSettings.PostEditTimeLimit = -1 - if _, _, err := s.SaveConfig(config, true); err != nil { + if _, _, err := s.platform.SaveConfig(config, true); err != nil { mlog.Error("Failed to update config in Advanced Permissions Phase 1 Migration.", mlog.Err(err)) } @@ -327,7 +327,7 @@ func (s *Server) doContentExtractionConfigDefaultTrueMigration() { return } - s.UpdateConfig(func(config *model.Config) { + s.platform.UpdateConfig(func(config *model.Config) { config.FileSettings.ExtractContent = model.NewBool(true) }) @@ -474,7 +474,7 @@ const existingInstallationPostsThreshold = 10 func (s *Server) doFirstAdminSetupCompleteMigration() { // Don't run the migration until the flag is turned on. - if !s.Config().FeatureFlags.UseCaseOnboarding { + if !s.platform.Config().FeatureFlags.UseCaseOnboarding { return } diff --git a/app/notification_push.go b/app/notification_push.go index e10b716c7d..b0643754a5 100644 --- a/app/notification_push.go +++ b/app/notification_push.go @@ -290,7 +290,7 @@ func (a *App) UpdateMobileAppBadge(userID string) { } func (s *Server) createPushNotificationsHub(c request.CTX) { - buffer := *s.Config().EmailSettings.PushNotificationBuffer + buffer := *s.platform.Config().EmailSettings.PushNotificationBuffer hub := PushNotificationsHub{ notificationsChan: make(chan PushNotification, buffer), app: New(ServerConnector(s.Channels())), diff --git a/app/notification_push_test.go b/app/notification_push_test.go index 53ac88db13..0f3e8a157f 100644 --- a/app/notification_push_test.go +++ b/app/notification_push_test.go @@ -17,6 +17,7 @@ import ( "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" + "github.com/mattermost/mattermost-server/v6/app/platform" "github.com/mattermost/mattermost-server/v6/config" "github.com/mattermost/mattermost-server/v6/model" fmocks "github.com/mattermost/mattermost-server/v6/shared/filestore/mocks" @@ -1443,9 +1444,13 @@ func TestPushNotificationRace(t *testing.T) { Router: mux.NewRouter(), filestore: &fmocks.FileBackend{}, } - s.configStore = &configWrapper{srv: s, Store: memoryStore} + var err error + s.platform, err = platform.New(platform.ServiceConfig{ + ConfigStore: memoryStore, + }) + require.NoError(t, err) serviceMap := map[ServiceKey]any{ - ConfigKey: s.configStore, + ConfigKey: s.platform, LicenseKey: &licenseWrapper{s}, FilestoreKey: s.filestore, } diff --git a/app/options.go b/app/options.go index 4c35cd0478..6452fd9092 100644 --- a/app/options.go +++ b/app/options.go @@ -6,6 +6,7 @@ package app import ( "github.com/pkg/errors" + "github.com/mattermost/mattermost-server/v6/app/platform" "github.com/mattermost/mattermost-server/v6/config" "github.com/mattermost/mattermost-server/v6/einterfaces" "github.com/mattermost/mattermost-server/v6/model" @@ -52,7 +53,22 @@ func Config(dsn string, readOnly bool, configDefaults *model.Config) Option { return errors.Wrap(err, "failed to apply Config option") } - s.configStore = &configWrapper{srv: s, Store: configStore} + platformCfg := platform.ServiceConfig{ + ConfigStore: configStore, + Logger: s.Log, + StartMetrics: s.startMetrics, + Cluster: s.Cluster, + } + if metricsInterface != nil { + platformCfg.Metrics = metricsInterface(s, *configStore.Get().SqlSettings.DriverName, *configStore.Get().SqlSettings.DataSource) + } + + ps, sErr := platform.New(platformCfg) + if sErr != nil { + return errors.Wrap(sErr, "failed to initialize platform") + } + s.platform = ps + return nil } } @@ -60,7 +76,21 @@ func Config(dsn string, readOnly bool, configDefaults *model.Config) Option { // ConfigStore applies the given config store, typically to replace the traditional sources with a memory store for testing. func ConfigStore(configStore *config.Store) Option { return func(s *Server) error { - s.configStore = &configWrapper{srv: s, Store: configStore} + platformCfg := platform.ServiceConfig{ + ConfigStore: configStore, + Logger: s.Log, + StartMetrics: s.startMetrics, + Cluster: s.Cluster, + } + if metricsInterface != nil { + platformCfg.Metrics = metricsInterface(s, *configStore.Get().SqlSettings.DriverName, *configStore.Get().SqlSettings.DataSource) + } + + ps, sErr := platform.New(platformCfg) + if sErr != nil { + return errors.Wrap(sErr, "failed to initialize platform") + } + s.platform = ps return nil } diff --git a/app/platform/cluster.go b/app/platform/cluster.go new file mode 100644 index 0000000000..75fe329cea --- /dev/null +++ b/app/platform/cluster.go @@ -0,0 +1,12 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +package platform + +func (ps *PlatformService) IsLeader() bool { + if ps.License() != nil && *ps.Config().ClusterSettings.Enable && ps.cluster != nil { + return ps.cluster.IsLeader() + } + + return true +} diff --git a/app/platform/config.go b/app/platform/config.go index 20c5a823d5..fc13aa3761 100644 --- a/app/platform/config.go +++ b/app/platform/config.go @@ -5,9 +5,14 @@ package platform import ( "errors" + "fmt" + "net/http" + "reflect" "github.com/mattermost/mattermost-server/v6/config" "github.com/mattermost/mattermost-server/v6/einterfaces" + "github.com/mattermost/mattermost-server/v6/model" + "github.com/mattermost/mattermost-server/v6/product" "github.com/mattermost/mattermost-server/v6/shared/mlog" ) @@ -30,7 +35,145 @@ func (c *ServiceConfig) validate() error { } if c.Logger == nil { - return errors.New("Logger is required") + var err error + // If Logger is not set, use a default logger temporarily. + // this should be removed once the logger is properly configured with the service config. + // MM-45841 + c.Logger, err = mlog.NewLogger() + if err != nil { + return err + } } return nil } + +// ensure the config wrapper implements `product.ConfigService` +var _ product.ConfigService = (*PlatformService)(nil) + +func (ps *PlatformService) Config() *model.Config { + return ps.configStore.Get() +} + +// Registers a function with a given listener to be called when the config is reloaded and may have changed. The function +// will be called with two arguments: the old config and the new config. AddConfigListener returns a unique ID +// for the listener that can later be used to remove it. +func (ps *PlatformService) AddConfigListener(listener func(*model.Config, *model.Config)) string { + return ps.configStore.AddListener(listener) +} + +func (ps *PlatformService) RemoveConfigListener(id string) { + ps.configStore.RemoveListener(id) +} + +func (ps *PlatformService) UpdateConfig(f func(*model.Config)) { + if ps.configStore.IsReadOnly() { + return + } + old := ps.Config() + updated := old.Clone() + f(updated) + if _, _, err := ps.configStore.Set(updated); err != nil { + ps.logger.Error("Failed to update config", mlog.Err(err)) + } +} + +// SaveConfig replaces the active configuration, optionally notifying cluster peers. +// It returns both the previous and current configs. +func (ps *PlatformService) SaveConfig(newCfg *model.Config, sendConfigChangeClusterMessage bool) (*model.Config, *model.Config, *model.AppError) { + oldCfg, newCfg, err := ps.configStore.Set(newCfg) + if errors.Is(err, config.ErrReadOnlyConfiguration) { + return nil, nil, model.NewAppError("saveConfig", "ent.cluster.save_config.error", nil, err.Error(), http.StatusForbidden) + } else if err != nil { + return nil, nil, model.NewAppError("saveConfig", "app.save_config.app_error", nil, err.Error(), http.StatusInternalServerError) + } + + if ps.serviceConfig.StartMetrics && *ps.Config().MetricsSettings.Enable { + ps.RestartMetrics() + } else { + ps.ShutdownMetrics() + } + + if ps.cluster != nil { + err := ps.cluster.ConfigChanged(ps.configStore.RemoveEnvironmentOverrides(oldCfg), + ps.configStore.RemoveEnvironmentOverrides(newCfg), sendConfigChangeClusterMessage) + if err != nil { + return nil, nil, err + } + } + + return oldCfg, newCfg, nil +} + +func (ps *PlatformService) ReloadConfig() error { + if err := ps.configStore.Load(); err != nil { + return err + } + return nil +} + +func (ps *PlatformService) GetEnvironmentOverridesWithFilter(filter func(reflect.StructField) bool) map[string]interface{} { + return ps.configStore.GetEnvironmentOverridesWithFilter(filter) +} + +func (ps *PlatformService) GetEnvironmentOverrides() map[string]interface{} { + return ps.configStore.GetEnvironmentOverrides() +} + +func (ps *PlatformService) DescribeConfig() string { + return ps.configStore.String() +} + +func (ps *PlatformService) CleanUpConfig() error { + return ps.configStore.CleanUp() +} + +// ConfigureLogger applies the specified configuration to a logger. +func (ps *PlatformService) ConfigureLogger(name string, logger *mlog.Logger, logSettings *model.LogSettings, getPath func(string) string) error { + // Advanced logging is E20 only, however logging must be initialized before the license + // file is loaded. If no valid E20 license exists then advanced logging will be + // shutdown once license is loaded/checked. + var err error + dsn := *logSettings.AdvancedLoggingConfig + var logConfigSrc config.LogConfigSrc + if dsn != "" { + logConfigSrc, err = config.NewLogConfigSrc(dsn, ps.configStore) + if err != nil { + return fmt.Errorf("invalid config source for %s, %w", name, err) + } + ps.logger.Info("Loaded configuration for "+name, mlog.String("source", dsn)) + } + + cfg, err := config.MloggerConfigFromLoggerConfig(logSettings, logConfigSrc, getPath) + if err != nil { + return fmt.Errorf("invalid config source for %s, %w", name, err) + } + + if err := logger.ConfigureTargets(cfg, nil); err != nil { + return fmt.Errorf("invalid config for %s, %w", name, err) + } + return nil +} + +func (ps *PlatformService) GetConfigStore() *config.Store { + return ps.configStore +} + +func (ps *PlatformService) GetConfigFile(name string) ([]byte, error) { + return ps.configStore.GetFile(name) +} + +func (ps *PlatformService) SetConfigFile(name string, data []byte) error { + return ps.configStore.SetFile(name, data) +} + +func (ps *PlatformService) RemoveConfigFile(name string) error { + return ps.configStore.RemoveFile(name) +} + +func (ps *PlatformService) HasConfigFile(name string) (bool, error) { + return ps.configStore.HasFile(name) +} + +func (ps *PlatformService) SetConfigReadOnlyFF(readOnly bool) { + ps.configStore.SetReadOnlyFF(readOnly) +} diff --git a/app/platform/config_test.go b/app/platform/config_test.go new file mode 100644 index 0000000000..62ecbce482 --- /dev/null +++ b/app/platform/config_test.go @@ -0,0 +1,47 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +package platform + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/mattermost/mattermost-server/v6/model" +) + +func TestConfigListener(t *testing.T) { + th := Setup(t) + defer th.TearDown() + + originalSiteName := th.Service.Config().TeamSettings.SiteName + + listenerCalled := false + listener := func(oldConfig *model.Config, newConfig *model.Config) { + assert.False(t, listenerCalled, "listener called twice") + + assert.Equal(t, *originalSiteName, *oldConfig.TeamSettings.SiteName, "old config contains incorrect site name") + assert.Equal(t, "test123", *newConfig.TeamSettings.SiteName, "new config contains incorrect site name") + + listenerCalled = true + } + listenerId := th.Service.AddConfigListener(listener) + defer th.Service.RemoveConfigListener(listenerId) + + listener2Called := false + listener2 := func(oldConfig *model.Config, newConfig *model.Config) { + assert.False(t, listener2Called, "listener2 called twice") + + listener2Called = true + } + listener2Id := th.Service.AddConfigListener(listener2) + defer th.Service.RemoveConfigListener(listener2Id) + + th.Service.UpdateConfig(func(cfg *model.Config) { + *cfg.TeamSettings.SiteName = "test123" + }) + + assert.True(t, listenerCalled, "listener should've been called") + assert.True(t, listener2Called, "listener 2 should've been called") +} diff --git a/app/platform/feature_flags.go b/app/platform/feature_flags.go new file mode 100644 index 0000000000..8bcc8843d5 --- /dev/null +++ b/app/platform/feature_flags.go @@ -0,0 +1,118 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +package platform + +import ( + "encoding/json" + "os" + "time" + + "github.com/mattermost/mattermost-server/v6/app/featureflag" + "github.com/mattermost/mattermost-server/v6/shared/mlog" +) + +// SetupFeatureFlags called on startup and when the cluster leader changes. +// Starts or stops the synchronization of feature flags from upstream management. +func (ps *PlatformService) SetupFeatureFlags() { + ps.featureFlagSynchronizerMutex.Lock() + defer ps.featureFlagSynchronizerMutex.Unlock() + splitKey := *ps.Config().ServiceSettings.SplitKey + splitConfigured := splitKey != "" + syncFeatureFlags := splitConfigured && ps.IsLeader() + + ps.configStore.SetReadOnlyFF(!splitConfigured) + + if syncFeatureFlags { + if err := ps.startFeatureFlagUpdateJob(); err != nil { + ps.logger.Warn("Unable to setup synchronization with feature flag management. Will fallback to cache.", mlog.Err(err)) + } + } else { + ps.StopFeatureFlagUpdateJob() + } + + if err := ps.configStore.Load(); err != nil { + ps.logger.Warn("Unable to load config store after feature flag setup.", mlog.Err(err)) + } +} + +func (ps *PlatformService) updateFeatureFlagValuesFromManagement() { + newCfg := ps.configStore.GetNoEnv().Clone() + oldFlags := *newCfg.FeatureFlags + newFlags := ps.featureFlagSynchronizer.UpdateFeatureFlagValues(oldFlags) + oldFlagsBytes, _ := json.Marshal(oldFlags) + newFlagsBytes, _ := json.Marshal(newFlags) + ps.logger.Debug("Checking feature flags from management service", mlog.String("old_flags", string(oldFlagsBytes)), mlog.String("new_flags", string(newFlagsBytes))) + if oldFlags != newFlags { + ps.logger.Debug("Feature flag change detected, updating config") + *newCfg.FeatureFlags = newFlags + ps.SaveConfig(newCfg, true) + } +} + +func (ps *PlatformService) startFeatureFlagUpdateJob() error { + // Can be run multiple times + if ps.featureFlagSynchronizer != nil { + return nil + } + + var log *mlog.Logger + if *ps.Config().ServiceSettings.DebugSplit { + log = ps.logger + } + + attributes := map[string]any{} + + // if we are part of a cloud installation, add its installation and group id + if installationId := os.Getenv("MM_CLOUD_INSTALLATION_ID"); installationId != "" { + attributes["installation_id"] = installationId + } + if groupId := os.Getenv("MM_CLOUD_GROUP_ID"); groupId != "" { + attributes["group_id"] = groupId + } + + synchronizer, err := featureflag.NewSynchronizer(featureflag.SyncParams{ + ServerID: ps.telemetryId, + SplitKey: *ps.Config().ServiceSettings.SplitKey, + Log: log, + Attributes: attributes, + }) + if err != nil { + return err + } + + ps.featureFlagStop = make(chan struct{}) + ps.featureFlagStopped = make(chan struct{}) + ps.featureFlagSynchronizer = synchronizer + syncInterval := *ps.Config().ServiceSettings.FeatureFlagSyncIntervalSeconds + + go func() { + ticker := time.NewTicker(time.Duration(syncInterval) * time.Second) + defer ticker.Stop() + defer close(ps.featureFlagStopped) + if err := synchronizer.EnsureReady(); err != nil { + ps.logger.Warn("Problem connecting to feature flag management. Will fallback to cloud cache.", mlog.Err(err)) + return + } + ps.updateFeatureFlagValuesFromManagement() + for { + select { + case <-ps.featureFlagStop: + return + case <-ticker.C: + ps.updateFeatureFlagValuesFromManagement() + } + } + }() + + return nil +} + +func (ps *PlatformService) StopFeatureFlagUpdateJob() { + if ps.featureFlagSynchronizer != nil { + close(ps.featureFlagStop) + <-ps.featureFlagStopped + ps.featureFlagSynchronizer.Close() + ps.featureFlagSynchronizer = nil + } +} diff --git a/app/platform/helper_test.go b/app/platform/helper_test.go new file mode 100644 index 0000000000..17b053093f --- /dev/null +++ b/app/platform/helper_test.go @@ -0,0 +1,87 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +package platform + +import ( + "io/ioutil" + "path/filepath" + "testing" + + "github.com/mattermost/mattermost-server/v6/config" + "github.com/mattermost/mattermost-server/v6/model" + "github.com/mattermost/mattermost-server/v6/store" +) + +type TestHelper struct { + Service *PlatformService +} + +func Setup(tb testing.TB) *TestHelper { + if testing.Short() { + tb.SkipNow() + } + dbStore := mainHelper.GetStore() + dbStore.DropAllTables() + dbStore.MarkSystemRanUnitTests() + mainHelper.PreloadMigrations() + + return setupTestHelper(dbStore, false, true, tb) +} + +func setupTestHelper(dbStore store.Store, enterprise bool, includeCacheLayer bool, tb testing.TB) *TestHelper { + tempWorkspace, err := ioutil.TempDir("", "apptest") + if err != nil { + panic(err) + } + + configStore := config.NewTestMemoryStore() + + memoryConfig := configStore.Get() + *memoryConfig.PluginSettings.Directory = filepath.Join(tempWorkspace, "plugins") + *memoryConfig.PluginSettings.ClientDirectory = filepath.Join(tempWorkspace, "webapp") + *memoryConfig.PluginSettings.AutomaticPrepackagedPlugins = false + *memoryConfig.LogSettings.EnableSentry = false // disable error reporting during tests + *memoryConfig.AnnouncementSettings.AdminNoticesEnabled = false + *memoryConfig.AnnouncementSettings.UserNoticesEnabled = false + configStore.Set(memoryConfig) + + ps, err := New(ServiceConfig{ + ConfigStore: configStore, + }) + if err != nil { + panic(err) + } + + th := &TestHelper{ + Service: ps, + } + + // Share same configuration with app.TestHelper + th.Service.UpdateConfig(func(cfg *model.Config) { + *cfg.TeamSettings.MaxUsersPerTeam = 50 + *cfg.RateLimitSettings.Enable = false + *cfg.TeamSettings.EnableOpenServer = true + }) + + // Disable strict password requirements for test + th.Service.UpdateConfig(func(cfg *model.Config) { + *cfg.PasswordSettings.MinimumLength = 5 + *cfg.PasswordSettings.Lowercase = false + *cfg.PasswordSettings.Uppercase = false + *cfg.PasswordSettings.Symbol = false + *cfg.PasswordSettings.Number = false + }) + + if enterprise { + th.Service.SetLicense(model.NewTestLicense()) + } else { + th.Service.SetLicense(nil) + } + + return th +} + +func (th *TestHelper) TearDown() { + // Add cleaning code here +} diff --git a/app/platform/main_test.go b/app/platform/main_test.go new file mode 100644 index 0000000000..e2e91836f5 --- /dev/null +++ b/app/platform/main_test.go @@ -0,0 +1,32 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +package platform + +import ( + "flag" + "testing" + + "github.com/mattermost/mattermost-server/v6/testlib" +) + +var mainHelper *testlib.MainHelper +var replicaFlag bool + +func TestMain(m *testing.M) { + if f := flag.Lookup("mysql-replica"); f == nil { + flag.BoolVar(&replicaFlag, "mysql-replica", false, "") + flag.Parse() + } + + var options = testlib.HelperOptions{ + EnableStore: true, + EnableResources: true, + WithReadReplica: replicaFlag, + } + + mainHelper = testlib.NewMainHelperWithOptions(&options) + defer mainHelper.Close() + + mainHelper.Main(m) +} diff --git a/app/platform/server_license.go b/app/platform/server_license.go new file mode 100644 index 0000000000..3ccc95999b --- /dev/null +++ b/app/platform/server_license.go @@ -0,0 +1,19 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +package platform + +import ( + "github.com/mattermost/mattermost-server/v6/model" +) + +// License returns the license stored in the server struct. +// This should be removed with MM-45839 +func (ps *PlatformService) License() *model.License { + license, _ := ps.licenseValue.Load().(*model.License) + return license +} + +func (ps *PlatformService) SetLicense(license *model.License) { + ps.licenseValue.Store(license) +} diff --git a/app/platform/service.go b/app/platform/service.go index baa4b1362e..2db592adc2 100644 --- a/app/platform/service.go +++ b/app/platform/service.go @@ -4,6 +4,11 @@ package platform import ( + "fmt" + "sync" + "sync/atomic" + + "github.com/mattermost/mattermost-server/v6/app/featureflag" "github.com/mattermost/mattermost-server/v6/config" "github.com/mattermost/mattermost-server/v6/einterfaces" "github.com/mattermost/mattermost-server/v6/shared/mlog" @@ -19,6 +24,14 @@ type PlatformService struct { metrics *platformMetrics + featureFlagSynchronizerMutex sync.Mutex + featureFlagSynchronizer *featureflag.Synchronizer + featureFlagStop chan struct{} + featureFlagStopped chan struct{} + + licenseValue atomic.Value + telemetryId string + cluster einterfaces.ClusterInterface } @@ -49,3 +62,18 @@ func (ps *PlatformService) ShutdownMetrics() error { return nil } + +func (ps *PlatformService) ShutdownConfig() error { + if ps.configStore != nil { + err := ps.configStore.Close() + if err != nil { + return fmt.Errorf("failed to close config store: %w", err) + } + } + + return nil +} + +func (ps *PlatformService) SetTelemetryId(id string) { + ps.telemetryId = id +} diff --git a/app/plugin_signature.go b/app/plugin_signature.go index 6dab66efb8..9724080aed 100644 --- a/app/plugin_signature.go +++ b/app/plugin_signature.go @@ -25,7 +25,7 @@ func (a *App) GetPublicKey(name string) ([]byte, *model.AppError) { } func (s *Server) getPublicKey(name string) ([]byte, *model.AppError) { - data, err := s.configStore.GetFile(name) + data, err := s.platform.GetConfigFile(name) if err != nil { return nil, model.NewAppError("GetPublicKey", "app.plugin.get_public_key.get_file.app_error", nil, err.Error(), http.StatusInternalServerError) } @@ -41,7 +41,7 @@ func (a *App) AddPublicKey(name string, key io.Reader) *model.AppError { if err != nil { return model.NewAppError("AddPublicKey", "app.plugin.write_file.read.app_error", nil, err.Error(), http.StatusInternalServerError) } - err = a.Srv().configStore.SetFile(name, data) + err = a.Srv().platform.SetConfigFile(name, data) if err != nil { return model.NewAppError("AddPublicKey", "app.plugin.write_file.saving.app_error", nil, err.Error(), http.StatusInternalServerError) } @@ -61,7 +61,7 @@ func (a *App) DeletePublicKey(name string) *model.AppError { return model.NewAppError("AddPublicKey", "app.plugin.modify_saml.app_error", nil, "", http.StatusInternalServerError) } filename := filepath.Base(name) - if err := a.Srv().configStore.RemoveFile(filename); err != nil { + if err := a.Srv().platform.RemoveConfigFile(filename); err != nil { return model.NewAppError("DeletePublicKey", "app.plugin.delete_public_key.delete.app_error", nil, err.Error(), http.StatusInternalServerError) } diff --git a/app/post_metadata.go b/app/post_metadata.go index 05996e9b0a..f7155e0a7c 100644 --- a/app/post_metadata.go +++ b/app/post_metadata.go @@ -41,7 +41,7 @@ var linkCache = cache.NewLRU(cache.LRUOptions{ func (s *Server) initPostMetadata() { // Dump any cached links if the proxy settings have changed so image URLs can be updated - s.AddConfigListener(func(before, after *model.Config) { + s.platform.AddConfigListener(func(before, after *model.Config) { if (before.ImageProxySettings.Enable != after.ImageProxySettings.Enable) || (before.ImageProxySettings.ImageProxyType != after.ImageProxySettings.ImageProxyType) || (before.ImageProxySettings.RemoteImageProxyURL != after.ImageProxySettings.RemoteImageProxyURL) || diff --git a/app/post_metadata_test.go b/app/post_metadata_test.go index 3bf8ebf334..63ee5c99d6 100644 --- a/app/post_metadata_test.go +++ b/app/post_metadata_test.go @@ -796,7 +796,7 @@ func TestPreparePostForClientWithImageProxy(t *testing.T) { *cfg.ImageProxySettings.RemoteImageProxyOptions = "foo" }) - th.App.ch.imageProxy = imageproxy.MakeImageProxy(th.Server, th.Server.HTTPService(), th.Server.Log) + th.App.ch.imageProxy = imageproxy.MakeImageProxy(th.Server.platform, th.Server.HTTPService(), th.Server.Log) return th } diff --git a/app/post_test.go b/app/post_test.go index 64c203e8f2..3e5429ffc0 100644 --- a/app/post_test.go +++ b/app/post_test.go @@ -472,7 +472,7 @@ func TestImageProxy(t *testing.T) { *cfg.ServiceSettings.SiteURL = "http://mymattermost.com" }) - th.App.ch.imageProxy = imageproxy.MakeImageProxy(th.Server, th.Server.HTTPService(), th.Server.Log) + th.App.ch.imageProxy = imageproxy.MakeImageProxy(th.Server.platform, th.Server.HTTPService(), th.Server.Log) for name, tc := range map[string]struct { ProxyType string @@ -686,7 +686,7 @@ func TestCreatePost(t *testing.T) { *cfg.ImageProxySettings.RemoteImageProxyOptions = "foo" }) - th.App.ch.imageProxy = imageproxy.MakeImageProxy(th.Server, th.Server.HTTPService(), th.Server.Log) + th.App.ch.imageProxy = imageproxy.MakeImageProxy(th.Server.platform, th.Server.HTTPService(), th.Server.Log) imageURL := "http://mydomain.com/myimage" proxiedImageURL := "http://mymattermost.com/api/v4/image?url=http%3A%2F%2Fmydomain.com%2Fmyimage" @@ -956,7 +956,7 @@ func TestPatchPost(t *testing.T) { *cfg.ImageProxySettings.RemoteImageProxyOptions = "foo" }) - th.App.ch.imageProxy = imageproxy.MakeImageProxy(th.Server, th.Server.HTTPService(), th.Server.Log) + th.App.ch.imageProxy = imageproxy.MakeImageProxy(th.Server.platform, th.Server.HTTPService(), th.Server.Log) imageURL := "http://mydomain.com/myimage" proxiedImageURL := "http://mymattermost.com/api/v4/image?url=http%3A%2F%2Fmydomain.com%2Fmyimage" @@ -1252,7 +1252,7 @@ func TestUpdatePost(t *testing.T) { *cfg.ImageProxySettings.RemoteImageProxyOptions = "foo" }) - th.App.ch.imageProxy = imageproxy.MakeImageProxy(th.Server, th.Server.HTTPService(), th.Server.Log) + th.App.ch.imageProxy = imageproxy.MakeImageProxy(th.Server.platform, th.Server.HTTPService(), th.Server.Log) imageURL := "http://mydomain.com/myimage" proxiedImageURL := "http://mymattermost.com/api/v4/image?url=http%3A%2F%2Fmydomain.com%2Fmyimage" diff --git a/app/reaction_test.go b/app/reaction_test.go index e0d536d775..3e60208b84 100644 --- a/app/reaction_test.go +++ b/app/reaction_test.go @@ -90,8 +90,8 @@ func TestGetTopReactionsForTeamSince(t *testing.T) { th := Setup(t).InitBasic() defer th.TearDown() - th.Server.configStore.SetReadOnlyFF(false) - defer th.Server.configStore.SetReadOnlyFF(true) + th.Server.platform.SetConfigReadOnlyFF(false) + defer th.Server.platform.SetConfigReadOnlyFF(true) userId := th.BasicUser.Id user2Id := th.BasicUser2.Id @@ -261,8 +261,8 @@ func TestGetTopReactionsForUserSince(t *testing.T) { th := Setup(t).InitBasic() defer th.TearDown() - th.Server.configStore.SetReadOnlyFF(false) - defer th.Server.configStore.SetReadOnlyFF(true) + th.Server.platform.SetConfigReadOnlyFF(false) + defer th.Server.platform.SetConfigReadOnlyFF(true) userId := th.BasicUser.Id diff --git a/app/saml.go b/app/saml.go index 58787bf08a..260d601cee 100644 --- a/app/saml.go +++ b/app/saml.go @@ -47,7 +47,7 @@ func (a *App) writeSamlFile(filename string, fileData *multipart.FileHeader) *mo return model.NewAppError("AddSamlCertificate", "api.admin.add_certificate.saving.app_error", nil, err.Error(), http.StatusInternalServerError) } - err = a.Srv().configStore.SetFile(filename, data) + err = a.Srv().platform.SetConfigFile(filename, data) if err != nil { return model.NewAppError("AddSamlCertificate", "api.admin.add_certificate.saving.app_error", nil, err.Error(), http.StatusInternalServerError) } @@ -107,7 +107,7 @@ func (a *App) AddSamlIdpCertificate(fileData *multipart.FileHeader) *model.AppEr } func (a *App) removeSamlFile(filename string) *model.AppError { - if err := a.Srv().configStore.RemoveFile(filename); err != nil { + if err := a.Srv().platform.RemoveConfigFile(filename); err != nil { return model.NewAppError("RemoveSamlFile", "api.admin.remove_certificate.delete.app_error", map[string]any{"Filename": filename}, err.Error(), http.StatusInternalServerError) } @@ -171,9 +171,9 @@ func (a *App) RemoveSamlIdpCertificate() *model.AppError { func (a *App) GetSamlCertificateStatus() *model.SamlCertificateStatus { status := &model.SamlCertificateStatus{} - status.IdpCertificateFile, _ = a.Srv().configStore.HasFile(*a.Config().SamlSettings.IdpCertificateFile) - status.PrivateKeyFile, _ = a.Srv().configStore.HasFile(*a.Config().SamlSettings.PrivateKeyFile) - status.PublicCertificateFile, _ = a.Srv().configStore.HasFile(*a.Config().SamlSettings.PublicCertificateFile) + status.IdpCertificateFile, _ = a.Srv().platform.HasConfigFile(*a.Config().SamlSettings.IdpCertificateFile) + status.PrivateKeyFile, _ = a.Srv().platform.HasConfigFile(*a.Config().SamlSettings.PrivateKeyFile) + status.PublicCertificateFile, _ = a.Srv().platform.HasConfigFile(*a.Config().SamlSettings.PublicCertificateFile) return status } @@ -267,7 +267,7 @@ func (a *App) SetSamlIdpCertificateFromMetadata(data []byte) *model.AppError { Bytes: block.Bytes, }) - if err := a.Srv().configStore.SetFile(SamlIdpCertificateName, data); err != nil { + if err := a.Srv().platform.SetConfigFile(SamlIdpCertificateName, data); err != nil { return model.NewAppError("SetSamlIdpCertificateFromMetadata", "api.admin.saml.failure_save_idp_certificate_file.app_error", nil, err.Error(), http.StatusInternalServerError) } diff --git a/app/security_update_check.go b/app/security_update_check.go index 3712465ed7..273f520e23 100644 --- a/app/security_update_check.go +++ b/app/security_update_check.go @@ -33,7 +33,7 @@ const ( ) func (s *Server) DoSecurityUpdateCheck() { - if !*s.Config().ServiceSettings.EnableSecurityFixAlert { + if !*s.platform.Config().ServiceSettings.EnableSecurityFixAlert { return } @@ -53,7 +53,7 @@ func (s *Server) DoSecurityUpdateCheck() { v.Set(PropSecurityID, s.TelemetryId()) v.Set(PropSecurityBuild, model.CurrentVersion+"."+model.BuildNumber) v.Set(PropSecurityEnterpriseReady, model.BuildEnterpriseReady) - v.Set(PropSecurityDatabase, *s.Config().SqlSettings.DriverName) + v.Set(PropSecurityDatabase, *s.platform.Config().SqlSettings.DriverName) v.Set(PropSecurityOS, runtime.GOOS) if props[model.SystemRanUnitTests] != "" { diff --git a/app/server.go b/app/server.go index 48b99eea35..8f641e8c7c 100644 --- a/app/server.go +++ b/app/server.go @@ -31,7 +31,6 @@ import ( "golang.org/x/crypto/acme/autocert" "github.com/mattermost/mattermost-server/v6/app/email" - "github.com/mattermost/mattermost-server/v6/app/featureflag" "github.com/mattermost/mattermost-server/v6/app/platform" "github.com/mattermost/mattermost-server/v6/app/request" "github.com/mattermost/mattermost-server/v6/app/teams" @@ -168,7 +167,6 @@ type Server struct { searchConfigListenerId string searchLicenseListenerId string loggerLicenseListenerId string - configStore *configWrapper filestore filestore.FileBackend platform *platform.PlatformService @@ -201,11 +199,6 @@ type Server struct { tracer *tracing.Tracer - featureFlagSynchronizer *featureflag.Synchronizer - featureFlagStop chan struct{} - featureFlagStopped chan struct{} - featureFlagSynchronizerMutex sync.Mutex - products map[string]Product } @@ -237,7 +230,7 @@ func NewServer(options ...Option) (*Server, error) { // and has dependency requirements with the previous step. // // Step 1: Config. - if s.configStore == nil { + if s.platform == nil { innerStore, err := config.NewFileStore("config.json", true) if err != nil { return nil, errors.Wrap(err, "failed to load config") @@ -247,7 +240,25 @@ func NewServer(options ...Option) (*Server, error) { return nil, errors.Wrap(err, "failed to load config") } - s.configStore = &configWrapper{srv: s, Store: configStore} + platformCfg := platform.ServiceConfig{ + ConfigStore: configStore, + Logger: s.Log, + StartMetrics: s.startMetrics, + Cluster: s.Cluster, + } + if metricsInterface != nil { + platformCfg.Metrics = metricsInterface(s, *configStore.Get().SqlSettings.DriverName, *configStore.Get().SqlSettings.DataSource) + } + + ps, sErr := platform.New(platformCfg) + if sErr != nil { + return nil, errors.Wrap(sErr, "failed to initialize platform") + } + s.platform = ps + + if s.licenseValue.Load() != nil { + ps.SetLicense(s.licenseValue.Load().(*model.License)) // in case license is set in server options + } } // Step 2: Logging @@ -255,7 +266,7 @@ func NewServer(options ...Option) (*Server, error) { mlog.Error("Could not initiate logging", mlog.Err(err)) } - subpath, err := utils.GetSubpathFromConfig(s.Config()) + subpath, err := utils.GetSubpathFromConfig(s.platform.Config()) if err != nil { return nil, errors.Wrap(err, "failed to parse SiteURL subpath") } @@ -264,12 +275,12 @@ func NewServer(options ...Option) (*Server, error) { // This is called after initLogging() to avoid a race condition. mlog.Info("Server is initializing...", mlog.String("go_version", runtime.Version())) - s.httpService = httpservice.MakeHTTPService(s) + s.httpService = httpservice.MakeHTTPService(s.platform) // Step 3: Search Engine // Depends on Step 1 (config). - searchEngine := searchengine.NewBroker(s.Config()) - bleveEngine := bleveengine.NewBleveEngine(s.Config()) + searchEngine := searchengine.NewBroker(s.platform.Config()) + bleveEngine := bleveengine.NewBleveEngine(s.platform.Config()) if err := bleveEngine.Start(); err != nil { return nil, err } @@ -280,22 +291,6 @@ func NewServer(options ...Option) (*Server, error) { // Depends on step 3 (s.SearchEngine must be non-nil) s.initEnterprise() - platformCfg := platform.ServiceConfig{ - ConfigStore: s.configStore.Store, - Logger: s.Log, - StartMetrics: s.startMetrics, - Cluster: s.Cluster, - } - if metricsInterface != nil { - platformCfg.Metrics = metricsInterface(s) - } - - ps, sErr := platform.New(platformCfg) - if sErr != nil { - return nil, errors.Wrap(sErr, "failed to initialize platform") - } - s.platform = ps - // Step 5: Cache provider. // At the moment we only have this implementation // in the future the cache provider will be built based on the loaded config @@ -308,7 +303,7 @@ func NewServer(options ...Option) (*Server, error) { // Depends on Step 1 (config), 4 (metrics, cluster) and 5 (cacheProvider). if s.newStore == nil { s.newStore = func() (store.Store, error) { - s.sqlStore = sqlstore.New(s.Config().SqlSettings, s.GetMetrics()) + s.sqlStore = sqlstore.New(s.platform.Config().SqlSettings, s.GetMetrics()) lcl, err2 := localcachelayer.NewLocalCacheLayer( retrylayer.New(s.sqlStore), @@ -323,10 +318,10 @@ func NewServer(options ...Option) (*Server, error) { searchStore := searchlayer.NewSearchLayer( lcl, s.SearchEngine, - s.Config(), + s.platform.Config(), ) - s.AddConfigListener(func(prevCfg, cfg *model.Config) { + s.platform.AddConfigListener(func(prevCfg, cfg *model.Config) { searchStore.UpdateConfig(cfg) }) @@ -352,7 +347,7 @@ func NewServer(options ...Option) (*Server, error) { UserStore: s.Store.User(), SessionStore: s.Store.Session(), OAuthStore: s.Store.OAuth(), - ConfigFn: s.Config, + ConfigFn: s.platform.Config, Metrics: s.GetMetrics(), Cluster: s.Cluster, LicenseFn: s.License, @@ -376,9 +371,9 @@ func NewServer(options ...Option) (*Server, error) { } license := s.License() - insecure := s.Config().ServiceSettings.EnableInsecureOutgoingConnections + insecure := s.platform.Config().ServiceSettings.EnableInsecureOutgoingConnections // Step 7: Initialize filestore - backend, err := filestore.NewFileBackend(s.Config().FileSettings.ToFileBackendSettings(license != nil && *license.Features.Compliance, insecure != nil && *insecure)) + backend, err := filestore.NewFileBackend(s.platform.Config().FileSettings.ToFileBackendSettings(license != nil && *license.Features.Compliance, insecure != nil && *insecure)) if err != nil { return nil, errors.Wrap(err, "failed to initialize filebackend") } @@ -398,7 +393,7 @@ func NewServer(options ...Option) (*Server, error) { GroupStore: s.Store.Group(), Users: s.userService, WebHub: s, - ConfigFn: s.Config, + ConfigFn: s.platform.Config, LicenseFn: s.License, }) if err != nil { @@ -410,7 +405,7 @@ func NewServer(options ...Option) (*Server, error) { serviceMap := map[ServiceKey]any{ ChannelKey: &channelsWrapper{srv: s}, - ConfigKey: s.configStore, + ConfigKey: s.platform, LicenseKey: s.licenseWrapper, FilestoreKey: s.filestore, FileInfoStoreKey: &fileInfoWrapper{srv: s}, @@ -441,7 +436,7 @@ func NewServer(options ...Option) (*Server, error) { // below this. Otherwise, please add it to Channels struct in app/channels.go. // ------------------------------------------------------------------------- - if *s.Config().LogSettings.EnableDiagnostics && *s.Config().LogSettings.EnableSentry { + if *s.platform.Config().LogSettings.EnableDiagnostics && *s.platform.Config().LogSettings.EnableSentry { if strings.Contains(SentryDSN, "placeholder") { mlog.Warn("Sentry reporting is enabled, but SENTRY_DSN is not set. Disabling reporting.") } else { @@ -468,7 +463,7 @@ func NewServer(options ...Option) (*Server, error) { } } - if *s.Config().ServiceSettings.EnableOpenTracing { + if *s.platform.Config().ServiceSettings.EnableOpenTracing { tracer, err2 := tracing.New() if err2 != nil { return nil, err2 @@ -496,7 +491,7 @@ func NewServer(options ...Option) (*Server, error) { s.createPushNotificationsHub(request.EmptyContext(s.GetLogger())) - if err2 := i18n.InitTranslations(*s.Config().LocalizationSettings.DefaultServerLocale, *s.Config().LocalizationSettings.DefaultClientLocale); err2 != nil { + if err2 := i18n.InitTranslations(*s.platform.Config().LocalizationSettings.DefaultServerLocale, *s.platform.Config().LocalizationSettings.DefaultClientLocale); err2 != nil { return nil, errors.Wrapf(err2, "unable to load Mattermost translation files") } @@ -515,7 +510,7 @@ func NewServer(options ...Option) (*Server, error) { }) s.htmlTemplateWatcher = htmlTemplateWatcher - s.configListenerId = s.AddConfigListener(func(_, _ *model.Config) { + s.configListenerId = s.platform.AddConfigListener(func(_, _ *model.Config) { ch := s.Channels() ch.regenerateClientConfig() @@ -544,9 +539,10 @@ func NewServer(options ...Option) (*Server, error) { }) s.telemetryService = telemetry.New(New(ServerConnector(s.Channels())), s.Store, s.SearchEngine, s.Log) + s.platform.SetTelemetryId(s.TelemetryId()) // TODO: move this into platform once telemetry service moved to platform. emailService, err := email.NewService(email.ServiceConfig{ - ConfigFn: s.Config, + ConfigFn: s.platform.Config, LicenseFn: s.License, GoFn: s.Go, TemplatesContainer: s.TemplatesContainer(), @@ -558,7 +554,7 @@ func NewServer(options ...Option) (*Server, error) { } s.EmailService = emailService - s.setupFeatureFlags() + s.platform.SetupFeatureFlags() s.initJobs() @@ -567,7 +563,7 @@ func NewServer(options ...Option) (*Server, error) { if s.Jobs != nil { s.Jobs.HandleClusterLeaderChange(s.IsLeader()) } - s.setupFeatureFlags() + s.platform.SetupFeatureFlags() }) // If configured with a subpath, redirect 404s at the root back into the subpath. @@ -578,12 +574,12 @@ func NewServer(options ...Option) (*Server, error) { }) } - if _, err = url.ParseRequestURI(*s.Config().ServiceSettings.SiteURL); err != nil { + if _, err = url.ParseRequestURI(*s.platform.Config().ServiceSettings.SiteURL); err != nil { mlog.Error("SiteURL must be set. Some features will operate incorrectly if the SiteURL is not set. See documentation for details: https://docs.mattermost.com/configure/configuration-settings.html#site-url") } // Start email batching because it's not like the other jobs - s.AddConfigListener(func(_, _ *model.Config) { + s.platform.AddConfigListener(func(_, _ *model.Config) { s.EmailService.InitEmailBatching() }) @@ -604,7 +600,7 @@ func NewServer(options ...Option) (*Server, error) { pwd, _ := os.Getwd() mlog.Info("Printing current working", mlog.String("directory", pwd)) - mlog.Info("Loaded config", mlog.String("source", s.configStore.String())) + mlog.Info("Loaded config", mlog.String("source", s.platform.DescribeConfig())) allowAdvancedLogging := license != nil && *license.Features.AdvancedLogging @@ -626,7 +622,7 @@ func NewServer(options ...Option) (*Server, error) { // Enable developer settings if this is a "dev" build if model.BuildNumber == "dev" { - s.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableDeveloper = true }) + s.platform.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableDeveloper = true }) } if s.startMetrics { @@ -649,13 +645,13 @@ func NewServer(options ...Option) (*Server, error) { } }) - s.SearchEngine.UpdateConfig(s.Config()) + s.SearchEngine.UpdateConfig(s.platform.Config()) searchConfigListenerId, searchLicenseListenerId := s.StartSearchEngine() s.searchConfigListenerId = searchConfigListenerId s.searchLicenseListenerId = searchLicenseListenerId // if enabled - perform initial product notices fetch - if *s.Config().AnnouncementSettings.AdminNoticesEnabled || *s.Config().AnnouncementSettings.UserNoticesEnabled { + if *s.platform.Config().AnnouncementSettings.AdminNoticesEnabled || *s.platform.Config().AnnouncementSettings.UserNoticesEnabled { go func() { appInstance := New(ServerConnector(s.Channels())) if err := appInstance.UpdateProductNotices(); err != nil { @@ -668,7 +664,7 @@ func NewServer(options ...Option) (*Server, error) { return s, nil } - s.AddConfigListener(func(old, new *model.Config) { + s.platform.AddConfigListener(func(old, new *model.Config) { appInstance := New(ServerConnector(s.Channels())) if *old.GuestAccountsSettings.Enable && !*new.GuestAccountsSettings.Enable { c := request.EmptyContext(s.GetLogger()) @@ -679,7 +675,7 @@ func NewServer(options ...Option) (*Server, error) { }) // Disable active guest accounts on first run if guest accounts are disabled - if !*s.Config().GuestAccountsSettings.Enable { + if !*s.platform.Config().GuestAccountsSettings.Enable { appInstance := New(ServerConnector(s.Channels())) c := request.EmptyContext(s.GetLogger()) if appErr := appInstance.DeactivateGuests(c); appErr != nil { @@ -703,7 +699,7 @@ func NewServer(options ...Option) (*Server, error) { s.initPostMetadata() // Dump the image cache if the proxy settings have changed. (need switch URLs to the correct proxy) - s.AddConfigListener(func(oldCfg, newCfg *model.Config) { + s.platform.AddConfigListener(func(oldCfg, newCfg *model.Config) { if (oldCfg.ImageProxySettings.Enable != newCfg.ImageProxySettings.Enable) || (oldCfg.ImageProxySettings.ImageProxyType != newCfg.ImageProxySettings.ImageProxyType) || (oldCfg.ImageProxySettings.RemoteImageProxyURL != newCfg.ImageProxySettings.RemoteImageProxyURL) || @@ -755,18 +751,18 @@ func (s *Server) runJobs() { complianceI.StartComplianceDailyJob() } - if *s.Config().JobSettings.RunJobs && s.Jobs != nil { + if *s.platform.Config().JobSettings.RunJobs && s.Jobs != nil { if err := s.Jobs.StartWorkers(); err != nil { mlog.Error("Failed to start job server workers", mlog.Err(err)) } } - if *s.Config().JobSettings.RunScheduler && s.Jobs != nil { + if *s.platform.Config().JobSettings.RunScheduler && s.Jobs != nil { if err := s.Jobs.StartSchedulers(); err != nil { mlog.Error("Failed to start job server schedulers", mlog.Err(err)) } } - if *s.Config().ServiceSettings.EnableAWSMetering { + if *s.platform.Config().ServiceSettings.EnableAWSMetering { runReportToAWSMeterJob(s) } } @@ -786,7 +782,7 @@ func (s *Server) Channels() *Channels { // Return Database type (postgres or mysql) and current version of the schema func (s *Server) DatabaseTypeAndSchemaVersion() (string, string) { schemaVersion, _ := s.Store.GetDBSchemaVersion() - return *s.Config().SqlSettings.DriverName, strconv.Itoa(schemaVersion) + return *s.platform.Config().SqlSettings.DriverName, strconv.Itoa(schemaVersion) } // initLogging initializes and configures the logger(s). This may be called more than once. @@ -809,7 +805,7 @@ func (s *Server) initLogging() error { s.NotificationsLog = l.With(mlog.String("logSource", "notifications")) } - if err := s.configureLogger("logging", s.Log, &s.Config().LogSettings, s.configStore.Store, config.GetLogFileLocation); err != nil { + if err := s.platform.ConfigureLogger("logging", s.Log, &s.platform.Config().LogSettings, config.GetLogFileLocation); err != nil { // if the config is locked then a unit test has already configured and locked the logger; not an error. if !errors.Is(err, mlog.ErrConfigurationLock) { // revert to default logger if the config is invalid @@ -824,8 +820,8 @@ func (s *Server) initLogging() error { // Use the app logger as the global logger (eventually remove all instances of global logging). mlog.InitGlobalLogger(s.Log) - notificationLogSettings := config.GetLogSettingsFromNotificationsLogSettings(&s.Config().NotificationLogSettings) - if err := s.configureLogger("notification logging", s.NotificationsLog, notificationLogSettings, s.configStore.Store, config.GetNotificationsLogFileLocation); err != nil { + notificationLogSettings := config.GetLogSettingsFromNotificationsLogSettings(&s.platform.Config().NotificationLogSettings) + if err := s.platform.ConfigureLogger("notification logging", s.NotificationsLog, notificationLogSettings, config.GetNotificationsLogFileLocation); err != nil { if !errors.Is(err, mlog.ErrConfigurationLock) { mlog.Error("Error configuring notification logger", mlog.Err(err)) return err @@ -834,33 +830,6 @@ func (s *Server) initLogging() error { return nil } -// configureLogger applies the specified configuration to a logger. -func (s *Server) configureLogger(name string, logger *mlog.Logger, logSettings *model.LogSettings, configStore *config.Store, getPath func(string) string) error { - // Advanced logging is E20 only, however logging must be initialized before the license - // file is loaded. If no valid E20 license exists then advanced logging will be - // shutdown once license is loaded/checked. - var err error - dsn := *logSettings.AdvancedLoggingConfig - var logConfigSrc config.LogConfigSrc - if dsn != "" { - logConfigSrc, err = config.NewLogConfigSrc(dsn, configStore) - if err != nil { - return fmt.Errorf("invalid config source for %s, %w", name, err) - } - mlog.Info("Loaded configuration for "+name, mlog.String("source", dsn)) - } - - cfg, err := config.MloggerConfigFromLoggerConfig(logSettings, logConfigSrc, getPath) - if err != nil { - return fmt.Errorf("invalid config source for %s, %w", name, err) - } - - if err := logger.ConfigureTargets(cfg, nil); err != nil { - return fmt.Errorf("invalid config for %s, %w", name, err) - } - return nil -} - // removeUnlicensedLogTargets removes any unlicensed log target types. func (s *Server) removeUnlicensedLogTargets(license *model.License) { if license != nil && *license.Features.AdvancedLogging { @@ -895,7 +864,7 @@ func (s *Server) startInterClusterServices(license *model.License) error { } // Config check - if !*s.Config().ExperimentalSettings.EnableRemoteClusterService { + if !*s.platform.Config().ExperimentalSettings.EnableRemoteClusterService { mlog.Debug("Remote Cluster Service disabled via config") return nil } @@ -924,7 +893,7 @@ func (s *Server) startInterClusterServices(license *model.License) error { } // Config check - if !*s.Config().ExperimentalSettings.EnableSharedChannels { + if !*s.platform.Config().ExperimentalSettings.EnableSharedChannels { mlog.Debug("Shared Channels Service disabled via config") return nil } @@ -1029,14 +998,16 @@ func (s *Server) Shutdown() { s.WaitForGoroutines() - s.RemoveConfigListener(s.configListenerId) + s.platform.RemoveConfigListener(s.configListenerId) s.stopSearchEngine() s.Audit.Shutdown() - s.stopFeatureFlagUpdateJob() + s.platform.StopFeatureFlagUpdateJob() - s.configStore.Close() + if err = s.platform.ShutdownConfig(); err != nil { + s.Log.Warn("Failed to shut down config store", mlog.Err(err)) + } if s.Cluster != nil { s.Cluster.StopInterNodeCommunication() @@ -1239,23 +1210,23 @@ func (s *Server) Start() error { s.checkPushNotificationServerURL() - s.ReloadConfig() + s.platform.ReloadConfig() mlog.Info("Starting Server...") var handler http.Handler = s.RootRouter - if *s.Config().LogSettings.EnableDiagnostics && *s.Config().LogSettings.EnableSentry && !strings.Contains(SentryDSN, "placeholder") { + if *s.platform.Config().LogSettings.EnableDiagnostics && *s.platform.Config().LogSettings.EnableSentry && !strings.Contains(SentryDSN, "placeholder") { sentryHandler := sentryhttp.New(sentryhttp.Options{ Repanic: true, }) handler = sentryHandler.Handle(handler) } - if allowedOrigins := *s.Config().ServiceSettings.AllowCorsFrom; allowedOrigins != "" { - exposedCorsHeaders := *s.Config().ServiceSettings.CorsExposedHeaders - allowCredentials := *s.Config().ServiceSettings.CorsAllowCredentials - debug := *s.Config().ServiceSettings.CorsDebug + if allowedOrigins := *s.platform.Config().ServiceSettings.AllowCorsFrom; allowedOrigins != "" { + exposedCorsHeaders := *s.platform.Config().ServiceSettings.CorsExposedHeaders + allowCredentials := *s.platform.Config().ServiceSettings.CorsAllowCredentials + debug := *s.platform.Config().ServiceSettings.CorsDebug corsWrapper := cors.New(cors.Options{ AllowedOrigins: strings.Fields(allowedOrigins), AllowedMethods: corsAllowedMethods, @@ -1274,10 +1245,10 @@ func (s *Server) Start() error { handler = corsWrapper.Handler(handler) } - if *s.Config().RateLimitSettings.Enable { + if *s.platform.Config().RateLimitSettings.Enable { mlog.Info("RateLimiter is enabled") - rateLimiter, err2 := NewRateLimiter(&s.Config().RateLimitSettings, s.Config().ServiceSettings.TrustedProxyIPHeader) + rateLimiter, err2 := NewRateLimiter(&s.platform.Config().RateLimitSettings, s.platform.Config().ServiceSettings.TrustedProxyIPHeader) if err2 != nil { return err2 } @@ -1292,15 +1263,15 @@ func (s *Server) Start() error { s.Server = &http.Server{ Handler: handler, - ReadTimeout: time.Duration(*s.Config().ServiceSettings.ReadTimeout) * time.Second, - WriteTimeout: time.Duration(*s.Config().ServiceSettings.WriteTimeout) * time.Second, - IdleTimeout: time.Duration(*s.Config().ServiceSettings.IdleTimeout) * time.Second, + ReadTimeout: time.Duration(*s.platform.Config().ServiceSettings.ReadTimeout) * time.Second, + WriteTimeout: time.Duration(*s.platform.Config().ServiceSettings.WriteTimeout) * time.Second, + IdleTimeout: time.Duration(*s.platform.Config().ServiceSettings.IdleTimeout) * time.Second, ErrorLog: errStdLog, } - addr := *s.Config().ServiceSettings.ListenAddress + addr := *s.platform.Config().ServiceSettings.ListenAddress if addr == "" { - if *s.Config().ServiceSettings.ConnectionSecurity == model.ConnSecurityTLS { + if *s.platform.Config().ServiceSettings.ConnectionSecurity == model.ConnSecurityTLS { addr = ":https" } else { addr = ":http" @@ -1317,11 +1288,11 @@ func (s *Server) Start() error { mlog.Info(logListeningPort, mlog.String("address", listener.Addr().String())) m := &autocert.Manager{ - Cache: autocert.DirCache(*s.Config().ServiceSettings.LetsEncryptCertificateCacheFile), + Cache: autocert.DirCache(*s.platform.Config().ServiceSettings.LetsEncryptCertificateCacheFile), Prompt: autocert.AcceptTOS, } - if *s.Config().ServiceSettings.Forward80To443 { + if *s.platform.Config().ServiceSettings.Forward80To443 { if host, port, err := net.SplitHostPort(addr); err != nil { mlog.Error("Unable to setup forwarding", mlog.Err(err)) } else if port != "443" { @@ -1329,7 +1300,7 @@ func (s *Server) Start() error { } else { httpListenAddress := net.JoinHostPort(host, "http") - if *s.Config().ServiceSettings.UseLetsEncrypt { + if *s.platform.Config().ServiceSettings.UseLetsEncrypt { server := &http.Server{ Addr: httpListenAddress, Handler: m.HTTPHandler(nil), @@ -1353,21 +1324,21 @@ func (s *Server) Start() error { }() } } - } else if *s.Config().ServiceSettings.UseLetsEncrypt { + } else if *s.platform.Config().ServiceSettings.UseLetsEncrypt { return errors.New(i18n.T("api.server.start_server.forward80to443.disabled_while_using_lets_encrypt")) } s.didFinishListen = make(chan struct{}) go func() { var err error - if *s.Config().ServiceSettings.ConnectionSecurity == model.ConnSecurityTLS { + if *s.platform.Config().ServiceSettings.ConnectionSecurity == model.ConnSecurityTLS { tlsConfig := &tls.Config{ PreferServerCipherSuites: true, CurvePreferences: []tls.CurveID{tls.CurveP521, tls.CurveP384, tls.CurveP256}, } - switch *s.Config().ServiceSettings.TLSMinVer { + switch *s.platform.Config().ServiceSettings.TLSMinVer { case "1.0": tlsConfig.MinVersion = tls.VersionTLS10 case "1.1": @@ -1385,11 +1356,11 @@ func (s *Server) Start() error { tls.TLS_RSA_WITH_AES_256_GCM_SHA384, } - if len(s.Config().ServiceSettings.TLSOverwriteCiphers) == 0 { + if len(s.platform.Config().ServiceSettings.TLSOverwriteCiphers) == 0 { tlsConfig.CipherSuites = defaultCiphers } else { var cipherSuites []uint16 - for _, cipher := range s.Config().ServiceSettings.TLSOverwriteCiphers { + for _, cipher := range s.platform.Config().ServiceSettings.TLSOverwriteCiphers { value, ok := model.ServerTLSSupportedCiphers[cipher] if !ok { @@ -1411,12 +1382,12 @@ func (s *Server) Start() error { certFile := "" keyFile := "" - if *s.Config().ServiceSettings.UseLetsEncrypt { + if *s.platform.Config().ServiceSettings.UseLetsEncrypt { tlsConfig.GetCertificate = m.GetCertificate tlsConfig.NextProtos = append(tlsConfig.NextProtos, "h2") } else { - certFile = *s.Config().ServiceSettings.TLSCertFile - keyFile = *s.Config().ServiceSettings.TLSKeyFile + certFile = *s.platform.Config().ServiceSettings.TLSCertFile + keyFile = *s.platform.Config().ServiceSettings.TLSKeyFile } s.Server.TLSConfig = tlsConfig @@ -1433,7 +1404,7 @@ func (s *Server) Start() error { close(s.didFinishListen) }() - if *s.Config().ServiceSettings.EnableLocalMode { + if *s.platform.Config().ServiceSettings.EnableLocalMode { if err := s.startLocalModeServer(); err != nil { mlog.Critical(err.Error()) } @@ -1451,7 +1422,7 @@ func (s *Server) startLocalModeServer() error { Handler: s.LocalRouter, } - socket := *s.configStore.Get().ServiceSettings.LocalModeSocketLocation + socket := *s.platform.Config().ServiceSettings.LocalModeSocketLocation if err := os.RemoveAll(socket); err != nil { return errors.Wrapf(err, i18n.T("api.server.start_server.starting.critical"), err) } @@ -1495,7 +1466,7 @@ func (a *App) OriginChecker() func(*http.Request) bool { } func (s *Server) checkPushNotificationServerURL() { - notificationServer := *s.Config().EmailSettings.PushNotificationServer + notificationServer := *s.platform.Config().EmailSettings.PushNotificationServer if strings.HasPrefix(notificationServer, "http://") { mlog.Warn("Your push notification server is configured with HTTP. For improved security, update to HTTPS in your configuration.") } @@ -1563,7 +1534,7 @@ func runReportToAWSMeterJob(s *Server) { } func doReportUsageToAWSMeteringService(s *Server) { - awsMeter := awsmeter.New(s.Store, s.Config()) + awsMeter := awsmeter.New(s.Store, s.platform.Config()) if awsMeter == nil { mlog.Error("Cannot obtain instance of AWS Metering Service.") return @@ -1604,12 +1575,12 @@ func doSessionCleanup(s *Server) { } func doJobsCleanup(s *Server) { - if *s.Config().JobSettings.CleanupJobsThresholdDays < 0 { + if *s.platform.Config().JobSettings.CleanupJobsThresholdDays < 0 { return } mlog.Debug("Cleaning up jobs store.") - dur := time.Duration(*s.Config().JobSettings.CleanupJobsThresholdDays) * time.Hour * 24 + dur := time.Duration(*s.platform.Config().JobSettings.CleanupJobsThresholdDays) * time.Hour * 24 expiry := model.GetMillisForTime(time.Now().Add(-dur)) err := s.Store.Job().Cleanup(expiry, jobsCleanupBatchSize) if err != nil { @@ -1618,12 +1589,12 @@ func doJobsCleanup(s *Server) { } func doConfigCleanup(s *Server) { - if *s.Config().JobSettings.CleanupConfigThresholdDays < 0 || !config.IsDatabaseDSN(s.ConfigStore().Store.String()) { + if *s.platform.Config().JobSettings.CleanupConfigThresholdDays < 0 || !config.IsDatabaseDSN(s.platform.DescribeConfig()) { return } mlog.Info("Cleaning up configuration store.") - if err := s.ConfigStore().Store.CleanUp(); err != nil { + if err := s.platform.CleanUpConfig(); err != nil { mlog.Warn("Error while cleaning up configurations", mlog.Err(err)) } } @@ -1654,7 +1625,7 @@ func (s *Server) sendLicenseUpForRenewalEmail(users map[string]*model.User, lice if name == "" { name = user.Username } - if err := s.EmailService.SendLicenseUpForRenewalEmail(user.Email, name, user.Locale, *s.Config().ServiceSettings.SiteURL, renewalLink, daysToExpiration); err != nil { + if err := s.EmailService.SendLicenseUpForRenewalEmail(user.Email, name, user.Locale, *s.platform.Config().ServiceSettings.SiteURL, renewalLink, daysToExpiration); err != nil { mlog.Error("Error sending license up for renewal email to", mlog.String("user_email", user.Email), mlog.Err(err)) countNotOks++ } @@ -1735,7 +1706,7 @@ func (s *Server) doLicenseExpirationCheck() { mlog.Debug("Sending license expired email.", mlog.String("user_email", user.Email)) s.Go(func() { - if err := s.SendRemoveExpiredLicenseEmail(user.Email, renewalLink, user.Locale, *s.Config().ServiceSettings.SiteURL); err != nil { + if err := s.SendRemoveExpiredLicenseEmail(user.Email, renewalLink, user.Locale, *s.platform.Config().ServiceSettings.SiteURL); err != nil { mlog.Error("Error while sending the license expired email.", mlog.String("user_email", user.Email), mlog.Err(err)) } }) @@ -1765,7 +1736,7 @@ func (s *Server) StartSearchEngine() (string, string) { }) } - configListenerId := s.AddConfigListener(func(oldConfig *model.Config, newConfig *model.Config) { + configListenerId := s.platform.AddConfigListener(func(oldConfig *model.Config, newConfig *model.Config) { if s.SearchEngine == nil { return } @@ -1824,7 +1795,7 @@ func (s *Server) StartSearchEngine() (string, string) { } func (s *Server) stopSearchEngine() { - s.RemoveConfigListener(s.searchConfigListenerId) + s.platform.RemoveConfigListener(s.searchConfigListenerId) s.RemoveLicenseListener(s.searchLicenseListenerId) if s.SearchEngine != nil && s.SearchEngine.ElasticsearchEngine != nil && s.SearchEngine.ElasticsearchEngine.IsActive() { s.SearchEngine.ElasticsearchEngine.Stop() @@ -1858,7 +1829,7 @@ func (ch *Channels) ClientConfigHash() string { } func (s *Server) initJobs() { - s.Jobs = jobs.NewJobServer(s, s.Store, s.GetMetrics()) + s.Jobs = jobs.NewJobServer(s.platform, s.Store, s.GetMetrics()) if jobsDataRetentionJobInterface != nil { builder := jobsDataRetentionJobInterface(s) @@ -2031,7 +2002,7 @@ func (s *Server) SetSharedChannelSyncService(sharedChannelService SharedChannelS } func (s *Server) GetProfileImage(user *model.User) ([]byte, bool, *model.AppError) { - if *s.Config().FileSettings.DriverName == "" { + if *s.platform.Config().FileSettings.DriverName == "" { img, appErr := s.GetDefaultProfileImage(user) if appErr != nil { return nil, false, appErr @@ -2141,3 +2112,8 @@ func (a *App) GetAppliedSchemaMigrations() ([]model.AppliedMigration, *model.App } return table, nil } + +// Expose platform service from server, this should be replaced with server itself in time. +func (s *Server) Platform() *platform.PlatformService { + return s.platform +} diff --git a/app/server_inactivity.go b/app/server_inactivity.go index 3bb83e7f0c..4c5b0b7a01 100644 --- a/app/server_inactivity.go +++ b/app/server_inactivity.go @@ -17,17 +17,17 @@ const inactivityEmailSent = "INACTIVITY" func (s *Server) doInactivityCheck() { - if *s.Config().ServiceSettings.EnableDeveloper { + if *s.platform.Config().ServiceSettings.EnableDeveloper { mlog.Info("No activity check because developer mode is enabled") return } - if !*s.Config().EmailSettings.EnableInactivityEmail { + if !*s.platform.Config().EmailSettings.EnableInactivityEmail { mlog.Info("No activity check because EnableInactivityEmail is false") return } - if !s.Config().FeatureFlags.EnableInactivityCheckJob { + if !s.platform.Config().FeatureFlags.EnableInactivityCheckJob { mlog.Info("No activity check because EnableInactivityCheckJob feature flag is disabled") return } @@ -70,7 +70,7 @@ func (s *Server) doInactivityCheck() { } func (s *Server) takeInactivityAction() { - siteURL := *s.Config().ServiceSettings.SiteURL + siteURL := *s.platform.Config().ServiceSettings.SiteURL if siteURL == "" { mlog.Warn("No SiteURL configured") } diff --git a/app/server_license.go b/app/server_license.go deleted file mode 100644 index ffb0dc68ca..0000000000 --- a/app/server_license.go +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. -// See LICENSE.txt for license information. - -package app - -import ( - "github.com/mattermost/mattermost-server/v6/model" -) - -func (s *Server) License() *model.License { - license, _ := s.licenseValue.Load().(*model.License) - return license -} diff --git a/app/server_test.go b/app/server_test.go index 710aa302a1..c1e0cd8fec 100644 --- a/app/server_test.go +++ b/app/server_test.go @@ -23,6 +23,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/mattermost/mattermost-server/v6/app/platform" "github.com/mattermost/mattermost-server/v6/config" "github.com/mattermost/mattermost-server/v6/model" "github.com/mattermost/mattermost-server/v6/shared/filestore" @@ -83,54 +84,70 @@ func TestReadReplicaDisabledBasedOnLicense(t *testing.T) { s, err := NewServer(func(server *Server) error { configStore := config.NewTestMemoryStore() configStore.Set(&cfg) - server.configStore = &configWrapper{srv: server, Store: configStore} + var err error + server.platform, err = platform.New(platform.ServiceConfig{ + ConfigStore: configStore, + }) + require.NoError(t, err) return nil }) require.NoError(t, err) defer s.Shutdown() require.Same(t, s.sqlStore.GetMasterX(), s.sqlStore.GetReplicaX()) - require.Len(t, s.Config().SqlSettings.DataSourceReplicas, 1) + require.Len(t, s.platform.Config().SqlSettings.DataSourceReplicas, 1) }) t.Run("Read Replicas With License", func(t *testing.T) { s, err := NewServer(func(server *Server) error { configStore := config.NewTestMemoryStore() configStore.Set(&cfg) - server.configStore = &configWrapper{srv: server, Store: configStore} + var err error + server.platform, err = platform.New(platform.ServiceConfig{ + ConfigStore: configStore, + }) + require.NoError(t, err) server.licenseValue.Store(model.NewTestLicense()) return nil }) require.NoError(t, err) defer s.Shutdown() require.NotSame(t, s.sqlStore.GetMasterX(), s.sqlStore.GetReplicaX()) - require.Len(t, s.Config().SqlSettings.DataSourceReplicas, 1) + require.Len(t, s.platform.Config().SqlSettings.DataSourceReplicas, 1) }) t.Run("Search Replicas with no License", func(t *testing.T) { s, err := NewServer(func(server *Server) error { configStore := config.NewTestMemoryStore() configStore.Set(&cfg) - server.configStore = &configWrapper{srv: server, Store: configStore} + var err error + server.platform, err = platform.New(platform.ServiceConfig{ + ConfigStore: configStore, + }) + require.NoError(t, err) return nil }) require.NoError(t, err) defer s.Shutdown() require.Same(t, s.sqlStore.GetMasterX(), s.sqlStore.GetSearchReplicaX()) - require.Len(t, s.Config().SqlSettings.DataSourceSearchReplicas, 1) + require.Len(t, s.platform.Config().SqlSettings.DataSourceSearchReplicas, 1) }) t.Run("Search Replicas With License", func(t *testing.T) { s, err := NewServer(func(server *Server) error { configStore := config.NewTestMemoryStore() configStore.Set(&cfg) - server.configStore = &configWrapper{srv: server, Store: configStore} + var err error + server.platform, err = platform.New(platform.ServiceConfig{ + ConfigStore: configStore, + }) + require.NoError(t, err) server.licenseValue.Store(model.NewTestLicense()) return nil }) require.NoError(t, err) defer s.Shutdown() require.NotSame(t, s.sqlStore.GetMasterX(), s.sqlStore.GetSearchReplicaX()) - require.Len(t, s.Config().SqlSettings.DataSourceSearchReplicas, 1) + require.Len(t, s.platform.Config().SqlSettings.DataSourceSearchReplicas, 1) }) } @@ -143,7 +160,7 @@ func TestStartServerPortUnavailable(t *testing.T) { require.NoError(t, err) // Attempt to listen on the port used above. - s.UpdateConfig(func(cfg *model.Config) { + s.platform.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.ListenAddress = listener.Addr().String() }) @@ -168,8 +185,12 @@ func TestStartServerNoS3Bucket(t *testing.T) { s, err := NewServer(func(server *Server) error { configStore, _ := config.NewFileStore("config.json", true) store, _ := config.NewStoreFromBacking(configStore, nil, false) - server.configStore = &configWrapper{srv: server, Store: store} - server.UpdateConfig(func(cfg *model.Config) { + var err error + server.platform, err = platform.New(platform.ServiceConfig{ + ConfigStore: store, + }) + require.NoError(t, err) + server.platform.UpdateConfig(func(cfg *model.Config) { cfg.FileSettings = model.FileSettings{ DriverName: model.NewString(model.ImageDriverS3), AmazonS3AccessKeyId: model.NewString(model.MinioAccessKey), @@ -393,7 +414,7 @@ func TestPanicLog(t *testing.T) { }) testDir, _ := fileutils.FindDir("tests") - s.UpdateConfig(func(cfg *model.Config) { + s.platform.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.ListenAddress = ":0" *cfg.ServiceSettings.ConnectionSecurity = "TLS" *cfg.ServiceSettings.TLSKeyFile = path.Join(testDir, "tls_test_key.pem") diff --git a/app/status_test.go b/app/status_test.go index e56ef60728..81ef4cebc4 100644 --- a/app/status_test.go +++ b/app/status_test.go @@ -104,7 +104,7 @@ func TestCustomStatusErrors(t *testing.T) { UserStore: &mockUserStore, SessionStore: &mockSessionStore, OAuthStore: &mockOAuthStore, - ConfigFn: th.App.ch.srv.Config, + ConfigFn: th.App.ch.srv.platform.Config, LicenseFn: th.App.ch.srv.License, }) require.NoError(t, err) diff --git a/app/team_test.go b/app/team_test.go index bb69aa762c..3938aaacff 100644 --- a/app/team_test.go +++ b/app/team_test.go @@ -1044,7 +1044,7 @@ func TestLeaveTeamPanic(t *testing.T) { UserStore: &mockUserStore, SessionStore: &mocks.SessionStore{}, OAuthStore: &mocks.OAuthStore{}, - ConfigFn: th.App.ch.srv.Config, + ConfigFn: th.App.ch.srv.platform.Config, LicenseFn: th.App.ch.srv.License, }) require.NoError(t, err) @@ -1088,7 +1088,7 @@ func TestLeaveTeamPanic(t *testing.T) { GroupStore: &mocks.GroupStore{}, Users: th.App.ch.srv.userService, WebHub: th.App.ch.srv, - ConfigFn: th.App.ch.srv.Config, + ConfigFn: th.App.ch.srv.platform.Config, LicenseFn: th.App.ch.srv.License, }) require.NoError(t, err) diff --git a/app/user_test.go b/app/user_test.go index 4d545f894f..75d5fa80f3 100644 --- a/app/user_test.go +++ b/app/user_test.go @@ -1712,7 +1712,7 @@ func TestUpdateThreadReadForUser(t *testing.T) { UserStore: &mockUserStore, SessionStore: &storemocks.SessionStore{}, OAuthStore: &storemocks.OAuthStore{}, - ConfigFn: th.App.ch.srv.Config, + ConfigFn: th.App.ch.srv.platform.Config, LicenseFn: th.App.ch.srv.License, }) require.NoError(t, err) @@ -1749,8 +1749,8 @@ func TestCreateUserWithInitialPreferences(t *testing.T) { }) t.Run("successfully create a user with insights feature flag disabled", func(t *testing.T) { - th.Server.configStore.SetReadOnlyFF(false) - defer th.Server.configStore.SetReadOnlyFF(true) + th.Server.platform.SetConfigReadOnlyFF(false) + defer th.Server.platform.SetConfigReadOnlyFF(true) th.App.UpdateConfig(func(cfg *model.Config) { cfg.FeatureFlags.InsightsEnabled = false }) defer th.App.UpdateConfig(func(cfg *model.Config) { cfg.FeatureFlags.InsightsEnabled = true }) testUser := th.CreateUser() @@ -1769,8 +1769,8 @@ func TestCreateUserWithInitialPreferences(t *testing.T) { }) t.Run("successfully create a guest user with initial tutorial, insights and recommended steps preferences", func(t *testing.T) { - th.Server.configStore.SetReadOnlyFF(false) - defer th.Server.configStore.SetReadOnlyFF(true) + th.Server.platform.SetConfigReadOnlyFF(false) + defer th.Server.platform.SetConfigReadOnlyFF(true) th.App.UpdateConfig(func(cfg *model.Config) { cfg.FeatureFlags.InsightsEnabled = true }) testUser := th.CreateGuest() defer th.App.PermanentDeleteUser(th.Context, testUser) diff --git a/app/web_hub_test.go b/app/web_hub_test.go index 10dd13c695..ee14d43fd2 100644 --- a/app/web_hub_test.go +++ b/app/web_hub_test.go @@ -167,7 +167,7 @@ func TestHubSessionRevokeRace(t *testing.T) { UserStore: &mockUserStore, SessionStore: &mockSessionStore, OAuthStore: &mockOAuthStore, - ConfigFn: th.App.ch.srv.Config, + ConfigFn: th.App.ch.srv.platform.Config, Metrics: th.App.Metrics(), Cluster: th.App.Cluster(), LicenseFn: th.App.ch.srv.License, diff --git a/cmd/mattermost/commands/init.go b/cmd/mattermost/commands/init.go index a4c58285fa..dfcb54b2ed 100644 --- a/cmd/mattermost/commands/init.go +++ b/cmd/mattermost/commands/init.go @@ -42,9 +42,10 @@ func initDBCommandContext(configDSN string, readOnlyConfigStore bool) (*app.App, model.AppErrorInit(i18n.T) s, err := app.NewServer( + // The option order is important as app.Config option reads app.StartMetrics option. + app.StartMetrics, app.Config(configDSN, readOnlyConfigStore, nil), app.StartSearchEngine, - app.StartMetrics, ) if err != nil { return nil, err diff --git a/cmd/mattermost/commands/server.go b/cmd/mattermost/commands/server.go index 3d0c430255..20309b31be 100644 --- a/cmd/mattermost/commands/server.go +++ b/cmd/mattermost/commands/server.go @@ -65,11 +65,12 @@ func runServer(configStore *config.Store, interruptChan chan os.Signal) error { debug.SetTraceback("crash") options := []app.Option{ + // The option order is important as app.Config option reads app.StartMetrics option. + app.StartMetrics, app.ConfigStore(configStore), app.RunEssentialJobs, app.JoinCluster, app.StartSearchEngine, - app.StartMetrics, } server, err := app.NewServer(options...) if err != nil { diff --git a/web/web_test.go b/web/web_test.go index 8c79c4cd33..d31503560e 100644 --- a/web/web_test.go +++ b/web/web_test.go @@ -102,16 +102,17 @@ func setupTestHelper(tb testing.TB, includeCacheLayer bool) *TestHelper { } } + a := app.New(app.ServerConnector(s.Channels())) prevListenAddress := *s.Config().ServiceSettings.ListenAddress - s.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.ListenAddress = ":0" }) + a.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.ListenAddress = ":0" }) serverErr := s.Start() if serverErr != nil { panic(serverErr) } - s.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.ListenAddress = prevListenAddress }) + a.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.ListenAddress = prevListenAddress }) // Disable strict password requirements for test - s.UpdateConfig(func(cfg *model.Config) { + a.UpdateConfig(func(cfg *model.Config) { *cfg.PasswordSettings.MinimumLength = 5 *cfg.PasswordSettings.Lowercase = false *cfg.PasswordSettings.Uppercase = false @@ -119,15 +120,13 @@ func setupTestHelper(tb testing.TB, includeCacheLayer bool) *TestHelper { *cfg.PasswordSettings.Number = false }) - a := app.New(app.ServerConnector(s.Channels())) - web := New(s) URL = fmt.Sprintf("http://localhost:%v", s.ListenAddr.Port) apiClient = model.NewAPIv4Client(URL) s.Store.MarkSystemRanUnitTests() - s.UpdateConfig(func(cfg *model.Config) { + a.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.EnableOpenServer = true }) From 97b3ffd7ead0166de3a4817ea28dd973c4f9e6f7 Mon Sep 17 00:00:00 2001 From: Agniva De Sarker Date: Mon, 8 Aug 2022 20:02:49 +0530 Subject: [PATCH 05/10] MM-43202: Change some 501 response codes to fix SLO violations (#20767) There were lots of cases where we were using the code 501 in an incorrect manner, and since 5xx codes are considered as SLO violations, these were flagged by our monitoring incorrectly. These were the guidelines to change the codes: 1. Any case of missing license or config not correctly enabled is set as Forbidden. The logic is that the user is correctly authenticated with a session, but does not have enough privileges to have the higher license, or hasn't changed the config correctly. 2. Any case of incorrectly formed request is obviously a 400. https://mattermost.atlassian.net/browse/MM-43202 ```release-note NONE ``` --- api4/channel.go | 8 ++++---- api4/channel_test.go | 2 +- api4/cloud.go | 22 ++++++++++----------- api4/cloud_test.go | 4 ++-- api4/file.go | 6 +++--- api4/file_test.go | 6 +++--- api4/group.go | 46 ++++++++++++++++++++++---------------------- api4/group_test.go | 30 ++++++++++++++++++----------- api4/user_test.go | 4 ++-- app/emoji.go | 20 +++++++++---------- 10 files changed, 78 insertions(+), 70 deletions(-) diff --git a/api4/channel.go b/api4/channel.go index 954ec5632e..40372dc068 100644 --- a/api4/channel.go +++ b/api4/channel.go @@ -1820,7 +1820,7 @@ func updateChannelScheme(c *Context, w http.ResponseWriter, r *http.Request) { auditRec.AddEventParameter("scheme_id", *schemeID) if c.App.Channels().License() == nil { - c.Err = model.NewAppError("Api4.UpdateChannelScheme", "api.channel.update_channel_scheme.license.error", nil, "", http.StatusNotImplemented) + c.Err = model.NewAppError("Api4.UpdateChannelScheme", "api.channel.update_channel_scheme.license.error", nil, "", http.StatusForbidden) return } @@ -1916,7 +1916,7 @@ func channelMembersMinusGroupMembers(c *Context, w http.ResponseWriter, r *http. func channelMemberCountsByGroup(c *Context, w http.ResponseWriter, r *http.Request) { if c.App.Channels().License() == nil { - c.Err = model.NewAppError("Api4.channelMemberCountsByGroup", "api.channel.channel_member_counts_by_group.license.error", nil, "", http.StatusNotImplemented) + c.Err = model.NewAppError("Api4.channelMemberCountsByGroup", "api.channel.channel_member_counts_by_group.license.error", nil, "", http.StatusForbidden) return } @@ -1949,7 +1949,7 @@ func channelMemberCountsByGroup(c *Context, w http.ResponseWriter, r *http.Reque func getChannelModerations(c *Context, w http.ResponseWriter, r *http.Request) { if c.App.Channels().License() == nil { - c.Err = model.NewAppError("Api4.GetChannelModerations", "api.channel.get_channel_moderations.license.error", nil, "", http.StatusNotImplemented) + c.Err = model.NewAppError("Api4.GetChannelModerations", "api.channel.get_channel_moderations.license.error", nil, "", http.StatusForbidden) return } @@ -1986,7 +1986,7 @@ func getChannelModerations(c *Context, w http.ResponseWriter, r *http.Request) { func patchChannelModerations(c *Context, w http.ResponseWriter, r *http.Request) { if c.App.Channels().License() == nil { - c.Err = model.NewAppError("Api4.patchChannelModerations", "api.channel.patch_channel_moderations.license.error", nil, "", http.StatusNotImplemented) + c.Err = model.NewAppError("Api4.patchChannelModerations", "api.channel.patch_channel_moderations.license.error", nil, "", http.StatusForbidden) return } diff --git a/api4/channel_test.go b/api4/channel_test.go index 216e54f082..e45312b71a 100644 --- a/api4/channel_test.go +++ b/api4/channel_test.go @@ -3840,7 +3840,7 @@ func TestUpdateChannelScheme(t *testing.T) { th.App.Srv().SetLicense(nil) resp, err = th.SystemAdminClient.UpdateChannelScheme(channel.Id, channelScheme.Id) require.Error(t, err) - CheckNotImplementedStatus(t, resp) + CheckForbiddenStatus(t, resp) th.App.Srv().SetLicense(model.NewTestLicense("")) // Test an invalid scheme scope. diff --git a/api4/cloud.go b/api4/cloud.go index 825db6d5bb..c9675bb118 100644 --- a/api4/cloud.go +++ b/api4/cloud.go @@ -73,7 +73,7 @@ func handleNotifyAdminToUpgrade(c *Context, w http.ResponseWriter, r *http.Reque func getSubscription(c *Context, w http.ResponseWriter, r *http.Request) { if c.App.Channels().License() == nil || !*c.App.Channels().License().Features.Cloud { - c.Err = model.NewAppError("Api4.getSubscription", "api.cloud.license_error", nil, "", http.StatusNotImplemented) + c.Err = model.NewAppError("Api4.getSubscription", "api.cloud.license_error", nil, "", http.StatusForbidden) return } @@ -296,7 +296,7 @@ func validateWorkspaceBusinessEmail(c *Context, w http.ResponseWriter, r *http.R func getCloudProducts(c *Context, w http.ResponseWriter, r *http.Request) { if c.App.Channels().License() == nil || !*c.App.Channels().License().Features.Cloud { - c.Err = model.NewAppError("Api4.getCloudProducts", "api.cloud.license_error", nil, "", http.StatusNotImplemented) + c.Err = model.NewAppError("Api4.getCloudProducts", "api.cloud.license_error", nil, "", http.StatusForbidden) return } @@ -338,7 +338,7 @@ func getCloudProducts(c *Context, w http.ResponseWriter, r *http.Request) { func getCloudLimits(c *Context, w http.ResponseWriter, r *http.Request) { if c.App.Channels().License() == nil || !*c.App.Channels().License().Features.Cloud { - c.Err = model.NewAppError("Api4.getCloudLimits", "api.cloud.license_error", nil, "", http.StatusNotImplemented) + c.Err = model.NewAppError("Api4.getCloudLimits", "api.cloud.license_error", nil, "", http.StatusForbidden) return } @@ -359,7 +359,7 @@ func getCloudLimits(c *Context, w http.ResponseWriter, r *http.Request) { func getCloudCustomer(c *Context, w http.ResponseWriter, r *http.Request) { if c.App.Channels().License() == nil || !*c.App.Channels().License().Features.Cloud { - c.Err = model.NewAppError("Api4.getCloudCustomer", "api.cloud.license_error", nil, "", http.StatusNotImplemented) + c.Err = model.NewAppError("Api4.getCloudCustomer", "api.cloud.license_error", nil, "", http.StatusForbidden) return } @@ -385,7 +385,7 @@ func getCloudCustomer(c *Context, w http.ResponseWriter, r *http.Request) { func updateCloudCustomer(c *Context, w http.ResponseWriter, r *http.Request) { if c.App.Channels().License() == nil || !*c.App.Channels().License().Features.Cloud { - c.Err = model.NewAppError("Api4.updateCloudCustomer", "api.cloud.license_error", nil, "", http.StatusNotImplemented) + c.Err = model.NewAppError("Api4.updateCloudCustomer", "api.cloud.license_error", nil, "", http.StatusForbidden) return } @@ -423,7 +423,7 @@ func updateCloudCustomer(c *Context, w http.ResponseWriter, r *http.Request) { func updateCloudCustomerAddress(c *Context, w http.ResponseWriter, r *http.Request) { if c.App.Channels().License() == nil || !*c.App.Channels().License().Features.Cloud { - c.Err = model.NewAppError("Api4.updateCloudCustomerAddress", "api.cloud.license_error", nil, "", http.StatusNotImplemented) + c.Err = model.NewAppError("Api4.updateCloudCustomerAddress", "api.cloud.license_error", nil, "", http.StatusForbidden) return } @@ -461,7 +461,7 @@ func updateCloudCustomerAddress(c *Context, w http.ResponseWriter, r *http.Reque func createCustomerPayment(c *Context, w http.ResponseWriter, r *http.Request) { if c.App.Channels().License() == nil || !*c.App.Channels().License().Features.Cloud { - c.Err = model.NewAppError("Api4.createCustomerPayment", "api.cloud.license_error", nil, "", http.StatusNotImplemented) + c.Err = model.NewAppError("Api4.createCustomerPayment", "api.cloud.license_error", nil, "", http.StatusForbidden) return } @@ -492,7 +492,7 @@ func createCustomerPayment(c *Context, w http.ResponseWriter, r *http.Request) { func confirmCustomerPayment(c *Context, w http.ResponseWriter, r *http.Request) { if c.App.Channels().License() == nil || !*c.App.Channels().License().Features.Cloud { - c.Err = model.NewAppError("Api4.confirmCustomerPayment", "api.cloud.license_error", nil, "", http.StatusNotImplemented) + c.Err = model.NewAppError("Api4.confirmCustomerPayment", "api.cloud.license_error", nil, "", http.StatusForbidden) return } @@ -529,7 +529,7 @@ func confirmCustomerPayment(c *Context, w http.ResponseWriter, r *http.Request) func getInvoicesForSubscription(c *Context, w http.ResponseWriter, r *http.Request) { if c.App.Channels().License() == nil || !*c.App.Channels().License().Features.Cloud { - c.Err = model.NewAppError("Api4.getInvoicesForSubscription", "api.cloud.license_error", nil, "", http.StatusNotImplemented) + c.Err = model.NewAppError("Api4.getInvoicesForSubscription", "api.cloud.license_error", nil, "", http.StatusForbidden) return } @@ -555,7 +555,7 @@ func getInvoicesForSubscription(c *Context, w http.ResponseWriter, r *http.Reque func getSubscriptionInvoicePDF(c *Context, w http.ResponseWriter, r *http.Request) { if c.App.Channels().License() == nil || !*c.App.Channels().License().Features.Cloud { - c.Err = model.NewAppError("Api4.getSubscriptionInvoicePDF", "api.cloud.license_error", nil, "", http.StatusNotImplemented) + c.Err = model.NewAppError("Api4.getSubscriptionInvoicePDF", "api.cloud.license_error", nil, "", http.StatusForbidden) return } @@ -590,7 +590,7 @@ func getSubscriptionInvoicePDF(c *Context, w http.ResponseWriter, r *http.Reques func handleCWSWebhook(c *Context, w http.ResponseWriter, r *http.Request) { if c.App.Channels().License() == nil || !*c.App.Channels().License().Features.Cloud { - c.Err = model.NewAppError("Api4.handleCWSWebhook", "api.cloud.license_error", nil, "", http.StatusNotImplemented) + c.Err = model.NewAppError("Api4.handleCWSWebhook", "api.cloud.license_error", nil, "", http.StatusForbidden) return } diff --git a/api4/cloud_test.go b/api4/cloud_test.go index a689c68a8e..1964c6981d 100644 --- a/api4/cloud_test.go +++ b/api4/cloud_test.go @@ -30,7 +30,7 @@ func Test_getCloudLimits(t *testing.T) { limits, r, err := th.Client.GetProductLimits() require.Error(t, err) require.Nil(t, limits) - require.Equal(t, http.StatusNotImplemented, r.StatusCode, "Expected 501 Not Implemented") + require.Equal(t, http.StatusForbidden, r.StatusCode, "Expected 403 forbidden") }) t.Run("non cloud license returns not implemented", func(t *testing.T) { @@ -44,7 +44,7 @@ func Test_getCloudLimits(t *testing.T) { limits, r, err := th.Client.GetProductLimits() require.Error(t, err) require.Nil(t, limits) - require.Equal(t, http.StatusNotImplemented, r.StatusCode, "Expected 501 Not Implemented") + require.Equal(t, http.StatusForbidden, r.StatusCode, "Expected 403 forbidden") }) t.Run("error fetching limits returns internal server error", func(t *testing.T) { diff --git a/api4/file.go b/api4/file.go index 1eadda69b8..c1cf36d4a5 100644 --- a/api4/file.go +++ b/api4/file.go @@ -103,7 +103,7 @@ func uploadFileStream(c *Context, w http.ResponseWriter, r *http.Request) { if !*c.App.Config().FileSettings.EnableFileAttachments { c.Err = model.NewAppError("uploadFileStream", "api.file.attachments.disabled.app_error", - nil, "", http.StatusNotImplemented) + nil, "", http.StatusForbidden) return } @@ -545,7 +545,7 @@ func getFileLink(c *Context, w http.ResponseWriter, r *http.Request) { } if !*c.App.Config().FileSettings.EnablePublicLink { - c.Err = model.NewAppError("getPublicLink", "api.file.get_public_link.disabled.app_error", nil, "", http.StatusNotImplemented) + c.Err = model.NewAppError("getPublicLink", "api.file.get_public_link.disabled.app_error", nil, "", http.StatusForbidden) return } @@ -643,7 +643,7 @@ func getPublicFile(c *Context, w http.ResponseWriter, r *http.Request) { } if !*c.App.Config().FileSettings.EnablePublicLink { - c.Err = model.NewAppError("getPublicFile", "api.file.get_public_link.disabled.app_error", nil, "", http.StatusNotImplemented) + c.Err = model.NewAppError("getPublicFile", "api.file.get_public_link.disabled.app_error", nil, "", http.StatusForbidden) return } diff --git a/api4/file_test.go b/api4/file_test.go index dafb76110e..cc9b055985 100644 --- a/api4/file_test.go +++ b/api4/file_test.go @@ -512,7 +512,7 @@ func TestUploadFiles(t *testing.T) { client: th.SystemAdminClient, names: []string{"test.png"}, skipSuccessValidation: true, - checkResponse: CheckNotImplementedStatus, + checkResponse: CheckForbiddenStatus, setupConfig: func(a *app.App) func(a *app.App) { enableFileAttachments := *a.Config().FileSettings.EnableFileAttachments a.UpdateConfig(func(cfg *model.Config) { *cfg.FileSettings.EnableFileAttachments = false }) @@ -919,7 +919,7 @@ func TestGetFileLink(t *testing.T) { th.App.UpdateConfig(func(cfg *model.Config) { *cfg.FileSettings.EnablePublicLink = false }) _, resp, err = client.GetFileLink(fileId) require.Error(t, err) - CheckNotImplementedStatus(t, resp) + CheckForbiddenStatus(t, resp) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.FileSettings.EnablePublicLink = true }) link, _, err := client.GetFileLink(fileId) @@ -1090,7 +1090,7 @@ func TestGetPublicFile(t *testing.T) { resp, err = http.Get(link) require.NoError(t, err) - require.Equal(t, http.StatusNotImplemented, resp.StatusCode, "should've failed to get image with disabled public link") + require.Equal(t, http.StatusForbidden, resp.StatusCode, "should've failed to get image with disabled public link") // test after the salt has changed th.App.UpdateConfig(func(cfg *model.Config) { *cfg.FileSettings.EnablePublicLink = true }) diff --git a/api4/group.go b/api4/group.go index 9d13c18325..fa7dd38e0c 100644 --- a/api4/group.go +++ b/api4/group.go @@ -137,7 +137,7 @@ func createGroup(c *Context, w http.ResponseWriter, r *http.Request) { } if group.Source != model.GroupSourceCustom { - c.Err = model.NewAppError("createGroup", "app.group.crud_permission", nil, "", http.StatusNotImplemented) + c.Err = model.NewAppError("createGroup", "app.group.crud_permission", nil, "", http.StatusBadRequest) return } @@ -153,12 +153,12 @@ func createGroup(c *Context, w http.ResponseWriter, r *http.Request) { } if !group.AllowReference { - c.Err = model.NewAppError("createGroup", "api.custom_groups.must_be_referenceable", nil, "", http.StatusNotImplemented) + c.Err = model.NewAppError("createGroup", "api.custom_groups.must_be_referenceable", nil, "", http.StatusBadRequest) return } if group.GetRemoteId() != "" { - c.Err = model.NewAppError("createGroup", "api.custom_groups.no_remote_id", nil, "", http.StatusNotImplemented) + c.Err = model.NewAppError("createGroup", "api.custom_groups.no_remote_id", nil, "", http.StatusBadRequest) return } @@ -234,13 +234,13 @@ func patchGroup(c *Context, w http.ResponseWriter, r *http.Request) { groupPatch.Name = &tmp } else { if *groupPatch.Name == model.UserNotifyAll || *groupPatch.Name == model.ChannelMentionsNotifyProp || *groupPatch.Name == model.UserNotifyHere { - c.Err = model.NewAppError("Api4.patchGroup", "api.ldap_groups.existing_reserved_name_error", nil, "", http.StatusNotImplemented) + c.Err = model.NewAppError("Api4.patchGroup", "api.ldap_groups.existing_reserved_name_error", nil, "", http.StatusBadRequest) return } //check if a user already has this group name user, _ := c.App.GetUserByUsername(*groupPatch.Name) if user != nil { - c.Err = model.NewAppError("Api4.patchGroup", "api.ldap_groups.existing_user_name_error", nil, "", http.StatusNotImplemented) + c.Err = model.NewAppError("Api4.patchGroup", "api.ldap_groups.existing_user_name_error", nil, "", http.StatusBadRequest) return } //check if a mentionable group already has this name @@ -249,7 +249,7 @@ func patchGroup(c *Context, w http.ResponseWriter, r *http.Request) { } existingGroup, _ := c.App.GetGroupByName(*groupPatch.Name, searchOpts) if existingGroup != nil { - c.Err = model.NewAppError("Api4.patchGroup", "api.ldap_groups.existing_group_name_error", nil, "", http.StatusNotImplemented) + c.Err = model.NewAppError("Api4.patchGroup", "api.ldap_groups.existing_group_name_error", nil, "", http.StatusBadRequest) return } } @@ -326,7 +326,7 @@ func linkGroupSyncable(c *Context, w http.ResponseWriter, r *http.Request) { auditRec.AddEventParameter("patch", patch) if !*c.App.Channels().License().Features.LDAPGroups { - c.Err = model.NewAppError("Api4.createGroupSyncable", "api.ldap_groups.license_error", nil, "", http.StatusNotImplemented) + c.Err = model.NewAppError("Api4.createGroupSyncable", "api.ldap_groups.license_error", nil, "", http.StatusForbidden) return } @@ -385,7 +385,7 @@ func getGroupSyncable(c *Context, w http.ResponseWriter, r *http.Request) { syncableType := c.Params.SyncableType if !*c.App.Channels().License().Features.LDAPGroups { - c.Err = model.NewAppError("Api4.getGroupSyncable", "api.ldap_groups.license_error", nil, "", http.StatusNotImplemented) + c.Err = model.NewAppError("Api4.getGroupSyncable", "api.ldap_groups.license_error", nil, "", http.StatusForbidden) return } @@ -422,7 +422,7 @@ func getGroupSyncables(c *Context, w http.ResponseWriter, r *http.Request) { syncableType := c.Params.SyncableType if !*c.App.Channels().License().Features.LDAPGroups { - c.Err = model.NewAppError("Api4.getGroupSyncables", "api.ldap_groups.license_error", nil, "", http.StatusNotImplemented) + c.Err = model.NewAppError("Api4.getGroupSyncables", "api.ldap_groups.license_error", nil, "", http.StatusForbidden) return } @@ -487,7 +487,7 @@ func patchGroupSyncable(c *Context, w http.ResponseWriter, r *http.Request) { if !*c.App.Channels().License().Features.LDAPGroups { c.Err = model.NewAppError("Api4.patchGroupSyncable", "api.ldap_groups.license_error", nil, "", - http.StatusNotImplemented) + http.StatusForbidden) return } @@ -552,7 +552,7 @@ func unlinkGroupSyncable(c *Context, w http.ResponseWriter, r *http.Request) { auditRec.AddEventParameter("syncable_type", syncableType) if !*c.App.Channels().License().Features.LDAPGroups { - c.Err = model.NewAppError("Api4.unlinkGroupSyncable", "api.ldap_groups.license_error", nil, "", http.StatusNotImplemented) + c.Err = model.NewAppError("Api4.unlinkGroupSyncable", "api.ldap_groups.license_error", nil, "", http.StatusForbidden) return } @@ -655,7 +655,7 @@ func getGroupStats(c *Context, w http.ResponseWriter, r *http.Request) { } if !*c.App.Channels().License().Features.LDAPGroups { - c.Err = model.NewAppError("Api4.getGroupStats", "api.ldap_groups.license_error", nil, "", http.StatusNotImplemented) + c.Err = model.NewAppError("Api4.getGroupStats", "api.ldap_groups.license_error", nil, "", http.StatusForbidden) return } @@ -695,7 +695,7 @@ func getGroupsByUserId(c *Context, w http.ResponseWriter, r *http.Request) { } if !*c.App.Channels().License().Features.LDAPGroups { - c.Err = model.NewAppError("Api4.getGroupsByUserId", "api.ldap_groups.license_error", nil, "", http.StatusNotImplemented) + c.Err = model.NewAppError("Api4.getGroupsByUserId", "api.ldap_groups.license_error", nil, "", http.StatusForbidden) return } @@ -721,7 +721,7 @@ func getGroupsByChannel(c *Context, w http.ResponseWriter, r *http.Request) { } if c.App.Channels().License() == nil || !*c.App.Channels().License().Features.LDAPGroups { - c.Err = model.NewAppError("Api4.getGroupsByChannel", "api.ldap_groups.license_error", nil, "", http.StatusNotImplemented) + c.Err = model.NewAppError("Api4.getGroupsByChannel", "api.ldap_groups.license_error", nil, "", http.StatusForbidden) return } @@ -778,7 +778,7 @@ func getGroupsByTeam(c *Context, w http.ResponseWriter, r *http.Request) { return } if c.App.Channels().License() == nil || !*c.App.Channels().License().Features.LDAPGroups { - c.Err = model.NewAppError("Api4.getGroupsByTeam", "api.ldap_groups.license_error", nil, "", http.StatusNotImplemented) + c.Err = model.NewAppError("Api4.getGroupsByTeam", "api.ldap_groups.license_error", nil, "", http.StatusForbidden) return } @@ -820,7 +820,7 @@ func getGroupsAssociatedToChannelsByTeam(c *Context, w http.ResponseWriter, r *h } if !*c.App.Channels().License().Features.LDAPGroups { - c.Err = model.NewAppError("Api4.getGroupsAssociatedToChannelsByTeam", "api.ldap_groups.license_error", nil, "", http.StatusNotImplemented) + c.Err = model.NewAppError("Api4.getGroupsAssociatedToChannelsByTeam", "api.ldap_groups.license_error", nil, "", http.StatusForbidden) return } @@ -970,7 +970,7 @@ func deleteGroup(c *Context, w http.ResponseWriter, r *http.Request) { } if group.Source != model.GroupSourceCustom { - c.Err = model.NewAppError("Api4.deleteGroup", "app.group.crud_permission", nil, "", http.StatusNotImplemented) + c.Err = model.NewAppError("Api4.deleteGroup", "app.group.crud_permission", nil, "", http.StatusBadRequest) return } @@ -1013,7 +1013,7 @@ func addGroupMembers(c *Context, w http.ResponseWriter, r *http.Request) { } if group.Source != model.GroupSourceCustom { - c.Err = model.NewAppError("Api4.deleteGroup", "app.group.crud_permission", nil, "", http.StatusNotImplemented) + c.Err = model.NewAppError("Api4.deleteGroup", "app.group.crud_permission", nil, "", http.StatusBadRequest) return } @@ -1066,7 +1066,7 @@ func deleteGroupMembers(c *Context, w http.ResponseWriter, r *http.Request) { } if group.Source != model.GroupSourceCustom { - c.Err = model.NewAppError("Api4.deleteGroup", "app.group.crud_permission", nil, "", http.StatusNotImplemented) + c.Err = model.NewAppError("Api4.deleteGroup", "app.group.crud_permission", nil, "", http.StatusBadRequest) return } @@ -1117,19 +1117,19 @@ func licensedAndConfiguredForGroupBySource(app app.AppIface, source model.GroupS lic := app.Srv().License() if lic == nil { - return model.NewAppError("", "api.license_error", nil, "", http.StatusNotImplemented) + return model.NewAppError("", "api.license_error", nil, "", http.StatusForbidden) } if source == model.GroupSourceLdap && !*lic.Features.LDAPGroups { - return model.NewAppError("", "api.ldap_groups.license_error", nil, "", http.StatusNotImplemented) + return model.NewAppError("", "api.ldap_groups.license_error", nil, "", http.StatusForbidden) } if source == model.GroupSourceCustom && lic.SkuShortName != model.LicenseShortSkuProfessional && lic.SkuShortName != model.LicenseShortSkuEnterprise { - return model.NewAppError("", "api.custom_groups.license_error", nil, "", http.StatusNotImplemented) + return model.NewAppError("", "api.custom_groups.license_error", nil, "", http.StatusBadRequest) } if source == model.GroupSourceCustom && (!app.Config().FeatureFlags.CustomGroups || !*app.Config().ServiceSettings.EnableCustomGroups) { - return model.NewAppError("", "api.custom_groups.feature_disabled", nil, "", http.StatusNotImplemented) + return model.NewAppError("", "api.custom_groups.feature_disabled", nil, "", http.StatusBadRequest) } return nil diff --git a/api4/group_test.go b/api4/group_test.go index 14688fc474..2c0f359caa 100644 --- a/api4/group_test.go +++ b/api4/group_test.go @@ -98,7 +98,7 @@ func TestCreateGroup(t *testing.T) { _, response, err := th.SystemAdminClient.CreateGroup(gbroken) require.Error(t, err) - CheckNotImplementedStatus(t, response) + CheckBadRequestStatus(t, response) validGroup := &model.Group{ DisplayName: "dn_" + model.NewId(), @@ -137,7 +137,7 @@ func TestCreateGroup(t *testing.T) { } _, response, err = th.SystemAdminClient.CreateGroup(unReferenceableCustomGroup) require.Error(t, err) - CheckNotImplementedStatus(t, response) + CheckBadRequestStatus(t, response) unReferenceableCustomGroup.AllowReference = true _, response, err = th.SystemAdminClient.CreateGroup(unReferenceableCustomGroup) require.NoError(t, err) @@ -152,7 +152,7 @@ func TestCreateGroup(t *testing.T) { } _, response, err = th.SystemAdminClient.CreateGroup(customGroupWithRemoteID) require.Error(t, err) - CheckNotImplementedStatus(t, response) + CheckBadRequestStatus(t, response) th.SystemAdminClient.Logout() _, response, err = th.SystemAdminClient.CreateGroup(g) @@ -178,16 +178,16 @@ func TestDeleteGroup(t *testing.T) { _, response, err := th.Client.DeleteGroup(g.Id) require.Error(t, err) - CheckNotImplementedStatus(t, response) + CheckBadRequestStatus(t, response) th.AddPermissionToRole(model.PermissionDeleteCustomGroup.Id, model.SystemUserRoleId) _, response, err = th.Client.DeleteGroup(g.Id) require.Error(t, err) - CheckNotImplementedStatus(t, response) + CheckBadRequestStatus(t, response) _, response, err = th.Client.DeleteGroup(g.Id) require.Error(t, err) - CheckNotImplementedStatus(t, response) + CheckBadRequestStatus(t, response) _, response, err = th.Client.DeleteGroup("wertyuijhbgvfcde") require.Error(t, err) @@ -939,7 +939,11 @@ func TestGetGroupsByChannel(t *testing.T) { th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) { _, _, response, err := client.GetGroupsByChannel(th.BasicChannel.Id, opts) require.Error(t, err) - CheckNotImplementedStatus(t, response) + if client == th.SystemAdminClient { + CheckNotImplementedStatus(t, response) + } else { + CheckForbiddenStatus(t, response) + } }) th.App.Srv().SetLicense(model.NewTestLicense("ldap")) @@ -1098,7 +1102,11 @@ func TestGetGroupsByTeam(t *testing.T) { th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) { _, _, response, err := client.GetGroupsByTeam(th.BasicTeam.Id, opts) require.Error(t, err) - CheckNotImplementedStatus(t, response) + if client == th.SystemAdminClient { + CheckNotImplementedStatus(t, response) + } else { + CheckForbiddenStatus(t, response) + } }) th.App.Srv().SetLicense(model.NewTestLicense("ldap")) @@ -1248,7 +1256,7 @@ func TestGetGroups(t *testing.T) { opts.Source = model.GroupSourceCustom _, response, err := th.Client.GetGroups(opts) require.Error(t, err) - CheckNotImplementedStatus(t, response) + CheckBadRequestStatus(t, response) // Specify ldap groups source when custom groups feature is disabled opts.Source = model.GroupSourceLdap @@ -1527,7 +1535,7 @@ func TestAddMembersToGroup(t *testing.T) { _, response, upsertErr = th.SystemAdminClient.UpsertGroupMembers(ldapGroup.Id, members) require.Error(t, upsertErr) - CheckNotImplementedStatus(t, response) + CheckBadRequestStatus(t, response) } func TestDeleteMembersFromGroup(t *testing.T) { @@ -1605,5 +1613,5 @@ func TestDeleteMembersFromGroup(t *testing.T) { _, response, deleteErr = th.SystemAdminClient.DeleteGroupMembers(ldapGroup.Id, members) require.Error(t, deleteErr) - CheckNotImplementedStatus(t, response) + CheckBadRequestStatus(t, response) } diff --git a/api4/user_test.go b/api4/user_test.go index 733f6e0e27..91b2df4703 100644 --- a/api4/user_test.go +++ b/api4/user_test.go @@ -1188,7 +1188,7 @@ func TestSearchUsers(t *testing.T) { t.Run("Requires ldap license when searching in group", func(t *testing.T) { _, resp, err = th.SystemAdminClient.SearchUsers(search) require.Error(t, err) - CheckNotImplementedStatus(t, resp) + CheckForbiddenStatus(t, resp) }) th.App.Srv().SetLicense(model.NewTestLicense("ldap")) @@ -2719,7 +2719,7 @@ func TestGetUsersInGroup(t *testing.T) { t.Run("Requires ldap license", func(t *testing.T) { _, response, err := th.SystemAdminClient.GetUsersInGroup(group.Id, 0, 60, "") require.Error(t, err) - CheckNotImplementedStatus(t, response) + CheckForbiddenStatus(t, response) }) th.App.Srv().SetLicense(model.NewTestLicense("ldap")) diff --git a/app/emoji.go b/app/emoji.go index 496868dff3..3de13ab795 100644 --- a/app/emoji.go +++ b/app/emoji.go @@ -39,11 +39,11 @@ const ( func (a *App) CreateEmoji(sessionUserId string, emoji *model.Emoji, multiPartImageData *multipart.Form) (*model.Emoji, *model.AppError) { if !*a.Config().ServiceSettings.EnableCustomEmoji { - return nil, model.NewAppError("UploadEmojiImage", "api.emoji.disabled.app_error", nil, "", http.StatusNotImplemented) + return nil, model.NewAppError("UploadEmojiImage", "api.emoji.disabled.app_error", nil, "", http.StatusForbidden) } if *a.Config().FileSettings.DriverName == "" { - return nil, model.NewAppError("GetEmoji", "api.emoji.storage.app_error", nil, "", http.StatusNotImplemented) + return nil, model.NewAppError("GetEmoji", "api.emoji.storage.app_error", nil, "", http.StatusForbidden) } // wipe the emoji id so that existing emojis can't get overwritten @@ -100,11 +100,11 @@ func (a *App) GetEmojiList(page, perPage int, sort string) ([]*model.Emoji, *mod func (a *App) UploadEmojiImage(id string, imageData *multipart.FileHeader) *model.AppError { if !*a.Config().ServiceSettings.EnableCustomEmoji { - return model.NewAppError("UploadEmojiImage", "api.emoji.disabled.app_error", nil, "", http.StatusNotImplemented) + return model.NewAppError("UploadEmojiImage", "api.emoji.disabled.app_error", nil, "", http.StatusForbidden) } if *a.Config().FileSettings.DriverName == "" { - return model.NewAppError("UploadEmojiImage", "api.emoji.storage.app_error", nil, "", http.StatusNotImplemented) + return model.NewAppError("UploadEmojiImage", "api.emoji.storage.app_error", nil, "", http.StatusForbidden) } file, err := imageData.Open() @@ -185,11 +185,11 @@ func (a *App) DeleteEmoji(emoji *model.Emoji) *model.AppError { func (a *App) GetEmoji(emojiId string) (*model.Emoji, *model.AppError) { if !*a.Config().ServiceSettings.EnableCustomEmoji { - return nil, model.NewAppError("GetEmoji", "api.emoji.disabled.app_error", nil, "", http.StatusNotImplemented) + return nil, model.NewAppError("GetEmoji", "api.emoji.disabled.app_error", nil, "", http.StatusForbidden) } if *a.Config().FileSettings.DriverName == "" { - return nil, model.NewAppError("GetEmoji", "api.emoji.storage.app_error", nil, "", http.StatusNotImplemented) + return nil, model.NewAppError("GetEmoji", "api.emoji.storage.app_error", nil, "", http.StatusForbidden) } emoji, err := a.Srv().Store.Emoji().Get(context.Background(), emojiId, true) @@ -208,11 +208,11 @@ func (a *App) GetEmoji(emojiId string) (*model.Emoji, *model.AppError) { func (a *App) GetEmojiByName(emojiName string) (*model.Emoji, *model.AppError) { if !*a.Config().ServiceSettings.EnableCustomEmoji { - return nil, model.NewAppError("GetEmojiByName", "api.emoji.disabled.app_error", nil, "", http.StatusNotImplemented) + return nil, model.NewAppError("GetEmojiByName", "api.emoji.disabled.app_error", nil, "", http.StatusForbidden) } if *a.Config().FileSettings.DriverName == "" { - return nil, model.NewAppError("GetEmojiByName", "api.emoji.storage.app_error", nil, "", http.StatusNotImplemented) + return nil, model.NewAppError("GetEmojiByName", "api.emoji.storage.app_error", nil, "", http.StatusForbidden) } emoji, err := a.Srv().Store.Emoji().GetByName(context.Background(), emojiName, true) @@ -231,7 +231,7 @@ func (a *App) GetEmojiByName(emojiName string) (*model.Emoji, *model.AppError) { func (a *App) GetMultipleEmojiByName(names []string) ([]*model.Emoji, *model.AppError) { if !*a.Config().ServiceSettings.EnableCustomEmoji { - return nil, model.NewAppError("GetMultipleEmojiByName", "api.emoji.disabled.app_error", nil, "", http.StatusNotImplemented) + return nil, model.NewAppError("GetMultipleEmojiByName", "api.emoji.disabled.app_error", nil, "", http.StatusForbidden) } emoji, err := a.Srv().Store.Emoji().GetMultipleByName(names) @@ -269,7 +269,7 @@ func (a *App) GetEmojiImage(emojiId string) ([]byte, string, *model.AppError) { func (a *App) SearchEmoji(name string, prefixOnly bool, limit int) ([]*model.Emoji, *model.AppError) { if !*a.Config().ServiceSettings.EnableCustomEmoji { - return nil, model.NewAppError("SearchEmoji", "api.emoji.disabled.app_error", nil, "", http.StatusNotImplemented) + return nil, model.NewAppError("SearchEmoji", "api.emoji.disabled.app_error", nil, "", http.StatusForbidden) } list, err := a.Srv().Store.Emoji().Search(name, prefixOnly, limit) From 15b6046a629572f01118711ea435ee4a5450cc10 Mon Sep 17 00:00:00 2001 From: Ashish Bhate Date: Tue, 9 Aug 2022 16:49:43 +0530 Subject: [PATCH 06/10] MM-44922: Flush log buffer before assert (#20795) Summary Flush log buffer before asserting log text. Ticket Link https://mattermost.atlassian.net/browse/MM-44922 --- app/import_functions_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/import_functions_test.go b/app/import_functions_test.go index c764e44c19..a6e47edddc 100644 --- a/app/import_functions_test.go +++ b/app/import_functions_test.go @@ -3100,7 +3100,6 @@ func TestImportImportPost(t *testing.T) { }) t.Run("Reply CreateAt before parent post CreateAt", func(t *testing.T) { - t.Skip("MM-44922") now := model.GetMillis() before := now - 10 data := LineImportWorkerData{ @@ -3128,6 +3127,7 @@ func TestImportImportPost(t *testing.T) { posts, nErr := th.App.Srv().Store.Post().GetPostsCreatedAt(channel.Id, now) require.NoError(t, nErr) require.Len(t, posts, 2, "Unexpected number of posts found.") + require.NoError(t, th.TestLogger.Flush()) testlib.AssertLog(t, th.LogBuffer, mlog.LvlWarn.Name, "Reply CreateAt is before parent post CreateAt, setting it to parent post CreateAt") rootPost := posts[0] From b4570afa9045014d6195b294019825c680c05f38 Mon Sep 17 00:00:00 2001 From: Tim Scheuermann Date: Tue, 9 Aug 2022 14:25:46 +0300 Subject: [PATCH 07/10] Replace deprecated ioutil with io and os (#20776) * Replace ioutil with io and os * Replace ioutil in utils/file.go * Minor fix to tests and excluded files Co-authored-by: Tim Scheuermann Co-authored-by: Mattermod --- api4/apitestlib.go | 3 +- api4/bot_test.go | 4 +- api4/cloud.go | 16 ++-- api4/config_test.go | 8 +- api4/emoji_test.go | 3 +- api4/export_test.go | 5 +- api4/file_test.go | 7 +- api4/group.go | 10 +-- api4/image_test.go | 4 +- api4/integration_action_test.go | 4 +- api4/license.go | 3 +- api4/plugin_test.go | 34 ++++----- api4/saml.go | 4 +- api4/system_test.go | 14 ++-- app/admin.go | 3 +- app/authorization_test.go | 4 +- app/command.go | 3 +- app/compliance.go | 4 +- app/download.go | 3 +- app/email/helper_test.go | 3 +- app/export_test.go | 3 +- app/extract_plugin_tar_test.go | 5 +- app/helper_test.go | 3 +- app/imaging/utils_test.go | 3 +- app/import_functions.go | 3 +- app/import_functions_test.go | 7 +- app/import_test.go | 3 +- app/integration_action.go | 6 +- app/integration_action_test.go | 16 ++-- app/layer_generators/main.go | 6 +- app/ldap.go | 4 +- app/oauth.go | 3 +- app/oauth_test.go | 4 +- app/plugin.go | 9 +-- app/plugin_api.go | 7 +- app/plugin_api_test.go | 42 +++++------ app/plugin_hooks_test.go | 13 ++-- app/plugin_install.go | 6 +- app/plugin_requests.go | 8 +- app/plugin_signature.go | 5 +- app/plugin_signature_test.go | 3 +- app/plugin_test.go | 8 +- app/response_transfer.go | 4 +- app/role_test.go | 4 +- app/saml.go | 6 +- app/security_update_check.go | 4 +- app/slashcommands/helper_test.go | 3 +- app/support_packet.go | 10 +-- app/support_packet_test.go | 13 ++-- app/teams/helper_test.go | 3 +- app/upload_test.go | 4 +- app/users/helper_test.go | 3 +- app/users/profile_picture.go | 4 +- app/webhub_fuzz.go | 3 +- audit/audit_test.go | 5 +- cmd/mattermost/commands/cmdtestlib.go | 3 +- cmd/mattermost/commands/server_test.go | 3 +- config/file.go | 10 +-- config/file_test.go | 39 +++++----- config/migrate_test.go | 3 +- config/store_test.go | 5 +- model/bundle_info_test.go | 3 +- model/client4.go | 29 ++++--- model/command_response.go | 5 +- model/file_info_test.go | 6 +- model/manifest.go | 75 +++++++++---------- model/manifest_test.go | 7 +- model/post_test.go | 6 +- plugin/client_rpc.go | 11 ++- plugin/environment.go | 5 +- plugin/environment_test.go | 7 +- plugin/health_check_test.go | 9 +-- plugin/interface_generator/main.go | 8 +- plugin/plugintest/example_hello_user_test.go | 4 +- plugin/supervisor_test.go | 13 ++-- scripts/config_generator/main_test.go | 5 +- services/docextractor/archive.go | 5 +- services/docextractor/mmpreview.go | 3 +- services/docextractor/pdf.go | 3 +- services/docextractor/plain.go | 3 +- services/httpservice/client_test.go | 4 +- services/imageproxy/atmos_camo_test.go | 4 +- services/imageproxy/local.go | 5 +- services/imageproxy/local_test.go | 8 +- services/remotecluster/sendfile.go | 4 +- services/remotecluster/sendmsg.go | 4 +- services/remotecluster/sendprofileImage.go | 3 +- .../searchengine/bleveengine/bleve_test.go | 3 +- .../bleveengine/indexer/indexing_job_test.go | 3 +- services/telemetry/telemetry_test.go | 8 +- services/upgrader/upgrader_linux.go | 5 +- services/upgrader/upgrader_linux_test.go | 20 ++--- shared/filestore/filesstore_test.go | 3 +- shared/filestore/localstore.go | 3 +- shared/filestore/s3store.go | 3 +- shared/i18n/i18n.go | 4 +- shared/mail/mail_test.go | 7 +- shared/mlog/global_test.go | 5 +- shared/mlog/mlog.go | 11 +-- shared/templates/templates_test.go | 7 +- store/layer_generators/main.go | 10 +-- testlib/helper.go | 5 +- testlib/resources.go | 5 +- utils/archive_test.go | 3 +- utils/file.go | 10 ++- utils/file_test.go | 13 ++-- utils/fileutils/fileutils_test.go | 13 ++-- utils/license.go | 4 +- utils/license_test.go | 5 +- utils/subpath.go | 9 +-- utils/subpath_test.go | 19 +++-- utils/test_files_compiler.go | 9 +-- utils/utils.go | 4 +- web/oauth_test.go | 3 +- web/web_test.go | 15 ++-- 115 files changed, 408 insertions(+), 475 deletions(-) diff --git a/api4/apitestlib.go b/api4/apitestlib.go index f2577e6ab9..b835853170 100644 --- a/api4/apitestlib.go +++ b/api4/apitestlib.go @@ -10,7 +10,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "math/rand" "net" "net/http" @@ -84,7 +83,7 @@ func SetMainHelper(mh *testlib.MainHelper) { func setupTestHelper(dbStore store.Store, searchEngine *searchengine.Broker, enterprise bool, includeCache bool, updateConfig func(*model.Config), options []app.Option) *TestHelper { - tempWorkspace, err := ioutil.TempDir("", "apptest") + tempWorkspace, err := os.MkdirTemp("", "apptest") if err != nil { panic(err) } diff --git a/api4/bot_test.go b/api4/bot_test.go index c5b7bc1413..5a76d23f45 100644 --- a/api4/bot_test.go +++ b/api4/bot_test.go @@ -5,7 +5,7 @@ package api4 import ( "encoding/json" - "io/ioutil" + "io" "strings" "testing" @@ -461,7 +461,7 @@ func TestPatchBot(t *testing.T) { r, err := th.Client.DoAPIPut("/bots/"+createdBot.UserId, `{"creator_id":"`+th.BasicUser2.Id+`"}`) require.NoError(t, err) defer func() { - _, _ = ioutil.ReadAll(r.Body) + _, _ = io.ReadAll(r.Body) _ = r.Body.Close() }() var patchedBot *model.Bot diff --git a/api4/cloud.go b/api4/cloud.go index c9675bb118..6ebeccf706 100644 --- a/api4/cloud.go +++ b/api4/cloud.go @@ -7,7 +7,7 @@ import ( "bytes" "encoding/binary" "encoding/json" - "io/ioutil" + "io" "net/http" "time" @@ -123,7 +123,7 @@ func changeSubscription(c *Context, w http.ResponseWriter, r *http.Request) { return } - bodyBytes, err := ioutil.ReadAll(r.Body) + bodyBytes, err := io.ReadAll(r.Body) if err != nil { c.Err = model.NewAppError("Api4.changeSubscription", "api.cloud.app_error", nil, err.Error(), http.StatusBadRequest) return @@ -174,7 +174,7 @@ func requestCloudTrial(c *Context, w http.ResponseWriter, r *http.Request) { } // check if the email needs to be set - bodyBytes, err := ioutil.ReadAll(r.Body) + bodyBytes, err := io.ReadAll(r.Body) if err != nil { c.Err = model.NewAppError("Api4.requestCloudTrial", "api.cloud.app_error", nil, err.Error(), http.StatusInternalServerError) return @@ -221,7 +221,7 @@ func validateBusinessEmail(c *Context, w http.ResponseWriter, r *http.Request) { return } - bodyBytes, err := ioutil.ReadAll(r.Body) + bodyBytes, err := io.ReadAll(r.Body) if err != nil { c.Err = model.NewAppError("Api4.requestCloudTrial", "api.cloud.app_error", nil, err.Error(), http.StatusInternalServerError) return @@ -394,7 +394,7 @@ func updateCloudCustomer(c *Context, w http.ResponseWriter, r *http.Request) { return } - bodyBytes, err := ioutil.ReadAll(r.Body) + bodyBytes, err := io.ReadAll(r.Body) if err != nil { c.Err = model.NewAppError("Api4.updateCloudCustomer", "api.cloud.app_error", nil, err.Error(), http.StatusInternalServerError) return @@ -432,7 +432,7 @@ func updateCloudCustomerAddress(c *Context, w http.ResponseWriter, r *http.Reque return } - bodyBytes, err := ioutil.ReadAll(r.Body) + bodyBytes, err := io.ReadAll(r.Body) if err != nil { c.Err = model.NewAppError("Api4.updateCloudCustomerAddress", "api.cloud.app_error", nil, err.Error(), http.StatusInternalServerError) return @@ -504,7 +504,7 @@ func confirmCustomerPayment(c *Context, w http.ResponseWriter, r *http.Request) auditRec := c.MakeAuditRecord("confirmCustomerPayment", audit.Fail) defer c.LogAuditRec(auditRec) - bodyBytes, err := ioutil.ReadAll(r.Body) + bodyBytes, err := io.ReadAll(r.Body) if err != nil { c.Err = model.NewAppError("Api4.confirmCustomerPayment", "api.cloud.app_error", nil, err.Error(), http.StatusInternalServerError) return @@ -594,7 +594,7 @@ func handleCWSWebhook(c *Context, w http.ResponseWriter, r *http.Request) { return } - bodyBytes, err := ioutil.ReadAll(r.Body) + bodyBytes, err := io.ReadAll(r.Body) if err != nil { c.Err = model.NewAppError("Api4.handleCWSWebhook", "api.cloud.app_error", nil, err.Error(), http.StatusInternalServerError) return diff --git a/api4/config_test.go b/api4/config_test.go index c200e306fc..52de0491c8 100644 --- a/api4/config_test.go +++ b/api4/config_test.go @@ -6,7 +6,7 @@ package api4 import ( "encoding/json" "fmt" - "io/ioutil" + "io" "net/http" "os" "strings" @@ -533,7 +533,7 @@ func TestUpdateConfigRestrictSystemAdmin(t *testing.T) { } func TestUpdateConfigDiffInAuditRecord(t *testing.T) { - logFile, err := ioutil.TempFile("", "adv.log") + logFile, err := os.CreateTemp("", "adv.log") require.NoError(t, err) defer os.Remove(logFile.Name()) @@ -569,7 +569,7 @@ func TestUpdateConfigDiffInAuditRecord(t *testing.T) { require.NoError(t, logFile.Sync()) - data, err := ioutil.ReadAll(logFile) + data, err := io.ReadAll(logFile) require.NoError(t, err) require.NotEmpty(t, data) @@ -955,7 +955,7 @@ func TestMigrateConfig(t *testing.T) { file, err := json.MarshalIndent(cfg, "", " ") require.NoError(t, err) - err = ioutil.WriteFile("from.json", file, 0644) + err = os.WriteFile("from.json", file, 0644) require.NoError(t, err) defer os.Remove("from.json") diff --git a/api4/emoji_test.go b/api4/emoji_test.go index ac8395c26e..93b915fc8f 100644 --- a/api4/emoji_test.go +++ b/api4/emoji_test.go @@ -7,7 +7,6 @@ import ( "bytes" "image" _ "image/gif" - "io/ioutil" "os" "path/filepath" "testing" @@ -100,7 +99,7 @@ func TestCreateEmoji(t *testing.T) { } path, _ := fileutils.FindDir("tests") - bytes, err := ioutil.ReadFile(filepath.Join(path, "testwebp.webp")) + bytes, err := os.ReadFile(filepath.Join(path, "testwebp.webp")) require.NoError(t, err) newEmoji, _, err = client.CreateEmoji(emoji, bytes, "image.webp") require.NoError(t, err) diff --git a/api4/export_test.go b/api4/export_test.go index db3a961807..5a591598d4 100644 --- a/api4/export_test.go +++ b/api4/export_test.go @@ -6,7 +6,6 @@ package api4 import ( "bytes" "fmt" - "io/ioutil" "os" "path/filepath" "testing" @@ -151,7 +150,7 @@ func TestDownloadExport(t *testing.T) { data := randomBytes(t, 1024*1024) var buf bytes.Buffer exportName := "export.zip" - err = ioutil.WriteFile(filepath.Join(exportDir, exportName), data, 0600) + err = os.WriteFile(filepath.Join(exportDir, exportName), data, 0600) require.NoError(t, err) n, _, err := c.DownloadExport(exportName, &buf, 0) @@ -168,7 +167,7 @@ func TestDownloadExport(t *testing.T) { data := randomBytes(t, 1024*1024) var buf bytes.Buffer exportName := "export.zip" - err = ioutil.WriteFile(filepath.Join(exportDir, exportName), data, 0600) + err = os.WriteFile(filepath.Join(exportDir, exportName), data, 0600) require.NoError(t, err) offset := 1024 * 512 diff --git a/api4/file_test.go b/api4/file_test.go index cc9b055985..49fcfd9b79 100644 --- a/api4/file_test.go +++ b/api4/file_test.go @@ -9,7 +9,6 @@ import ( "encoding/json" "fmt" "io" - "io/ioutil" "mime/multipart" "net/http" "net/textproto" @@ -55,7 +54,7 @@ func fileBytes(t *testing.T, path string) []byte { f, err := os.Open(path) require.NoError(t, err) defer f.Close() - bb, err := ioutil.ReadAll(f) + bb, err := io.ReadAll(f) require.NoError(t, err) return bb } @@ -701,10 +700,10 @@ func TestUploadFiles(t *testing.T) { data, _, err := get(ri.Id) require.NoError(t, err) - expected, err := ioutil.ReadFile(filepath.Join(testDir, name)) + expected, err := os.ReadFile(filepath.Join(testDir, name)) require.NoError(t, err) if !bytes.Equal(data, expected) { - tf, err := ioutil.TempFile("", fmt.Sprintf("test_%v_*_%s", i, name)) + tf, err := os.CreateTemp("", fmt.Sprintf("test_%v_*_%s", i, name)) require.NoError(t, err) defer tf.Close() _, err = io.Copy(tf, bytes.NewReader(data)) diff --git a/api4/group.go b/api4/group.go index fa7dd38e0c..e249637a81 100644 --- a/api4/group.go +++ b/api4/group.go @@ -6,7 +6,7 @@ package api4 import ( "encoding/json" "fmt" - "io/ioutil" + "io" "net/http" "strconv" "strings" @@ -293,7 +293,7 @@ func linkGroupSyncable(c *Context, w http.ResponseWriter, r *http.Request) { } syncableType := c.Params.SyncableType - body, err := ioutil.ReadAll(r.Body) + body, err := io.ReadAll(r.Body) if err != nil { c.Err = model.NewAppError("Api4.createGroupSyncable", "api.io_error", nil, err.Error(), http.StatusBadRequest) return @@ -464,7 +464,7 @@ func patchGroupSyncable(c *Context, w http.ResponseWriter, r *http.Request) { } syncableType := c.Params.SyncableType - body, err := ioutil.ReadAll(r.Body) + body, err := io.ReadAll(r.Body) if err != nil { c.Err = model.NewAppError("Api4.patchGroupSyncable", "api.io_error", nil, err.Error(), http.StatusBadRequest) return @@ -1109,8 +1109,8 @@ func deleteGroupMembers(c *Context, w http.ResponseWriter, r *http.Request) { // licensedAndConfiguredForGroupBySource returns an app error if not properly license or configured for the given group type. The returned app error // will have a blank 'Where' field, which should be subsequently set by the caller, for example: // -// err := licensedAndConfiguredForGroupBySource(c.App, group.Source) -// err.Where = "Api4.getGroup" +// err := licensedAndConfiguredForGroupBySource(c.App, group.Source) +// err.Where = "Api4.getGroup" // // Temporarily, this function also checks for the CustomGroups feature flag. func licensedAndConfiguredForGroupBySource(app app.AppIface, source model.GroupSource) *model.AppError { diff --git a/api4/image_test.go b/api4/image_test.go index aead2b5bf0..4c552e7d86 100644 --- a/api4/image_test.go +++ b/api4/image_test.go @@ -4,7 +4,7 @@ package api4 import ( - "io/ioutil" + "io" "net/http" "net/http/httptest" "net/url" @@ -89,7 +89,7 @@ func TestGetImage(t *testing.T) { require.NoError(t, err) assert.Equal(t, http.StatusOK, resp.StatusCode) - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) require.NoError(t, err) assert.Equal(t, "success", string(respBody)) diff --git a/api4/integration_action_test.go b/api4/integration_action_test.go index 975e90ee90..92b4f2ccbe 100644 --- a/api4/integration_action_test.go +++ b/api4/integration_action_test.go @@ -5,7 +5,7 @@ package api4 import ( "encoding/json" - "io/ioutil" + "io" "net/http" "net/http/httptest" "testing" @@ -21,7 +21,7 @@ type testHandler struct { } func (th *testHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { - bb, err := ioutil.ReadAll(r.Body) + bb, err := io.ReadAll(r.Body) assert.NoError(th.t, err) assert.NotEmpty(th.t, string(bb)) var poir model.PostActionIntegrationRequest diff --git a/api4/license.go b/api4/license.go index 4e308a1a45..ee7a79fa54 100644 --- a/api4/license.go +++ b/api4/license.go @@ -8,7 +8,6 @@ import ( "encoding/json" "fmt" "io" - "io/ioutil" "net/http" "github.com/mattermost/mattermost-server/v6/shared/mlog" @@ -203,7 +202,7 @@ func requestTrialLicense(c *Context, w http.ResponseWriter, r *http.Request) { ReceiveEmailsAccepted bool `json:"receive_emails_accepted"` } - b, readErr := ioutil.ReadAll(r.Body) + b, readErr := io.ReadAll(r.Body) if readErr != nil { c.Err = model.NewAppError("requestTrialLicense", "api.license.request-trial.bad-request", nil, "", http.StatusBadRequest) return diff --git a/api4/plugin_test.go b/api4/plugin_test.go index a6382ce32a..da5f145412 100644 --- a/api4/plugin_test.go +++ b/api4/plugin_test.go @@ -8,7 +8,7 @@ import ( "encoding/base64" "encoding/json" "fmt" - "io/ioutil" + "io" "net/http" "net/http/httptest" "os" @@ -44,7 +44,7 @@ func TestPlugin(t *testing.T) { }) path, _ := fileutils.FindDir("tests") - tarData, err := ioutil.ReadFile(filepath.Join(path, "testplugin.tar.gz")) + tarData, err := os.ReadFile(filepath.Join(path, "testplugin.tar.gz")) require.NoError(t, err) // Install from URL @@ -295,7 +295,7 @@ func TestNotifyClusterPluginEvent(t *testing.T) { }) path, _ := fileutils.FindDir("tests") - tarData, err := ioutil.ReadFile(filepath.Join(path, "testplugin.tar.gz")) + tarData, err := os.ReadFile(filepath.Join(path, "testplugin.tar.gz")) require.NoError(t, err) testCluster.ClearMessages() @@ -378,7 +378,7 @@ func TestNotifyClusterPluginEvent(t *testing.T) { func TestDisableOnRemove(t *testing.T) { path, _ := fileutils.FindDir("tests") - tarData, err := ioutil.ReadFile(filepath.Join(path, "testplugin.tar.gz")) + tarData, err := os.ReadFile(filepath.Join(path, "testplugin.tar.gz")) require.NoError(t, err) testCases := []struct { @@ -723,7 +723,7 @@ func TestGetInstalledMarketplacePlugins(t *testing.T) { } path, _ := fileutils.FindDir("tests") - tarData, err := ioutil.ReadFile(filepath.Join(path, "testplugin.tar.gz")) + tarData, err := os.ReadFile(filepath.Join(path, "testplugin.tar.gz")) require.NoError(t, err) t.Run("marketplace client returns not-installed plugin", func(t *testing.T) { @@ -752,7 +752,7 @@ func TestGetInstalledMarketplacePlugins(t *testing.T) { manifest, _, err := th.SystemAdminClient.UploadPlugin(bytes.NewReader(tarData)) require.NoError(t, err) - testIcon, err := ioutil.ReadFile(filepath.Join(path, "test.svg")) + testIcon, err := os.ReadFile(filepath.Join(path, "test.svg")) require.NoError(t, err) require.True(t, svg.Is(testIcon)) testIconData := fmt.Sprintf("data:image/svg+xml;base64,%s", base64.StdEncoding.EncodeToString(testIcon)) @@ -860,13 +860,13 @@ func TestSearchGetMarketplacePlugins(t *testing.T) { } path, _ := fileutils.FindDir("tests") - tarData, err := ioutil.ReadFile(filepath.Join(path, "testplugin.tar.gz")) + tarData, err := os.ReadFile(filepath.Join(path, "testplugin.tar.gz")) require.NoError(t, err) - tarDataV2, err := ioutil.ReadFile(filepath.Join(path, "testplugin2.tar.gz")) + tarDataV2, err := os.ReadFile(filepath.Join(path, "testplugin2.tar.gz")) require.NoError(t, err) - testIcon, err := ioutil.ReadFile(filepath.Join(path, "test.svg")) + testIcon, err := os.ReadFile(filepath.Join(path, "test.svg")) require.NoError(t, err) require.True(t, svg.Is(testIcon)) testIconData := fmt.Sprintf("data:image/svg+xml;base64,%s", base64.StdEncoding.EncodeToString(testIcon)) @@ -1021,7 +1021,7 @@ func TestGetLocalPluginInMarketplace(t *testing.T) { // Upload one local plugin path, _ := fileutils.FindDir("tests") - tarData, err := ioutil.ReadFile(filepath.Join(path, "testplugin.tar.gz")) + tarData, err := os.ReadFile(filepath.Join(path, "testplugin.tar.gz")) require.NoError(t, err) manifest, _, err := th.SystemAdminClient.UploadPlugin(bytes.NewReader(tarData)) @@ -1050,13 +1050,13 @@ func TestGetLocalPluginInMarketplace(t *testing.T) { // Upload one local plugin path, _ := fileutils.FindDir("tests") - tarData, err := ioutil.ReadFile(filepath.Join(path, "testplugin.tar.gz")) + tarData, err := os.ReadFile(filepath.Join(path, "testplugin.tar.gz")) require.NoError(t, err) manifest, _, err := th.SystemAdminClient.UploadPlugin(bytes.NewReader(tarData)) require.NoError(t, err) - testIcon, err := ioutil.ReadFile(filepath.Join(path, "test.svg")) + testIcon, err := os.ReadFile(filepath.Join(path, "test.svg")) require.NoError(t, err) require.True(t, svg.Is(testIcon)) testIconData := fmt.Sprintf("data:image/svg+xml;base64,%s", base64.StdEncoding.EncodeToString(testIcon)) @@ -1090,13 +1090,13 @@ func TestGetLocalPluginInMarketplace(t *testing.T) { // Upload one local plugin path, _ := fileutils.FindDir("tests") - tarData, err := ioutil.ReadFile(filepath.Join(path, "testplugin.tar.gz")) + tarData, err := os.ReadFile(filepath.Join(path, "testplugin.tar.gz")) require.NoError(t, err) manifest, _, err := th.SystemAdminClient.UploadPlugin(bytes.NewReader(tarData)) require.NoError(t, err) - testIcon, err := ioutil.ReadFile(filepath.Join(path, "test.svg")) + testIcon, err := os.ReadFile(filepath.Join(path, "test.svg")) require.NoError(t, err) require.True(t, svg.Is(testIcon)) testIconData := fmt.Sprintf("data:image/svg+xml;base64,%s", base64.StdEncoding.EncodeToString(testIcon)) @@ -1262,11 +1262,11 @@ func TestInstallMarketplacePlugin(t *testing.T) { signatureFilename := "testplugin2.tar.gz.sig" signatureFileReader, err := os.Open(filepath.Join(path, signatureFilename)) require.NoError(t, err) - sigFile, err := ioutil.ReadAll(signatureFileReader) + sigFile, err := io.ReadAll(signatureFileReader) require.NoError(t, err) pluginSignature := base64.StdEncoding.EncodeToString(sigFile) - tarData, err := ioutil.ReadFile(filepath.Join(path, "testplugin2.tar.gz")) + tarData, err := os.ReadFile(filepath.Join(path, "testplugin2.tar.gz")) require.NoError(t, err) pluginServer := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) { res.WriteHeader(http.StatusOK) @@ -1622,7 +1622,7 @@ func TestInstallMarketplacePlugin(t *testing.T) { th2.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) { pluginSignatureFile, err := os.Open(filepath.Join(path, "testplugin.tar.gz.asc")) require.NoError(t, err) - pluginSignatureData, err := ioutil.ReadAll(pluginSignatureFile) + pluginSignatureData, err := io.ReadAll(pluginSignatureFile) require.NoError(t, err) key, err := os.Open(filepath.Join(path, "development-private-key.asc")) diff --git a/api4/saml.go b/api4/saml.go index f102870be6..893e34f797 100644 --- a/api4/saml.go +++ b/api4/saml.go @@ -5,7 +5,7 @@ package api4 import ( "encoding/json" - "io/ioutil" + "io" "mime" "mime/multipart" "net/http" @@ -139,7 +139,7 @@ func addSamlIdpCertificate(c *Context, w http.ResponseWriter, r *http.Request) { auditRec.AddMeta("type", d) if d == "application/x-pem-file" { - body, err := ioutil.ReadAll(r.Body) + body, err := io.ReadAll(r.Body) if err != nil { c.Err = model.NewAppError("addSamlIdpCertificate", "api.admin.saml.set_certificate_from_metadata.invalid_body.app_error", nil, err.Error(), http.StatusBadRequest) return diff --git a/api4/system_test.go b/api4/system_test.go index 13eced3f1f..56373ce581 100644 --- a/api4/system_test.go +++ b/api4/system_test.go @@ -8,7 +8,7 @@ import ( "encoding/base64" "encoding/json" "fmt" - "io/ioutil" + "io" "net/http" "net/http/httptest" "os" @@ -64,7 +64,7 @@ func TestGetPing(t *testing.T) { resp, err := client.DoAPIGet("/system/ping", "") require.NoError(t, err) require.Equal(t, http.StatusOK, resp.StatusCode) - respBytes, err := ioutil.ReadAll(resp.Body) + respBytes, err := io.ReadAll(resp.Body) require.NoError(t, err) respString := string(respBytes) require.NotContains(t, respString, "TestFeatureFlag") @@ -77,7 +77,7 @@ func TestGetPing(t *testing.T) { resp, err = client.DoAPIGet("/system/ping", "") require.NoError(t, err) require.Equal(t, http.StatusOK, resp.StatusCode) - respBytes, err = ioutil.ReadAll(resp.Body) + respBytes, err = io.ReadAll(resp.Body) require.NoError(t, err) respString = string(respBytes) require.Contains(t, respString, "testvalue") @@ -130,7 +130,7 @@ func TestEmailTest(t *testing.T) { defer th.TearDown() client := th.Client - dir, err := ioutil.TempDir("", "") + dir, err := os.MkdirTemp("", "") require.NoError(t, err) defer os.RemoveAll(dir) @@ -817,7 +817,7 @@ func TestPushNotificationAck(t *testing.T) { resp := httptest.NewRecorder() req := httptest.NewRequest("POST", "/api/v4/notifications/ack", nil) req.Header.Set(model.HeaderAuth, "Bearer "+session.Token) - req.Body = ioutil.NopCloser(bytes.NewBufferString(fmt.Sprintf(`{"id":"123", "is_id_loaded":true, "post_id":"%s", "type": "%s"}`, privatePost.Id, model.PushTypeMessage))) + req.Body = io.NopCloser(bytes.NewBufferString(fmt.Sprintf(`{"id":"123", "is_id_loaded":true, "post_id":"%s", "type": "%s"}`, privatePost.Id, model.PushTypeMessage))) handler.ServeHTTP(resp, req) assert.Equal(t, http.StatusForbidden, resp.Code) @@ -833,11 +833,11 @@ func TestCompleteOnboarding(t *testing.T) { signatureFilename := "testplugin2.tar.gz.sig" signatureFileReader, err := os.Open(filepath.Join(path, signatureFilename)) require.NoError(t, err) - sigFile, err := ioutil.ReadAll(signatureFileReader) + sigFile, err := io.ReadAll(signatureFileReader) require.NoError(t, err) pluginSignature := base64.StdEncoding.EncodeToString(sigFile) - tarData, err := ioutil.ReadFile(filepath.Join(path, "testplugin2.tar.gz")) + tarData, err := os.ReadFile(filepath.Join(path, "testplugin2.tar.gz")) require.NoError(t, err) pluginServer := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) { res.WriteHeader(http.StatusOK) diff --git a/app/admin.go b/app/admin.go index 8b901b1b5d..7abca6951c 100644 --- a/app/admin.go +++ b/app/admin.go @@ -7,7 +7,6 @@ import ( "encoding/json" "fmt" "io" - "io/ioutil" "net/http" "os" "runtime/debug" @@ -261,7 +260,7 @@ func (a *App) GetLatestVersion(latestVersionUrl string) (*model.GithubReleaseInf defer res.Body.Close() - responseData, err := ioutil.ReadAll(res.Body) + responseData, err := io.ReadAll(res.Body) if err != nil { return nil, model.NewAppError("GetLatestVersion", "app.admin.latest_version_read_all.failure", nil, "", http.StatusInternalServerError) } diff --git a/app/authorization_test.go b/app/authorization_test.go index c115fa8e64..9d3cc45264 100644 --- a/app/authorization_test.go +++ b/app/authorization_test.go @@ -7,7 +7,7 @@ import ( "context" "encoding/csv" "fmt" - "io/ioutil" + "io" "os" "strconv" "strings" @@ -133,7 +133,7 @@ func TestSessionHasPermissionToGroup(t *testing.T) { require.NoError(t, e) defer file.Close() - b, e := ioutil.ReadAll(file) + b, e := io.ReadAll(file) require.NoError(t, e) r := csv.NewReader(strings.NewReader(string(b))) diff --git a/app/command.go b/app/command.go index 7d4ac80551..31a3c01554 100644 --- a/app/command.go +++ b/app/command.go @@ -7,7 +7,6 @@ import ( "context" "errors" "io" - "io/ioutil" "net/http" "net/url" "regexp" @@ -521,7 +520,7 @@ func (a *App) DoCommandRequest(cmd *model.Command, p url.Values) (*model.Command if resp.StatusCode != http.StatusOK { // Ignore the error below because the resulting string will just be the empty string if bodyBytes is nil - bodyBytes, _ := ioutil.ReadAll(body) + bodyBytes, _ := io.ReadAll(body) return cmd, nil, model.NewAppError("command", "api.command.execute_command.failed_resp.app_error", map[string]any{"Trigger": cmd.Trigger, "Status": resp.Status}, string(bodyBytes), http.StatusInternalServerError) } diff --git a/app/compliance.go b/app/compliance.go index a79ff37d31..0a398c6693 100644 --- a/app/compliance.go +++ b/app/compliance.go @@ -5,8 +5,8 @@ package app import ( "errors" - "io/ioutil" "net/http" + "os" "github.com/mattermost/mattermost-server/v6/model" "github.com/mattermost/mattermost-server/v6/shared/mlog" @@ -75,7 +75,7 @@ func (a *App) GetComplianceReport(reportId string) (*model.Compliance, *model.Ap } func (a *App) GetComplianceFile(job *model.Compliance) ([]byte, *model.AppError) { - f, err := ioutil.ReadFile(*a.Config().ComplianceSettings.Directory + "compliance/" + job.JobName() + ".zip") + f, err := os.ReadFile(*a.Config().ComplianceSettings.Directory + "compliance/" + job.JobName() + ".zip") if err != nil { return nil, model.NewAppError("readFile", "api.file.read_file.reading_local.app_error", nil, err.Error(), http.StatusNotImplemented) } diff --git a/app/download.go b/app/download.go index d83299d483..449f787c46 100644 --- a/app/download.go +++ b/app/download.go @@ -5,7 +5,6 @@ package app import ( "io" - "io/ioutil" "net/http" "net/url" "time" @@ -64,5 +63,5 @@ func (s *Server) downloadFromURL(downloadURL string) ([]byte, error) { defer resp.Body.Close() - return ioutil.ReadAll(resp.Body) + return io.ReadAll(resp.Body) } diff --git a/app/email/helper_test.go b/app/email/helper_test.go index 2aabf04a3e..75fa7605b1 100644 --- a/app/email/helper_test.go +++ b/app/email/helper_test.go @@ -5,7 +5,6 @@ package email import ( "bytes" - "io/ioutil" "os" "path/filepath" "testing" @@ -64,7 +63,7 @@ func SetupWithStoreMock(tb testing.TB) *TestHelper { } func setupTestHelper(s store.Store, tb testing.TB) *TestHelper { - tempWorkspace, err := ioutil.TempDir("", "userservicetest") + tempWorkspace, err := os.MkdirTemp("", "userservicetest") if err != nil { panic(err) } diff --git a/app/export_test.go b/app/export_test.go index e9231a3af4..3ed17d9547 100644 --- a/app/export_test.go +++ b/app/export_test.go @@ -6,7 +6,6 @@ package app import ( "bytes" "fmt" - "io/ioutil" "os" "path/filepath" "sort" @@ -590,7 +589,7 @@ func TestBulkExport(t *testing.T) { th := Setup(t) testsDir, _ := fileutils.FindDir("tests") - dir, err := ioutil.TempDir("", "import_test") + dir, err := os.MkdirTemp("", "import_test") require.NoError(t, err) defer os.RemoveAll(dir) diff --git a/app/extract_plugin_tar_test.go b/app/extract_plugin_tar_test.go index 3cacff7272..f1662fafa0 100644 --- a/app/extract_plugin_tar_test.go +++ b/app/extract_plugin_tar_test.go @@ -8,7 +8,6 @@ import ( "bytes" "compress/gzip" "fmt" - "io/ioutil" "os" "path/filepath" "sort" @@ -81,7 +80,7 @@ func TestExtractTarGz(t *testing.T) { }) } - dst, err := ioutil.TempDir("", "TestExtractTarGz") + dst, err := os.MkdirTemp("", "TestExtractTarGz") require.NoError(t, err) defer os.RemoveAll(dst) @@ -175,7 +174,7 @@ func TestExtractTarGz(t *testing.T) { for i, testCase := range testCases { t.Run(fmt.Sprintf("test-%d", i), func(t *testing.T) { - dst, err := ioutil.TempDir("", "TestExtractTarGz") + dst, err := os.MkdirTemp("", "TestExtractTarGz") require.NoError(t, err) defer os.RemoveAll(dst) diff --git a/app/helper_test.go b/app/helper_test.go index 3cbaa72497..5b15d3f519 100644 --- a/app/helper_test.go +++ b/app/helper_test.go @@ -5,7 +5,6 @@ package app import ( "context" - "io/ioutil" "os" "path/filepath" "strings" @@ -48,7 +47,7 @@ type TestHelper struct { } func setupTestHelper(dbStore store.Store, enterprise bool, includeCacheLayer bool, options []Option, tb testing.TB) *TestHelper { - tempWorkspace, err := ioutil.TempDir("", "apptest") + tempWorkspace, err := os.MkdirTemp("", "apptest") if err != nil { panic(err) } diff --git a/app/imaging/utils_test.go b/app/imaging/utils_test.go index cdd81db44d..6d0c5383ae 100644 --- a/app/imaging/utils_test.go +++ b/app/imaging/utils_test.go @@ -6,7 +6,6 @@ package imaging import ( "bytes" "image/color" - "io/ioutil" "os" "testing" @@ -77,7 +76,7 @@ func TestFillImageTransparency(t *testing.T) { require.NotNil(t, inputImg) require.Equal(t, "png", format) - expectedBytes, err := ioutil.ReadFile(imgDir + "/" + tc.outputName) + expectedBytes, err := os.ReadFile(imgDir + "/" + tc.outputName) require.NoError(t, err) FillImageTransparency(inputImg, tc.fillColor) diff --git a/app/import_functions.go b/app/import_functions.go index 44f89737a5..f84af9e500 100644 --- a/app/import_functions.go +++ b/app/import_functions.go @@ -10,7 +10,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "net/http" "os" "path" @@ -1217,7 +1216,7 @@ func (a *App) importAttachment(c *request.Context, data *AttachmentImportData, p timestamp := utils.TimeFromMillis(post.CreateAt) - fileData, err := ioutil.ReadAll(file) + fileData, err := io.ReadAll(file) if err != nil { return nil, model.NewAppError("BulkImport", "app.import.attachment.read_file_data.error", map[string]any{"FilePath": *data.Path}, "", http.StatusBadRequest) } diff --git a/app/import_functions_test.go b/app/import_functions_test.go index a6e47edddc..8ac8ff6e69 100644 --- a/app/import_functions_test.go +++ b/app/import_functions_test.go @@ -6,7 +6,6 @@ package app import ( "archive/zip" "context" - "io/ioutil" "os" "path/filepath" "strings" @@ -4378,11 +4377,11 @@ func TestImportDirectPostWithAttachments(t *testing.T) { testImage := filepath.Join(testsDir, "test.png") testImage2 := filepath.Join(testsDir, "test.svg") // create a temp file with same name as original but with a different first byte - tmpFolder, _ := ioutil.TempDir("", "imgFake") + tmpFolder, _ := os.MkdirTemp("", "imgFake") testImageFake := filepath.Join(tmpFolder, "test.png") - fakeFileData, _ := ioutil.ReadFile(testImage) + fakeFileData, _ := os.ReadFile(testImage) fakeFileData[0] = 0 - _ = ioutil.WriteFile(testImageFake, fakeFileData, 0644) + _ = os.WriteFile(testImageFake, fakeFileData, 0644) defer os.RemoveAll(tmpFolder) // Create a user. diff --git a/app/import_test.go b/app/import_test.go index 3286f3f03a..f3676b6e10 100644 --- a/app/import_test.go +++ b/app/import_test.go @@ -6,7 +6,6 @@ package app import ( "archive/zip" "io" - "io/ioutil" "net/http" "os" "path/filepath" @@ -439,7 +438,7 @@ func BenchmarkBulkImport(b *testing.B) { info, err := importFile.Stat() require.NoError(b, err) - dir, err := ioutil.TempDir("", "testimport") + dir, err := os.MkdirTemp("", "testimport") require.NoError(b, err) defer os.RemoveAll(dir) diff --git a/app/integration_action.go b/app/integration_action.go index 6f3d703808..dfc85cfbdc 100644 --- a/app/integration_action.go +++ b/app/integration_action.go @@ -23,7 +23,7 @@ import ( "encoding/json" "errors" "fmt" - "io/ioutil" + "io" "net/http" "net/url" "path" @@ -253,7 +253,7 @@ func (a *App) DoPostActionWithCookie(c *request.Context, postID, actionId, userI defer resp.Body.Close() var response model.PostActionIntegrationResponse - respBytes, err := ioutil.ReadAll(resp.Body) + respBytes, err := io.ReadAll(resp.Body) if err != nil { return "", model.NewAppError("DoPostActionWithCookie", "api.post.do_action.action_integration.app_error", nil, "err="+err.Error(), http.StatusBadRequest) } @@ -435,7 +435,7 @@ func (ch *Channels) doPluginRequest(c *request.Context, method, rawURL string, v ProtoMajor: 1, ProtoMinor: 1, Header: w.headers, - Body: ioutil.NopCloser(bytes.NewReader(w.data)), + Body: io.NopCloser(bytes.NewReader(w.data)), } if resp.StatusCode == 0 { resp.StatusCode = http.StatusOK diff --git a/app/integration_action_test.go b/app/integration_action_test.go index 6dde72a2be..8fa6debe5d 100644 --- a/app/integration_action_test.go +++ b/app/integration_action_test.go @@ -6,7 +6,7 @@ package app import ( "encoding/json" "fmt" - "io/ioutil" + "io" "net/http" "net/http/httptest" "net/url" @@ -1079,47 +1079,47 @@ func TestDoPluginRequest(t *testing.T) { resp, err := th.App.doPluginRequest(th.Context, "GET", "/plugins/myplugin", nil, nil) assert.Nil(t, err) require.NotNil(t, resp) - body, _ := ioutil.ReadAll(resp.Body) + body, _ := io.ReadAll(resp.Body) assert.Equal(t, "could not find param abc=xyz", string(body)) resp, err = th.App.doPluginRequest(th.Context, "GET", "/plugins/myplugin?abc=xyz", nil, nil) assert.Nil(t, err) require.NotNil(t, resp) - body, _ = ioutil.ReadAll(resp.Body) + body, _ = io.ReadAll(resp.Body) assert.Equal(t, "param multiple should have 3 values", string(body)) resp, err = th.App.doPluginRequest(th.Context, "GET", "/plugins/myplugin", url.Values{"abc": []string{"xyz"}, "multiple": []string{"1 first", "2 second", "3 third"}}, nil) assert.Nil(t, err) require.NotNil(t, resp) - body, _ = ioutil.ReadAll(resp.Body) + body, _ = io.ReadAll(resp.Body) assert.Equal(t, "OK", string(body)) resp, err = th.App.doPluginRequest(th.Context, "GET", "/plugins/myplugin?abc=xyz&multiple=1%20first", url.Values{"multiple": []string{"2 second", "3 third"}}, nil) assert.Nil(t, err) require.NotNil(t, resp) - body, _ = ioutil.ReadAll(resp.Body) + body, _ = io.ReadAll(resp.Body) assert.Equal(t, "OK", string(body)) resp, err = th.App.doPluginRequest(th.Context, "GET", "/plugins/myplugin?abc=xyz&multiple=1%20first&multiple=3%20third", url.Values{"multiple": []string{"2 second"}}, nil) assert.Nil(t, err) require.NotNil(t, resp) - body, _ = ioutil.ReadAll(resp.Body) + body, _ = io.ReadAll(resp.Body) assert.Equal(t, "OK", string(body)) resp, err = th.App.doPluginRequest(th.Context, "GET", "/plugins/myplugin?multiple=1%20first&multiple=3%20third", url.Values{"multiple": []string{"2 second"}, "abc": []string{"xyz"}}, nil) assert.Nil(t, err) require.NotNil(t, resp) - body, _ = ioutil.ReadAll(resp.Body) + body, _ = io.ReadAll(resp.Body) assert.Equal(t, "OK", string(body)) resp, err = th.App.doPluginRequest(th.Context, "GET", "/plugins/myplugin?multiple=1%20first&multiple=3%20third", url.Values{"multiple": []string{"4 fourth"}, "abc": []string{"xyz"}}, nil) assert.Nil(t, err) require.NotNil(t, resp) - body, _ = ioutil.ReadAll(resp.Body) + body, _ = io.ReadAll(resp.Body) assert.Equal(t, "param multiple not correct", string(body)) } diff --git a/app/layer_generators/main.go b/app/layer_generators/main.go index 4fe3586f06..1a15ff4318 100644 --- a/app/layer_generators/main.go +++ b/app/layer_generators/main.go @@ -10,7 +10,7 @@ import ( "go/ast" "go/parser" "go/token" - "io/ioutil" + "io" "log" "os" "path" @@ -58,7 +58,7 @@ func main() { log.Fatal(err) } - err = ioutil.WriteFile(outputFile, formattedCode, 0644) + err = os.WriteFile(outputFile, formattedCode, 0644) if err != nil { log.Fatal(err) } @@ -162,7 +162,7 @@ func extractStoreMetadata() (*storeMetadata, error) { if err != nil { return nil, fmt.Errorf("unable to open %s file: %w", inputFile, err) } - src, err := ioutil.ReadAll(file) + src, err := io.ReadAll(file) if err != nil { return nil, err } diff --git a/app/ldap.go b/app/ldap.go index 40399f50f4..a782b4715c 100644 --- a/app/ldap.go +++ b/app/ldap.go @@ -4,7 +4,7 @@ package app import ( - "io/ioutil" + "io" "mime/multipart" "net/http" @@ -186,7 +186,7 @@ func (a *App) writeLdapFile(filename string, fileData *multipart.FileHeader) *mo } defer file.Close() - data, err := ioutil.ReadAll(file) + data, err := io.ReadAll(file) if err != nil { return model.NewAppError("AddLdapCertificate", "api.admin.add_certificate.saving.app_error", nil, err.Error(), http.StatusInternalServerError) } diff --git a/app/oauth.go b/app/oauth.go index 104fe654c6..8dd67ffdcb 100644 --- a/app/oauth.go +++ b/app/oauth.go @@ -11,7 +11,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "net/http" "net/url" "strconv" @@ -891,7 +890,7 @@ func (a *App) AuthorizeOAuthUser(w http.ResponseWriter, r *http.Request, service defer resp.Body.Close() // Ignore the error below because the resulting string will just be the empty string if bodyBytes is nil - bodyBytes, _ := ioutil.ReadAll(resp.Body) + bodyBytes, _ := io.ReadAll(resp.Body) bodyString := string(bodyBytes) mlog.Error("Error getting OAuth user", mlog.Int("response", resp.StatusCode), mlog.String("body_string", bodyString)) diff --git a/app/oauth_test.go b/app/oauth_test.go index 1d7807fa3b..57a394a710 100644 --- a/app/oauth_test.go +++ b/app/oauth_test.go @@ -7,7 +7,7 @@ import ( "encoding/base64" "encoding/json" "errors" - "io/ioutil" + "io" "net/http" "net/http/httptest" "testing" @@ -517,7 +517,7 @@ func TestAuthorizeOAuthUser(t *testing.T) { body, receivedTeamId, receivedStateProps, _, err := th.App.AuthorizeOAuthUser(&recorder, request, model.ServiceGitlab, "", state, "") require.NotNil(t, body) - bodyBytes, bodyErr := ioutil.ReadAll(body) + bodyBytes, bodyErr := io.ReadAll(body) require.NoError(t, bodyErr) assert.Equal(t, userData, string(bodyBytes)) diff --git a/app/plugin.go b/app/plugin.go index 38be469d17..2775eb0d86 100644 --- a/app/plugin.go +++ b/app/plugin.go @@ -7,7 +7,6 @@ import ( "encoding/base64" "fmt" "io" - "io/ioutil" "net/http" "os" "path/filepath" @@ -39,7 +38,7 @@ type pluginSignaturePath struct { signaturePath string } -//Ensure routerService implements `product.RouterService` +// Ensure routerService implements `product.RouterService` var _ product.RouterService = (*routerService)(nil) type routerService struct { @@ -976,7 +975,7 @@ func (ch *Channels) processPrepackagedPlugin(pluginPath *pluginSignaturePath) (* } defer fileReader.Close() - tmpDir, err := ioutil.TempDir("", "plugintmp") + tmpDir, err := os.MkdirTemp("", "plugintmp") if err != nil { return nil, errors.Wrap(err, "Failed to create temp dir plugintmp") } @@ -1086,7 +1085,7 @@ func getPrepackagedPlugin(pluginPath *pluginSignaturePath, pluginFile io.ReadSee if sigErr != nil { return nil, "", errors.Wrapf(sigErr, "Failed to open prepackaged plugin signature %s", sig) } - bytes, sigErr := ioutil.ReadAll(sigReader) + bytes, sigErr := io.ReadAll(sigReader) if sigErr != nil { return nil, "", errors.Wrapf(sigErr, "Failed to read prepackaged plugin signature %s", sig) } @@ -1105,7 +1104,7 @@ func getPrepackagedPlugin(pluginPath *pluginSignaturePath, pluginFile io.ReadSee } func getIcon(iconPath string) (string, error) { - icon, err := ioutil.ReadFile(iconPath) + icon, err := os.ReadFile(iconPath) if err != nil { return "", errors.Wrapf(err, "failed to open icon at path %s", iconPath) } diff --git a/app/plugin_api.go b/app/plugin_api.go index d42d08613d..f2afc5e7ce 100644 --- a/app/plugin_api.go +++ b/app/plugin_api.go @@ -8,7 +8,6 @@ import ( "encoding/json" "fmt" "io" - "io/ioutil" "net/http" "net/url" "path/filepath" @@ -897,7 +896,7 @@ func (api *PluginAPI) InstallPlugin(file io.Reader, replace bool) (*model.Manife return nil, model.NewAppError("installPlugin", "app.plugin.upload_disabled.app_error", nil, "", http.StatusNotImplemented) } - fileBuffer, err := ioutil.ReadAll(file) + fileBuffer, err := io.ReadAll(file) if err != nil { return nil, model.NewAppError("InstallPlugin", "api.plugin.upload.file.app_error", nil, "", http.StatusBadRequest) } @@ -1029,7 +1028,7 @@ func (api *PluginAPI) PluginHTTP(request *http.Request) *http.Response { if len(split) != 3 { return &http.Response{ StatusCode: http.StatusBadRequest, - Body: ioutil.NopCloser(bytes.NewBufferString("Not enough URL. Form of URL should be //*")), + Body: io.NopCloser(bytes.NewBufferString("Not enough URL. Form of URL should be //*")), } } destinationPluginId := split[1] @@ -1043,7 +1042,7 @@ func (api *PluginAPI) PluginHTTP(request *http.Request) *http.Response { } return &http.Response{ StatusCode: http.StatusBadRequest, - Body: ioutil.NopCloser(bytes.NewBufferString(message)), + Body: io.NopCloser(bytes.NewBufferString(message)), } } responseTransfer := &PluginResponseWriter{} diff --git a/app/plugin_api_test.go b/app/plugin_api_test.go index 6bb40a78cd..541d0f3a18 100644 --- a/app/plugin_api_test.go +++ b/app/plugin_api_test.go @@ -11,7 +11,7 @@ import ( "image" "image/color" "image/png" - "io/ioutil" + "io" "net/http" "net/http/httptest" "os" @@ -70,7 +70,7 @@ func setDefaultPluginConfig(th *TestHelper, pluginID string) { } func setupMultiPluginAPITest(t *testing.T, pluginCodes []string, pluginManifests []string, pluginIDs []string, asMain bool, app *App, c *request.Context) string { - pluginDir, err := ioutil.TempDir("", "") + pluginDir, err := os.MkdirTemp("", "") require.NoError(t, err) t.Cleanup(func() { err = os.RemoveAll(pluginDir) @@ -79,7 +79,7 @@ func setupMultiPluginAPITest(t *testing.T, pluginCodes []string, pluginManifests } }) - webappPluginDir, err := ioutil.TempDir("", "") + webappPluginDir, err := os.MkdirTemp("", "") require.NoError(t, err) t.Cleanup(func() { err = os.RemoveAll(webappPluginDir) @@ -106,7 +106,7 @@ func setupMultiPluginAPITest(t *testing.T, pluginCodes []string, pluginManifests utils.CompileGoTest(t, pluginCodes[i], backend) } - ioutil.WriteFile(filepath.Join(pluginDir, pluginID, "plugin.json"), []byte(pluginManifests[i]), 0600) + os.WriteFile(filepath.Join(pluginDir, pluginID, "plugin.json"), []byte(pluginManifests[i]), 0600) manifest, activated, reterr := env.Activate(pluginID) require.NoError(t, reterr) require.NotNil(t, manifest) @@ -841,9 +841,9 @@ func TestPluginAPIGetPlugins(t *testing.T) { } ` - pluginDir, err := ioutil.TempDir("", "") + pluginDir, err := os.MkdirTemp("", "") require.NoError(t, err) - webappPluginDir, err := ioutil.TempDir("", "") + webappPluginDir, err := os.MkdirTemp("", "") require.NoError(t, err) defer os.RemoveAll(pluginDir) defer os.RemoveAll(webappPluginDir) @@ -857,7 +857,7 @@ func TestPluginAPIGetPlugins(t *testing.T) { backend := filepath.Join(pluginDir, pluginID, "backend.exe") utils.CompileGo(t, pluginCode, backend) - ioutil.WriteFile(filepath.Join(pluginDir, pluginID, "plugin.json"), []byte(fmt.Sprintf(`{"id": "%s", "server": {"executable": "backend.exe"}}`, pluginID)), 0600) + os.WriteFile(filepath.Join(pluginDir, pluginID, "plugin.json"), []byte(fmt.Sprintf(`{"id": "%s", "server": {"executable": "backend.exe"}}`, pluginID)), 0600) manifest, activated, reterr := env.Activate(pluginID) require.NoError(t, reterr) @@ -884,7 +884,7 @@ func TestPluginAPIInstallPlugin(t *testing.T) { api := th.SetupPluginAPI() path, _ := fileutils.FindDir("tests") - tarData, err := ioutil.ReadFile(filepath.Join(path, "testplugin.tar.gz")) + tarData, err := os.ReadFile(filepath.Join(path, "testplugin.tar.gz")) require.NoError(t, err) _, appErr := api.InstallPlugin(bytes.NewReader(tarData), true) @@ -922,9 +922,9 @@ func TestInstallPlugin(t *testing.T) { // since it removes plugin dirs right after it returns, does not update App configs with the plugin // dirs and this behavior tends to break this test as a result. setupTest := func(t *testing.T, pluginCode string, pluginManifest string, pluginID string, app *App, c *request.Context) (func(), string) { - pluginDir, err := ioutil.TempDir("", "") + pluginDir, err := os.MkdirTemp("", "") require.NoError(t, err) - webappPluginDir, err := ioutil.TempDir("", "") + webappPluginDir, err := os.MkdirTemp("", "") require.NoError(t, err) app.UpdateConfig(func(cfg *model.Config) { @@ -944,7 +944,7 @@ func TestInstallPlugin(t *testing.T) { backend := filepath.Join(pluginDir, pluginID, "backend.exe") utils.CompileGo(t, pluginCode, backend) - ioutil.WriteFile(filepath.Join(pluginDir, pluginID, "plugin.json"), []byte(pluginManifest), 0600) + os.WriteFile(filepath.Join(pluginDir, pluginID, "plugin.json"), []byte(pluginManifest), 0600) manifest, activated, reterr := env.Activate(pluginID) require.NoError(t, reterr) require.NotNil(t, manifest) @@ -1126,7 +1126,7 @@ func TestPluginAPIRemoveTeamIcon(t *testing.T) { } func pluginAPIHookTest(t *testing.T, th *TestHelper, fileName string, id string, settingsSchema string) error { - data, err := ioutil.ReadFile(fileName) + data, err := os.ReadFile(fileName) if err != nil { return err } @@ -1161,7 +1161,7 @@ func TestBasicAPIPlugins(t *testing.T) { defaultSchema := getDefaultPluginSettingsSchema() testFolder, found := fileutils.FindDir("mattermost-server/app/plugin_api_tests") require.True(t, found, "Cannot read find app folder") - dirs, err := ioutil.ReadDir(testFolder) + dirs, err := os.ReadDir(testFolder) require.NoError(t, err, "Cannot read test folder %v", testFolder) for _, dir := range dirs { d := dir.Name() @@ -1523,7 +1523,7 @@ func TestInterpluginPluginHTTP(t *testing.T) { "github.com/mattermost/mattermost-server/v6/model" "bytes" "net/http" - "io/ioutil" + "io" ) type MyPlugin struct { @@ -1545,7 +1545,7 @@ func TestInterpluginPluginHTTP(t *testing.T) { if resp.Body == nil { return nil, "Nil body" } - respbody, err := ioutil.ReadAll(resp.Body) + respbody, err := io.ReadAll(resp.Body) if err != nil { return nil, err.Error() } @@ -1605,9 +1605,9 @@ func TestAPIMetrics(t *testing.T) { t.Run("", func(t *testing.T) { metricsMock := &mocks.MetricsInterface{} - pluginDir, err := ioutil.TempDir("", "") + pluginDir, err := os.MkdirTemp("", "") require.NoError(t, err) - webappPluginDir, err := ioutil.TempDir("", "") + webappPluginDir, err := os.MkdirTemp("", "") require.NoError(t, err) defer os.RemoveAll(pluginDir) defer os.RemoveAll(webappPluginDir) @@ -1642,7 +1642,7 @@ func TestAPIMetrics(t *testing.T) { } ` utils.CompileGo(t, code, backend) - ioutil.WriteFile(filepath.Join(pluginDir, pluginID, "plugin.json"), []byte(`{"id": "`+pluginID+`", "server": {"executable": "backend.exe"}}`), 0600) + os.WriteFile(filepath.Join(pluginDir, pluginID, "plugin.json"), []byte(`{"id": "`+pluginID+`", "server": {"executable": "backend.exe"}}`), 0600) // Don't care about these mocks metricsMock.On("ObservePluginHookDuration", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return() @@ -1730,7 +1730,7 @@ func TestPluginHTTPConnHijack(t *testing.T) { require.True(t, found, "Cannot find tests folder") fullPath := path.Join(testFolder, "manual.test_http_hijack_plugin", "main.go") - pluginCode, err := ioutil.ReadFile(fullPath) + pluginCode, err := os.ReadFile(fullPath) require.NoError(t, err) require.NotEmpty(t, pluginCode) @@ -1752,7 +1752,7 @@ func TestPluginHTTPConnHijack(t *testing.T) { defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) + body, err := io.ReadAll(resp.Body) require.NoError(t, err) require.Equal(t, "OK", string(body)) } @@ -1765,7 +1765,7 @@ func TestPluginHTTPUpgradeWebSocket(t *testing.T) { require.True(t, found, "Cannot find tests folder") fullPath := path.Join(testFolder, "manual.test_http_upgrade_websocket_plugin", "main.go") - pluginCode, err := ioutil.ReadFile(fullPath) + pluginCode, err := os.ReadFile(fullPath) require.NoError(t, err) require.NotEmpty(t, pluginCode) diff --git a/app/plugin_hooks_test.go b/app/plugin_hooks_test.go index e4eaa4d23e..b6e26b562f 100644 --- a/app/plugin_hooks_test.go +++ b/app/plugin_hooks_test.go @@ -7,7 +7,6 @@ import ( "bytes" "context" "io" - "io/ioutil" "net/http" "net/http/httptest" "os" @@ -29,9 +28,9 @@ import ( ) func SetAppEnvironmentWithPlugins(t *testing.T, pluginCode []string, app *App, apiFunc func(*model.Manifest) plugin.API) (func(), []string, []error) { - pluginDir, err := ioutil.TempDir("", "") + pluginDir, err := os.MkdirTemp("", "") require.NoError(t, err) - webappPluginDir, err := ioutil.TempDir("", "") + webappPluginDir, err := os.MkdirTemp("", "") require.NoError(t, err) env, err := plugin.NewEnvironment(apiFunc, NewDriverImpl(app.Srv()), pluginDir, webappPluginDir, app.Log(), nil) @@ -45,7 +44,7 @@ func SetAppEnvironmentWithPlugins(t *testing.T, pluginCode []string, app *App, a backend := filepath.Join(pluginDir, pluginID, "backend.exe") utils.CompileGo(t, code, backend) - ioutil.WriteFile(filepath.Join(pluginDir, pluginID, "plugin.json"), []byte(`{"id": "`+pluginID+`", "server": {"executable": "backend.exe"}}`), 0600) + os.WriteFile(filepath.Join(pluginDir, pluginID, "plugin.json"), []byte(`{"id": "`+pluginID+`", "server": {"executable": "backend.exe"}}`), 0600) _, _, activationErr := env.Activate(pluginID) pluginIDs = append(pluginIDs, pluginID) activationErrors = append(activationErrors, activationErr) @@ -1024,9 +1023,9 @@ func TestHookMetrics(t *testing.T) { t.Run("", func(t *testing.T) { metricsMock := &mocks.MetricsInterface{} - pluginDir, err := ioutil.TempDir("", "") + pluginDir, err := os.MkdirTemp("", "") require.NoError(t, err) - webappPluginDir, err := ioutil.TempDir("", "") + webappPluginDir, err := os.MkdirTemp("", "") require.NoError(t, err) defer os.RemoveAll(pluginDir) defer os.RemoveAll(webappPluginDir) @@ -1069,7 +1068,7 @@ func TestHookMetrics(t *testing.T) { } ` utils.CompileGo(t, code, backend) - ioutil.WriteFile(filepath.Join(pluginDir, pluginID, "plugin.json"), []byte(`{"id": "`+pluginID+`", "server": {"executable": "backend.exe"}}`), 0600) + os.WriteFile(filepath.Join(pluginDir, pluginID, "plugin.json"), []byte(`{"id": "`+pluginID+`", "server": {"executable": "backend.exe"}}`), 0600) // Setup mocks before activating metricsMock.On("ObservePluginHookDuration", pluginID, "Implemented", true, mock.Anything).Return() diff --git a/app/plugin_install.go b/app/plugin_install.go index 73d6a9e20f..12eb1f3046 100644 --- a/app/plugin_install.go +++ b/app/plugin_install.go @@ -33,14 +33,12 @@ // Prepackaged plugins are included with the server. They otherwise follow the above flow, except do not get uploaded // to the filestore. Prepackaged plugins override all other plugins with the same plugin id, but only when the prepackaged // plugin is newer. Managed plugins unconditionally override unmanaged plugins with the same plugin id. -// package app import ( "bytes" "fmt" "io" - "io/ioutil" "net/http" "os" "path/filepath" @@ -280,7 +278,7 @@ func (ch *Channels) installPluginLocally(pluginFile, signature io.ReadSeeker, in } } - tmpDir, err := ioutil.TempDir("", "plugintmp") + tmpDir, err := os.MkdirTemp("", "plugintmp") if err != nil { return nil, model.NewAppError("installPluginLocally", "app.plugin.filesystem.app_error", nil, err.Error(), http.StatusInternalServerError) } @@ -305,7 +303,7 @@ func extractPlugin(pluginFile io.ReadSeeker, extractDir string) (*model.Manifest return nil, "", model.NewAppError("extractPlugin", "app.plugin.extract.app_error", nil, err.Error(), http.StatusBadRequest) } - dir, err := ioutil.ReadDir(extractDir) + dir, err := os.ReadDir(extractDir) if err != nil { return nil, "", model.NewAppError("extractPlugin", "app.plugin.filesystem.app_error", nil, err.Error(), http.StatusInternalServerError) } diff --git a/app/plugin_requests.go b/app/plugin_requests.go index 17301c54ce..5e75a10457 100644 --- a/app/plugin_requests.go +++ b/app/plugin_requests.go @@ -6,7 +6,7 @@ package app import ( "bytes" "fmt" - "io/ioutil" + "io" "net/http" "path" "path/filepath" @@ -157,11 +157,11 @@ func (ch *Channels) servePluginRequest(w http.ResponseWriter, r *http.Request, h sentToken := "" if r.Header.Get(model.HeaderCsrfToken) == "" { - bodyBytes, _ := ioutil.ReadAll(r.Body) - r.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes)) + bodyBytes, _ := io.ReadAll(r.Body) + r.Body = io.NopCloser(bytes.NewBuffer(bodyBytes)) r.ParseForm() sentToken = r.FormValue("csrf") - r.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes)) + r.Body = io.NopCloser(bytes.NewBuffer(bodyBytes)) } else { sentToken = r.Header.Get(model.HeaderCsrfToken) } diff --git a/app/plugin_signature.go b/app/plugin_signature.go index 9724080aed..bedb6946a1 100644 --- a/app/plugin_signature.go +++ b/app/plugin_signature.go @@ -6,7 +6,6 @@ package app import ( "bytes" "io" - "io/ioutil" "net/http" "path/filepath" @@ -37,7 +36,7 @@ func (a *App) AddPublicKey(name string, key io.Reader) *model.AppError { if isSamlFile(&a.Config().SamlSettings, name) { return model.NewAppError("AddPublicKey", "app.plugin.modify_saml.app_error", nil, "", http.StatusInternalServerError) } - data, err := ioutil.ReadAll(key) + data, err := io.ReadAll(key) if err != nil { return model.NewAppError("AddPublicKey", "app.plugin.write_file.read.app_error", nil, err.Error(), http.StatusInternalServerError) } @@ -122,7 +121,7 @@ func verifyBinarySignature(publicKey, signedFile, signature io.Reader) error { } func decodeIfArmored(reader io.Reader) (io.Reader, error) { - readBytes, err := ioutil.ReadAll(reader) + readBytes, err := io.ReadAll(reader) if err != nil { return nil, errors.Wrap(err, "can't read the file") } diff --git a/app/plugin_signature_test.go b/app/plugin_signature_test.go index f1b0d31d1d..20e50bc414 100644 --- a/app/plugin_signature_test.go +++ b/app/plugin_signature_test.go @@ -4,7 +4,6 @@ package app import ( - "io/ioutil" "os" "path/filepath" "testing" @@ -38,7 +37,7 @@ func TestPluginPublicKeys(t *testing.T) { path, _ := fileutils.FindDir("tests") publicKeyFilename := "test-public-key.plugin.gpg" - publicKey, err := ioutil.ReadFile(filepath.Join(path, publicKeyFilename)) + publicKey, err := os.ReadFile(filepath.Join(path, publicKeyFilename)) require.NoError(t, err) fileReader, err := os.Open(filepath.Join(path, publicKeyFilename)) require.NoError(t, err) diff --git a/app/plugin_test.go b/app/plugin_test.go index d5b21aefe5..47f7a2a86a 100644 --- a/app/plugin_test.go +++ b/app/plugin_test.go @@ -9,7 +9,7 @@ import ( "encoding/base64" "errors" "fmt" - "io/ioutil" + "io" "net/http" "net/http/httptest" "os" @@ -384,7 +384,7 @@ func TestPrivateServePluginRequest(t *testing.T) { handler := func(context *plugin.Context, w http.ResponseWriter, r *http.Request) { assert.Equal(t, testCase.ExpectedURL, r.URL.Path) - body, _ := ioutil.ReadAll(r.Body) + body, _ := io.ReadAll(r.Body) assert.Equal(t, expectedBody, body) } @@ -827,7 +827,7 @@ func TestProcessPrepackagedPlugins(t *testing.T) { t.Run("automatic, enabled plugin, no signature", func(t *testing.T) { // Install the plugin and enable - pluginBytes, err := ioutil.ReadFile(testPluginPath) + pluginBytes, err := os.ReadFile(testPluginPath) require.NoError(t, err) require.NotNil(t, pluginBytes) @@ -935,7 +935,7 @@ func TestProcessPrepackagedPlugins(t *testing.T) { require.NoError(t, err) // Install first plugin and enable - pluginBytes, err := ioutil.ReadFile(testPluginPath) + pluginBytes, err := os.ReadFile(testPluginPath) require.NoError(t, err) require.NotNil(t, pluginBytes) diff --git a/app/response_transfer.go b/app/response_transfer.go index 624d940a3f..e3acf3b527 100644 --- a/app/response_transfer.go +++ b/app/response_transfer.go @@ -6,7 +6,7 @@ package app import ( "bytes" "fmt" - "io/ioutil" + "io" "net/http" "strconv" "strings" @@ -59,7 +59,7 @@ func (rt *PluginResponseWriter) GenerateResponse() *http.Response { res.Status = fmt.Sprintf("%03d %s", res.StatusCode, http.StatusText(res.StatusCode)) if rt.Len() > 0 { - res.Body = ioutil.NopCloser(rt) + res.Body = io.NopCloser(rt) } else { res.Body = http.NoBody } diff --git a/app/role_test.go b/app/role_test.go index 2e10c0d3c0..1bf9420ae4 100644 --- a/app/role_test.go +++ b/app/role_test.go @@ -6,7 +6,7 @@ package app import ( "context" "encoding/csv" - "io/ioutil" + "io" "os" "strconv" "strings" @@ -130,7 +130,7 @@ func testPermissionInheritance(t *testing.T, testCallback func(t *testing.T, th require.NoError(t, e) defer file.Close() - b, e := ioutil.ReadAll(file) + b, e := io.ReadAll(file) require.NoError(t, e) r := csv.NewReader(strings.NewReader(string(b))) diff --git a/app/saml.go b/app/saml.go index 260d601cee..b0b83ba159 100644 --- a/app/saml.go +++ b/app/saml.go @@ -8,7 +8,7 @@ import ( "encoding/pem" "encoding/xml" "fmt" - "io/ioutil" + "io" "mime/multipart" "net/http" "strings" @@ -42,7 +42,7 @@ func (a *App) writeSamlFile(filename string, fileData *multipart.FileHeader) *mo } defer file.Close() - data, err := ioutil.ReadAll(file) + data, err := io.ReadAll(file) if err != nil { return model.NewAppError("AddSamlCertificate", "api.admin.add_certificate.saving.app_error", nil, err.Error(), http.StatusInternalServerError) } @@ -212,7 +212,7 @@ func (a *App) FetchSamlMetadataFromIdp(url string) ([]byte, *model.AppError) { } defer resp.Body.Close() - bodyXML, err := ioutil.ReadAll(resp.Body) + bodyXML, err := io.ReadAll(resp.Body) if err != nil { return nil, model.NewAppError("FetchSamlMetadataFromIdp", "app.admin.saml.failure_read_response_body_from_idp.app_error", nil, err.Error(), http.StatusInternalServerError) } diff --git a/app/security_update_check.go b/app/security_update_check.go index 273f520e23..cf8d9cc2c5 100644 --- a/app/security_update_check.go +++ b/app/security_update_check.go @@ -5,7 +5,7 @@ package app import ( "encoding/json" - "io/ioutil" + "io" "net/http" "net/url" "runtime" @@ -110,7 +110,7 @@ func (s *Server) DoSecurityUpdateCheck() { return } - body, err := ioutil.ReadAll(resBody.Body) + body, err := io.ReadAll(resBody.Body) resBody.Body.Close() if err != nil || resBody.StatusCode != 200 { mlog.Error("Failed to read security bulletin details") diff --git a/app/slashcommands/helper_test.go b/app/slashcommands/helper_test.go index c7fa8fcf3a..ff145921c7 100644 --- a/app/slashcommands/helper_test.go +++ b/app/slashcommands/helper_test.go @@ -6,7 +6,6 @@ package slashcommands import ( "bytes" "context" - "io/ioutil" "os" "path/filepath" "strings" @@ -42,7 +41,7 @@ type TestHelper struct { } func setupTestHelper(dbStore store.Store, enterprise bool, includeCacheLayer bool, tb testing.TB, configSet func(*model.Config)) *TestHelper { - tempWorkspace, err := ioutil.TempDir("", "apptest") + tempWorkspace, err := os.MkdirTemp("", "apptest") if err != nil { panic(err) } diff --git a/app/support_packet.go b/app/support_packet.go index ea1a6b73ce..9b91471f02 100644 --- a/app/support_packet.go +++ b/app/support_packet.go @@ -6,7 +6,7 @@ package app import ( "encoding/json" "fmt" - "io/ioutil" + "os" "runtime" "strings" @@ -145,7 +145,7 @@ func (a *App) getNotificationsLog() (*model.FileData, string) { // notifications.log notificationsLog := config.GetNotificationsLogFileLocation(*a.Config().LogSettings.FileLocation) - notificationsLogFileData, notificationsLogFileDataErr := ioutil.ReadFile(notificationsLog) + notificationsLogFileData, notificationsLogFileDataErr := os.ReadFile(notificationsLog) if notificationsLogFileDataErr == nil { fileData := model.FileData{ @@ -155,7 +155,7 @@ func (a *App) getNotificationsLog() (*model.FileData, string) { return &fileData, "" } - warning = fmt.Sprintf("ioutil.ReadFile(notificationsLog) Error: %s", notificationsLogFileDataErr.Error()) + warning = fmt.Sprintf("os.ReadFile(notificationsLog) Error: %s", notificationsLogFileDataErr.Error()) } else { warning = "Unable to retrieve notifications.log because LogSettings: EnableFile is false in config.json" @@ -172,7 +172,7 @@ func (a *App) getMattermostLog() (*model.FileData, string) { // mattermost.log mattermostLog := config.GetLogFileLocation(*a.Config().LogSettings.FileLocation) - mattermostLogFileData, mattermostLogFileDataErr := ioutil.ReadFile(mattermostLog) + mattermostLogFileData, mattermostLogFileDataErr := os.ReadFile(mattermostLog) if mattermostLogFileDataErr == nil { fileData := model.FileData{ @@ -181,7 +181,7 @@ func (a *App) getMattermostLog() (*model.FileData, string) { } return &fileData, "" } - warning = fmt.Sprintf("ioutil.ReadFile(mattermostLog) Error: %s", mattermostLogFileDataErr.Error()) + warning = fmt.Sprintf("os.ReadFile(mattermostLog) Error: %s", mattermostLogFileDataErr.Error()) } else { warning = "Unable to retrieve mattermost.log because LogSettings: EnableFile is false in config.json" diff --git a/app/support_packet_test.go b/app/support_packet_test.go index 05e7d0418a..9ac966c0fa 100644 --- a/app/support_packet_test.go +++ b/app/support_packet_test.go @@ -4,7 +4,6 @@ package app import ( - "io/ioutil" "os" "testing" @@ -61,9 +60,9 @@ func TestGenerateSupportPacket(t *testing.T) { defer th.TearDown() d1 := []byte("hello\ngo\n") - err := ioutil.WriteFile("mattermost.log", d1, 0777) + err := os.WriteFile("mattermost.log", d1, 0777) require.NoError(t, err) - err = ioutil.WriteFile("notifications.log", d1, 0777) + err = os.WriteFile("notifications.log", d1, 0777) require.NoError(t, err) fileDatas := th.App.GenerateSupportPacket() @@ -111,11 +110,11 @@ func TestGetNotificationsLog(t *testing.T) { fileData, warning = th.App.getNotificationsLog() assert.Nil(t, fileData) - assert.Contains(t, warning, "ioutil.ReadFile(notificationsLog) Error:") + assert.Contains(t, warning, "os.ReadFile(notificationsLog) Error:") // Happy path where we have file and no warning d1 := []byte("hello\ngo\n") - err := ioutil.WriteFile("notifications.log", d1, 0777) + err := os.WriteFile("notifications.log", d1, 0777) defer os.Remove("notifications.log") require.NoError(t, err) @@ -149,11 +148,11 @@ func TestGetMattermostLog(t *testing.T) { fileData, warning = th.App.getMattermostLog() assert.Nil(t, fileData) - assert.Contains(t, warning, "ioutil.ReadFile(mattermostLog) Error:") + assert.Contains(t, warning, "os.ReadFile(mattermostLog) Error:") // Happy path where we get a log file and no warning d1 := []byte("hello\ngo\n") - err := ioutil.WriteFile("mattermost.log", d1, 0777) + err := os.WriteFile("mattermost.log", d1, 0777) defer os.Remove("mattermost.log") require.NoError(t, err) diff --git a/app/teams/helper_test.go b/app/teams/helper_test.go index 4aa6987bce..176a63e9e2 100644 --- a/app/teams/helper_test.go +++ b/app/teams/helper_test.go @@ -5,7 +5,6 @@ package teams import ( "bytes" - "io/ioutil" "os" "path/filepath" "testing" @@ -43,7 +42,7 @@ func Setup(tb testing.TB) *TestHelper { } func setupTestHelper(s store.Store, includeCacheLayer bool, tb testing.TB) *TestHelper { - tempWorkspace, err := ioutil.TempDir("", "teamservicetest") + tempWorkspace, err := os.MkdirTemp("", "teamservicetest") if err != nil { panic(err) } diff --git a/app/upload_test.go b/app/upload_test.go index 447914fa25..128f157912 100644 --- a/app/upload_test.go +++ b/app/upload_test.go @@ -6,8 +6,8 @@ package app import ( "bytes" "io" - "io/ioutil" "math/rand" + "os" "path/filepath" "sync" "sync/atomic" @@ -213,7 +213,7 @@ func TestUploadData(t *testing.T) { t.Run("image processing", func(t *testing.T) { testDir, _ := fileutils.FindDir("tests") - data, err := ioutil.ReadFile(filepath.Join(testDir, "test.png")) + data, err := os.ReadFile(filepath.Join(testDir, "test.png")) require.NoError(t, err) require.NotEmpty(t, data) diff --git a/app/users/helper_test.go b/app/users/helper_test.go index 8ddf4d97e5..44e55114b6 100644 --- a/app/users/helper_test.go +++ b/app/users/helper_test.go @@ -5,7 +5,6 @@ package users import ( "bytes" - "io/ioutil" "os" "path/filepath" "runtime" @@ -48,7 +47,7 @@ func Setup(tb testing.TB) *TestHelper { } func setupTestHelper(s store.Store, includeCacheLayer bool, tb testing.TB) *TestHelper { - tempWorkspace, err := ioutil.TempDir("", "userservicetest") + tempWorkspace, err := os.MkdirTemp("", "userservicetest") if err != nil { panic(err) } diff --git a/app/users/profile_picture.go b/app/users/profile_picture.go index c0260c5a5b..1858140e52 100644 --- a/app/users/profile_picture.go +++ b/app/users/profile_picture.go @@ -11,7 +11,7 @@ import ( "image/draw" "image/png" "io" - "io/ioutil" + "os" "path" "path/filepath" "strings" @@ -174,7 +174,7 @@ func getFont(initialFont string) (*truetype.Font, error) { } fontDir, _ := fileutils.FindDir("fonts") - fontBytes, err := ioutil.ReadFile(filepath.Join(fontDir, initialFont)) + fontBytes, err := os.ReadFile(filepath.Join(fontDir, initialFont)) if err != nil { return nil, err } diff --git a/app/webhub_fuzz.go b/app/webhub_fuzz.go index 5f39d8952d..a305b3cfc0 100644 --- a/app/webhub_fuzz.go +++ b/app/webhub_fuzz.go @@ -6,7 +6,6 @@ package app import ( - "io/ioutil" "math/rand" "net" "net/http" @@ -273,7 +272,7 @@ func generateInitialCorpus() error { if err != nil { return err } - err = ioutil.WriteFile("./workdir/corpus"+strconv.Itoa(i), data, 0644) + err = os.WriteFile("./workdir/corpus"+strconv.Itoa(i), data, 0644) if err != nil { return err } diff --git a/audit/audit_test.go b/audit/audit_test.go index cc3ce3d676..f6055c8166 100644 --- a/audit/audit_test.go +++ b/audit/audit_test.go @@ -6,7 +6,6 @@ package audit import ( "encoding/json" "fmt" - "io/ioutil" "os" "path/filepath" "regexp" @@ -72,7 +71,7 @@ func TestAudit_LogRecord(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.description, func(t *testing.T) { - tempDir, err := ioutil.TempDir(os.TempDir(), "TestAudit_LogRecord") + tempDir, err := os.MkdirTemp(os.TempDir(), "TestAudit_LogRecord") require.NoError(t, err) defer os.Remove(tempDir) @@ -92,7 +91,7 @@ func TestAudit_LogRecord(t *testing.T) { err = logger.Shutdown() require.NoError(t, err) - logs, err := ioutil.ReadFile(filePath) + logs, err := os.ReadFile(filePath) require.NoError(t, err) actual := strings.TrimSpace(string(logs)) diff --git a/cmd/mattermost/commands/cmdtestlib.go b/cmd/mattermost/commands/cmdtestlib.go index f79fdf9340..34a572d6b1 100644 --- a/cmd/mattermost/commands/cmdtestlib.go +++ b/cmd/mattermost/commands/cmdtestlib.go @@ -9,7 +9,6 @@ import ( "flag" "fmt" "io" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -127,7 +126,7 @@ func (h *testHelper) SetConfig(config *model.Config) { if err != nil { panic("failed to marshal config: " + err.Error()) } - if err := ioutil.WriteFile(h.configFilePath, buf, 0600); err != nil { + if err := os.WriteFile(h.configFilePath, buf, 0600); err != nil { panic("failed to write file " + h.configFilePath + ": " + err.Error()) } } diff --git a/cmd/mattermost/commands/server_test.go b/cmd/mattermost/commands/server_test.go index 8d94a4de17..5a7d9aa8f3 100644 --- a/cmd/mattermost/commands/server_test.go +++ b/cmd/mattermost/commands/server_test.go @@ -4,7 +4,6 @@ package commands import ( - "io/ioutil" "net" "os" "syscall" @@ -77,7 +76,7 @@ func TestRunServerSystemdNotification(t *testing.T) { defer th.TearDownServerTest() // Get a random temporary filename for using as a mock systemd socket - socketFile, err := ioutil.TempFile("", "mattermost-systemd-mock-socket-") + socketFile, err := os.CreateTemp("", "mattermost-systemd-mock-socket-") if err != nil { panic(err) } diff --git a/config/file.go b/config/file.go index cbf53cf73e..1455a4d99e 100644 --- a/config/file.go +++ b/config/file.go @@ -5,7 +5,7 @@ package config import ( "fmt" - "io/ioutil" + "io" "os" "path/filepath" @@ -111,7 +111,7 @@ func (fs *FileStore) persist(cfg *model.Config) error { return errors.Wrap(err, "failed to serialize") } - err = ioutil.WriteFile(fs.path, b, 0600) + err = os.WriteFile(fs.path, b, 0600) if err != nil { return errors.Wrap(err, "failed to write file") } @@ -130,7 +130,7 @@ func (fs *FileStore) Load() ([]byte, error) { } defer f.Close() - fileBytes, err := ioutil.ReadAll(f) + fileBytes, err := io.ReadAll(f) if err != nil { return nil, err } @@ -142,7 +142,7 @@ func (fs *FileStore) Load() ([]byte, error) { func (fs *FileStore) GetFile(name string) ([]byte, error) { resolvedPath := fs.resolveFilePath(name) - data, err := ioutil.ReadFile(resolvedPath) + data, err := os.ReadFile(resolvedPath) if err != nil { return nil, errors.Wrapf(err, "failed to read file from %s", resolvedPath) } @@ -160,7 +160,7 @@ func (fs *FileStore) GetFilePath(name string) string { func (fs *FileStore) SetFile(name string, data []byte) error { resolvedPath := fs.resolveFilePath(name) - err := ioutil.WriteFile(resolvedPath, data, 0600) + err := os.WriteFile(resolvedPath, data, 0600) if err != nil { return errors.Wrapf(err, "failed to write file to %s", resolvedPath) } diff --git a/config/file_test.go b/config/file_test.go index 0ae493b499..35bf30f474 100644 --- a/config/file_test.go +++ b/config/file_test.go @@ -5,7 +5,6 @@ package config import ( "encoding/json" - "io/ioutil" "os" "path/filepath" "strings" @@ -24,7 +23,7 @@ func setupConfigFile(t *testing.T, cfg *model.Config) (string, func()) { os.Clearenv() t.Helper() - tempDir, err := ioutil.TempDir("", "setupConfigFile") + tempDir, err := os.MkdirTemp("", "setupConfigFile") require.NoError(t, err) err = os.Chdir(tempDir) @@ -32,13 +31,13 @@ func setupConfigFile(t *testing.T, cfg *model.Config) (string, func()) { var name string if cfg != nil { - f, err := ioutil.TempFile(tempDir, "setupConfigFile") + f, err := os.CreateTemp(tempDir, "setupConfigFile") require.NoError(t, err) cfgData, err := marshalConfig(cfg) require.NoError(t, err) - ioutil.WriteFile(f.Name(), cfgData, 0644) + os.WriteFile(f.Name(), cfgData, 0644) name = f.Name() } @@ -165,7 +164,7 @@ func TestFileStoreNew(t *testing.T) { _, tearDown := setupConfigFile(t, nil) defer tearDown() - tempDir, err := ioutil.TempDir("", "TestFileStoreNew") + tempDir, err := os.MkdirTemp("", "TestFileStoreNew") require.NoError(t, err) defer os.RemoveAll(tempDir) @@ -184,7 +183,7 @@ func TestFileStoreNew(t *testing.T) { _, tearDown := setupConfigFile(t, nil) defer tearDown() - tempDir, err := ioutil.TempDir("", "TestFileStoreNew") + tempDir, err := os.MkdirTemp("", "TestFileStoreNew") require.NoError(t, err) defer os.RemoveAll(tempDir) @@ -203,7 +202,7 @@ func TestFileStoreNew(t *testing.T) { _, tearDown := setupConfigFile(t, nil) defer tearDown() - tempDir, err := ioutil.TempDir("", "TestFileStoreNew") + tempDir, err := os.MkdirTemp("", "TestFileStoreNew") require.NoError(t, err) defer os.RemoveAll(tempDir) @@ -225,7 +224,7 @@ func TestFileStoreNew(t *testing.T) { cfgData, err := marshalConfig(testConfig) require.NoError(t, err) - ioutil.WriteFile(path, cfgData, 0644) + os.WriteFile(path, cfgData, 0644) fs, err := NewFileStore(path, false) require.NoError(t, err) @@ -815,7 +814,7 @@ func TestFileStoreLoad(t *testing.T) { cfgData, err := marshalConfig(invalidConfig) require.NoError(t, err) - ioutil.WriteFile(path, cfgData, 0644) + os.WriteFile(path, cfgData, 0644) err = fs.Load() if assert.Error(t, err) { @@ -876,7 +875,7 @@ func TestFileStoreLoad(t *testing.T) { cfgData, err := marshalConfig(minimalConfig) require.NoError(t, err) - err = ioutil.WriteFile(path, cfgData, 0644) + err = os.WriteFile(path, cfgData, 0644) require.NoError(t, err) err = fs.Load() @@ -971,11 +970,11 @@ func TestFileGetFile(t *testing.T) { err := os.MkdirAll("config", 0700) require.NoError(t, err) - f, err := ioutil.TempFile("config", "empty-file") + f, err := os.CreateTemp("config", "empty-file") require.NoError(t, err) defer os.Remove(f.Name()) - err = ioutil.WriteFile(f.Name(), nil, 0777) + err = os.WriteFile(f.Name(), nil, 0777) require.NoError(t, err) data, err := fs.GetFile(f.Name()) @@ -987,11 +986,11 @@ func TestFileGetFile(t *testing.T) { err := os.MkdirAll("config", 0700) require.NoError(t, err) - f, err := ioutil.TempFile("config", "test-file") + f, err := os.CreateTemp("config", "test-file") require.NoError(t, err) defer os.Remove(f.Name()) - err = ioutil.WriteFile(f.Name(), []byte("test"), 0777) + err = os.WriteFile(f.Name(), []byte("test"), 0777) require.NoError(t, err) data, err := fs.GetFile(f.Name()) @@ -1102,11 +1101,11 @@ func TestFileHasFile(t *testing.T) { err = os.MkdirAll("config", 0700) require.NoError(t, err) - f, err := ioutil.TempFile("config", "test-file") + f, err := os.CreateTemp("config", "test-file") require.NoError(t, err) defer os.Remove(f.Name()) - err = ioutil.WriteFile(f.Name(), []byte("test"), 0777) + err = os.WriteFile(f.Name(), []byte("test"), 0777) require.NoError(t, err) has, err := fs.HasFile(f.Name()) @@ -1191,11 +1190,11 @@ func TestFileRemoveFile(t *testing.T) { err = os.MkdirAll("config", 0700) require.NoError(t, err) - f, err := ioutil.TempFile("config", "test-file") + f, err := os.CreateTemp("config", "test-file") require.NoError(t, err) defer os.Remove(f.Name()) - err = ioutil.WriteFile(f.Name(), []byte("test"), 0777) + err = os.WriteFile(f.Name(), []byte("test"), 0777) require.NoError(t, err) err = fs.RemoveFile(f.Name()) @@ -1314,7 +1313,7 @@ func TestFileStoreSetReadOnlyFF(t *testing.T) { func TestResolveConfigPath(t *testing.T) { t.Run("should be able to resolve an absolute path", func(t *testing.T) { - cf, err := ioutil.TempFile("", "config-test.json") + cf, err := os.CreateTemp("", "config-test.json") require.NoError(t, err) info, err := cf.Stat() require.NoError(t, err) @@ -1329,7 +1328,7 @@ func TestResolveConfigPath(t *testing.T) { }) t.Run("should be able to resolve relative path", func(t *testing.T) { - tempDir, err := ioutil.TempDir("", "resolveconfig") + tempDir, err := os.MkdirTemp("", "resolveconfig") require.NoError(t, err) defer os.RemoveAll(tempDir) diff --git a/config/migrate_test.go b/config/migrate_test.go index 348f29bd5f..27a1b9ccda 100644 --- a/config/migrate_test.go +++ b/config/migrate_test.go @@ -4,7 +4,6 @@ package config import ( - "io/ioutil" "os" "path" "testing" @@ -39,7 +38,7 @@ func TestMigrate(t *testing.T) { os.Clearenv() t.Helper() - tempDir, err := ioutil.TempDir("", "TestMigrate") + tempDir, err := os.MkdirTemp("", "TestMigrate") require.NoError(t, err) t.Cleanup(func() { os.RemoveAll(tempDir) diff --git a/config/store_test.go b/config/store_test.go index dc13329522..35a999f75e 100644 --- a/config/store_test.go +++ b/config/store_test.go @@ -4,7 +4,6 @@ package config import ( - "io/ioutil" "os" "path/filepath" "testing" @@ -18,7 +17,7 @@ func TestNewStoreFromDSN(t *testing.T) { } sqlSettings := mainHelper.GetSQLSettings() - tempDir, err := ioutil.TempDir("", "TestNewStore") + tempDir, err := os.MkdirTemp("", "TestNewStore") require.NoError(t, err) err = os.Chdir(tempDir) @@ -46,7 +45,7 @@ func TestNewStoreReadOnly(t *testing.T) { } sqlSettings := mainHelper.GetSQLSettings() - tempDir, tErr := ioutil.TempDir("", "TestNewStore") + tempDir, tErr := os.MkdirTemp("", "TestNewStore") require.NoError(t, tErr) tErr = os.Chdir(tempDir) diff --git a/model/bundle_info_test.go b/model/bundle_info_test.go index e91ec0efb4..eb771baea6 100644 --- a/model/bundle_info_test.go +++ b/model/bundle_info_test.go @@ -4,7 +4,6 @@ package model import ( - "io/ioutil" "os" "path/filepath" "testing" @@ -14,7 +13,7 @@ import ( ) func TestBundleInfoForPath(t *testing.T) { - dir, err := ioutil.TempDir("", "mm-plugin-test") + dir, err := os.MkdirTemp("", "mm-plugin-test") require.NoError(t, err) defer os.RemoveAll(dir) diff --git a/model/client4.go b/model/client4.go index 2ce96173ef..7225c94a1c 100644 --- a/model/client4.go +++ b/model/client4.go @@ -8,7 +8,6 @@ import ( "encoding/json" "fmt" "io" - "io/ioutil" "mime/multipart" "net" "net/http" @@ -1010,7 +1009,7 @@ func (c *Client4) GetDefaultProfileImage(userId string) ([]byte, *Response, erro } defer closeBody(r) - data, err := ioutil.ReadAll(r.Body) + data, err := io.ReadAll(r.Body) if err != nil { return nil, BuildResponse(r), NewAppError("GetDefaultProfileImage", "model.client.read_file.app_error", nil, err.Error(), r.StatusCode) } @@ -1026,7 +1025,7 @@ func (c *Client4) GetProfileImage(userId, etag string) ([]byte, *Response, error } defer closeBody(r) - data, err := ioutil.ReadAll(r.Body) + data, err := io.ReadAll(r.Body) if err != nil { return nil, BuildResponse(r), NewAppError("GetProfileImage", "model.client.read_file.app_error", nil, err.Error(), r.StatusCode) } @@ -2774,7 +2773,7 @@ func (c *Client4) GetTeamIcon(teamId, etag string) ([]byte, *Response, error) { } defer closeBody(r) - data, err := ioutil.ReadAll(r.Body) + data, err := io.ReadAll(r.Body) if err != nil { return nil, BuildResponse(r), NewAppError("GetTeamIcon", "model.client.get_team_icon.app_error", nil, err.Error(), r.StatusCode) } @@ -4311,7 +4310,7 @@ func (c *Client4) GetFile(fileId string) ([]byte, *Response, error) { } defer closeBody(r) - data, err := ioutil.ReadAll(r.Body) + data, err := io.ReadAll(r.Body) if err != nil { return nil, BuildResponse(r), NewAppError("GetFile", "model.client.read_file.app_error", nil, err.Error(), r.StatusCode) } @@ -4326,7 +4325,7 @@ func (c *Client4) DownloadFile(fileId string, download bool) ([]byte, *Response, } defer closeBody(r) - data, err := ioutil.ReadAll(r.Body) + data, err := io.ReadAll(r.Body) if err != nil { return nil, BuildResponse(r), NewAppError("DownloadFile", "model.client.read_file.app_error", nil, err.Error(), r.StatusCode) } @@ -4341,7 +4340,7 @@ func (c *Client4) GetFileThumbnail(fileId string) ([]byte, *Response, error) { } defer closeBody(r) - data, err := ioutil.ReadAll(r.Body) + data, err := io.ReadAll(r.Body) if err != nil { return nil, BuildResponse(r), NewAppError("GetFileThumbnail", "model.client.read_file.app_error", nil, err.Error(), r.StatusCode) } @@ -4356,7 +4355,7 @@ func (c *Client4) DownloadFileThumbnail(fileId string, download bool) ([]byte, * } defer closeBody(r) - data, err := ioutil.ReadAll(r.Body) + data, err := io.ReadAll(r.Body) if err != nil { return nil, BuildResponse(r), NewAppError("DownloadFileThumbnail", "model.client.read_file.app_error", nil, err.Error(), r.StatusCode) } @@ -4381,7 +4380,7 @@ func (c *Client4) GetFilePreview(fileId string) ([]byte, *Response, error) { } defer closeBody(r) - data, err := ioutil.ReadAll(r.Body) + data, err := io.ReadAll(r.Body) if err != nil { return nil, BuildResponse(r), NewAppError("GetFilePreview", "model.client.read_file.app_error", nil, err.Error(), r.StatusCode) } @@ -4396,7 +4395,7 @@ func (c *Client4) DownloadFilePreview(fileId string, download bool) ([]byte, *Re } defer closeBody(r) - data, err := ioutil.ReadAll(r.Body) + data, err := io.ReadAll(r.Body) if err != nil { return nil, BuildResponse(r), NewAppError("DownloadFilePreview", "model.client.read_file.app_error", nil, err.Error(), r.StatusCode) } @@ -4464,7 +4463,7 @@ func (c *Client4) GenerateSupportPacket() ([]byte, *Response, error) { } defer closeBody(r) - data, err := ioutil.ReadAll(r.Body) + data, err := io.ReadAll(r.Body) if err != nil { return nil, BuildResponse(r), NewAppError("GetFile", "model.client.read_job_result_file.app_error", nil, err.Error(), r.StatusCode) } @@ -5268,7 +5267,7 @@ func (c *Client4) DownloadComplianceReport(reportId string) ([]byte, *Response, return nil, BuildResponse(rp), AppErrorFromJSON(rp.Body) } - data, err := ioutil.ReadAll(rp.Body) + data, err := io.ReadAll(rp.Body) if err != nil { return nil, BuildResponse(rp), NewAppError("DownloadComplianceReport", "model.client.read_file.app_error", nil, err.Error(), rp.StatusCode) } @@ -5614,7 +5613,7 @@ func (c *Client4) GetBrandImage() ([]byte, *Response, error) { return nil, BuildResponse(r), AppErrorFromJSON(r.Body) } - data, err := ioutil.ReadAll(r.Body) + data, err := io.ReadAll(r.Body) if err != nil { return nil, BuildResponse(r), NewAppError("GetBrandImage", "model.client.read_file.app_error", nil, err.Error(), r.StatusCode) } @@ -6560,7 +6559,7 @@ func (c *Client4) GetEmojiImage(emojiId string) ([]byte, *Response, error) { } defer closeBody(r) - data, err := ioutil.ReadAll(r.Body) + data, err := io.ReadAll(r.Body) if err != nil { return nil, BuildResponse(r), NewAppError("GetEmojiImage", "model.client.read_file.app_error", nil, err.Error(), r.StatusCode) } @@ -6801,7 +6800,7 @@ func (c *Client4) DownloadJob(jobId string) ([]byte, *Response, error) { } defer closeBody(r) - data, err := ioutil.ReadAll(r.Body) + data, err := io.ReadAll(r.Body) if err != nil { return nil, BuildResponse(r), NewAppError("GetFile", "model.client.read_job_result_file.app_error", nil, err.Error(), r.StatusCode) } diff --git a/model/command_response.go b/model/command_response.go index b2521f8e0f..381a0f0c3d 100644 --- a/model/command_response.go +++ b/model/command_response.go @@ -6,7 +6,6 @@ package model import ( "encoding/json" "io" - "io/ioutil" "strings" "github.com/mattermost/mattermost-server/v6/utils/jsonutils" @@ -36,7 +35,7 @@ func CommandResponseFromHTTPBody(contentType string, body io.Reader) (*CommandRe if strings.TrimSpace(strings.Split(contentType, ";")[0]) == "application/json" { return CommandResponseFromJSON(body) } - if b, err := ioutil.ReadAll(body); err == nil { + if b, err := io.ReadAll(body); err == nil { return CommandResponseFromPlainText(string(b)), nil } return nil, nil @@ -49,7 +48,7 @@ func CommandResponseFromPlainText(text string) *CommandResponse { } func CommandResponseFromJSON(data io.Reader) (*CommandResponse, error) { - b, err := ioutil.ReadAll(data) + b, err := io.ReadAll(data) if err != nil { return nil, err } diff --git a/model/file_info_test.go b/model/file_info_test.go index 9d060f34c1..e2552dd77c 100644 --- a/model/file_info_test.go +++ b/model/file_info_test.go @@ -8,7 +8,7 @@ import ( "encoding/base64" _ "image/gif" _ "image/png" - "io/ioutil" + "os" "strings" "testing" @@ -76,13 +76,13 @@ func TestFileInfoIsImage(t *testing.T) { func TestGetInfoForFile(t *testing.T) { fakeFile := make([]byte, 1000) - pngFile, err := ioutil.ReadFile("../tests/test.png") + pngFile, err := os.ReadFile("../tests/test.png") require.NoError(t, err, "Failed to load test.png") // base 64 encoded version of handtinywhite.gif from http://probablyprogramming.com/2009/03/15/the-tiniest-gif-ever gifFile, _ := base64.StdEncoding.DecodeString("R0lGODlhAQABAIABAP///wAAACwAAAAAAQABAAACAkQBADs=") - animatedGifFile, err := ioutil.ReadFile("../tests/testgif.gif") + animatedGifFile, err := os.ReadFile("../tests/testgif.gif") require.NoError(t, err, "Failed to load testgif.gif") var ttc = []struct { diff --git a/model/manifest.go b/model/manifest.go index 6b7ddbd84d..9b1551e921 100644 --- a/model/manifest.go +++ b/model/manifest.go @@ -6,7 +6,7 @@ package model import ( "encoding/json" "fmt" - "io/ioutil" + "io" "os" "path/filepath" "strings" @@ -108,42 +108,41 @@ type PluginSettingsSchema struct { // // Example plugin.json: // -// -// { -// "id": "com.mycompany.myplugin", -// "name": "My Plugin", -// "description": "This is my plugin", -// "homepage_url": "https://example.com", -// "support_url": "https://example.com/support", -// "release_notes_url": "https://example.com/releases/v0.0.1", -// "icon_path": "assets/logo.svg", -// "version": "0.1.0", -// "min_server_version": "5.6.0", -// "server": { -// "executables": { -// "linux-amd64": "server/dist/plugin-linux-amd64", -// "darwin-amd64": "server/dist/plugin-darwin-amd64", -// "windows-amd64": "server/dist/plugin-windows-amd64.exe" -// } -// }, -// "webapp": { -// "bundle_path": "webapp/dist/main.js" -// }, -// "settings_schema": { -// "header": "Some header text", -// "footer": "Some footer text", -// "settings": [{ -// "key": "someKey", -// "display_name": "Enable Extra Feature", -// "type": "bool", -// "help_text": "When true, an extra feature will be enabled!", -// "default": "false" -// }] -// }, -// "props": { -// "someKey": "someData" -// } -// } +// { +// "id": "com.mycompany.myplugin", +// "name": "My Plugin", +// "description": "This is my plugin", +// "homepage_url": "https://example.com", +// "support_url": "https://example.com/support", +// "release_notes_url": "https://example.com/releases/v0.0.1", +// "icon_path": "assets/logo.svg", +// "version": "0.1.0", +// "min_server_version": "5.6.0", +// "server": { +// "executables": { +// "linux-amd64": "server/dist/plugin-linux-amd64", +// "darwin-amd64": "server/dist/plugin-darwin-amd64", +// "windows-amd64": "server/dist/plugin-windows-amd64.exe" +// } +// }, +// "webapp": { +// "bundle_path": "webapp/dist/main.js" +// }, +// "settings_schema": { +// "header": "Some header text", +// "footer": "Some footer text", +// "settings": [{ +// "key": "someKey", +// "display_name": "Enable Extra Feature", +// "type": "bool", +// "help_text": "When true, an extra feature will be enabled!", +// "default": "false" +// }] +// }, +// "props": { +// "someKey": "someData" +// } +// } type Manifest struct { // The id is a globally unique identifier that represents your plugin. Ids must be at least // 3 characters, at most 190 characters and must match ^[a-zA-Z0-9-_\.]+$. @@ -426,7 +425,7 @@ func FindManifest(dir string) (manifest *Manifest, path string, err error) { } continue } - b, ioerr := ioutil.ReadAll(f) + b, ioerr := io.ReadAll(f) f.Close() if ioerr != nil { return nil, path, ioerr diff --git a/model/manifest_test.go b/model/manifest_test.go index ae816b340d..de93569b53 100644 --- a/model/manifest_test.go +++ b/model/manifest_test.go @@ -5,7 +5,6 @@ package model import ( "encoding/json" - "io/ioutil" "os" "path/filepath" "strings" @@ -244,7 +243,7 @@ func TestFindManifest(t *testing.T) { {"plugin.yml", `id: FOO`, false, false}, {"plugin.yml", "bar", true, false}, } { - dir, err := ioutil.TempDir("", "mm-plugin-test") + dir, err := os.MkdirTemp("", "mm-plugin-test") require.NoError(t, err) defer os.RemoveAll(dir) @@ -396,7 +395,7 @@ settings_schema: func TestFindManifest_FileErrors(t *testing.T) { for _, tc := range []string{"plugin.yaml", "plugin.json"} { - dir, err := ioutil.TempDir("", "mm-plugin-test") + dir, err := os.MkdirTemp("", "mm-plugin-test") require.NoError(t, err) defer os.RemoveAll(dir) @@ -417,7 +416,7 @@ func TestFindManifest_FolderPermission(t *testing.T) { } for _, tc := range []string{"plugin.yaml", "plugin.json"} { - dir, err := ioutil.TempDir("", "mm-plugin-test") + dir, err := os.MkdirTemp("", "mm-plugin-test") require.NoError(t, err) defer os.RemoveAll(dir) diff --git a/model/post_test.go b/model/post_test.go index f6935c7ca6..3cbb785100 100644 --- a/model/post_test.go +++ b/model/post_test.go @@ -5,7 +5,7 @@ package model import ( "encoding/json" - "io/ioutil" + "os" "strings" "sync" "testing" @@ -369,13 +369,13 @@ func TestPost_AttachmentsEqual(t *testing.T) { var markdownSample, markdownSampleWithRewrittenImageURLs string func init() { - bytes, err := ioutil.ReadFile("testdata/markdown-sample.md") + bytes, err := os.ReadFile("testdata/markdown-sample.md") if err != nil { panic(err) } markdownSample = string(bytes) - bytes, err = ioutil.ReadFile("testdata/markdown-sample-with-rewritten-image-urls.md") + bytes, err = os.ReadFile("testdata/markdown-sample-with-rewritten-image-urls.md") if err != nil { panic(err) } diff --git a/plugin/client_rpc.go b/plugin/client_rpc.go index 12c54b61ba..feea87005a 100644 --- a/plugin/client_rpc.go +++ b/plugin/client_rpc.go @@ -13,7 +13,6 @@ import ( "encoding/json" "fmt" "io" - "io/ioutil" "log" "net/http" "net/rpc" @@ -444,7 +443,7 @@ func (s *hooksRPCServer) ServeHTTP(args *Z_ServeHTTPArgs, returns *struct{}) err } r.Body = connectIOReader(connection) } else { - r.Body = ioutil.NopCloser(&bytes.Buffer{}) + r.Body = io.NopCloser(&bytes.Buffer{}) } defer r.Body.Close() @@ -487,7 +486,7 @@ func (g *apiRPCClient) PluginHTTP(request *http.Request) *http.Response { } if request.Body != nil { - requestBody, err := ioutil.ReadAll(request.Body) + requestBody, err := io.ReadAll(request.Body) if err != nil { log.Printf("RPC call to PluginHTTP API failed: %s", err.Error()) return nil @@ -504,20 +503,20 @@ func (g *apiRPCClient) PluginHTTP(request *http.Request) *http.Response { return nil } - _returns.Response.Body = ioutil.NopCloser(bytes.NewBuffer(_returns.ResponseBody)) + _returns.Response.Body = io.NopCloser(bytes.NewBuffer(_returns.ResponseBody)) return _returns.Response } func (s *apiRPCServer) PluginHTTP(args *Z_PluginHTTPArgs, returns *Z_PluginHTTPReturns) error { - args.Request.Body = ioutil.NopCloser(bytes.NewBuffer(args.RequestBody)) + args.Request.Body = io.NopCloser(bytes.NewBuffer(args.RequestBody)) if hook, ok := s.impl.(interface { PluginHTTP(request *http.Request) *http.Response }); ok { response := hook.PluginHTTP(args.Request) - responseBody, err := ioutil.ReadAll(response.Body) + responseBody, err := io.ReadAll(response.Body) if err != nil { return encodableError(fmt.Errorf("RPC call to PluginHTTP API failed: %s", err.Error())) } diff --git a/plugin/environment.go b/plugin/environment.go index 6469c9352b..9226a2e878 100644 --- a/plugin/environment.go +++ b/plugin/environment.go @@ -6,7 +6,6 @@ package plugin import ( "fmt" "hash/fnv" - "io/ioutil" "os" "path/filepath" "sync" @@ -86,7 +85,7 @@ func NewEnvironment(newAPIImpl apiImplCreatorFunc, // // Plugins are found non-recursively and paths beginning with a dot are always ignored. func scanSearchPath(path string) ([]*model.BundleInfo, error) { - files, err := ioutil.ReadDir(path) + files, err := os.ReadDir(path) if err != nil { return nil, err } @@ -468,7 +467,7 @@ func (env *Environment) UnpackWebappBundle(id string) (*model.Manifest, error) { sourceBundleFilepath := filepath.Join(destinationPath, filepath.Base(bundlePath)) - sourceBundleFileContents, err := ioutil.ReadFile(sourceBundleFilepath) + sourceBundleFileContents, err := os.ReadFile(sourceBundleFilepath) if err != nil { return nil, errors.Wrapf(err, "unable to read webapp bundle: %v", id) } diff --git a/plugin/environment_test.go b/plugin/environment_test.go index 827b822422..389021040c 100644 --- a/plugin/environment_test.go +++ b/plugin/environment_test.go @@ -5,7 +5,6 @@ package plugin import ( "encoding/json" - "io/ioutil" "os" "path/filepath" "testing" @@ -16,7 +15,7 @@ import ( ) func TestAvailablePlugins(t *testing.T) { - dir, err1 := ioutil.TempDir("", "mm-plugin-test") + dir, err1 := os.MkdirTemp("", "mm-plugin-test") require.NoError(t, err1) t.Cleanup(func() { os.RemoveAll(dir) @@ -40,7 +39,7 @@ func TestAvailablePlugins(t *testing.T) { path := filepath.Join(dir, "plugin1", "plugin.json") manifestJSON, jsonErr := json.Marshal(bundle1.Manifest) require.NoError(t, jsonErr) - err = ioutil.WriteFile(path, manifestJSON, 0644) + err = os.WriteFile(path, manifestJSON, 0644) require.NoError(t, err) bundles, err := env.Available() @@ -54,7 +53,7 @@ func TestAvailablePlugins(t *testing.T) { defer os.RemoveAll(filepath.Join(dir, "plugin2")) path := filepath.Join(dir, "plugin2", "manifest.json") - err = ioutil.WriteFile(path, []byte("{}"), 0644) + err = os.WriteFile(path, []byte("{}"), 0644) require.NoError(t, err) bundles, err := env.Available() diff --git a/plugin/health_check_test.go b/plugin/health_check_test.go index 1854af0a9e..f2dc44c766 100644 --- a/plugin/health_check_test.go +++ b/plugin/health_check_test.go @@ -4,7 +4,6 @@ package plugin import ( - "io/ioutil" "os" "path/filepath" "testing" @@ -27,7 +26,7 @@ func TestPluginHealthCheck(t *testing.T) { } func testPluginHealthCheckSuccess(t *testing.T) { - dir, err := ioutil.TempDir("", "") + dir, err := os.MkdirTemp("", "") require.NoError(t, err) defer os.RemoveAll(dir) @@ -48,7 +47,7 @@ func testPluginHealthCheckSuccess(t *testing.T) { } `, backend) - err = ioutil.WriteFile(filepath.Join(dir, "plugin.json"), []byte(`{"id": "foo", "server": {"executable": "backend.exe"}}`), 0600) + err = os.WriteFile(filepath.Join(dir, "plugin.json"), []byte(`{"id": "foo", "server": {"executable": "backend.exe"}}`), 0600) require.NoError(t, err) bundle := model.BundleInfoForPath(dir) @@ -65,7 +64,7 @@ func testPluginHealthCheckSuccess(t *testing.T) { } func testPluginHealthCheckPanic(t *testing.T) { - dir, err := ioutil.TempDir("", "") + dir, err := os.MkdirTemp("", "") require.NoError(t, err) defer os.RemoveAll(dir) @@ -91,7 +90,7 @@ func testPluginHealthCheckPanic(t *testing.T) { } `, backend) - err = ioutil.WriteFile(filepath.Join(dir, "plugin.json"), []byte(`{"id": "foo", "server": {"executable": "backend.exe"}}`), 0600) + err = os.WriteFile(filepath.Join(dir, "plugin.json"), []byte(`{"id": "foo", "server": {"executable": "backend.exe"}}`), 0600) require.NoError(t, err) bundle := model.BundleInfoForPath(dir) diff --git a/plugin/interface_generator/main.go b/plugin/interface_generator/main.go index 878b94501b..763868f52e 100644 --- a/plugin/interface_generator/main.go +++ b/plugin/interface_generator/main.go @@ -10,8 +10,8 @@ import ( "go/parser" "go/printer" "go/token" - "io/ioutil" "log" + "os" "os/exec" "path/filepath" "strings" @@ -580,7 +580,7 @@ func generateHooksGlue(info *PluginInterfaceInfo) { panic(err) } - if err := ioutil.WriteFile(filepath.Join(getPluginPackageDir(), "client_rpc_generated.go"), formatted, 0664); err != nil { + if err := os.WriteFile(filepath.Join(getPluginPackageDir(), "client_rpc_generated.go"), formatted, 0664); err != nil { panic(err) } } @@ -613,7 +613,7 @@ func generateProductHooksInterfaces(info *PluginInterfaceInfo) { panic(err) } - if err := ioutil.WriteFile(filepath.Join(getPluginPackageDir(), "product_hooks_generated.go"), formatted, 0664); err != nil { + if err := os.WriteFile(filepath.Join(getPluginPackageDir(), "product_hooks_generated.go"), formatted, 0664); err != nil { panic(err) } } @@ -667,7 +667,7 @@ func generatePluginTimerLayer(info *PluginInterfaceInfo) { panic(err) } - if err := ioutil.WriteFile(filepath.Join(getPluginPackageDir(), fileName), formatted, 0664); err != nil { + if err := os.WriteFile(filepath.Join(getPluginPackageDir(), fileName), formatted, 0664); err != nil { panic(err) } } diff --git a/plugin/plugintest/example_hello_user_test.go b/plugin/plugintest/example_hello_user_test.go index 36b57f65b2..2095b914d3 100644 --- a/plugin/plugintest/example_hello_user_test.go +++ b/plugin/plugintest/example_hello_user_test.go @@ -5,7 +5,7 @@ package plugintest_test import ( "fmt" - "io/ioutil" + io "io" "net/http" "net/http/httptest" "testing" @@ -52,7 +52,7 @@ func Example() { r := httptest.NewRequest("GET", "/", nil) r.Header.Add("Mattermost-User-Id", user.Id) p.ServeHTTP(&plugin.Context{}, w, r) - body, err := ioutil.ReadAll(w.Result().Body) + body, err := io.ReadAll(w.Result().Body) require.NoError(t, err) assert.Equal(t, "Welcome back, billybob!", string(body)) } diff --git a/plugin/supervisor_test.go b/plugin/supervisor_test.go index 81b8d6a912..f5aa7538c0 100644 --- a/plugin/supervisor_test.go +++ b/plugin/supervisor_test.go @@ -4,7 +4,6 @@ package plugin import ( - "io/ioutil" "os" "path/filepath" "testing" @@ -28,11 +27,11 @@ func TestSupervisor(t *testing.T) { } func testSupervisorInvalidExecutablePath(t *testing.T) { - dir, err := ioutil.TempDir("", "") + dir, err := os.MkdirTemp("", "") require.NoError(t, err) defer os.RemoveAll(dir) - ioutil.WriteFile(filepath.Join(dir, "plugin.json"), []byte(`{"id": "foo", "server": {"executable": "/foo/../../backend.exe"}}`), 0600) + os.WriteFile(filepath.Join(dir, "plugin.json"), []byte(`{"id": "foo", "server": {"executable": "/foo/../../backend.exe"}}`), 0600) bundle := model.BundleInfoForPath(dir) log := mlog.CreateConsoleTestLogger(true, mlog.LvlError) @@ -43,11 +42,11 @@ func testSupervisorInvalidExecutablePath(t *testing.T) { } func testSupervisorNonExistentExecutablePath(t *testing.T) { - dir, err := ioutil.TempDir("", "") + dir, err := os.MkdirTemp("", "") require.NoError(t, err) defer os.RemoveAll(dir) - ioutil.WriteFile(filepath.Join(dir, "plugin.json"), []byte(`{"id": "foo", "server": {"executable": "thisfileshouldnotexist"}}`), 0600) + os.WriteFile(filepath.Join(dir, "plugin.json"), []byte(`{"id": "foo", "server": {"executable": "thisfileshouldnotexist"}}`), 0600) bundle := model.BundleInfoForPath(dir) log := mlog.CreateConsoleTestLogger(true, mlog.LvlError) @@ -59,7 +58,7 @@ func testSupervisorNonExistentExecutablePath(t *testing.T) { // If plugin development goes really wrong, let's make sure plugin activation won't block forever. func testSupervisorStartTimeout(t *testing.T) { - dir, err := ioutil.TempDir("", "") + dir, err := os.MkdirTemp("", "") require.NoError(t, err) defer os.RemoveAll(dir) @@ -73,7 +72,7 @@ func testSupervisorStartTimeout(t *testing.T) { } `, backend) - ioutil.WriteFile(filepath.Join(dir, "plugin.json"), []byte(`{"id": "foo", "server": {"executable": "backend.exe"}}`), 0600) + os.WriteFile(filepath.Join(dir, "plugin.json"), []byte(`{"id": "foo", "server": {"executable": "backend.exe"}}`), 0600) bundle := model.BundleInfoForPath(dir) log := mlog.CreateConsoleTestLogger(true, mlog.LvlError) diff --git a/scripts/config_generator/main_test.go b/scripts/config_generator/main_test.go index e0afc34d04..8dba358c44 100644 --- a/scripts/config_generator/main_test.go +++ b/scripts/config_generator/main_test.go @@ -5,7 +5,6 @@ package main import ( "encoding/json" - "io/ioutil" "os" "testing" @@ -15,14 +14,14 @@ import ( ) func TestDefaultsGenerator(t *testing.T) { - tmpFile, err := ioutil.TempFile("", "tempconfig") + tmpFile, err := os.CreateTemp("", "tempconfig") defer os.Remove(tmpFile.Name()) require.NoError(t, err) require.NoError(t, generateDefaultConfig(tmpFile)) _ = tmpFile.Close() var config model.Config - b, err := ioutil.ReadFile(tmpFile.Name()) + b, err := os.ReadFile(tmpFile.Name()) require.NoError(t, err) require.NoError(t, json.Unmarshal(b, &config)) require.Equal(t, *config.SqlSettings.AtRestEncryptKey, "") diff --git a/services/docextractor/archive.go b/services/docextractor/archive.go index 96194252cb..1c0e228afb 100644 --- a/services/docextractor/archive.go +++ b/services/docextractor/archive.go @@ -7,7 +7,6 @@ import ( "bytes" "fmt" "io" - "io/ioutil" "os" "path/filepath" "strings" @@ -25,7 +24,7 @@ func (ae *archiveExtractor) Match(filename string) bool { } func (ae *archiveExtractor) Extract(name string, r io.ReadSeeker) (string, error) { - dir, err := ioutil.TempDir(os.TempDir(), "archiver") + dir, err := os.MkdirTemp(os.TempDir(), "archiver") if err != nil { return "", fmt.Errorf("error creating temporary file: %v", err) } @@ -49,7 +48,7 @@ func (ae *archiveExtractor) Extract(name string, r io.ReadSeeker) (string, error filename = strings.ReplaceAll(filename, "-", " ") filename = strings.ReplaceAll(filename, ".", " ") filename = strings.ReplaceAll(filename, ",", " ") - data, err2 := ioutil.ReadAll(file) + data, err2 := io.ReadAll(file) if err2 != nil { return err2 } diff --git a/services/docextractor/mmpreview.go b/services/docextractor/mmpreview.go index a46cc3f956..b38e16c5af 100644 --- a/services/docextractor/mmpreview.go +++ b/services/docextractor/mmpreview.go @@ -10,7 +10,6 @@ package docextractor import ( "bytes" "io" - "io/ioutil" "mime/multipart" "net/http" "path" @@ -63,7 +62,7 @@ func (mpe *mmPreviewExtractor) Extract(filename string, file io.ReadSeeker) (str if resp.StatusCode != 200 { return "", errors.New("Unable to generate file preview using mmpreview (The server has replied with an error)") } - data, err := ioutil.ReadAll(resp.Body) + data, err := io.ReadAll(resp.Body) if err != nil { return "", errors.Wrap(err, "unable to read the response from mmpreview") } diff --git a/services/docextractor/pdf.go b/services/docextractor/pdf.go index 43010d4d29..baa7d6685e 100644 --- a/services/docextractor/pdf.go +++ b/services/docextractor/pdf.go @@ -8,7 +8,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "os" "path" "strings" @@ -33,7 +32,7 @@ func (pe *pdfExtractor) Extract(filename string, r io.ReadSeeker) (out string, o outErr = errors.New("error extracting pdf text") } }() - f, err := ioutil.TempFile(os.TempDir(), "pdflib") + f, err := os.CreateTemp(os.TempDir(), "pdflib") if err != nil { return "", fmt.Errorf("error creating temporary file: %v", err) } diff --git a/services/docextractor/plain.go b/services/docextractor/plain.go index 4d3b084502..e97bb1d0b8 100644 --- a/services/docextractor/plain.go +++ b/services/docextractor/plain.go @@ -5,7 +5,6 @@ package docextractor import ( "io" - "io/ioutil" "unicode" "unicode/utf8" ) @@ -47,6 +46,6 @@ func (pe *plainExtractor) Extract(filename string, r io.ReadSeeker) (string, err } } - text, _ := ioutil.ReadAll(r) + text, _ := io.ReadAll(r) return string(runes[0:total]) + string(text), nil } diff --git a/services/httpservice/client_test.go b/services/httpservice/client_test.go index a57e5134ad..a274ebf5f3 100644 --- a/services/httpservice/client_test.go +++ b/services/httpservice/client_test.go @@ -6,7 +6,7 @@ package httpservice import ( "context" "fmt" - "io/ioutil" + "io" "net" "net/http" "net/http/httptest" @@ -108,7 +108,7 @@ func TestHTTPClientWithProxy(t *testing.T) { require.NoError(t, err) defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) + body, err := io.ReadAll(resp.Body) require.NoError(t, err) require.Equal(t, "proxy", string(body)) } diff --git a/services/imageproxy/atmos_camo_test.go b/services/imageproxy/atmos_camo_test.go index 114071b4e6..087724e122 100644 --- a/services/imageproxy/atmos_camo_test.go +++ b/services/imageproxy/atmos_camo_test.go @@ -4,7 +4,7 @@ package imageproxy import ( - "io/ioutil" + "io" "net/http" "net/http/httptest" "net/url" @@ -85,7 +85,7 @@ func TestAtmosCamoBackend_GetImageDirect(t *testing.T) { assert.Equal(t, "image/png", contentType) require.NotNil(t, body) - respBody, _ := ioutil.ReadAll(body) + respBody, _ := io.ReadAll(body) assert.Equal(t, []byte("1111111111"), respBody) } diff --git a/services/imageproxy/local.go b/services/imageproxy/local.go index fc98f6eeb8..950582ebf1 100644 --- a/services/imageproxy/local.go +++ b/services/imageproxy/local.go @@ -8,7 +8,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "mime" "net" "net/http" @@ -134,7 +133,7 @@ func (backend *LocalBackend) GetImageDirect(imageURL string) (io.ReadCloser, str return nil, "", ErrLocalRequestFailed } - return ioutil.NopCloser(recorder.Body), recorder.Header().Get("Content-Type"), nil + return io.NopCloser(recorder.Body), recorder.Header().Get("Content-Type"), nil } func (backend *LocalBackend) ServeImage(w http.ResponseWriter, req *http.Request) { @@ -176,7 +175,7 @@ func (backend *LocalBackend) ServeImage(w http.ResponseWriter, req *http.Request if contentType == "" || contentType == "application/octet-stream" || contentType == "binary/octet-stream" { // try to detect content type b := bufio.NewReader(resp.Body) - resp.Body = ioutil.NopCloser(b) + resp.Body = io.NopCloser(b) contentType = peekContentType(b) } if resp.ContentLength != 0 && !contentTypeMatches(imageContentTypes, contentType) { diff --git a/services/imageproxy/local_test.go b/services/imageproxy/local_test.go index da32132546..fe724bca4b 100644 --- a/services/imageproxy/local_test.go +++ b/services/imageproxy/local_test.go @@ -4,7 +4,7 @@ package imageproxy import ( - "io/ioutil" + "io" "net/http" "net/http/httptest" "testing" @@ -60,7 +60,7 @@ func TestLocalBackend_GetImage(t *testing.T) { assert.Equal(t, "max-age=2592000, private", resp.Header.Get("Cache-Control")) assert.Equal(t, "10", resp.Header.Get("Content-Length")) - respBody, _ := ioutil.ReadAll(resp.Body) + respBody, _ := io.ReadAll(resp.Body) assert.Equal(t, []byte("1111111111"), respBody) }) @@ -190,7 +190,7 @@ func TestLocalBackend_GetImage(t *testing.T) { assert.Equal(t, http.StatusOK, resp.StatusCode) assert.Equal(t, "attachment;filename=\"test.svg\"", resp.Header.Get("Content-Disposition")) - _, err = ioutil.ReadAll(resp.Body) + _, err = io.ReadAll(resp.Body) require.NoError(t, err) }) @@ -247,7 +247,7 @@ func TestLocalBackend_GetImageDirect(t *testing.T) { assert.NoError(t, err) assert.Equal(t, "image/png", contentType) - respBody, _ := ioutil.ReadAll(body) + respBody, _ := io.ReadAll(body) assert.Equal(t, []byte("1111111111"), respBody) }) diff --git a/services/remotecluster/sendfile.go b/services/remotecluster/sendfile.go index d94434e2bf..9bf224cbf6 100644 --- a/services/remotecluster/sendfile.go +++ b/services/remotecluster/sendfile.go @@ -7,7 +7,7 @@ import ( "context" "encoding/json" "fmt" - "io/ioutil" + "io" "net/http" "net/url" "path" @@ -117,7 +117,7 @@ func (rcs *Service) sendFileToRemote(timeout time.Duration, task sendFileTask) ( } defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) + body, err := io.ReadAll(resp.Body) if err != nil { return nil, err } diff --git a/services/remotecluster/sendmsg.go b/services/remotecluster/sendmsg.go index 2b66cdcb6a..78350a3e4a 100644 --- a/services/remotecluster/sendmsg.go +++ b/services/remotecluster/sendmsg.go @@ -8,7 +8,7 @@ import ( "context" "encoding/json" "fmt" - "io/ioutil" + "io" "net/http" "net/url" "os" @@ -163,7 +163,7 @@ func (rcs *Service) sendFrameToRemote(timeout time.Duration, rc *model.RemoteClu return nil, err } defer resp.Body.Close() - body, err = ioutil.ReadAll(resp.Body) + body, err = io.ReadAll(resp.Body) if err != nil { return nil, err } diff --git a/services/remotecluster/sendprofileImage.go b/services/remotecluster/sendprofileImage.go index ff148a3472..e86adff2ba 100644 --- a/services/remotecluster/sendprofileImage.go +++ b/services/remotecluster/sendprofileImage.go @@ -8,7 +8,6 @@ import ( "context" "fmt" "io" - "io/ioutil" "mime/multipart" "net/http" "net/url" @@ -134,7 +133,7 @@ func (rcs *Service) sendProfileImageToRemote(timeout time.Duration, task sendPro } defer resp.Body.Close() - _, err = ioutil.ReadAll(resp.Body) + _, err = io.ReadAll(resp.Body) if err != nil { return err } diff --git a/services/searchengine/bleveengine/bleve_test.go b/services/searchengine/bleveengine/bleve_test.go index a0ed1e1736..62e30386eb 100644 --- a/services/searchengine/bleveengine/bleve_test.go +++ b/services/searchengine/bleveengine/bleve_test.go @@ -4,7 +4,6 @@ package bleveengine import ( - "io/ioutil" "os" "testing" @@ -37,7 +36,7 @@ func TestBleveEngineTestSuite(t *testing.T) { } func (s *BleveEngineTestSuite) setupIndexes() { - indexDir, err := ioutil.TempDir("", "mmbleve") + indexDir, err := os.MkdirTemp("", "mmbleve") if err != nil { s.Require().FailNow("Cannot setup bleveengine tests: %s", err.Error()) } diff --git a/services/searchengine/bleveengine/indexer/indexing_job_test.go b/services/searchengine/bleveengine/indexer/indexing_job_test.go index 16de60201e..ce6f169306 100644 --- a/services/searchengine/bleveengine/indexer/indexing_job_test.go +++ b/services/searchengine/bleveengine/indexer/indexing_job_test.go @@ -5,7 +5,6 @@ package indexer import ( "errors" - "io/ioutil" "os" "testing" @@ -33,7 +32,7 @@ func TestBleveIndexer(t *testing.T) { mockStore.JobStore.On("UpdateOptimistically", job, model.JobStatusInProgress).Return(true, nil) mockStore.PostStore.On("GetOldestEntityCreationTime").Return(int64(1), errors.New("")) // intentionally return error to return from function - tempDir, err := ioutil.TempDir("", "setupConfigFile") + tempDir, err := os.MkdirTemp("", "setupConfigFile") require.NoError(t, err) t.Cleanup(func() { diff --git a/services/telemetry/telemetry_test.go b/services/telemetry/telemetry_test.go index cd5d0626aa..31ab7656ad 100644 --- a/services/telemetry/telemetry_test.go +++ b/services/telemetry/telemetry_test.go @@ -9,7 +9,7 @@ import ( "encoding/json" "errors" "fmt" - "io/ioutil" + "io" "net/http" "net/http/httptest" "os" @@ -108,7 +108,7 @@ func makeTelemetryServiceAndReceiver(t *testing.T, cloudLicense bool) (*Telemetr pchan := make(chan testTelemetryPayload, 100) receiver := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - body, err := ioutil.ReadAll(r.Body) + body, err := io.ReadAll(r.Body) require.NoError(t, err) var p testTelemetryPayload @@ -154,8 +154,8 @@ func initializeMocks(cfg *model.Config, cloudLicense bool) (*mocks.ServerIface, serverIfaceMock.On("Config").Return(cfg) serverIfaceMock.On("IsLeader").Return(true) - pluginDir, _ := ioutil.TempDir("", "") - webappPluginDir, _ := ioutil.TempDir("", "") + pluginDir, _ := os.MkdirTemp("", "") + webappPluginDir, _ := os.MkdirTemp("", "") cleanUp := func() { os.RemoveAll(pluginDir) os.RemoveAll(webappPluginDir) diff --git a/services/upgrader/upgrader_linux.go b/services/upgrader/upgrader_linux.go index fa45dd4951..b76c4d2d28 100644 --- a/services/upgrader/upgrader_linux.go +++ b/services/upgrader/upgrader_linux.go @@ -10,7 +10,6 @@ import ( _ "embed" "fmt" "io" - "io/ioutil" "net/http" "os" "os/user" @@ -257,7 +256,7 @@ func download(url string, limit int64) (string, error) { } defer resp.Body.Close() - out, err := ioutil.TempFile("", "*_mattermost.tar.gz") + out, err := os.CreateTemp("", "*_mattermost.tar.gz") if err != nil { return "", err } @@ -310,7 +309,7 @@ func extractBinary(executablePath string, filename string) error { if header.Typeflag == tar.TypeReg && header.Name == "mattermost/bin/mattermost" { permissions := getFilePermissionsOrDefault(executablePath, 0755) - tmpFile, err := ioutil.TempFile(path.Dir(executablePath), "*") + tmpFile, err := os.CreateTemp(path.Dir(executablePath), "*") if err != nil { return err } diff --git a/services/upgrader/upgrader_linux_test.go b/services/upgrader/upgrader_linux_test.go index 43583a243a..73853b3281 100644 --- a/services/upgrader/upgrader_linux_test.go +++ b/services/upgrader/upgrader_linux_test.go @@ -6,7 +6,7 @@ package upgrader import ( "archive/tar" "compress/gzip" - "io/ioutil" + "io" "os" "testing" @@ -75,12 +75,12 @@ func TestGetCurrentVersionTgzURL(t *testing.T) { func TestExtractBinary(t *testing.T) { t.Run("extract from empty file", func(t *testing.T) { - tmpMockTarGz, err := ioutil.TempFile("", "mock_tgz") + tmpMockTarGz, err := os.CreateTemp("", "mock_tgz") require.NoError(t, err) defer os.Remove(tmpMockTarGz.Name()) tmpMockTarGz.Close() - tmpMockExecutable, err := ioutil.TempFile("", "mock_exe") + tmpMockExecutable, err := os.CreateTemp("", "mock_exe") require.NoError(t, err) defer os.Remove(tmpMockExecutable.Name()) tmpMockExecutable.Close() @@ -89,7 +89,7 @@ func TestExtractBinary(t *testing.T) { }) t.Run("extract from empty tar.gz file", func(t *testing.T) { - tmpMockTarGz, err := ioutil.TempFile("", "mock_tgz") + tmpMockTarGz, err := os.CreateTemp("", "mock_tgz") require.NoError(t, err) defer os.Remove(tmpMockTarGz.Name()) gz := gzip.NewWriter(tmpMockTarGz) @@ -98,7 +98,7 @@ func TestExtractBinary(t *testing.T) { gz.Close() tmpMockTarGz.Close() - tmpMockExecutable, err := ioutil.TempFile("", "mock_exe") + tmpMockExecutable, err := os.CreateTemp("", "mock_exe") require.NoError(t, err) defer os.Remove(tmpMockExecutable.Name()) tmpMockExecutable.Close() @@ -107,7 +107,7 @@ func TestExtractBinary(t *testing.T) { }) t.Run("extract from tar.gz without mattermost/bin/mattermost file", func(t *testing.T) { - tmpMockTarGz, err := ioutil.TempFile("", "mock_tgz") + tmpMockTarGz, err := os.CreateTemp("", "mock_tgz") require.NoError(t, err) defer os.Remove(tmpMockTarGz.Name()) gz := gzip.NewWriter(tmpMockTarGz) @@ -123,7 +123,7 @@ func TestExtractBinary(t *testing.T) { gz.Close() tmpMockTarGz.Close() - tmpMockExecutable, err := ioutil.TempFile("", "mock_exe") + tmpMockExecutable, err := os.CreateTemp("", "mock_exe") require.NoError(t, err) defer os.Remove(tmpMockExecutable.Name()) tmpMockExecutable.Close() @@ -132,7 +132,7 @@ func TestExtractBinary(t *testing.T) { }) t.Run("extract from tar.gz with mattermost/bin/mattermost file", func(t *testing.T) { - tmpMockTarGz, err := ioutil.TempFile("", "mock_tgz") + tmpMockTarGz, err := os.CreateTemp("", "mock_tgz") require.NoError(t, err) defer os.Remove(tmpMockTarGz.Name()) gz := gzip.NewWriter(tmpMockTarGz) @@ -148,7 +148,7 @@ func TestExtractBinary(t *testing.T) { gz.Close() tmpMockTarGz.Close() - tmpMockExecutable, err := ioutil.TempFile("", "mock_exe") + tmpMockExecutable, err := os.CreateTemp("", "mock_exe") require.NoError(t, err) defer os.Remove(tmpMockExecutable.Name()) tmpMockExecutable.Close() @@ -157,7 +157,7 @@ func TestExtractBinary(t *testing.T) { tmpMockExecutableAfter, err := os.Open(tmpMockExecutable.Name()) require.NoError(t, err) defer tmpMockExecutableAfter.Close() - bytes, err := ioutil.ReadAll(tmpMockExecutableAfter) + bytes, err := io.ReadAll(tmpMockExecutableAfter) require.NoError(t, err) require.Equal(t, []byte("test"), bytes) }) diff --git a/shared/filestore/filesstore_test.go b/shared/filestore/filesstore_test.go index 662b2ef150..ea8dae2435 100644 --- a/shared/filestore/filesstore_test.go +++ b/shared/filestore/filesstore_test.go @@ -6,7 +6,6 @@ package filestore import ( "bytes" "fmt" - "io/ioutil" "math/rand" "os" "testing" @@ -38,7 +37,7 @@ func TestLocalFileBackendTestSuite(t *testing.T) { mlog.InitGlobalLogger(logger) - dir, err := ioutil.TempDir("", "") + dir, err := os.MkdirTemp("", "") require.NoError(t, err) defer os.RemoveAll(dir) diff --git a/shared/filestore/localstore.go b/shared/filestore/localstore.go index e2d53e4942..1a21305bda 100644 --- a/shared/filestore/localstore.go +++ b/shared/filestore/localstore.go @@ -6,7 +6,6 @@ package filestore import ( "bytes" "io" - "io/ioutil" "os" "path/filepath" "time" @@ -88,7 +87,7 @@ func (b *LocalFileBackend) Reader(path string) (ReadCloseSeeker, error) { } func (b *LocalFileBackend) ReadFile(path string) ([]byte, error) { - f, err := ioutil.ReadFile(filepath.Join(b.directory, path)) + f, err := os.ReadFile(filepath.Join(b.directory, path)) if err != nil { return nil, errors.Wrapf(err, "unable to read file %s", path) } diff --git a/shared/filestore/s3store.go b/shared/filestore/s3store.go index c8738a7b5a..1cdaddd812 100644 --- a/shared/filestore/s3store.go +++ b/shared/filestore/s3store.go @@ -8,7 +8,6 @@ import ( "context" "crypto/tls" "io" - "io/ioutil" "net/http" "os" "path/filepath" @@ -241,7 +240,7 @@ func (b *S3FileBackend) ReadFile(path string) ([]byte, error) { } defer minioObject.Close() - f, err := ioutil.ReadAll(minioObject) + f, err := io.ReadAll(minioObject) if err != nil { return nil, errors.Wrapf(err, "unable to read file %s", path) } diff --git a/shared/i18n/i18n.go b/shared/i18n/i18n.go index 42108b38b4..5bf0f13bfe 100644 --- a/shared/i18n/i18n.go +++ b/shared/i18n/i18n.go @@ -6,8 +6,8 @@ package i18n import ( "fmt" "html/template" - "io/ioutil" "net/http" + "os" "path/filepath" "reflect" "strings" @@ -59,7 +59,7 @@ func InitTranslations(serverLocale, clientLocale string) error { } func initTranslationsWithDir(dir string) error { - files, _ := ioutil.ReadDir(dir) + files, _ := os.ReadDir(dir) for _, f := range files { if filepath.Ext(f.Name()) == ".json" { filename := f.Name() diff --git a/shared/mail/mail_test.go b/shared/mail/mail_test.go index 207da90442..ff5c0cd71c 100644 --- a/shared/mail/mail_test.go +++ b/shared/mail/mail_test.go @@ -7,7 +7,6 @@ import ( "bytes" "context" "io" - "io/ioutil" "net" "net/mail" "net/smtp" @@ -195,12 +194,12 @@ func TestSendMailUsingConfigAdvanced(t *testing.T) { DeleteMailBox("test2@example.com") // create two files with the same name that will both be attached to the email - file1, err := ioutil.TempFile("", "*") + file1, err := os.CreateTemp("", "*") require.NoError(t, err) defer os.Remove(file1.Name()) file1.Write([]byte("hello world")) file1.Close() - file2, err := ioutil.TempFile("", "*") + file2, err := os.CreateTemp("", "*") require.NoError(t, err) defer os.Remove(file2.Name()) @@ -326,7 +325,7 @@ func (m *mockMailer) Write(p []byte) (int, error) { func (m *mockMailer) Close() error { return nil } func TestSendMail(t *testing.T) { - dir, err := ioutil.TempDir(".", "mail-test-") + dir, err := os.MkdirTemp(".", "mail-test-") require.NoError(t, err) defer os.RemoveAll(dir) mocm := &mockMailer{} diff --git a/shared/mlog/global_test.go b/shared/mlog/global_test.go index 3fae371f76..d97b3b15a3 100644 --- a/shared/mlog/global_test.go +++ b/shared/mlog/global_test.go @@ -6,7 +6,6 @@ package mlog_test import ( "encoding/json" "fmt" - "io/ioutil" "os" "path/filepath" "regexp" @@ -99,7 +98,7 @@ func TestLoggingAfterInitialized(t *testing.T) { t.Run(testCase.description, func(t *testing.T) { var filePath string if testCase.cfg.Type == "file" { - tempDir, err := ioutil.TempDir(os.TempDir(), "TestLoggingAfterInitialized") + tempDir, err := os.MkdirTemp(os.TempDir(), "TestLoggingAfterInitialized") require.NoError(t, err) defer os.Remove(tempDir) @@ -122,7 +121,7 @@ func TestLoggingAfterInitialized(t *testing.T) { logger.Shutdown() if testCase.cfg.Type == "file" { - logs, err := ioutil.ReadFile(filePath) + logs, err := os.ReadFile(filePath) require.NoError(t, err) actual := strings.TrimSpace(string(logs)) diff --git a/shared/mlog/mlog.go b/shared/mlog/mlog.go index 8618b28352..060f3cd302 100644 --- a/shared/mlog/mlog.go +++ b/shared/mlog/mlog.go @@ -10,7 +10,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "log" "os" "strings" @@ -181,12 +180,14 @@ func NewLogger(options ...Option) (*Logger, error) { // Configure provides a new configuration for this logger. // Zero or more sources of config can be provided: -// cfgFile - path to file containing JSON -// cfgEscaped - JSON string probably from ENV var +// +// cfgFile - path to file containing JSON +// cfgEscaped - JSON string probably from ENV var // // For each case JSON containing log targets is provided. Target name collisions are resolved // using the following precedence: -// cfgFile > cfgEscaped +// +// cfgFile > cfgEscaped // // An optional set of factories can be provided which will be called to create any target // types or formatters not built-in. @@ -199,7 +200,7 @@ func (l *Logger) Configure(cfgFile string, cfgEscaped string, factories *Factori // Add config from file if cfgFile != "" { - b, err := ioutil.ReadFile(cfgFile) + b, err := os.ReadFile(cfgFile) if err != nil { return fmt.Errorf("error reading logger config file %s: %w", cfgFile, err) } diff --git a/shared/templates/templates_test.go b/shared/templates/templates_test.go index f847790cfe..4a11207db9 100644 --- a/shared/templates/templates_test.go +++ b/shared/templates/templates_test.go @@ -6,7 +6,6 @@ package templates import ( "bytes" "html/template" - "io/ioutil" "os" "path/filepath" "testing" @@ -17,12 +16,12 @@ import ( ) func TestHTMLTemplateWatcher(t *testing.T) { - dir, err := ioutil.TempDir("", "") + dir, err := os.MkdirTemp("", "") require.NoError(t, err) defer os.RemoveAll(dir) require.NoError(t, os.Mkdir(filepath.Join(dir, "templates"), 0700)) - require.NoError(t, ioutil.WriteFile(filepath.Join(dir, "templates", "foo.html"), []byte(`{{ define "foo" }}foo{{ end }}`), 0600)) + require.NoError(t, os.WriteFile(filepath.Join(dir, "templates", "foo.html"), []byte(`{{ define "foo" }}foo{{ end }}`), 0600)) prevDir, err := os.Getwd() require.NoError(t, err) @@ -45,7 +44,7 @@ func TestHTMLTemplateWatcher(t *testing.T) { require.NoError(t, err) assert.Equal(t, "foo", text) - require.NoError(t, ioutil.WriteFile(filepath.Join(dir, "templates", "foo.html"), []byte(`{{ define "foo" }}bar{{ end }}`), 0600)) + require.NoError(t, os.WriteFile(filepath.Join(dir, "templates", "foo.html"), []byte(`{{ define "foo" }}bar{{ end }}`), 0600)) require.Eventually(t, func() bool { text, err := watcher.RenderToString("foo", Data{}) diff --git a/store/layer_generators/main.go b/store/layer_generators/main.go index 28b015ac0c..cfb95abdb8 100644 --- a/store/layer_generators/main.go +++ b/store/layer_generators/main.go @@ -10,7 +10,7 @@ import ( "go/format" "go/parser" "go/token" - "io/ioutil" + "io" "log" "os" "path" @@ -49,7 +49,7 @@ func buildRetryLayer() error { return err } - return ioutil.WriteFile(path.Join("retrylayer/retrylayer.go"), formatedCode, 0644) + return os.WriteFile(path.Join("retrylayer/retrylayer.go"), formatedCode, 0644) } func buildTimerLayer() error { @@ -62,7 +62,7 @@ func buildTimerLayer() error { return err } - return ioutil.WriteFile(path.Join("timerlayer", "timerlayer.go"), formatedCode, 0644) + return os.WriteFile(path.Join("timerlayer", "timerlayer.go"), formatedCode, 0644) } func buildOpenTracingLayer() error { @@ -75,7 +75,7 @@ func buildOpenTracingLayer() error { return err } - return ioutil.WriteFile(path.Join("opentracinglayer", "opentracinglayer.go"), formatedCode, 0644) + return os.WriteFile(path.Join("opentracinglayer", "opentracinglayer.go"), formatedCode, 0644) } type methodParam struct { @@ -155,7 +155,7 @@ func extractStoreMetadata() (*storeMetadata, error) { if err != nil { return nil, fmt.Errorf("unable to open store/store.go file: %w", err) } - src, err := ioutil.ReadAll(file) + src, err := io.ReadAll(file) if err != nil { return nil, err } diff --git a/testlib/helper.go b/testlib/helper.go index c28d998bfd..e4b4021404 100644 --- a/testlib/helper.go +++ b/testlib/helper.go @@ -6,7 +6,6 @@ package testlib import ( "flag" "fmt" - "io/ioutil" "log" "os" "path/filepath" @@ -164,7 +163,7 @@ func (h *MainHelper) PreloadMigrations() { } else { finalPath = filepath.Join("mattermost-server", relPath, "postgres_migration_warmup.sql") } - buf, err = ioutil.ReadFile(finalPath) + buf, err = os.ReadFile(finalPath) if err != nil { panic(fmt.Errorf("cannot read file: %v", err)) } @@ -175,7 +174,7 @@ func (h *MainHelper) PreloadMigrations() { } else { finalPath = filepath.Join("mattermost-server", relPath, "mysql_migration_warmup.sql") } - buf, err = ioutil.ReadFile(finalPath) + buf, err = os.ReadFile(finalPath) if err != nil { panic(fmt.Errorf("cannot read file: %v", err)) } diff --git a/testlib/resources.go b/testlib/resources.go index 716692a447..15bc08bc5d 100644 --- a/testlib/resources.go +++ b/testlib/resources.go @@ -6,7 +6,6 @@ package testlib import ( "encoding/json" "fmt" - "io/ioutil" "os" "path" "path/filepath" @@ -116,7 +115,7 @@ func CopyFile(src, dst string) error { func SetupTestResources() (string, error) { testResourcesToSetup := getTestResourcesToSetup() - tempDir, err := ioutil.TempDir("", "testlib") + tempDir, err := os.MkdirTemp("", "testlib") if err != nil { return "", errors.Wrap(err, "failed to create temporary directory") } @@ -195,7 +194,7 @@ func setupConfig(configDir string) error { } configJSON := path.Join(configDir, "config.json") - err = ioutil.WriteFile(configJSON, buf, 0644) + err = os.WriteFile(configJSON, buf, 0644) if err != nil { return errors.Wrapf(err, "failed to write config to %s", configJSON) } diff --git a/utils/archive_test.go b/utils/archive_test.go index 37444311ab..576c4e91f9 100644 --- a/utils/archive_test.go +++ b/utils/archive_test.go @@ -6,7 +6,6 @@ package utils import ( "archive/zip" "errors" - "io/ioutil" "os" "path/filepath" "testing" @@ -90,7 +89,7 @@ func TestUnzipToPath(t *testing.T) { testDir, _ := fileutils.FindDir("tests") require.NotEmpty(t, testDir) - dir, err := ioutil.TempDir("", "unzip") + dir, err := os.MkdirTemp("", "unzip") require.NoError(t, err) defer os.RemoveAll(dir) diff --git a/utils/file.go b/utils/file.go index 175aa9ac21..4338f51508 100644 --- a/utils/file.go +++ b/utils/file.go @@ -7,7 +7,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "os" "path/filepath" ) @@ -85,7 +84,7 @@ func CopyDir(src string, dst string) (err error) { return } - items, err := ioutil.ReadDir(src) + items, err := os.ReadDir(src) if err != nil { return } @@ -100,7 +99,12 @@ func CopyDir(src string, dst string) (err error) { return } } else { - if item.Mode()&os.ModeSymlink != 0 { + info, ierr := item.Info() + if ierr != nil { + continue + } + + if info.Mode()&os.ModeSymlink != 0 { continue } diff --git a/utils/file_test.go b/utils/file_test.go index e74c273cb7..f41c092c42 100644 --- a/utils/file_test.go +++ b/utils/file_test.go @@ -7,7 +7,6 @@ import ( "bytes" "crypto/rand" "io" - "io/ioutil" "os" "path/filepath" "testing" @@ -17,18 +16,18 @@ import ( ) func TestCopyDir(t *testing.T) { - srcDir, err := ioutil.TempDir("", "src") + srcDir, err := os.MkdirTemp("", "src") require.NoError(t, err) defer os.RemoveAll(srcDir) - dstParentDir, err := ioutil.TempDir("", "dstparent") + dstParentDir, err := os.MkdirTemp("", "dstparent") require.NoError(t, err) defer os.RemoveAll(dstParentDir) dstDir := filepath.Join(dstParentDir, "dst") tempFile := "temp.txt" - err = ioutil.WriteFile(filepath.Join(srcDir, tempFile), []byte("test file"), 0655) + err = os.WriteFile(filepath.Join(srcDir, tempFile), []byte("test file"), 0655) require.NoError(t, err) childDir := "child" @@ -36,7 +35,7 @@ func TestCopyDir(t *testing.T) { require.NoError(t, err) childTempFile := "childtemp.txt" - err = ioutil.WriteFile(filepath.Join(srcDir, childDir, childTempFile), []byte("test file"), 0755) + err = os.WriteFile(filepath.Join(srcDir, childDir, childTempFile), []byte("test file"), 0755) require.NoError(t, err) err = CopyDir(srcDir, dstDir) @@ -46,7 +45,7 @@ func TestCopyDir(t *testing.T) { assert.NoError(t, err) assert.Equal(t, uint32(0655), uint32(stat.Mode())) assert.False(t, stat.IsDir()) - data, err := ioutil.ReadFile(filepath.Join(dstDir, tempFile)) + data, err := os.ReadFile(filepath.Join(dstDir, tempFile)) assert.NoError(t, err) assert.Equal(t, "test file", string(data)) @@ -58,7 +57,7 @@ func TestCopyDir(t *testing.T) { assert.NoError(t, err) assert.Equal(t, uint32(0755), uint32(stat.Mode())) assert.False(t, stat.IsDir()) - data, err = ioutil.ReadFile(filepath.Join(dstDir, childDir, childTempFile)) + data, err = os.ReadFile(filepath.Join(dstDir, childDir, childTempFile)) assert.NoError(t, err) assert.Equal(t, "test file", string(data)) diff --git a/utils/fileutils/fileutils_test.go b/utils/fileutils/fileutils_test.go index 93dcfffd10..c223586443 100644 --- a/utils/fileutils/fileutils_test.go +++ b/utils/fileutils/fileutils_test.go @@ -5,7 +5,6 @@ package fileutils import ( "fmt" - "io/ioutil" "os" "path/filepath" "testing" @@ -26,23 +25,23 @@ func TestFindFile(t *testing.T) { // tmpDir3/ // tmpDir4/ // tmpDir5/ - tmpDir1, err := ioutil.TempDir("", "") + tmpDir1, err := os.MkdirTemp("", "") require.NoError(t, err) defer os.RemoveAll(tmpDir1) - tmpDir2, err := ioutil.TempDir(tmpDir1, "") + tmpDir2, err := os.MkdirTemp(tmpDir1, "") require.NoError(t, err) err = os.Mkdir(filepath.Join(tmpDir2, "other.txt"), 0700) require.NoError(t, err) - tmpDir3, err := ioutil.TempDir(tmpDir2, "") + tmpDir3, err := os.MkdirTemp(tmpDir2, "") require.NoError(t, err) - tmpDir4, err := ioutil.TempDir(tmpDir3, "") + tmpDir4, err := os.MkdirTemp(tmpDir3, "") require.NoError(t, err) - tmpDir5, err := ioutil.TempDir(tmpDir4, "") + tmpDir5, err := os.MkdirTemp(tmpDir4, "") require.NoError(t, err) type testCase struct { @@ -56,7 +55,7 @@ func TestFindFile(t *testing.T) { for _, fileName := range []string{"file1.json", "file2.xml", "other.txt"} { filePath := filepath.Join(tmpDir1, fileName) - require.NoError(t, ioutil.WriteFile(filePath, []byte("{}"), 0600)) + require.NoError(t, os.WriteFile(filePath, []byte("{}"), 0600)) // Relative paths end up getting symlinks fully resolved, so use this below as necessary. filePathResolved, err := filepath.EvalSymlinks(filePath) diff --git a/utils/license.go b/utils/license.go index 96a228ba8e..c18b9fad7f 100644 --- a/utils/license.go +++ b/utils/license.go @@ -11,7 +11,7 @@ import ( "encoding/base64" "encoding/json" "encoding/pem" - "io/ioutil" + "io" "net/http" "os" "path/filepath" @@ -141,7 +141,7 @@ func GetLicenseFileFromDisk(fileName string) []byte { } defer file.Close() - licenseBytes, err := ioutil.ReadAll(file) + licenseBytes, err := io.ReadAll(file) if err != nil { mlog.Error("Failed to read license key from disk at", mlog.String("filename", fileName), mlog.Err(err)) return nil diff --git a/utils/license_test.go b/utils/license_test.go index c32faa044f..8c57685444 100644 --- a/utils/license_test.go +++ b/utils/license_test.go @@ -6,7 +6,6 @@ package utils import ( "bytes" "encoding/base64" - "io/ioutil" "os" "testing" @@ -80,10 +79,10 @@ func TestGetLicenseFileFromDisk(t *testing.T) { }) t.Run("not a license file", func(t *testing.T) { - f, err := ioutil.TempFile("", "TestGetLicenseFileFromDisk") + f, err := os.CreateTemp("", "TestGetLicenseFileFromDisk") require.NoError(t, err) defer os.Remove(f.Name()) - ioutil.WriteFile(f.Name(), []byte("not a license"), 0777) + os.WriteFile(f.Name(), []byte("not a license"), 0777) fileBytes := GetLicenseFileFromDisk(f.Name()) require.NotEmpty(t, fileBytes, "should have read the file") diff --git a/utils/subpath.go b/utils/subpath.go index 078527244c..f70b299472 100644 --- a/utils/subpath.go +++ b/utils/subpath.go @@ -7,7 +7,6 @@ import ( "crypto/sha256" "encoding/base64" "fmt" - "io/ioutil" "net/url" "os" "path" @@ -63,7 +62,7 @@ func UpdateAssetsSubpathInDir(subpath, directory string) error { } rootHTMLPath := filepath.Join(staticDir, "root.html") - oldRootHTML, err := ioutil.ReadFile(rootHTMLPath) + oldRootHTML, err := os.ReadFile(rootHTMLPath) if err != nil { return errors.Wrap(err, "failed to open root.html") } @@ -113,19 +112,19 @@ func UpdateAssetsSubpathInDir(subpath, directory string) error { } // Write out the updated root.html. - if err = ioutil.WriteFile(rootHTMLPath, []byte(newRootHTML), 0); err != nil { + if err = os.WriteFile(rootHTMLPath, []byte(newRootHTML), 0); err != nil { return errors.Wrapf(err, "failed to update root.html with subpath %s", subpath) } // Rewrite the manifest.json and *.css references to `/static/*` (or a previously rewritten subpath). err = filepath.Walk(staticDir, func(walkPath string, info os.FileInfo, err error) error { if filepath.Base(walkPath) == "manifest.json" || filepath.Ext(walkPath) == ".css" { - old, err := ioutil.ReadFile(walkPath) + old, err := os.ReadFile(walkPath) if err != nil { return errors.Wrapf(err, "failed to open %s", walkPath) } new := strings.Replace(string(old), pathToReplace, newPath, -1) - if err = ioutil.WriteFile(walkPath, []byte(new), 0); err != nil { + if err = os.WriteFile(walkPath, []byte(new), 0); err != nil { return errors.Wrapf(err, "failed to update %s with subpath %s", walkPath, subpath) } } diff --git a/utils/subpath_test.go b/utils/subpath_test.go index efc9c383e3..85724aabaa 100644 --- a/utils/subpath_test.go +++ b/utils/subpath_test.go @@ -5,7 +5,6 @@ package utils_test import ( "fmt" - "io/ioutil" "os" "path/filepath" "strings" @@ -41,7 +40,7 @@ func TestUpdateAssetsSubpathFromConfig(t *testing.T) { }) t.Run("no config", func(t *testing.T) { - tempDir, err := ioutil.TempDir("", "test_update_assets_subpath") + tempDir, err := os.MkdirTemp("", "test_update_assets_subpath") require.NoError(t, err) defer os.RemoveAll(tempDir) os.Chdir(tempDir) @@ -53,7 +52,7 @@ func TestUpdateAssetsSubpathFromConfig(t *testing.T) { func TestUpdateAssetsSubpath(t *testing.T) { t.Run("no client dir", func(t *testing.T) { - tempDir, err := ioutil.TempDir("", "test_update_assets_subpath") + tempDir, err := os.MkdirTemp("", "test_update_assets_subpath") require.NoError(t, err) defer os.RemoveAll(tempDir) os.Chdir(tempDir) @@ -63,7 +62,7 @@ func TestUpdateAssetsSubpath(t *testing.T) { }) t.Run("valid", func(t *testing.T) { - tempDir, err := ioutil.TempDir("", "test_update_assets_subpath") + tempDir, err := os.MkdirTemp("", "test_update_assets_subpath") require.NoError(t, err) defer os.RemoveAll(tempDir) os.Chdir(tempDir) @@ -163,9 +162,9 @@ func TestUpdateAssetsSubpath(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.Description, func(t *testing.T) { - ioutil.WriteFile(filepath.Join(tempDir, model.ClientDir, "root.html"), []byte(testCase.RootHTML), 0700) - ioutil.WriteFile(filepath.Join(tempDir, model.ClientDir, "main.css"), []byte(testCase.MainCSS), 0700) - ioutil.WriteFile(filepath.Join(tempDir, model.ClientDir, "manifest.json"), []byte(testCase.ManifestJSON), 0700) + os.WriteFile(filepath.Join(tempDir, model.ClientDir, "root.html"), []byte(testCase.RootHTML), 0700) + os.WriteFile(filepath.Join(tempDir, model.ClientDir, "main.css"), []byte(testCase.MainCSS), 0700) + os.WriteFile(filepath.Join(tempDir, model.ClientDir, "manifest.json"), []byte(testCase.ManifestJSON), 0700) err := utils.UpdateAssetsSubpath(testCase.Subpath) if testCase.ExpectedError != nil { require.Equal(t, testCase.ExpectedError, err) @@ -173,7 +172,7 @@ func TestUpdateAssetsSubpath(t *testing.T) { require.NoError(t, err) } - contents, err := ioutil.ReadFile(filepath.Join(tempDir, model.ClientDir, "root.html")) + contents, err := os.ReadFile(filepath.Join(tempDir, model.ClientDir, "root.html")) require.NoError(t, err) // Rewrite the expected and contents for simpler diffs when failed. @@ -181,11 +180,11 @@ func TestUpdateAssetsSubpath(t *testing.T) { contentsStr := strings.Replace(string(contents), ">", ">\n", -1) require.Equal(t, expectedRootHTML, contentsStr) - contents, err = ioutil.ReadFile(filepath.Join(tempDir, model.ClientDir, "main.css")) + contents, err = os.ReadFile(filepath.Join(tempDir, model.ClientDir, "main.css")) require.NoError(t, err) require.Equal(t, testCase.ExpectedMainCSS, string(contents)) - contents, err = ioutil.ReadFile(filepath.Join(tempDir, model.ClientDir, "manifest.json")) + contents, err = os.ReadFile(filepath.Join(tempDir, model.ClientDir, "manifest.json")) require.NoError(t, err) require.Equal(t, testCase.ExpectedManifestJSON, string(contents)) }) diff --git a/utils/test_files_compiler.go b/utils/test_files_compiler.go index 77ad84ce02..904cb4b6e9 100644 --- a/utils/test_files_compiler.go +++ b/utils/test_files_compiler.go @@ -5,7 +5,6 @@ package utils import ( "bytes" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -16,7 +15,7 @@ import ( ) func CompileGo(t *testing.T, sourceCode, outputPath string) { - dir, err := ioutil.TempDir(".", "") + dir, err := os.MkdirTemp(".", "") require.NoError(t, err) defer os.RemoveAll(dir) @@ -25,7 +24,7 @@ func CompileGo(t *testing.T, sourceCode, outputPath string) { // Write out main.go given the source code. main := filepath.Join(dir, "main.go") - err = ioutil.WriteFile(main, []byte(sourceCode), 0600) + err = os.WriteFile(main, []byte(sourceCode), 0600) require.NoError(t, err) _, sourceFile, _, ok := runtime.Caller(0) @@ -45,7 +44,7 @@ func CompileGo(t *testing.T, sourceCode, outputPath string) { } func CompileGoTest(t *testing.T, sourceCode, outputPath string) { - dir, err := ioutil.TempDir(".", "") + dir, err := os.MkdirTemp(".", "") require.NoError(t, err) defer os.RemoveAll(dir) @@ -54,7 +53,7 @@ func CompileGoTest(t *testing.T, sourceCode, outputPath string) { // Write out main.go given the source code. main := filepath.Join(dir, "main_test.go") - err = ioutil.WriteFile(main, []byte(sourceCode), 0600) + err = os.WriteFile(main, []byte(sourceCode), 0600) require.NoError(t, err) _, sourceFile, _, ok := runtime.Caller(0) diff --git a/utils/utils.go b/utils/utils.go index 9fad79e6d7..cf53e19f55 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -4,7 +4,7 @@ package utils import ( - "io/ioutil" + "io" "math" "net" "net/http" @@ -165,7 +165,7 @@ func GetURLWithCache(url string, cache *RequestCache, skip bool) ([]byte, error) return nil, errors.Errorf("Fetching notices failed with status code %d", resp.StatusCode) } - cache.Data, err = ioutil.ReadAll(resp.Body) + cache.Data, err = io.ReadAll(resp.Body) if err != nil { cache.Data = nil return nil, err diff --git a/web/oauth_test.go b/web/oauth_test.go index d8513d1579..1f8c610cc5 100644 --- a/web/oauth_test.go +++ b/web/oauth_test.go @@ -8,7 +8,6 @@ import ( "encoding/base64" "encoding/json" "io" - "io/ioutil" "net/http" "net/http/httptest" "net/url" @@ -636,7 +635,7 @@ func HTTPGet(url string, httpClient *http.Client, authToken string, followRedire func closeBody(r *http.Response) { if r != nil && r.Body != nil { - ioutil.ReadAll(r.Body) + io.ReadAll(r.Body) r.Body.Close() } } diff --git a/web/web_test.go b/web/web_test.go index d31503560e..d68abdf754 100644 --- a/web/web_test.go +++ b/web/web_test.go @@ -5,7 +5,6 @@ package web import ( "fmt" - "io/ioutil" "net/http" "net/http/httptest" "os" @@ -218,12 +217,12 @@ func TestStaticFilesRequest(t *testing.T) { mainJS := `var x = alert();` mainJSPath := filepath.Join(pluginDir, "main.js") require.NoError(t, err) - err = ioutil.WriteFile(mainJSPath, []byte(mainJS), 0777) + err = os.WriteFile(mainJSPath, []byte(mainJS), 0777) require.NoError(t, err) // Write the plugin.json manifest pluginManifest := `{"id": "com.mattermost.sample", "server": {"executable": "backend.exe"}, "webapp": {"bundle_path":"main.js"}, "settings_schema": {"settings": []}}` - ioutil.WriteFile(filepath.Join(pluginDir, "plugin.json"), []byte(pluginManifest), 0600) + os.WriteFile(filepath.Join(pluginDir, "plugin.json"), []byte(pluginManifest), 0600) // Activate the plugin manifest, activated, reterr := th.App.GetPluginsEnvironment().Activate(pluginID) @@ -272,9 +271,9 @@ func TestPublicFilesRequest(t *testing.T) { th := Setup(t).InitPlugins() defer th.TearDown() - pluginDir, err := ioutil.TempDir("", "") + pluginDir, err := os.MkdirTemp("", "") require.NoError(t, err) - webappPluginDir, err := ioutil.TempDir("", "") + webappPluginDir, err := os.MkdirTemp("", "") require.NoError(t, err) defer os.RemoveAll(pluginDir) defer os.RemoveAll(webappPluginDir) @@ -306,7 +305,7 @@ func TestPublicFilesRequest(t *testing.T) { // Write the plugin.json manifest pluginManifest := `{"id": "com.mattermost.sample", "server": {"executable": "backend.exe"}, "settings_schema": {"settings": []}}` - ioutil.WriteFile(filepath.Join(pluginDir, pluginID, "plugin.json"), []byte(pluginManifest), 0600) + os.WriteFile(filepath.Join(pluginDir, pluginID, "plugin.json"), []byte(pluginManifest), 0600) // Write the test public file helloHTML := `Hello from the static files public folder for the com.mattermost.sample plugin!` @@ -314,11 +313,11 @@ func TestPublicFilesRequest(t *testing.T) { os.MkdirAll(htmlFolderPath, os.ModePerm) htmlFilePath := filepath.Join(htmlFolderPath, "hello.html") - htmlFileErr := ioutil.WriteFile(htmlFilePath, []byte(helloHTML), 0600) + htmlFileErr := os.WriteFile(htmlFilePath, []byte(helloHTML), 0600) assert.NoError(t, htmlFileErr) nefariousHTML := `You shouldn't be able to get here!` - htmlFileErr = ioutil.WriteFile(filepath.Join(pluginDir, pluginID, "nefarious-file-access.html"), []byte(nefariousHTML), 0600) + htmlFileErr = os.WriteFile(filepath.Join(pluginDir, pluginID, "nefarious-file-access.html"), []byte(nefariousHTML), 0600) assert.NoError(t, htmlFileErr) manifest, activated, reterr := env.Activate(pluginID) From f6307be7f49aafa1fea9464d0f83c4783b243db1 Mon Sep 17 00:00:00 2001 From: Christopher Poile Date: Tue, 9 Aug 2022 15:38:00 -0400 Subject: [PATCH 08/10] prepackage calls 0.7.1 (#20788) Co-authored-by: Mattermod --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index d005e85722..3a29ed9e75 100644 --- a/Makefile +++ b/Makefile @@ -149,7 +149,7 @@ TEMPLATES_DIR=templates PLUGIN_PACKAGES ?= mattermost-plugin-antivirus-v0.1.2 PLUGIN_PACKAGES += mattermost-plugin-autolink-v1.2.2 PLUGIN_PACKAGES += mattermost-plugin-aws-SNS-v1.2.0 -PLUGIN_PACKAGES += mattermost-plugin-calls-v0.7.0 +PLUGIN_PACKAGES += mattermost-plugin-calls-v0.7.1 PLUGIN_PACKAGES += mattermost-plugin-channel-export-v1.0.0 PLUGIN_PACKAGES += mattermost-plugin-custom-attributes-v1.3.0 PLUGIN_PACKAGES += mattermost-plugin-github-v2.0.1 From fdee1df6fe3773e2b65de62595720a92be8338a1 Mon Sep 17 00:00:00 2001 From: Jesse Hallam Date: Wed, 10 Aug 2022 01:09:02 -0300 Subject: [PATCH 09/10] Pre-package Playbooks v1.31.0 (#20797) --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 3a29ed9e75..c0f5a19bd8 100644 --- a/Makefile +++ b/Makefile @@ -154,7 +154,7 @@ PLUGIN_PACKAGES += mattermost-plugin-channel-export-v1.0.0 PLUGIN_PACKAGES += mattermost-plugin-custom-attributes-v1.3.0 PLUGIN_PACKAGES += mattermost-plugin-github-v2.0.1 PLUGIN_PACKAGES += mattermost-plugin-gitlab-v1.3.0 -PLUGIN_PACKAGES += mattermost-plugin-playbooks-v1.29.1 +PLUGIN_PACKAGES += mattermost-plugin-playbooks-v1.31.0 PLUGIN_PACKAGES += mattermost-plugin-jenkins-v1.1.0 PLUGIN_PACKAGES += mattermost-plugin-jira-v2.4.0 PLUGIN_PACKAGES += mattermost-plugin-nps-v1.2.0 From 1738bd6e9286e375133956fbf68fef0767d6b7ec Mon Sep 17 00:00:00 2001 From: Tim Scheuermann Date: Wed, 10 Aug 2022 11:56:58 +0300 Subject: [PATCH 10/10] [MM-45991] Check and return JSON errors (#20735) --- api4/channel.go | 48 +- api4/channel_category.go | 59 +- api4/cloud.go | 94 +- api4/cluster.go | 6 +- api4/command.go | 12 +- api4/config.go | 106 +- api4/config_local.go | 44 +- api4/data_retention.go | 118 +- api4/elasticsearch.go | 8 +- api4/export.go | 2 +- api4/group.go | 335 ++--- api4/import.go | 2 +- api4/insights.go | 152 ++- api4/integration_action.go | 17 +- api4/job.go | 25 +- api4/ldap.go | 42 +- api4/oauth.go | 30 +- api4/permission.go | 3 +- api4/plugin.go | 17 +- api4/post.go | 13 +- api4/reaction.go | 25 +- api4/remote_cluster.go | 36 +- api4/role.go | 41 +- api4/scheme.go | 32 +- api4/shared_channel.go | 5 +- api4/status.go | 13 +- api4/system.go | 119 +- api4/system_local.go | 2 +- api4/team.go | 300 +++-- api4/team_local.go | 46 +- api4/usage.go | 18 +- api4/user.go | 344 ++--- api4/user_local.go | 67 +- api4/webhook.go | 87 +- app/channel.go | 116 +- app/channel_category.go | 2 +- app/command_autocomplete.go | 2 +- app/emoji.go | 15 +- app/export.go | 8 +- app/group.go | 61 +- app/import_validators.go | 4 +- app/integration_action.go | 61 +- app/license.go | 14 +- app/notification_push.go | 34 +- app/oauth.go | 2 +- app/post.go | 71 +- app/preference.go | 8 +- app/reaction.go | 6 +- app/security_update_check.go | 2 +- app/slashcommands/command_expand_collapse.go | 6 +- app/slashcommands/command_loadtest.go | 2 +- app/status.go | 50 +- app/user.go | 16 +- app/webhook.go | 12 +- .../advanced_permissions_phase_2.go | 22 +- model/channel.go | 1 - model/client4.go | 1130 +++++++++-------- model/preference.go | 14 +- model/utils.go | 30 +- services/slackimport/parsers.go | 4 +- shared/filestore/filesstore_test.go | 19 +- shared/mail/mail.go | 1 - web/context.go | 10 +- web/oauth.go | 4 +- web/webhook.go | 11 +- 65 files changed, 2068 insertions(+), 1938 deletions(-) diff --git a/api4/channel.go b/api4/channel.go index 40372dc068..1bc8c1db06 100644 --- a/api4/channel.go +++ b/api4/channel.go @@ -1891,23 +1891,23 @@ func channelMembersMinusGroupMembers(c *Context, w http.ResponseWriter, r *http. return } - users, totalCount, err := c.App.ChannelMembersMinusGroupMembers( + users, totalCount, appErr := c.App.ChannelMembersMinusGroupMembers( c.Params.ChannelId, groupIDs, c.Params.Page, c.Params.PerPage, ) - if err != nil { - c.Err = err + if appErr != nil { + c.Err = appErr return } - b, marshalErr := json.Marshal(&model.UsersWithGroupsAndCount{ + b, err := json.Marshal(&model.UsersWithGroupsAndCount{ Users: users, Count: totalCount, }) - if marshalErr != nil { - c.Err = model.NewAppError("Api4.channelMembersMinusGroupMembers", "api.marshal_error", nil, marshalErr.Error(), http.StatusInternalServerError) + if err != nil { + c.Err = model.NewAppError("Api4.channelMembersMinusGroupMembers", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } @@ -1932,15 +1932,15 @@ func channelMemberCountsByGroup(c *Context, w http.ResponseWriter, r *http.Reque includeTimezones := r.URL.Query().Get("include_timezones") == "true" - channelMemberCounts, err := c.App.GetMemberCountsByGroup(app.WithMaster(context.Background()), c.Params.ChannelId, includeTimezones) - if err != nil { - c.Err = err + channelMemberCounts, appErr := c.App.GetMemberCountsByGroup(app.WithMaster(context.Background()), c.Params.ChannelId, includeTimezones) + if appErr != nil { + c.Err = appErr return } - b, marshalErr := json.Marshal(channelMemberCounts) - if marshalErr != nil { - c.Err = model.NewAppError("Api4.channelMemberCountsByGroup", "api.marshal_error", nil, marshalErr.Error(), http.StatusInternalServerError) + b, err := json.Marshal(channelMemberCounts) + if err != nil { + c.Err = model.NewAppError("Api4.channelMemberCountsByGroup", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } @@ -1963,21 +1963,21 @@ func getChannelModerations(c *Context, w http.ResponseWriter, r *http.Request) { return } - channel, err := c.App.GetChannel(c.AppContext, c.Params.ChannelId) - if err != nil { - c.Err = err + channel, appErr := c.App.GetChannel(c.AppContext, c.Params.ChannelId) + if appErr != nil { + c.Err = appErr return } - channelModerations, err := c.App.GetChannelModerationsForChannel(c.AppContext, channel) - if err != nil { - c.Err = err + channelModerations, appErr := c.App.GetChannelModerationsForChannel(c.AppContext, channel) + if appErr != nil { + c.Err = appErr return } - b, marshalErr := json.Marshal(channelModerations) - if marshalErr != nil { - c.Err = model.NewAppError("Api4.getChannelModerations", "api.marshal_error", nil, marshalErr.Error(), http.StatusInternalServerError) + b, err := json.Marshal(channelModerations) + if err != nil { + c.Err = model.NewAppError("Api4.getChannelModerations", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } @@ -2024,9 +2024,9 @@ func patchChannelModerations(c *Context, w http.ResponseWriter, r *http.Request) } auditRec.AddEventParameter("patch", channelModerationsPatch) - b, marshalErr := json.Marshal(channelModerations) - if marshalErr != nil { - c.Err = model.NewAppError("Api4.patchChannelModerations", "api.marshal_error", nil, marshalErr.Error(), http.StatusInternalServerError) + b, err := json.Marshal(channelModerations) + if err != nil { + c.Err = model.NewAppError("Api4.patchChannelModerations", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } diff --git a/api4/channel_category.go b/api4/channel_category.go index c92b3ff27b..ce40ef3560 100644 --- a/api4/channel_category.go +++ b/api4/channel_category.go @@ -23,15 +23,15 @@ func getCategoriesForTeamForUser(c *Context, w http.ResponseWriter, r *http.Requ return } - categories, err := c.App.GetSidebarCategoriesForTeamForUser(c.AppContext, c.Params.UserId, c.Params.TeamId) - if err != nil { - c.Err = err + categories, appErr := c.App.GetSidebarCategoriesForTeamForUser(c.AppContext, c.Params.UserId, c.Params.TeamId) + if appErr != nil { + c.Err = appErr return } - categoriesJSON, jsonErr := json.Marshal(categories) - if jsonErr != nil { - c.Err = model.NewAppError("getCategoriesForTeamForUser", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + categoriesJSON, err := json.Marshal(categories) + if err != nil { + c.Err = model.NewAppError("getCategoriesForTeamForUser", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } @@ -70,9 +70,9 @@ func createCategoryForTeamForUser(c *Context, w http.ResponseWriter, r *http.Req return } - categoryJSON, jsonErr := json.Marshal(category) - if jsonErr != nil { - c.Err = model.NewAppError("createCategoryForTeamForUser", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + categoryJSON, err := json.Marshal(category) + if err != nil { + c.Err = model.NewAppError("createCategoryForTeamForUser", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } @@ -92,13 +92,16 @@ func getCategoryOrderForTeamForUser(c *Context, w http.ResponseWriter, r *http.R return } - order, err := c.App.GetSidebarCategoryOrder(c.AppContext, c.Params.UserId, c.Params.TeamId) - if err != nil { - c.Err = err + order, appErr := c.App.GetSidebarCategoryOrder(c.AppContext, c.Params.UserId, c.Params.TeamId) + if appErr != nil { + c.Err = appErr return } - w.Write([]byte(model.ArrayToJSON(order))) + err := json.NewEncoder(w).Encode(order) + if err != nil { + c.Logger.Warn("Error writing response", mlog.Err(err)) + } } func updateCategoryOrderForTeamForUser(c *Context, w http.ResponseWriter, r *http.Request) { @@ -145,15 +148,15 @@ func getCategoryForTeamForUser(c *Context, w http.ResponseWriter, r *http.Reques return } - categories, err := c.App.GetSidebarCategory(c.AppContext, c.Params.CategoryId) - if err != nil { - c.Err = err + categories, appErr := c.App.GetSidebarCategory(c.AppContext, c.Params.CategoryId) + if appErr != nil { + c.Err = appErr return } - categoriesJSON, jsonErr := json.Marshal(categories) - if jsonErr != nil { - c.Err = model.NewAppError("getCategoryForTeamForUser", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + categoriesJSON, err := json.Marshal(categories) + if err != nil { + c.Err = model.NewAppError("getCategoryForTeamForUser", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } @@ -199,9 +202,9 @@ func updateCategoriesForTeamForUser(c *Context, w http.ResponseWriter, r *http.R return } - categoriesJSON, jsonErr := json.Marshal(categories) - if jsonErr != nil { - c.Err = model.NewAppError("updateCategoriesForTeamForUser", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + categoriesJSON, err := json.Marshal(categories) + if err != nil { + c.Err = model.NewAppError("updateCategoriesForTeamForUser", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } @@ -210,12 +213,12 @@ func updateCategoriesForTeamForUser(c *Context, w http.ResponseWriter, r *http.R } func validateSidebarCategory(c *Context, teamId, userId string, category *model.SidebarCategoryWithChannels) *model.AppError { - channels, err := c.App.GetChannelsForTeamForUser(c.AppContext, teamId, userId, &model.ChannelSearchOpts{ + channels, appErr := c.App.GetChannelsForTeamForUser(c.AppContext, teamId, userId, &model.ChannelSearchOpts{ IncludeDeleted: true, LastDeleteAt: 0, }) - if err != nil { - return model.NewAppError("validateSidebarCategory", "api.invalid_channel", nil, err.Error(), http.StatusBadRequest) + if appErr != nil { + return model.NewAppError("validateSidebarCategory", "api.invalid_channel", nil, "", http.StatusBadRequest).Wrap(appErr) } category.Channels = validateSidebarCategoryChannels(c, userId, category.Channels, channels) @@ -295,9 +298,9 @@ func updateCategoryForTeamForUser(c *Context, w http.ResponseWriter, r *http.Req return } - categoryJSON, jsonErr := json.Marshal(categories[0]) - if jsonErr != nil { - c.Err = model.NewAppError("updateCategoryForTeamForUser", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + categoryJSON, err := json.Marshal(categories[0]) + if err != nil { + c.Err = model.NewAppError("updateCategoryForTeamForUser", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } diff --git a/api4/cloud.go b/api4/cloud.go index 6ebeccf706..655eddd4ad 100644 --- a/api4/cloud.go +++ b/api4/cloud.go @@ -105,7 +105,7 @@ func getSubscription(c *Context, w http.ResponseWriter, r *http.Request) { json, err := json.Marshal(subscription) if err != nil { - c.Err = model.NewAppError("Api4.getSubscription", "api.cloud.request_error", nil, err.Error(), http.StatusInternalServerError) + c.Err = model.NewAppError("Api4.getSubscription", "api.cloud.request_error", nil, "", http.StatusInternalServerError).Wrap(err) return } @@ -125,38 +125,38 @@ func changeSubscription(c *Context, w http.ResponseWriter, r *http.Request) { bodyBytes, err := io.ReadAll(r.Body) if err != nil { - c.Err = model.NewAppError("Api4.changeSubscription", "api.cloud.app_error", nil, err.Error(), http.StatusBadRequest) + c.Err = model.NewAppError("Api4.changeSubscription", "api.cloud.app_error", nil, "", http.StatusBadRequest).Wrap(err) return } var subscriptionChange *model.SubscriptionChange if err = json.Unmarshal(bodyBytes, &subscriptionChange); err != nil { - c.Err = model.NewAppError("Api4.changeSubscription", "api.cloud.app_error", nil, err.Error(), http.StatusBadRequest) + c.Err = model.NewAppError("Api4.changeSubscription", "api.cloud.app_error", nil, "", http.StatusBadRequest).Wrap(err) return } currentSubscription, appErr := c.App.Cloud().GetSubscription(c.AppContext.Session().UserId) if appErr != nil { - c.Err = model.NewAppError("Api4.changeSubscription", "api.cloud.app_error", nil, appErr.Error(), http.StatusInternalServerError) + c.Err = model.NewAppError("Api4.changeSubscription", "api.cloud.app_error", nil, "", http.StatusInternalServerError).Wrap(appErr) return } changedSub, err := c.App.Cloud().ChangeSubscription(c.AppContext.Session().UserId, currentSubscription.ID, subscriptionChange) if err != nil { - c.Err = model.NewAppError("Api4.changeSubscription", "api.cloud.app_error", nil, err.Error(), http.StatusInternalServerError) + c.Err = model.NewAppError("Api4.changeSubscription", "api.cloud.app_error", nil, "", http.StatusInternalServerError).Wrap(err) return } json, err := json.Marshal(changedSub) if err != nil { - c.Err = model.NewAppError("Api4.changeSubscription", "api.cloud.app_error", nil, err.Error(), http.StatusInternalServerError) + c.Err = model.NewAppError("Api4.changeSubscription", "api.cloud.app_error", nil, "", http.StatusInternalServerError).Wrap(err) return } // Log failures for purchase confirmation email, but don't show an error to the user so as not to confuse them // At this point, the upgrade is complete. - if nErr := c.App.SendUpgradeConfirmationEmail(); nErr != nil { - c.Logger.Error("Error sending purchase confirmation email") + if appErr := c.App.SendUpgradeConfirmationEmail(); appErr != nil { + c.Logger.Error("Error sending purchase confirmation email", mlog.Err(appErr)) } w.Write(json) @@ -176,26 +176,26 @@ func requestCloudTrial(c *Context, w http.ResponseWriter, r *http.Request) { // check if the email needs to be set bodyBytes, err := io.ReadAll(r.Body) if err != nil { - c.Err = model.NewAppError("Api4.requestCloudTrial", "api.cloud.app_error", nil, err.Error(), http.StatusInternalServerError) + c.Err = model.NewAppError("Api4.requestCloudTrial", "api.cloud.app_error", nil, "", http.StatusInternalServerError).Wrap(err) return } // this value will not be empty when both emails (user admin and CWS customer) are not business email and // we need to request a new email from the user via the request business email modal var startTrialRequest *model.StartCloudTrialRequest if err = json.Unmarshal(bodyBytes, &startTrialRequest); err != nil { - c.Err = model.NewAppError("Api4.requestCloudTrial", "api.cloud.app_error", nil, err.Error(), http.StatusInternalServerError) + c.Err = model.NewAppError("Api4.requestCloudTrial", "api.cloud.app_error", nil, "", http.StatusInternalServerError).Wrap(err) return } changedSub, err := c.App.Cloud().RequestCloudTrial(c.AppContext.Session().UserId, startTrialRequest.SubscriptionID, startTrialRequest.Email) if err != nil { - c.Err = model.NewAppError("Api4.requestCloudTrial", "api.cloud.app_error", nil, err.Error(), http.StatusInternalServerError) + c.Err = model.NewAppError("Api4.requestCloudTrial", "api.cloud.app_error", nil, "", http.StatusInternalServerError).Wrap(err) return } json, err := json.Marshal(changedSub) if err != nil { - c.Err = model.NewAppError("Api4.requestCloudTrial", "api.cloud.app_error", nil, err.Error(), http.StatusInternalServerError) + c.Err = model.NewAppError("Api4.requestCloudTrial", "api.cloud.app_error", nil, "", http.StatusInternalServerError).Wrap(err) return } @@ -215,36 +215,37 @@ func validateBusinessEmail(c *Context, w http.ResponseWriter, r *http.Request) { return } - user, userErr := c.App.GetUser(c.AppContext.Session().UserId) - if userErr != nil { - c.Err = model.NewAppError("Api4.validateBusinessEmail", "api.cloud.request_error", nil, "", http.StatusInternalServerError) + user, appErr := c.App.GetUser(c.AppContext.Session().UserId) + if appErr != nil { + c.Err = model.NewAppError("Api4.validateBusinessEmail", "api.cloud.request_error", nil, "", http.StatusInternalServerError).Wrap(appErr) return } bodyBytes, err := io.ReadAll(r.Body) if err != nil { - c.Err = model.NewAppError("Api4.requestCloudTrial", "api.cloud.app_error", nil, err.Error(), http.StatusInternalServerError) + c.Err = model.NewAppError("Api4.requestCloudTrial", "api.cloud.app_error", nil, "", http.StatusInternalServerError).Wrap(err) return } var emailToValidate *model.ValidateBusinessEmailRequest - if err := json.Unmarshal(bodyBytes, &emailToValidate); err != nil { - c.Err = model.NewAppError("Api4.requestCloudTrial", "api.cloud.app_error", nil, err.Error(), http.StatusInternalServerError) + err = json.Unmarshal(bodyBytes, &emailToValidate) + if err != nil { + c.Err = model.NewAppError("Api4.requestCloudTrial", "api.cloud.app_error", nil, "", http.StatusInternalServerError).Wrap(err) return } - emailErr := c.App.Cloud().ValidateBusinessEmail(user.Id, emailToValidate.Email) - if emailErr != nil { - c.Err = model.NewAppError("Api4.validateBusinessEmail", "api.cloud.request_error", nil, emailErr.Error(), http.StatusForbidden) + err = c.App.Cloud().ValidateBusinessEmail(user.Id, emailToValidate.Email) + if err != nil { + c.Err = model.NewAppError("Api4.validateBusinessEmail", "api.cloud.request_error", nil, "", http.StatusForbidden).Wrap(err) emailResp := model.ValidateBusinessEmailResponse{IsValid: false} if err := json.NewEncoder(w).Encode(emailResp); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } return } emailResp := model.ValidateBusinessEmailResponse{IsValid: true} if err := json.NewEncoder(w).Encode(emailResp); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -304,28 +305,27 @@ func getCloudProducts(c *Context, w http.ResponseWriter, r *http.Request) { products, err := c.App.Cloud().GetCloudProducts(c.AppContext.Session().UserId, includeLegacyProducts) if err != nil { - c.Err = model.NewAppError("Api4.getCloudProducts", "api.cloud.request_error", nil, err.Error(), http.StatusInternalServerError) + c.Err = model.NewAppError("Api4.getCloudProducts", "api.cloud.request_error", nil, "", http.StatusInternalServerError).Wrap(err) return } byteProductsData, err := json.Marshal(products) if err != nil { - c.Err = model.NewAppError("Api4.getCloudProducts", "api.cloud.app_error", nil, err.Error(), http.StatusInternalServerError) + c.Err = model.NewAppError("Api4.getCloudProducts", "api.cloud.app_error", nil, "", http.StatusInternalServerError).Wrap(err) return } if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionSysconsoleReadBilling) { - sanitizedProducts := []model.UserFacingProduct{} err = json.Unmarshal(byteProductsData, &sanitizedProducts) if err != nil { - c.Err = model.NewAppError("Api4.getCloudProducts", "api.cloud.app_error", nil, err.Error(), http.StatusInternalServerError) + c.Err = model.NewAppError("Api4.getCloudProducts", "api.cloud.app_error", nil, "", http.StatusInternalServerError).Wrap(err) return } byteSanitizedProductsData, err := json.Marshal(sanitizedProducts) if err != nil { - c.Err = model.NewAppError("Api4.getCloudProducts", "api.cloud.app_error", nil, err.Error(), http.StatusInternalServerError) + c.Err = model.NewAppError("Api4.getCloudProducts", "api.cloud.app_error", nil, "", http.StatusInternalServerError).Wrap(err) return } @@ -344,13 +344,13 @@ func getCloudLimits(c *Context, w http.ResponseWriter, r *http.Request) { limits, err := c.App.Cloud().GetCloudLimits(c.AppContext.Session().UserId) if err != nil { - c.Err = model.NewAppError("Api4.getCloudLimits", "api.cloud.request_error", nil, err.Error(), http.StatusInternalServerError) + c.Err = model.NewAppError("Api4.getCloudLimits", "api.cloud.request_error", nil, "", http.StatusInternalServerError).Wrap(err) return } json, err := json.Marshal(limits) if err != nil { - c.Err = model.NewAppError("Api4.getCloudLimits", "api.cloud.app_error", nil, err.Error(), http.StatusInternalServerError) + c.Err = model.NewAppError("Api4.getCloudLimits", "api.cloud.app_error", nil, "", http.StatusInternalServerError).Wrap(err) return } @@ -370,13 +370,13 @@ func getCloudCustomer(c *Context, w http.ResponseWriter, r *http.Request) { customer, err := c.App.Cloud().GetCloudCustomer(c.AppContext.Session().UserId) if err != nil { - c.Err = model.NewAppError("Api4.getCloudCustomer", "api.cloud.request_error", nil, err.Error(), http.StatusInternalServerError) + c.Err = model.NewAppError("Api4.getCloudCustomer", "api.cloud.request_error", nil, "", http.StatusInternalServerError).Wrap(err) return } json, err := json.Marshal(customer) if err != nil { - c.Err = model.NewAppError("Api4.getCloudCustomer", "api.cloud.app_error", nil, err.Error(), http.StatusInternalServerError) + c.Err = model.NewAppError("Api4.getCloudCustomer", "api.cloud.app_error", nil, "", http.StatusInternalServerError).Wrap(err) return } @@ -396,25 +396,25 @@ func updateCloudCustomer(c *Context, w http.ResponseWriter, r *http.Request) { bodyBytes, err := io.ReadAll(r.Body) if err != nil { - c.Err = model.NewAppError("Api4.updateCloudCustomer", "api.cloud.app_error", nil, err.Error(), http.StatusInternalServerError) + c.Err = model.NewAppError("Api4.updateCloudCustomer", "api.cloud.app_error", nil, "", http.StatusInternalServerError).Wrap(err) return } var customerInfo *model.CloudCustomerInfo if err = json.Unmarshal(bodyBytes, &customerInfo); err != nil { - c.Err = model.NewAppError("Api4.updateCloudCustomer", "api.cloud.app_error", nil, err.Error(), http.StatusInternalServerError) + c.Err = model.NewAppError("Api4.updateCloudCustomer", "api.cloud.app_error", nil, "", http.StatusInternalServerError).Wrap(err) return } customer, appErr := c.App.Cloud().UpdateCloudCustomer(c.AppContext.Session().UserId, customerInfo) if appErr != nil { - c.Err = model.NewAppError("Api4.updateCloudCustomer", "api.cloud.request_error", nil, appErr.Error(), http.StatusInternalServerError) + c.Err = model.NewAppError("Api4.updateCloudCustomer", "api.cloud.request_error", nil, "", http.StatusInternalServerError).Wrap(appErr) return } json, err := json.Marshal(customer) if err != nil { - c.Err = model.NewAppError("Api4.updateCloudCustomer", "api.cloud.app_error", nil, err.Error(), http.StatusInternalServerError) + c.Err = model.NewAppError("Api4.updateCloudCustomer", "api.cloud.app_error", nil, "", http.StatusInternalServerError).Wrap(err) return } @@ -434,25 +434,25 @@ func updateCloudCustomerAddress(c *Context, w http.ResponseWriter, r *http.Reque bodyBytes, err := io.ReadAll(r.Body) if err != nil { - c.Err = model.NewAppError("Api4.updateCloudCustomerAddress", "api.cloud.app_error", nil, err.Error(), http.StatusInternalServerError) + c.Err = model.NewAppError("Api4.updateCloudCustomerAddress", "api.cloud.app_error", nil, "", http.StatusInternalServerError).Wrap(err) return } var address *model.Address if err = json.Unmarshal(bodyBytes, &address); err != nil { - c.Err = model.NewAppError("Api4.updateCloudCustomerAddress", "api.cloud.app_error", nil, err.Error(), http.StatusInternalServerError) + c.Err = model.NewAppError("Api4.updateCloudCustomerAddress", "api.cloud.app_error", nil, "", http.StatusInternalServerError).Wrap(err) return } customer, appErr := c.App.Cloud().UpdateCloudCustomerAddress(c.AppContext.Session().UserId, address) if appErr != nil { - c.Err = model.NewAppError("Api4.updateCloudCustomerAddress", "api.cloud.request_error", nil, appErr.Error(), http.StatusInternalServerError) + c.Err = model.NewAppError("Api4.updateCloudCustomerAddress", "api.cloud.request_error", nil, "", http.StatusInternalServerError).Wrap(appErr) return } json, err := json.Marshal(customer) if err != nil { - c.Err = model.NewAppError("Api4.updateCloudCustomerAddress", "api.cloud.app_error", nil, err.Error(), http.StatusInternalServerError) + c.Err = model.NewAppError("Api4.updateCloudCustomerAddress", "api.cloud.app_error", nil, "", http.StatusInternalServerError).Wrap(err) return } @@ -475,13 +475,13 @@ func createCustomerPayment(c *Context, w http.ResponseWriter, r *http.Request) { intent, err := c.App.Cloud().CreateCustomerPayment(c.AppContext.Session().UserId) if err != nil { - c.Err = model.NewAppError("Api4.createCustomerPayment", "api.cloud.request_error", nil, err.Error(), http.StatusInternalServerError) + c.Err = model.NewAppError("Api4.createCustomerPayment", "api.cloud.request_error", nil, "", http.StatusInternalServerError).Wrap(err) return } json, err := json.Marshal(intent) if err != nil { - c.Err = model.NewAppError("Api4.createCustomerPayment", "api.cloud.app_error", nil, err.Error(), http.StatusInternalServerError) + c.Err = model.NewAppError("Api4.createCustomerPayment", "api.cloud.app_error", nil, "", http.StatusInternalServerError).Wrap(err) return } @@ -506,19 +506,19 @@ func confirmCustomerPayment(c *Context, w http.ResponseWriter, r *http.Request) bodyBytes, err := io.ReadAll(r.Body) if err != nil { - c.Err = model.NewAppError("Api4.confirmCustomerPayment", "api.cloud.app_error", nil, err.Error(), http.StatusInternalServerError) + c.Err = model.NewAppError("Api4.confirmCustomerPayment", "api.cloud.app_error", nil, "", http.StatusInternalServerError).Wrap(err) return } var confirmRequest *model.ConfirmPaymentMethodRequest if err = json.Unmarshal(bodyBytes, &confirmRequest); err != nil { - c.Err = model.NewAppError("Api4.confirmCustomerPayment", "api.cloud.app_error", nil, err.Error(), http.StatusInternalServerError) + c.Err = model.NewAppError("Api4.confirmCustomerPayment", "api.cloud.app_error", nil, "", http.StatusInternalServerError).Wrap(err) return } err = c.App.Cloud().ConfirmCustomerPayment(c.AppContext.Session().UserId, confirmRequest) if err != nil { - c.Err = model.NewAppError("Api4.createCustomerPayment", "api.cloud.request_error", nil, err.Error(), http.StatusInternalServerError) + c.Err = model.NewAppError("Api4.createCustomerPayment", "api.cloud.request_error", nil, "", http.StatusInternalServerError).Wrap(err) return } @@ -540,13 +540,13 @@ func getInvoicesForSubscription(c *Context, w http.ResponseWriter, r *http.Reque invoices, appErr := c.App.Cloud().GetInvoicesForSubscription(c.AppContext.Session().UserId) if appErr != nil { - c.Err = model.NewAppError("Api4.getInvoicesForSubscription", "api.cloud.request_error", nil, appErr.Error(), http.StatusInternalServerError) + c.Err = model.NewAppError("Api4.getInvoicesForSubscription", "api.cloud.request_error", nil, "", http.StatusInternalServerError).Wrap(appErr) return } json, err := json.Marshal(invoices) if err != nil { - c.Err = model.NewAppError("Api4.getInvoicesForSubscription", "api.cloud.app_error", nil, err.Error(), http.StatusInternalServerError) + c.Err = model.NewAppError("Api4.getInvoicesForSubscription", "api.cloud.app_error", nil, "", http.StatusInternalServerError).Wrap(err) return } diff --git a/api4/cluster.go b/api4/cluster.go index a51c7fbb06..74e6e2b26d 100644 --- a/api4/cluster.go +++ b/api4/cluster.go @@ -26,9 +26,9 @@ func getClusterStatus(c *Context, w http.ResponseWriter, r *http.Request) { } infos := c.App.GetClusterStatus() - js, jsonErr := json.Marshal(infos) - if jsonErr != nil { - c.Err = model.NewAppError("getClusterStatus", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(infos) + if err != nil { + c.Err = model.NewAppError("getClusterStatus", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } w.Write(js) diff --git a/api4/command.go b/api4/command.go index c267c869fc..1025424c83 100644 --- a/api4/command.go +++ b/api4/command.go @@ -417,9 +417,9 @@ func listCommandAutocompleteSuggestions(c *Context, w http.ResponseWriter, r *ht } userInput = strings.TrimPrefix(userInput, "/") - commands, err := c.App.ListAutocompleteCommands(c.Params.TeamId, c.AppContext.T) - if err != nil { - c.Err = err + commands, appErr := c.App.ListAutocompleteCommands(c.Params.TeamId, c.AppContext.T) + if appErr != nil { + c.Err = appErr return } @@ -436,9 +436,9 @@ func listCommandAutocompleteSuggestions(c *Context, w http.ResponseWriter, r *ht suggestions := c.App.GetSuggestions(c.AppContext, commandArgs, commands, roleId) - js, jsonErr := json.Marshal(suggestions) - if jsonErr != nil { - c.Err = model.NewAppError("listCommandAutocompleteSuggestions", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(suggestions) + if err != nil { + c.Err = model.NewAppError("listCommandAutocompleteSuggestions", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } w.Write(js) diff --git a/api4/config.go b/api4/config.go index c20e3e2912..2b6779c31f 100644 --- a/api4/config.go +++ b/api4/config.go @@ -108,9 +108,10 @@ func configReload(c *Context, w http.ResponseWriter, r *http.Request) { } func updateConfig(c *Context, w http.ResponseWriter, r *http.Request) { - cfg := model.ConfigFromJSON(r.Body) - if cfg == nil { - c.SetInvalidParam("config") + var cfg *model.Config + err := json.NewDecoder(r.Body).Decode(&cfg) + if err != nil || cfg == nil { + c.SetInvalidParamWithErr("config", err) return } @@ -132,14 +133,13 @@ func updateConfig(c *Context, w http.ResponseWriter, r *http.Request) { return } - var err1 error - cfg, err1 = config.Merge(appCfg, cfg, &utils.MergeConfig{ + cfg, err = config.Merge(appCfg, cfg, &utils.MergeConfig{ StructFieldFilter: func(structField reflect.StructField, base, patch reflect.Value) bool { return writeFilter(c, structField) }, }) - if err1 != nil { - c.Err = model.NewAppError("updateConfig", "api.config.update_config.restricted_merge.app_error", nil, err1.Error(), http.StatusInternalServerError) + if err != nil { + c.Err = model.NewAppError("updateConfig", "api.config.update_config.restricted_merge.app_error", nil, "", http.StatusInternalServerError).Wrap(err) return } @@ -156,8 +156,8 @@ func updateConfig(c *Context, w http.ResponseWriter, r *http.Request) { *cfg.PluginSettings.MarketplaceURL = *appCfg.PluginSettings.MarketplaceURL } - if err := c.App.CheckFreemiumLimitsForConfigSave(appCfg, cfg); err != nil { - c.Err = err + if appErr := c.App.CheckFreemiumLimitsForConfigSave(appCfg, cfg); appErr != nil { + c.Err = appErr return } @@ -173,33 +173,33 @@ func updateConfig(c *Context, w http.ResponseWriter, r *http.Request) { c.App.HandleMessageExportConfig(cfg, appCfg) - if err := cfg.IsValid(); err != nil { - c.Err = err + if appErr := cfg.IsValid(); appErr != nil { + c.Err = appErr return } - oldCfg, newCfg, err := c.App.SaveConfig(cfg, true) + oldCfg, newCfg, appErr := c.App.SaveConfig(cfg, true) + if appErr != nil { + c.Err = appErr + return + } + + diffs, err := config.Diff(oldCfg, newCfg) if err != nil { - c.Err = err - return - } - - diffs, diffErr := config.Diff(oldCfg, newCfg) - if diffErr != nil { - c.Err = model.NewAppError("updateConfig", "api.config.update_config.diff.app_error", nil, diffErr.Error(), http.StatusInternalServerError) + c.Err = model.NewAppError("updateConfig", "api.config.update_config.diff.app_error", nil, "", http.StatusInternalServerError).Wrap(err) return } auditRec.AddEventPriorState(&diffs) newCfg.Sanitize() - cfg, mergeErr := config.Merge(&model.Config{}, newCfg, &utils.MergeConfig{ + cfg, err = config.Merge(&model.Config{}, newCfg, &utils.MergeConfig{ StructFieldFilter: func(structField reflect.StructField, base, patch reflect.Value) bool { return readFilter(c, structField) }, }) - if mergeErr != nil { - c.Err = model.NewAppError("updateConfig", "api.config.update_config.restricted_merge.app_error", nil, mergeErr.Error(), http.StatusInternalServerError) + if err != nil { + c.Err = model.NewAppError("updateConfig", "api.config.update_config.restricted_merge.app_error", nil, "", http.StatusInternalServerError).Wrap(err) return } @@ -210,9 +210,9 @@ func updateConfig(c *Context, w http.ResponseWriter, r *http.Request) { w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate") if c.App.Channels().License() != nil && *c.App.Channels().License().Features.Cloud { - js, jsonErr := cfg.ToJSONFiltered(model.ConfigAccessTagType, model.ConfigAccessTagCloudRestrictable) - if jsonErr != nil { - c.Err = model.NewAppError("updateConfig", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := cfg.ToJSONFiltered(model.ConfigAccessTagType, model.ConfigAccessTagCloudRestrictable) + if err != nil { + c.Err = model.NewAppError("updateConfig", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } w.Write(js) @@ -259,9 +259,10 @@ func getEnvironmentConfig(c *Context, w http.ResponseWriter, r *http.Request) { } func patchConfig(c *Context, w http.ResponseWriter, r *http.Request) { - cfg := model.ConfigFromJSON(r.Body) - if cfg == nil { - c.SetInvalidParam("config") + var cfg *model.Config + err := json.NewDecoder(r.Body).Decode(&cfg) + if err != nil || cfg == nil { + c.SetInvalidParamWithErr("config", err) return } @@ -298,8 +299,8 @@ func patchConfig(c *Context, w http.ResponseWriter, r *http.Request) { } } - if err := c.App.CheckFreemiumLimitsForConfigSave(appCfg, cfg); err != nil { - c.Err = err + if appErr := c.App.CheckFreemiumLimitsForConfigSave(appCfg, cfg); appErr != nil { + c.Err = appErr return } @@ -315,30 +316,29 @@ func patchConfig(c *Context, w http.ResponseWriter, r *http.Request) { c.App.HandleMessageExportConfig(cfg, appCfg) } - updatedCfg, mergeErr := config.Merge(appCfg, cfg, &utils.MergeConfig{ + updatedCfg, err := 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 + c.Err = model.NewAppError("patchConfig", "api.config.update_config.restricted_merge.app_error", nil, "", http.StatusInternalServerError).Wrap(err) return } - oldCfg, newCfg, err := c.App.SaveConfig(updatedCfg, true) + appErr := updatedCfg.IsValid() + if appErr != nil { + c.Err = appErr + return + } + + oldCfg, newCfg, appErr := c.App.SaveConfig(updatedCfg, true) + if appErr != nil { + c.Err = appErr + return + } + + diffs, err := config.Diff(oldCfg, newCfg) if err != nil { - c.Err = err - return - } - - diffs, diffErr := config.Diff(oldCfg, newCfg) - if diffErr != nil { - c.Err = model.NewAppError("patchConfig", "api.config.patch_config.diff.app_error", nil, diffErr.Error(), http.StatusInternalServerError) + c.Err = model.NewAppError("patchConfig", "api.config.patch_config.diff.app_error", nil, "", http.StatusInternalServerError).Wrap(err) return } @@ -348,21 +348,21 @@ func patchConfig(c *Context, w http.ResponseWriter, r *http.Request) { auditRec.Success() - cfg, mergeErr = config.Merge(&model.Config{}, newCfg, &utils.MergeConfig{ + cfg, err = config.Merge(&model.Config{}, newCfg, &utils.MergeConfig{ StructFieldFilter: func(structField reflect.StructField, base, patch reflect.Value) bool { return readFilter(c, structField) }, }) - if mergeErr != nil { - c.Err = model.NewAppError("patchConfig", "api.config.patch_config.restricted_merge.app_error", nil, mergeErr.Error(), http.StatusInternalServerError) + if err != nil { + c.Err = model.NewAppError("patchConfig", "api.config.patch_config.restricted_merge.app_error", nil, "", http.StatusInternalServerError).Wrap(err) return } w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate") if c.App.Channels().License() != nil && *c.App.Channels().License().Features.Cloud { - js, jsonErr := cfg.ToJSONFiltered(model.ConfigAccessTagType, model.ConfigAccessTagCloudRestrictable) - if jsonErr != nil { - c.Err = model.NewAppError("patchConfig", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := cfg.ToJSONFiltered(model.ConfigAccessTagType, model.ConfigAccessTagCloudRestrictable) + if err != nil { + c.Err = model.NewAppError("patchConfig", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } w.Write(js) diff --git a/api4/config_local.go b/api4/config_local.go index baf019ecc9..910c938e3e 100644 --- a/api4/config_local.go +++ b/api4/config_local.go @@ -35,9 +35,10 @@ func localGetConfig(c *Context, w http.ResponseWriter, r *http.Request) { } func localUpdateConfig(c *Context, w http.ResponseWriter, r *http.Request) { - cfg := model.ConfigFromJSON(r.Body) - if cfg == nil { - c.SetInvalidParam("config") + var cfg *model.Config + err := json.NewDecoder(r.Body).Decode(&cfg) + if err != nil || cfg == nil { + c.SetInvalidParamWithErr("config", err) return } @@ -56,15 +57,15 @@ func localUpdateConfig(c *Context, w http.ResponseWriter, r *http.Request) { c.App.HandleMessageExportConfig(cfg, appCfg) - err := cfg.IsValid() - if err != nil { - c.Err = err + appErr := cfg.IsValid() + if appErr != nil { + c.Err = appErr return } - oldCfg, newCfg, err := c.App.SaveConfig(cfg, true) - if err != nil { - c.Err = err + oldCfg, newCfg, appErr := c.App.SaveConfig(cfg, true) + if appErr != nil { + c.Err = appErr return } @@ -87,9 +88,10 @@ func localUpdateConfig(c *Context, w http.ResponseWriter, r *http.Request) { } func localPatchConfig(c *Context, w http.ResponseWriter, r *http.Request) { - cfg := model.ConfigFromJSON(r.Body) - if cfg == nil { - c.SetInvalidParam("config") + var cfg *model.Config + err := json.NewDecoder(r.Body).Decode(&cfg) + if err != nil || cfg == nil { + c.SetInvalidParamWithErr("config", err) return } @@ -114,21 +116,21 @@ func localPatchConfig(c *Context, w http.ResponseWriter, r *http.Request) { return } - err := updatedCfg.IsValid() - if err != nil { - c.Err = err + appErr := updatedCfg.IsValid() + if appErr != nil { + c.Err = appErr return } - oldCfg, newCfg, err := c.App.SaveConfig(updatedCfg, true) - if err != nil { - c.Err = err + oldCfg, newCfg, appErr := c.App.SaveConfig(updatedCfg, true) + if appErr != nil { + c.Err = appErr return } - diffs, diffErr := config.Diff(oldCfg, newCfg) - if diffErr != nil { - c.Err = model.NewAppError("patchConfig", "api.config.patch_config.diff.app_error", nil, diffErr.Error(), http.StatusInternalServerError) + diffs, err := config.Diff(oldCfg, newCfg) + if err != nil { + c.Err = model.NewAppError("patchConfig", "api.config.patch_config.diff.app_error", nil, "", http.StatusInternalServerError).Wrap(err) return } auditRec.AddEventPriorState(&diffs) diff --git a/api4/data_retention.go b/api4/data_retention.go index 0059e8ea89..8fdabc9f7c 100644 --- a/api4/data_retention.go +++ b/api4/data_retention.go @@ -9,6 +9,7 @@ import ( "github.com/mattermost/mattermost-server/v6/audit" "github.com/mattermost/mattermost-server/v6/model" + "github.com/mattermost/mattermost-server/v6/shared/mlog" ) func (api *API) InitDataRetention() { @@ -34,15 +35,15 @@ func (api *API) InitDataRetention() { func getGlobalPolicy(c *Context, w http.ResponseWriter, r *http.Request) { // No permission check required. - policy, err := c.App.GetGlobalRetentionPolicy() - if err != nil { - c.Err = err + policy, appErr := c.App.GetGlobalRetentionPolicy() + if appErr != nil { + c.Err = appErr return } - js, jsonErr := json.Marshal(policy) - if jsonErr != nil { - c.Err = model.NewAppError("getGlobalPolicy", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(policy) + if err != nil { + c.Err = model.NewAppError("getGlobalPolicy", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } w.Write(js) @@ -57,15 +58,15 @@ func getPolicies(c *Context, w http.ResponseWriter, r *http.Request) { limit := c.Params.PerPage offset := c.Params.Page * limit - policies, err := c.App.GetRetentionPolicies(offset, limit) - if err != nil { - c.Err = err + policies, appErr := c.App.GetRetentionPolicies(offset, limit) + if appErr != nil { + c.Err = appErr return } - js, jsonErr := json.Marshal(policies) - if jsonErr != nil { - c.Err = model.NewAppError("getPolicies", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(policies) + if err != nil { + c.Err = model.NewAppError("getPolicies", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } w.Write(js) @@ -77,14 +78,19 @@ func getPoliciesCount(c *Context, w http.ResponseWriter, r *http.Request) { return } - count, err := c.App.GetRetentionPoliciesCount() - if err != nil { - c.Err = err + count, appErr := c.App.GetRetentionPoliciesCount() + if appErr != nil { + c.Err = appErr return } - body := map[string]int64{"total_count": count} - b, _ := json.Marshal(body) - w.Write(b) + + body := struct { + TotalCount int64 `json:"total_count"` + }{count} + err := json.NewEncoder(w).Encode(body) + if err != nil { + c.Logger.Warn("Error writing response", mlog.Err(err)) + } } func getPolicy(c *Context, w http.ResponseWriter, r *http.Request) { @@ -94,15 +100,15 @@ func getPolicy(c *Context, w http.ResponseWriter, r *http.Request) { } c.RequirePolicyId() - policy, err := c.App.GetRetentionPolicy(c.Params.PolicyId) - if err != nil { - c.Err = err + policy, appErr := c.App.GetRetentionPolicy(c.Params.PolicyId) + if appErr != nil { + c.Err = appErr return } - js, jsonErr := json.Marshal(policy) - if jsonErr != nil { - c.Err = model.NewAppError("getPolicy", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(policy) + if err != nil { + c.Err = model.NewAppError("getPolicy", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } w.Write(js) @@ -123,17 +129,17 @@ func createPolicy(c *Context, w http.ResponseWriter, r *http.Request) { return } - newPolicy, err := c.App.CreateRetentionPolicy(&policy) - if err != nil { - c.Err = err + newPolicy, appErr := c.App.CreateRetentionPolicy(&policy) + if appErr != nil { + c.Err = appErr return } auditRec.AddEventResultState(newPolicy) auditRec.AddEventObjectType("policy") - js, jsonErr := json.Marshal(newPolicy) - if jsonErr != nil { - c.Err = model.NewAppError("createPolicy", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(newPolicy) + if err != nil { + c.Err = model.NewAppError("createPolicy", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } auditRec.Success() @@ -159,18 +165,18 @@ func patchPolicy(c *Context, w http.ResponseWriter, r *http.Request) { return } - policy, err := c.App.PatchRetentionPolicy(&patch) - if err != nil { - c.Err = err + policy, appErr := c.App.PatchRetentionPolicy(&patch) + if appErr != nil { + c.Err = appErr return } auditRec.AddEventResultState(policy) auditRec.AddEventObjectType("retention_policy") - js, jsonErr := json.Marshal(policy) - if jsonErr != nil { - c.Err = model.NewAppError("patchPolicy", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(policy) + if err != nil { + c.Err = model.NewAppError("patchPolicy", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } auditRec.Success() @@ -209,15 +215,15 @@ func getTeamsForPolicy(c *Context, w http.ResponseWriter, r *http.Request) { limit := c.Params.PerPage offset := c.Params.Page * limit - teams, err := c.App.GetTeamsForRetentionPolicy(policyId, offset, limit) - if err != nil { - c.Err = err + teams, appErr := c.App.GetTeamsForRetentionPolicy(policyId, offset, limit) + if appErr != nil { + c.Err = appErr return } - b, jsonErr := json.Marshal(teams) - if jsonErr != nil { - c.Err = model.NewAppError("Api4.getTeamsForPolicy", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + b, err := json.Marshal(teams) + if err != nil { + c.Err = model.NewAppError("Api4.getTeamsForPolicy", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } w.Write(b) @@ -232,24 +238,24 @@ func searchTeamsInPolicy(c *Context, w http.ResponseWriter, r *http.Request) { } var props model.TeamSearch - if jsonErr := json.NewDecoder(r.Body).Decode(&props); jsonErr != nil { - c.SetInvalidParamWithErr("team_search", jsonErr) + if err := json.NewDecoder(r.Body).Decode(&props); err != nil { + c.SetInvalidParamWithErr("team_search", err) return } props.PolicyID = model.NewString(c.Params.PolicyId) props.IncludePolicyID = model.NewBool(true) - teams, _, err := c.App.SearchAllTeams(&props) - if err != nil { - c.Err = err + teams, _, appErr := c.App.SearchAllTeams(&props) + if appErr != nil { + c.Err = appErr return } c.App.SanitizeTeams(*c.AppContext.Session(), teams) - js, jsonErr := json.Marshal(teams) - if jsonErr != nil { - c.Err = model.NewAppError("searchTeamsInPolicy", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(teams) + if err != nil { + c.Err = model.NewAppError("searchTeamsInPolicy", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } w.Write(js) @@ -323,15 +329,15 @@ func getChannelsForPolicy(c *Context, w http.ResponseWriter, r *http.Request) { limit := c.Params.PerPage offset := c.Params.Page * limit - channels, err := c.App.GetChannelsForRetentionPolicy(policyId, offset, limit) - if err != nil { - c.Err = err + channels, appErr := c.App.GetChannelsForRetentionPolicy(policyId, offset, limit) + if appErr != nil { + c.Err = appErr return } - b, jsonErr := json.Marshal(channels) - if jsonErr != nil { - c.Err = model.NewAppError("Api4.getChannelsForPolicy", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + b, err := json.Marshal(channels) + if err != nil { + c.Err = model.NewAppError("Api4.getChannelsForPolicy", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } w.Write(b) diff --git a/api4/elasticsearch.go b/api4/elasticsearch.go index 6bda0aa75a..9ae796157c 100644 --- a/api4/elasticsearch.go +++ b/api4/elasticsearch.go @@ -4,10 +4,12 @@ package api4 import ( + "encoding/json" "net/http" "github.com/mattermost/mattermost-server/v6/audit" "github.com/mattermost/mattermost-server/v6/model" + "github.com/mattermost/mattermost-server/v6/shared/mlog" ) func (api *API) InitElasticsearch() { @@ -16,7 +18,11 @@ func (api *API) InitElasticsearch() { } func testElasticsearch(c *Context, w http.ResponseWriter, r *http.Request) { - cfg := model.ConfigFromJSON(r.Body) + var cfg *model.Config + err := json.NewDecoder(r.Body).Decode(&cfg) + if err != nil { + c.Logger.Warn("Error decoding config.", mlog.Err(err)) + } if cfg == nil { cfg = c.App.Config() } diff --git a/api4/export.go b/api4/export.go index 36248746fe..4abec62fde 100644 --- a/api4/export.go +++ b/api4/export.go @@ -33,7 +33,7 @@ func listExports(c *Context, w http.ResponseWriter, r *http.Request) { data, err := json.Marshal(exports) if err != nil { - c.Err = model.NewAppError("listImports", "app.export.marshal.app_error", nil, err.Error(), http.StatusInternalServerError) + c.Err = model.NewAppError("listImports", "app.export.marshal.app_error", nil, "", http.StatusInternalServerError).Wrap(err) return } diff --git a/api4/group.go b/api4/group.go index e249637a81..4be5bc4201 100644 --- a/api4/group.go +++ b/api4/group.go @@ -99,11 +99,11 @@ func getGroup(c *Context, w http.ResponseWriter, r *http.Request) { return } - group, err := c.App.GetGroup(c.Params.GroupId, &model.GetGroupOpts{ + group, appErr := c.App.GetGroup(c.Params.GroupId, &model.GetGroupOpts{ IncludeMemberCount: c.Params.IncludeMemberCount, }) - if err != nil { - c.Err = err + if appErr != nil { + c.Err = appErr return } @@ -114,15 +114,15 @@ func getGroup(c *Context, w http.ResponseWriter, r *http.Request) { } } - if lcErr := licensedAndConfiguredForGroupBySource(c.App, group.Source); lcErr != nil { - lcErr.Where = "Api4.getGroup" - c.Err = lcErr + if appErr := licensedAndConfiguredForGroupBySource(c.App, group.Source); appErr != nil { + appErr.Where = "Api4.getGroup" + c.Err = appErr return } - b, marshalErr := json.Marshal(group) - if marshalErr != nil { - c.Err = model.NewAppError("Api4.getGroup", "api.marshal_error", nil, marshalErr.Error(), http.StatusInternalServerError) + b, err := json.Marshal(group) + if err != nil { + c.Err = model.NewAppError("Api4.getGroup", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } @@ -131,8 +131,8 @@ func getGroup(c *Context, w http.ResponseWriter, r *http.Request) { func createGroup(c *Context, w http.ResponseWriter, r *http.Request) { var group *model.GroupWithUserIds - if jsonErr := json.NewDecoder(r.Body).Decode(&group); jsonErr != nil { - c.SetInvalidParamWithErr("group", jsonErr) + if err := json.NewDecoder(r.Body).Decode(&group); err != nil { + c.SetInvalidParamWithErr("group", err) return } @@ -141,9 +141,9 @@ func createGroup(c *Context, w http.ResponseWriter, r *http.Request) { return } - if lcErr := licensedAndConfiguredForGroupBySource(c.App, group.Source); lcErr != nil { - lcErr.Where = "Api4.createGroup" - c.Err = lcErr + if appErr := licensedAndConfiguredForGroupBySource(c.App, group.Source); appErr != nil { + appErr.Where = "Api4.createGroup" + c.Err = appErr return } @@ -166,17 +166,17 @@ func createGroup(c *Context, w http.ResponseWriter, r *http.Request) { defer c.LogAuditRec(auditRec) auditRec.AddEventParameter("group", group) - newGroup, err := c.App.CreateGroupWithUserIds(group) - if err != nil { - c.Err = err + newGroup, appErr := c.App.CreateGroupWithUserIds(group) + if appErr != nil { + c.Err = appErr return } auditRec.AddEventResultState(newGroup) auditRec.AddEventObjectType("group") - js, jsonErr := json.Marshal(newGroup) - if jsonErr != nil { - c.Err = model.NewAppError("createGroup", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(newGroup) + if err != nil { + c.Err = model.NewAppError("createGroup", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } auditRec.Success() @@ -190,15 +190,16 @@ func patchGroup(c *Context, w http.ResponseWriter, r *http.Request) { return } - group, err := c.App.GetGroup(c.Params.GroupId, nil) - if err != nil { - c.Err = err + group, appErr := c.App.GetGroup(c.Params.GroupId, nil) + if appErr != nil { + c.Err = appErr return } - if lcErr := licensedAndConfiguredForGroupBySource(c.App, group.Source); lcErr != nil { - lcErr.Where = "Api4.patchGroup" - c.Err = lcErr + appErr = licensedAndConfiguredForGroupBySource(c.App, group.Source) + if appErr != nil { + appErr.Where = "Api4.patchGroup" + c.Err = appErr return } @@ -214,8 +215,8 @@ func patchGroup(c *Context, w http.ResponseWriter, r *http.Request) { } var groupPatch model.GroupPatch - if jsonErr := json.NewDecoder(r.Body).Decode(&groupPatch); jsonErr != nil { - c.SetInvalidParamWithErr("group", jsonErr) + if err := json.NewDecoder(r.Body).Decode(&groupPatch); err != nil { + c.SetInvalidParamWithErr("group", err) return } @@ -257,17 +258,17 @@ func patchGroup(c *Context, w http.ResponseWriter, r *http.Request) { group.Patch(&groupPatch) - group, err = c.App.UpdateGroup(group) - if err != nil { - c.Err = err + group, appErr = c.App.UpdateGroup(group) + if appErr != nil { + c.Err = appErr return } auditRec.AddEventResultState(group) auditRec.AddEventObjectType("group") - b, marshalErr := json.Marshal(group) - if marshalErr != nil { - c.Err = model.NewAppError("Api4.patchGroup", "api.marshal_error", nil, marshalErr.Error(), http.StatusInternalServerError) + b, err := json.Marshal(group) + if err != nil { + c.Err = model.NewAppError("Api4.patchGroup", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } @@ -295,13 +296,13 @@ func linkGroupSyncable(c *Context, w http.ResponseWriter, r *http.Request) { body, err := io.ReadAll(r.Body) if err != nil { - c.Err = model.NewAppError("Api4.createGroupSyncable", "api.io_error", nil, err.Error(), http.StatusBadRequest) + c.Err = model.NewAppError("Api4.createGroupSyncable", "api.io_error", nil, "", http.StatusBadRequest).Wrap(err) return } - group, groupErr := c.App.GetGroup(c.Params.GroupId, nil) - if groupErr != nil { - c.Err = groupErr + group, appErr := c.App.GetGroup(c.Params.GroupId, nil) + if appErr != nil { + c.Err = appErr return } @@ -319,7 +320,7 @@ func linkGroupSyncable(c *Context, w http.ResponseWriter, r *http.Request) { var patch *model.GroupSyncablePatch err = json.Unmarshal(body, &patch) if err != nil || patch == nil { - c.SetInvalidParam(fmt.Sprintf("Group%s", syncableType.String())) + c.SetInvalidParamWithErr(fmt.Sprintf("Group%s", syncableType), err) return } @@ -330,7 +331,7 @@ func linkGroupSyncable(c *Context, w http.ResponseWriter, r *http.Request) { return } - appErr := verifyLinkUnlinkPermission(c, syncableType, syncableID) + appErr = verifyLinkUnlinkPermission(c, syncableType, syncableID) if appErr != nil { c.Err = appErr return @@ -357,9 +358,9 @@ func linkGroupSyncable(c *Context, w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusCreated) - b, marshalErr := json.Marshal(groupSyncable) - if marshalErr != nil { - c.Err = model.NewAppError("Api4.createGroupSyncable", "api.marshal_error", nil, marshalErr.Error(), http.StatusInternalServerError) + b, err := json.Marshal(groupSyncable) + if err != nil { + c.Err = model.NewAppError("Api4.createGroupSyncable", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } auditRec.Success() @@ -394,15 +395,15 @@ func getGroupSyncable(c *Context, w http.ResponseWriter, r *http.Request) { return } - groupSyncable, err := c.App.GetGroupSyncable(c.Params.GroupId, syncableID, syncableType) - if err != nil { - c.Err = err + groupSyncable, appErr := c.App.GetGroupSyncable(c.Params.GroupId, syncableID, syncableType) + if appErr != nil { + c.Err = appErr return } - b, marshalErr := json.Marshal(groupSyncable) - if marshalErr != nil { - c.Err = model.NewAppError("Api4.getGroupSyncable", "api.marshal_error", nil, marshalErr.Error(), http.StatusInternalServerError) + b, err := json.Marshal(groupSyncable) + if err != nil { + c.Err = model.NewAppError("Api4.getGroupSyncable", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } @@ -431,15 +432,15 @@ func getGroupSyncables(c *Context, w http.ResponseWriter, r *http.Request) { return } - groupSyncables, err := c.App.GetGroupSyncables(c.Params.GroupId, syncableType) - if err != nil { - c.Err = err + groupSyncables, appErr := c.App.GetGroupSyncables(c.Params.GroupId, syncableType) + if appErr != nil { + c.Err = appErr return } - b, marshalErr := json.Marshal(groupSyncables) - if marshalErr != nil { - c.Err = model.NewAppError("Api4.getGroupSyncables", "api.marshal_error", nil, marshalErr.Error(), http.StatusInternalServerError) + b, err := json.Marshal(groupSyncables) + if err != nil { + c.Err = model.NewAppError("Api4.getGroupSyncables", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } @@ -466,7 +467,7 @@ func patchGroupSyncable(c *Context, w http.ResponseWriter, r *http.Request) { body, err := io.ReadAll(r.Body) if err != nil { - c.Err = model.NewAppError("Api4.patchGroupSyncable", "api.io_error", nil, err.Error(), http.StatusBadRequest) + c.Err = model.NewAppError("Api4.patchGroupSyncable", "api.io_error", nil, "", http.StatusBadRequest).Wrap(err) return } @@ -479,7 +480,7 @@ func patchGroupSyncable(c *Context, w http.ResponseWriter, r *http.Request) { var patch *model.GroupSyncablePatch err = json.Unmarshal(body, &patch) if err != nil || patch == nil { - c.SetInvalidParam(fmt.Sprintf("Group[%s]Patch", syncableType.String())) + c.SetInvalidParamWithErr(fmt.Sprintf("Group[%s]Patch", syncableType), err) return } @@ -518,9 +519,9 @@ func patchGroupSyncable(c *Context, w http.ResponseWriter, r *http.Request) { c.App.SyncRolesAndMembership(c.AppContext, syncableID, syncableType, false) }) - b, marshalErr := json.Marshal(groupSyncable) - if marshalErr != nil { - c.Err = model.NewAppError("Api4.patchGroupSyncable", "api.marshal_error", nil, marshalErr.Error(), http.StatusInternalServerError) + b, err := json.Marshal(groupSyncable) + if err != nil { + c.Err = model.NewAppError("Api4.patchGroupSyncable", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } auditRec.Success() @@ -556,15 +557,15 @@ func unlinkGroupSyncable(c *Context, w http.ResponseWriter, r *http.Request) { return } - err := verifyLinkUnlinkPermission(c, syncableType, syncableID) - if err != nil { - c.Err = err + appErr := verifyLinkUnlinkPermission(c, syncableType, syncableID) + if appErr != nil { + c.Err = appErr return } - _, err = c.App.DeleteGroupSyncable(c.Params.GroupId, syncableID, syncableType) - if err != nil { - c.Err = err + _, appErr = c.App.DeleteGroupSyncable(c.Params.GroupId, syncableID, syncableType) + if appErr != nil { + c.Err = appErr return } @@ -610,15 +611,16 @@ func getGroupMembers(c *Context, w http.ResponseWriter, r *http.Request) { return } - group, err := c.App.GetGroup(c.Params.GroupId, nil) - if err != nil { - c.Err = err + group, appErr := c.App.GetGroup(c.Params.GroupId, nil) + if appErr != nil { + c.Err = appErr return } - if lcErr := licensedAndConfiguredForGroupBySource(c.App, group.Source); lcErr != nil { - lcErr.Where = "Api4.getGroupMembers" - c.Err = lcErr + appErr = licensedAndConfiguredForGroupBySource(c.App, group.Source) + if appErr != nil { + appErr.Where = "Api4.getGroupMembers" + c.Err = appErr return } @@ -627,21 +629,21 @@ func getGroupMembers(c *Context, w http.ResponseWriter, r *http.Request) { return } - members, count, err := c.App.GetGroupMemberUsersPage(c.Params.GroupId, c.Params.Page, c.Params.PerPage) - if err != nil { - c.Err = err + members, count, appErr := c.App.GetGroupMemberUsersPage(c.Params.GroupId, c.Params.Page, c.Params.PerPage) + if appErr != nil { + c.Err = appErr return } - b, marshalErr := json.Marshal(struct { + b, err := json.Marshal(struct { Members []*model.User `json:"members"` Count int `json:"total_member_count"` }{ Members: members, Count: count, }) - if marshalErr != nil { - c.Err = model.NewAppError("Api4.getGroupMembers", "api.marshal_error", nil, marshalErr.Error(), http.StatusInternalServerError) + if err != nil { + c.Err = model.NewAppError("Api4.getGroupMembers", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } @@ -665,18 +667,18 @@ func getGroupStats(c *Context, w http.ResponseWriter, r *http.Request) { } groupID := c.Params.GroupId - count, err := c.App.GetGroupMemberCount(groupID) - if err != nil { - c.Err = err + count, appErr := c.App.GetGroupMemberCount(groupID) + if appErr != nil { + c.Err = appErr return } - b, marshalErr := json.Marshal(model.GroupStats{ + b, err := json.Marshal(model.GroupStats{ GroupID: groupID, TotalMemberCount: count, }) - if marshalErr != nil { - c.Err = model.NewAppError("Api4.getGroupStats", "api.marshal_error", nil, marshalErr.Error(), http.StatusInternalServerError) + if err != nil { + c.Err = model.NewAppError("Api4.getGroupStats", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } @@ -699,15 +701,15 @@ func getGroupsByUserId(c *Context, w http.ResponseWriter, r *http.Request) { return } - groups, err := c.App.GetGroupsByUserId(c.Params.UserId) - if err != nil { - c.Err = err + groups, appErr := c.App.GetGroupsByUserId(c.Params.UserId) + if appErr != nil { + c.Err = appErr return } - b, marshalErr := json.Marshal(groups) - if marshalErr != nil { - c.Err = model.NewAppError("Api4.getGroupsByUserId", "api.marshal_error", nil, marshalErr.Error(), http.StatusInternalServerError) + b, err := json.Marshal(groups) + if err != nil { + c.Err = model.NewAppError("Api4.getGroupsByUserId", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } @@ -725,11 +727,12 @@ func getGroupsByChannel(c *Context, w http.ResponseWriter, r *http.Request) { return } - channel, err := c.App.GetChannel(c.AppContext, c.Params.ChannelId) - if err != nil { - c.Err = err + channel, appErr := c.App.GetChannel(c.AppContext, c.Params.ChannelId) + if appErr != nil { + c.Err = appErr return } + var permission *model.Permission if channel.Type == model.ChannelTypePrivate { permission = model.PermissionReadPrivateChannelGroups @@ -750,22 +753,21 @@ func getGroupsByChannel(c *Context, w http.ResponseWriter, r *http.Request) { opts.PageOpts = &model.PageOpts{Page: c.Params.Page, PerPage: c.Params.PerPage} } - groups, totalCount, err := c.App.GetGroupsByChannel(c.Params.ChannelId, opts) - if err != nil { - c.Err = err + groups, totalCount, appErr := c.App.GetGroupsByChannel(c.Params.ChannelId, opts) + if appErr != nil { + c.Err = appErr return } - b, marshalErr := json.Marshal(struct { + b, err := json.Marshal(struct { Groups []*model.GroupWithSchemeAdmin `json:"groups"` Count int `json:"total_group_count"` }{ Groups: groups, Count: totalCount, }) - - if marshalErr != nil { - c.Err = model.NewAppError("Api4.getGroupsByChannel", "api.marshal_error", nil, marshalErr.Error(), http.StatusInternalServerError) + if err != nil { + c.Err = model.NewAppError("Api4.getGroupsByChannel", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } @@ -791,13 +793,13 @@ func getGroupsByTeam(c *Context, w http.ResponseWriter, r *http.Request) { opts.PageOpts = &model.PageOpts{Page: c.Params.Page, PerPage: c.Params.PerPage} } - groups, totalCount, err := c.App.GetGroupsByTeam(c.Params.TeamId, opts) - if err != nil { - c.Err = err + groups, totalCount, appErr := c.App.GetGroupsByTeam(c.Params.TeamId, opts) + if appErr != nil { + c.Err = appErr return } - b, marshalErr := json.Marshal(struct { + b, err := json.Marshal(struct { Groups []*model.GroupWithSchemeAdmin `json:"groups"` Count int `json:"total_group_count"` }{ @@ -805,8 +807,8 @@ func getGroupsByTeam(c *Context, w http.ResponseWriter, r *http.Request) { Count: totalCount, }) - if marshalErr != nil { - c.Err = model.NewAppError("Api4.getGroupsByTeam", "api.marshal_error", nil, marshalErr.Error(), http.StatusInternalServerError) + if err != nil { + c.Err = model.NewAppError("Api4.getGroupsByTeam", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } @@ -833,20 +835,19 @@ func getGroupsAssociatedToChannelsByTeam(c *Context, w http.ResponseWriter, r *h opts.PageOpts = &model.PageOpts{Page: c.Params.Page, PerPage: c.Params.PerPage} } - groupsAssociatedByChannelID, err := c.App.GetGroupsAssociatedToChannelsByTeam(c.Params.TeamId, opts) - if err != nil { - c.Err = err + groupsAssociatedByChannelID, appErr := c.App.GetGroupsAssociatedToChannelsByTeam(c.Params.TeamId, opts) + if appErr != nil { + c.Err = appErr return } - b, marshalErr := json.Marshal(struct { + b, err := json.Marshal(struct { GroupsAssociatedToChannels map[string][]*model.GroupWithSchemeAdmin `json:"groups"` }{ GroupsAssociatedToChannels: groupsAssociatedByChannelID, }) - - if marshalErr != nil { - c.Err = model.NewAppError("Api4.getGroupsAssociatedToChannelsByTeam", "api.marshal_error", nil, marshalErr.Error(), http.StatusInternalServerError) + if err != nil { + c.Err = model.NewAppError("Api4.getGroupsAssociatedToChannelsByTeam", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } @@ -867,9 +868,9 @@ func getGroups(c *Context, w http.ResponseWriter, r *http.Request) { } // If they specify the group_source as custom when the feature is disabled, throw an error - if lcErr := licensedAndConfiguredForGroupBySource(c.App, source); lcErr != nil { - lcErr.Where = "Api4.getGroups" - c.Err = lcErr + if appErr := licensedAndConfiguredForGroupBySource(c.App, source); appErr != nil { + appErr.Where = "Api4.getGroups" + c.Err = appErr return } @@ -888,9 +889,9 @@ func getGroups(c *Context, w http.ResponseWriter, r *http.Request) { } if teamID != "" { - _, err := c.App.GetTeam(teamID) - if err != nil { - c.Err = err + _, appErr := c.App.GetTeam(teamID) + if appErr != nil { + c.Err = appErr return } @@ -898,9 +899,9 @@ func getGroups(c *Context, w http.ResponseWriter, r *http.Request) { } if channelID != "" { - channel, err := c.App.GetChannel(c.AppContext, channelID) - if err != nil { - c.Err = err + channel, appErr := c.App.GetChannel(c.AppContext, channelID) + if appErr != nil { + c.Err = appErr return } var permission *model.Permission @@ -918,39 +919,41 @@ func getGroups(c *Context, w http.ResponseWriter, r *http.Request) { sinceString := r.URL.Query().Get("since") if sinceString != "" { - since, parseError := strconv.ParseInt(sinceString, 10, 64) - if parseError != nil { - c.SetInvalidParam("since") + since, err := strconv.ParseInt(sinceString, 10, 64) + if err != nil { + c.SetInvalidParamWithErr("since", err) return } opts.Since = since } - groups, err := c.App.GetGroups(c.Params.Page, c.Params.PerPage, opts) - if err != nil { - c.Err = err + groups, appErr := c.App.GetGroups(c.Params.Page, c.Params.PerPage, opts) + if appErr != nil { + c.Err = appErr return } - var b []byte - var marshalErr error + var ( + b []byte + err error + ) if c.Params.IncludeTotalCount { - totalCount, countErr := c.App.Srv().Store.Group().GroupCount() - if countErr != nil { - c.Err = model.NewAppError("Api4.getGroups", "api.custom_groups.count_err", nil, countErr.Error(), http.StatusInternalServerError) + totalCount, cerr := c.App.Srv().Store.Group().GroupCount() + if cerr != nil { + c.Err = model.NewAppError("Api4.getGroups", "api.custom_groups.count_err", nil, "", http.StatusInternalServerError).Wrap(cerr) return } gwc := &model.GroupsWithCount{ Groups: groups, TotalCount: totalCount, } - b, marshalErr = json.Marshal(gwc) + b, err = json.Marshal(gwc) } else { - b, marshalErr = json.Marshal(groups) + b, err = json.Marshal(groups) } - if marshalErr != nil { - c.Err = model.NewAppError("Api4.getGroups", "api.marshal_error", nil, marshalErr.Error(), http.StatusInternalServerError) + if err != nil { + c.Err = model.NewAppError("Api4.getGroups", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } @@ -1006,9 +1009,9 @@ func addGroupMembers(c *Context, w http.ResponseWriter, r *http.Request) { return } - group, err := c.App.GetGroup(c.Params.GroupId, nil) - if err != nil { - c.Err = err + group, appErr := c.App.GetGroup(c.Params.GroupId, nil) + if appErr != nil { + c.Err = appErr return } @@ -1017,9 +1020,10 @@ func addGroupMembers(c *Context, w http.ResponseWriter, r *http.Request) { return } - if lcErr := licensedAndConfiguredForGroupBySource(c.App, model.GroupSourceCustom); lcErr != nil { - lcErr.Where = "Api4.deleteGroup" - c.Err = lcErr + appErr = licensedAndConfiguredForGroupBySource(c.App, model.GroupSourceCustom) + if appErr != nil { + appErr.Where = "Api4.deleteGroup" + c.Err = appErr return } @@ -1029,8 +1033,8 @@ func addGroupMembers(c *Context, w http.ResponseWriter, r *http.Request) { } var newMembers *model.GroupModifyMembers - if jsonErr := json.NewDecoder(r.Body).Decode(&newMembers); jsonErr != nil { - c.SetInvalidParamWithErr("addGroupMembers", jsonErr) + if err := json.NewDecoder(r.Body).Decode(&newMembers); err != nil { + c.SetInvalidParamWithErr("addGroupMembers", err) return } @@ -1038,15 +1042,15 @@ func addGroupMembers(c *Context, w http.ResponseWriter, r *http.Request) { defer c.LogAuditRec(auditRec) auditRec.AddEventParameter("addGroupMembers", newMembers) - members, err := c.App.UpsertGroupMembers(c.Params.GroupId, newMembers.UserIds) - if err != nil { - c.Err = err + members, appErr := c.App.UpsertGroupMembers(c.Params.GroupId, newMembers.UserIds) + if appErr != nil { + c.Err = appErr return } - b, marshalErr := json.Marshal(members) - if marshalErr != nil { - c.Err = model.NewAppError("Api4.addGroupMembers", "api.marshal_error", nil, marshalErr.Error(), http.StatusInternalServerError) + b, err := json.Marshal(members) + if err != nil { + c.Err = model.NewAppError("Api4.addGroupMembers", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } auditRec.Success() @@ -1059,9 +1063,9 @@ func deleteGroupMembers(c *Context, w http.ResponseWriter, r *http.Request) { return } - group, err := c.App.GetGroup(c.Params.GroupId, nil) - if err != nil { - c.Err = err + group, appErr := c.App.GetGroup(c.Params.GroupId, nil) + if appErr != nil { + c.Err = appErr return } @@ -1070,9 +1074,10 @@ func deleteGroupMembers(c *Context, w http.ResponseWriter, r *http.Request) { return } - if lcErr := licensedAndConfiguredForGroupBySource(c.App, model.GroupSourceCustom); lcErr != nil { - lcErr.Where = "Api4.deleteGroup" - c.Err = lcErr + appErr = licensedAndConfiguredForGroupBySource(c.App, model.GroupSourceCustom) + if appErr != nil { + appErr.Where = "Api4.deleteGroup" + c.Err = appErr return } @@ -1082,8 +1087,8 @@ func deleteGroupMembers(c *Context, w http.ResponseWriter, r *http.Request) { } var deleteBody *model.GroupModifyMembers - if jsonErr := json.NewDecoder(r.Body).Decode(&deleteBody); jsonErr != nil { - c.SetInvalidParamWithErr("deleteGroupMembers", jsonErr) + if err := json.NewDecoder(r.Body).Decode(&deleteBody); err != nil { + c.SetInvalidParamWithErr("deleteGroupMembers", err) return } @@ -1091,15 +1096,15 @@ func deleteGroupMembers(c *Context, w http.ResponseWriter, r *http.Request) { defer c.LogAuditRec(auditRec) auditRec.AddEventParameter("deleteGroupMembers", deleteBody) - members, err := c.App.DeleteGroupMembers(c.Params.GroupId, deleteBody.UserIds) - if err != nil { - c.Err = err + members, appErr := c.App.DeleteGroupMembers(c.Params.GroupId, deleteBody.UserIds) + if appErr != nil { + c.Err = appErr return } - b, marshalErr := json.Marshal(members) - if marshalErr != nil { - c.Err = model.NewAppError("Api4.addGroupMembers", "api.marshal_error", nil, marshalErr.Error(), http.StatusInternalServerError) + b, err := json.Marshal(members) + if err != nil { + c.Err = model.NewAppError("Api4.addGroupMembers", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } auditRec.Success() diff --git a/api4/import.go b/api4/import.go index bbb7784f5e..e86cf98bd0 100644 --- a/api4/import.go +++ b/api4/import.go @@ -28,7 +28,7 @@ func listImports(c *Context, w http.ResponseWriter, r *http.Request) { data, err := json.Marshal(imports) if err != nil { - c.Err = model.NewAppError("listImports", "app.import.marshal.app_error", nil, err.Error(), http.StatusInternalServerError) + c.Err = model.NewAppError("listImports", "app.import.marshal.app_error", nil, "", http.StatusInternalServerError).Wrap(err) return } diff --git a/api4/insights.go b/api4/insights.go index 39493a97f3..ef06e54afe 100644 --- a/api4/insights.go +++ b/api4/insights.go @@ -33,9 +33,9 @@ func getTopReactionsForTeamSince(c *Context, w http.ResponseWriter, r *http.Requ return } - team, err := c.App.GetTeam(c.Params.TeamId) - if err != nil { - c.Err = err + team, appErr := c.App.GetTeam(c.Params.TeamId) + if appErr != nil { + c.Err = appErr return } @@ -44,27 +44,27 @@ func getTopReactionsForTeamSince(c *Context, w http.ResponseWriter, r *http.Requ return } - user, err := c.App.GetUser(c.AppContext.Session().UserId) - if err != nil { - c.Err = err + user, appErr := c.App.GetUser(c.AppContext.Session().UserId) + if appErr != nil { + c.Err = appErr return } startTime := model.StartOfDayForTimeRange(c.Params.TimeRange, user.GetTimezoneLocation()) - topReactionList, err := c.App.GetTopReactionsForTeamSince(c.Params.TeamId, c.AppContext.Session().UserId, &model.InsightsOpts{ + topReactionList, appErr := c.App.GetTopReactionsForTeamSince(c.Params.TeamId, c.AppContext.Session().UserId, &model.InsightsOpts{ StartUnixMilli: startTime.UnixMilli(), Page: c.Params.Page, PerPage: c.Params.PerPage, }) - if err != nil { - c.Err = err + if appErr != nil { + c.Err = appErr return } - js, jsonErr := json.Marshal(topReactionList) - if jsonErr != nil { - c.Err = model.NewAppError("getTopReactionsForTeamSince", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(topReactionList) + if err != nil { + c.Err = model.NewAppError("getTopReactionsForTeamSince", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } @@ -81,9 +81,9 @@ func getTopReactionsForUserSince(c *Context, w http.ResponseWriter, r *http.Requ return } - team, teamErr := c.App.GetTeam(c.Params.TeamId) - if teamErr != nil { - c.Err = teamErr + team, appErr := c.App.GetTeam(c.Params.TeamId) + if appErr != nil { + c.Err = appErr return } @@ -93,27 +93,27 @@ func getTopReactionsForUserSince(c *Context, w http.ResponseWriter, r *http.Requ } } - user, err := c.App.GetUser(c.AppContext.Session().UserId) - if err != nil { - c.Err = err + user, appErr := c.App.GetUser(c.AppContext.Session().UserId) + if appErr != nil { + c.Err = appErr return } startTime := model.StartOfDayForTimeRange(c.Params.TimeRange, user.GetTimezoneLocation()) - topReactionList, err := c.App.GetTopReactionsForUserSince(c.AppContext.Session().UserId, c.Params.TeamId, &model.InsightsOpts{ + topReactionList, appErr := c.App.GetTopReactionsForUserSince(c.AppContext.Session().UserId, c.Params.TeamId, &model.InsightsOpts{ StartUnixMilli: startTime.UnixMilli(), Page: c.Params.Page, PerPage: c.Params.PerPage, }) - if err != nil { - c.Err = err + if appErr != nil { + c.Err = appErr return } - js, jsonErr := json.Marshal(topReactionList) - if jsonErr != nil { - c.Err = model.NewAppError("getTopReactionsForUserSince", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(topReactionList) + if err != nil { + c.Err = model.NewAppError("getTopReactionsForUserSince", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } @@ -128,9 +128,9 @@ func getTopChannelsForTeamSince(c *Context, w http.ResponseWriter, r *http.Reque return } - team, err := c.App.GetTeam(c.Params.TeamId) - if err != nil { - c.Err = err + team, appErr := c.App.GetTeam(c.Params.TeamId) + if appErr != nil { + c.Err = appErr return } @@ -139,34 +139,34 @@ func getTopChannelsForTeamSince(c *Context, w http.ResponseWriter, r *http.Reque return } - user, err := c.App.GetUser(c.AppContext.Session().UserId) - if err != nil { - c.Err = err + user, appErr := c.App.GetUser(c.AppContext.Session().UserId) + if appErr != nil { + c.Err = appErr return } loc := user.GetTimezoneLocation() startTime := model.StartOfDayForTimeRange(c.Params.TimeRange, loc) - topChannels, err := c.App.GetTopChannelsForTeamSince(c.AppContext, c.Params.TeamId, c.AppContext.Session().UserId, &model.InsightsOpts{ + topChannels, appErr := c.App.GetTopChannelsForTeamSince(c.AppContext, c.Params.TeamId, c.AppContext.Session().UserId, &model.InsightsOpts{ StartUnixMilli: startTime.UnixMilli(), Page: c.Params.Page, PerPage: c.Params.PerPage, }) - if err != nil { - c.Err = err + if appErr != nil { + c.Err = appErr return } - topChannels.PostCountByDuration, err = postCountByDurationViewModel(c, topChannels, startTime, c.Params.TimeRange, nil, loc) - if err != nil { - c.Err = err + topChannels.PostCountByDuration, appErr = postCountByDurationViewModel(c, topChannels, startTime, c.Params.TimeRange, nil, loc) + if appErr != nil { + c.Err = appErr return } - js, jsonErr := json.Marshal(topChannels) - if jsonErr != nil { - c.Err = model.NewAppError("getTopChannelsForTeamSince", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(topChannels) + if err != nil { + c.Err = model.NewAppError("getTopChannelsForTeamSince", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } @@ -183,9 +183,9 @@ func getTopChannelsForUserSince(c *Context, w http.ResponseWriter, r *http.Reque return } - team, teamErr := c.App.GetTeam(c.Params.TeamId) - if teamErr != nil { - c.Err = teamErr + team, appErr := c.App.GetTeam(c.Params.TeamId) + if appErr != nil { + c.Err = appErr return } @@ -195,35 +195,34 @@ func getTopChannelsForUserSince(c *Context, w http.ResponseWriter, r *http.Reque } } - user, err := c.App.GetUser(c.AppContext.Session().UserId) - if err != nil { - c.Err = err + user, appErr := c.App.GetUser(c.AppContext.Session().UserId) + if appErr != nil { + c.Err = appErr return } loc := user.GetTimezoneLocation() startTime := model.StartOfDayForTimeRange(c.Params.TimeRange, loc) - topChannels, err := c.App.GetTopChannelsForUserSince(c.AppContext, c.AppContext.Session().UserId, c.Params.TeamId, &model.InsightsOpts{ + topChannels, appErr := c.App.GetTopChannelsForUserSince(c.AppContext, c.AppContext.Session().UserId, c.Params.TeamId, &model.InsightsOpts{ StartUnixMilli: startTime.UnixMilli(), Page: c.Params.Page, PerPage: c.Params.PerPage, }) - - if err != nil { - c.Err = err + if appErr != nil { + c.Err = appErr return } - topChannels.PostCountByDuration, err = postCountByDurationViewModel(c, topChannels, startTime, c.Params.TimeRange, &c.AppContext.Session().UserId, loc) - if err != nil { - c.Err = err + topChannels.PostCountByDuration, appErr = postCountByDurationViewModel(c, topChannels, startTime, c.Params.TimeRange, &c.AppContext.Session().UserId, loc) + if appErr != nil { + c.Err = appErr return } - js, jsonErr := json.Marshal(topChannels) - if jsonErr != nil { - c.Err = model.NewAppError("getTopChannelsForUserSince", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(topChannels) + if err != nil { + c.Err = model.NewAppError("getTopChannelsForUserSince", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } @@ -237,9 +236,9 @@ func getTopThreadsForTeamSince(c *Context, w http.ResponseWriter, r *http.Reques return } - team, err := c.App.GetTeam(c.Params.TeamId) - if err != nil { - c.Err = err + team, appErr := c.App.GetTeam(c.Params.TeamId) + if appErr != nil { + c.Err = appErr return } @@ -251,9 +250,9 @@ func getTopThreadsForTeamSince(c *Context, w http.ResponseWriter, r *http.Reques } // restrict guests and users with no access to team - user, err := c.App.GetUser(c.AppContext.Session().UserId) - if err != nil { - c.Err = err + user, appErr := c.App.GetUser(c.AppContext.Session().UserId) + if appErr != nil { + c.Err = appErr return } @@ -264,19 +263,19 @@ func getTopThreadsForTeamSince(c *Context, w http.ResponseWriter, r *http.Reques startTime := model.StartOfDayForTimeRange(c.Params.TimeRange, user.GetTimezoneLocation()) - topThreads, err := c.App.GetTopThreadsForTeamSince(c.AppContext, c.Params.TeamId, c.AppContext.Session().UserId, &model.InsightsOpts{ + topThreads, appErr := c.App.GetTopThreadsForTeamSince(c.AppContext, c.Params.TeamId, c.AppContext.Session().UserId, &model.InsightsOpts{ StartUnixMilli: startTime.UnixMilli(), Page: c.Params.Page, PerPage: c.Params.PerPage, }) - if err != nil { - c.Err = err + if appErr != nil { + c.Err = appErr return } - js, jsonErr := json.Marshal(topThreads) - if jsonErr != nil { - c.Err = model.NewAppError("getTopThreadsForTeamSince", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(topThreads) + if err != nil { + c.Err = model.NewAppError("getTopThreadsForTeamSince", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } @@ -287,9 +286,9 @@ func getTopThreadsForUserSince(c *Context, w http.ResponseWriter, r *http.Reques c.Params.TeamId = r.URL.Query().Get("team_id") // restrict guests and users with no access to team - user, err := c.App.GetUser(c.AppContext.Session().UserId) - if err != nil { - c.Err = err + user, appErr := c.App.GetUser(c.AppContext.Session().UserId) + if appErr != nil { + c.Err = appErr return } // TeamId is an optional parameter @@ -320,20 +319,19 @@ func getTopThreadsForUserSince(c *Context, w http.ResponseWriter, r *http.Reques startTime := model.StartOfDayForTimeRange(c.Params.TimeRange, user.GetTimezoneLocation()) - topThreads, err := c.App.GetTopThreadsForUserSince(c.AppContext, c.Params.TeamId, c.AppContext.Session().UserId, &model.InsightsOpts{ + topThreads, appErr := c.App.GetTopThreadsForUserSince(c.AppContext, c.Params.TeamId, c.AppContext.Session().UserId, &model.InsightsOpts{ StartUnixMilli: startTime.UnixMilli(), Page: c.Params.Page, PerPage: c.Params.PerPage, }) - - if err != nil { - c.Err = err + if appErr != nil { + c.Err = appErr return } - js, jsonErr := json.Marshal(topThreads) - if jsonErr != nil { - c.Err = model.NewAppError("getTopThreadsForUserSince", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(topThreads) + if err != nil { + c.Err = model.NewAppError("getTopThreadsForUserSince", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } diff --git a/api4/integration_action.go b/api4/integration_action.go index aa7e5d7319..41b1e3703c 100644 --- a/api4/integration_action.go +++ b/api4/integration_action.go @@ -33,14 +33,15 @@ func doPostAction(c *Context, w http.ResponseWriter, r *http.Request) { var cookie *model.PostActionCookie if actionRequest.Cookie != "" { cookie = &model.PostActionCookie{} - cookieStr, err := model.DecryptPostActionCookie(actionRequest.Cookie, c.App.PostActionCookieSecret()) + cookieStr := "" + cookieStr, err = model.DecryptPostActionCookie(actionRequest.Cookie, c.App.PostActionCookieSecret()) if err != nil { - c.Err = model.NewAppError("DoPostAction", "api.post.do_action.action_integration.app_error", nil, "err="+err.Error(), http.StatusBadRequest) + c.Err = model.NewAppError("DoPostAction", "api.post.do_action.action_integration.app_error", nil, "", http.StatusBadRequest).Wrap(err) return } err = json.Unmarshal([]byte(cookieStr), &cookie) if err != nil { - c.Err = model.NewAppError("DoPostAction", "api.post.do_action.action_integration.app_error", nil, "err="+err.Error(), http.StatusBadRequest) + c.Err = model.NewAppError("DoPostAction", "api.post.do_action.action_integration.app_error", nil, "", http.StatusBadRequest).Wrap(err) return } if !c.App.SessionHasPermissionToChannel(c.AppContext, *c.AppContext.Session(), cookie.ChannelId, model.PermissionReadChannel) { @@ -64,8 +65,10 @@ func doPostAction(c *Context, w http.ResponseWriter, r *http.Request) { return } - b, _ := json.Marshal(resp) - w.Write(b) + err = json.NewEncoder(w).Encode(resp) + if err != nil { + c.Logger.Warn("Error writing response", mlog.Err(err)) + } } func openDialog(c *Context, w http.ResponseWriter, r *http.Request) { @@ -81,8 +84,8 @@ func openDialog(c *Context, w http.ResponseWriter, r *http.Request) { return } - if err := c.App.OpenInteractiveDialog(dialog); err != nil { - c.Err = err + if appErr := c.App.OpenInteractiveDialog(dialog); appErr != nil { + c.Err = appErr return } diff --git a/api4/job.go b/api4/job.go index b0622ae8e3..58ee1350e2 100644 --- a/api4/job.go +++ b/api4/job.go @@ -162,15 +162,15 @@ func getJobs(c *Context, w http.ResponseWriter, r *http.Request) { return } - jobs, err := c.App.GetJobsByTypesPage(validJobTypes, c.Params.Page, c.Params.PerPage) - if err != nil { - c.Err = err + jobs, appErr := c.App.GetJobsByTypesPage(validJobTypes, c.Params.Page, c.Params.PerPage) + if appErr != nil { + c.Err = appErr return } - js, jsonErr := json.Marshal(jobs) - if jsonErr != nil { - c.Err = model.NewAppError("getJobs", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(jobs) + if err != nil { + c.Err = model.NewAppError("getJobs", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } w.Write(js) @@ -192,17 +192,18 @@ func getJobsByType(c *Context, w http.ResponseWriter, r *http.Request) { return } - jobs, err := c.App.GetJobsByTypePage(c.Params.JobType, c.Params.Page, c.Params.PerPage) - if err != nil { - c.Err = err + jobs, appErr := c.App.GetJobsByTypePage(c.Params.JobType, c.Params.Page, c.Params.PerPage) + if appErr != nil { + c.Err = appErr return } - js, jsonErr := json.Marshal(jobs) - if jsonErr != nil { - c.Err = model.NewAppError("getJobsByType", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(jobs) + if err != nil { + c.Err = model.NewAppError("getJobsByType", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } + w.Write(js) } diff --git a/api4/ldap.go b/api4/ldap.go index 60cd176c65..b71415c940 100644 --- a/api4/ldap.go +++ b/api4/ldap.go @@ -111,9 +111,9 @@ func getLdapGroups(c *Context, w http.ResponseWriter, r *http.Request) { opts.IsConfigured = c.Params.IsConfigured } - groups, total, err := c.App.GetAllLdapGroupsPage(c.Params.Page, c.Params.PerPage, opts) - if err != nil { - c.Err = err + groups, total, appErr := c.App.GetAllLdapGroupsPage(c.Params.Page, c.Params.PerPage, opts) + if appErr != nil { + c.Err = appErr return } @@ -130,12 +130,12 @@ func getLdapGroups(c *Context, w http.ResponseWriter, r *http.Request) { mugs = append(mugs, mug) } - b, marshalErr := json.Marshal(struct { + b, err := json.Marshal(struct { Count int `json:"count"` Groups []*mixedUnlinkedGroup `json:"groups"` }{Count: total, Groups: mugs}) - if marshalErr != nil { - c.Err = model.NewAppError("Api4.getLdapGroups", "api.marshal_error", nil, marshalErr.Error(), http.StatusInternalServerError) + if err != nil { + c.Err = model.NewAppError("Api4.getLdapGroups", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } @@ -162,9 +162,9 @@ func linkLdapGroup(c *Context, w http.ResponseWriter, r *http.Request) { return } - ldapGroup, err := c.App.GetLdapGroup(c.Params.RemoteId) - if err != nil { - c.Err = err + ldapGroup, appErr := c.App.GetLdapGroup(c.Params.RemoteId) + if appErr != nil { + c.Err = appErr return } @@ -175,9 +175,9 @@ func linkLdapGroup(c *Context, w http.ResponseWriter, r *http.Request) { return } - group, err := c.App.GetGroupByRemoteID(ldapGroup.GetRemoteId(), model.GroupSourceLdap) - if err != nil && err.Id != "app.group.no_rows" { - c.Err = err + group, appErr := c.App.GetGroupByRemoteID(ldapGroup.GetRemoteId(), model.GroupSourceLdap) + if appErr != nil && appErr.Id != "app.group.no_rows" { + c.Err = appErr return } if group != nil { @@ -203,9 +203,9 @@ func linkLdapGroup(c *Context, w http.ResponseWriter, r *http.Request) { group.DeleteAt = 0 group.DisplayName = displayName group.RemoteId = ldapGroup.RemoteId - newOrUpdatedGroup, err = c.App.UpdateGroup(group) - if err != nil { - c.Err = err + newOrUpdatedGroup, appErr = c.App.UpdateGroup(group) + if appErr != nil { + c.Err = appErr return } auditRec.AddEventResultState(newOrUpdatedGroup) @@ -222,9 +222,9 @@ func linkLdapGroup(c *Context, w http.ResponseWriter, r *http.Request) { RemoteId: ldapGroup.RemoteId, Source: model.GroupSourceLdap, } - newOrUpdatedGroup, err = c.App.CreateGroup(newGroup) - if err != nil { - c.Err = err + newOrUpdatedGroup, appErr = c.App.CreateGroup(newGroup) + if appErr != nil { + c.Err = appErr return } auditRec.AddEventResultState(newOrUpdatedGroup) @@ -232,9 +232,9 @@ func linkLdapGroup(c *Context, w http.ResponseWriter, r *http.Request) { status = http.StatusCreated } - b, marshalErr := json.Marshal(newOrUpdatedGroup) - if marshalErr != nil { - c.Err = model.NewAppError("Api4.linkLdapGroup", "api.marshal_error", nil, marshalErr.Error(), http.StatusInternalServerError) + b, err := json.Marshal(newOrUpdatedGroup) + if err != nil { + c.Err = model.NewAppError("Api4.linkLdapGroup", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } diff --git a/api4/oauth.go b/api4/oauth.go index 96a7ae4586..aa0e72bbfb 100644 --- a/api4/oauth.go +++ b/api4/oauth.go @@ -132,26 +132,27 @@ func getOAuthApps(c *Context, w http.ResponseWriter, r *http.Request) { } var apps []*model.OAuthApp - var err *model.AppError + var appErr *model.AppError if c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionManageSystemWideOAuth) { - apps, err = c.App.GetOAuthApps(c.Params.Page, c.Params.PerPage) + apps, appErr = c.App.GetOAuthApps(c.Params.Page, c.Params.PerPage) } else if c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionManageOAuth) { - apps, err = c.App.GetOAuthAppsByCreator(c.AppContext.Session().UserId, c.Params.Page, c.Params.PerPage) + apps, appErr = c.App.GetOAuthAppsByCreator(c.AppContext.Session().UserId, c.Params.Page, c.Params.PerPage) } else { c.SetPermissionError(model.PermissionManageOAuth) return } - if err != nil { - c.Err = err + if appErr != nil { + c.Err = appErr return } - js, jsonErr := json.Marshal(apps) - if jsonErr != nil { - c.Err = model.NewAppError("getOAuthApps", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(apps) + if err != nil { + c.Err = model.NewAppError("getOAuthApps", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } + w.Write(js) } @@ -295,16 +296,17 @@ func getAuthorizedOAuthApps(c *Context, w http.ResponseWriter, r *http.Request) return } - apps, err := c.App.GetAuthorizedAppsForUser(c.Params.UserId, c.Params.Page, c.Params.PerPage) - if err != nil { - c.Err = err + apps, appErr := c.App.GetAuthorizedAppsForUser(c.Params.UserId, c.Params.Page, c.Params.PerPage) + if appErr != nil { + c.Err = appErr return } - js, jsonErr := json.Marshal(apps) - if jsonErr != nil { - c.Err = model.NewAppError("getAuthorizedOAuthApps", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(apps) + if err != nil { + c.Err = model.NewAppError("getAuthorizedOAuthApps", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } + w.Write(js) } diff --git a/api4/permission.go b/api4/permission.go index 0ed4351071..a0aac0a6eb 100644 --- a/api4/permission.go +++ b/api4/permission.go @@ -26,8 +26,9 @@ func appendAncillaryPermissions(c *Context, w http.ResponseWriter, r *http.Reque permissions := strings.Split(keys[0], ",") b, err := json.Marshal(model.AddAncillaryPermissions(permissions)) if err != nil { - c.SetJSONEncodingError() + c.SetJSONEncodingError(err) return } + w.Write(b) } diff --git a/api4/plugin.go b/api4/plugin.go index 1ab0aae92c..775b515a57 100644 --- a/api4/plugin.go +++ b/api4/plugin.go @@ -251,9 +251,9 @@ func getWebappPlugins(c *Context, w http.ResponseWriter, r *http.Request) { return } - manifests, err := c.App.GetActivePluginManifests() - if err != nil { - c.Err = err + manifests, appErr := c.App.GetActivePluginManifests() + if appErr != nil { + c.Err = appErr return } @@ -268,11 +268,12 @@ func getWebappPlugins(c *Context, w http.ResponseWriter, r *http.Request) { } } - js, jsonErr := json.Marshal(clientManifests) - if jsonErr != nil { - c.Err = model.NewAppError("getWebappPlugins", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(clientManifests) + if err != nil { + c.Err = model.NewAppError("getWebappPlugins", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } + w.Write(js) } @@ -294,7 +295,7 @@ func getMarketplacePlugins(c *Context, w http.ResponseWriter, r *http.Request) { filter, err := parseMarketplacePluginFilter(r.URL) if err != nil { - c.Err = model.NewAppError("getMarketplacePlugins", "app.plugin.marshal.app_error", nil, err.Error(), http.StatusInternalServerError) + c.Err = model.NewAppError("getMarketplacePlugins", "app.plugin.marshal.app_error", nil, "", http.StatusInternalServerError).Wrap(err) return } @@ -306,7 +307,7 @@ func getMarketplacePlugins(c *Context, w http.ResponseWriter, r *http.Request) { json, err := json.Marshal(plugins) if err != nil { - c.Err = model.NewAppError("getMarketplacePlugins", "app.plugin.marshal.app_error", nil, err.Error(), http.StatusInternalServerError) + c.Err = model.NewAppError("getMarketplacePlugins", "app.plugin.marshal.app_error", nil, "", http.StatusInternalServerError).Wrap(err) return } diff --git a/api4/post.go b/api4/post.go index 7ae86bbc28..5f9cf2e7b1 100644 --- a/api4/post.go +++ b/api4/post.go @@ -970,9 +970,9 @@ func getFileInfosForPost(c *Context, w http.ResponseWriter, r *http.Request) { return } - infos, err := c.App.GetFileInfosForPostWithMigration(c.Params.PostId, includeDeleted) - if err != nil { - c.Err = err + infos, appErr := c.App.GetFileInfosForPostWithMigration(c.Params.PostId, includeDeleted) + if appErr != nil { + c.Err = appErr return } @@ -980,11 +980,12 @@ func getFileInfosForPost(c *Context, w http.ResponseWriter, r *http.Request) { return } - js, jsonErr := json.Marshal(infos) - if jsonErr != nil { - c.Err = model.NewAppError("getFileInfosForPost", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(infos) + if err != nil { + c.Err = model.NewAppError("getFileInfosForPost", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } + w.Header().Set("Cache-Control", "max-age=2592000, private") w.Header().Set(model.HeaderEtagServer, model.GetEtagForFileInfos(infos)) w.Write(js) diff --git a/api4/reaction.go b/api4/reaction.go index da95d63f5b..df097619cf 100644 --- a/api4/reaction.go +++ b/api4/reaction.go @@ -62,17 +62,18 @@ func getReactions(c *Context, w http.ResponseWriter, r *http.Request) { return } - reactions, err := c.App.GetReactionsForPost(c.Params.PostId) - if err != nil { - c.Err = err + reactions, appErr := c.App.GetReactionsForPost(c.Params.PostId) + if appErr != nil { + c.Err = appErr return } - js, jsonErr := json.Marshal(reactions) - if jsonErr != nil { - c.Err = model.NewAppError("getReactions", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(reactions) + if err != nil { + c.Err = model.NewAppError("getReactions", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } + w.Write(js) } @@ -125,15 +126,15 @@ func getBulkReactions(c *Context, w http.ResponseWriter, r *http.Request) { return } } - reactions, err := c.App.GetBulkReactionsForPosts(postIds) - if err != nil { - c.Err = err + reactions, appErr := c.App.GetBulkReactionsForPosts(postIds) + if appErr != nil { + c.Err = appErr return } - js, jsonErr := json.Marshal(reactions) - if jsonErr != nil { - c.Err = model.NewAppError("getBulkReactions", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(reactions) + if err != nil { + c.Err = model.NewAppError("getBulkReactions", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } w.Write(js) diff --git a/api4/remote_cluster.go b/api4/remote_cluster.go index d0956a38a9..0fe0be57be 100644 --- a/api4/remote_cluster.go +++ b/api4/remote_cluster.go @@ -31,8 +31,8 @@ func remoteClusterPing(c *Context, w http.ResponseWriter, r *http.Request) { } var frame model.RemoteClusterFrame - if jsonErr := json.NewDecoder(r.Body).Decode(&frame); jsonErr != nil { - c.Err = model.NewAppError("remoteClusterPing", "api.unmarshal_error", nil, "", http.StatusBadRequest).Wrap(jsonErr) + if err := json.NewDecoder(r.Body).Decode(&frame); err != nil { + c.Err = model.NewAppError("remoteClusterPing", "api.unmarshal_error", nil, "", http.StatusBadRequest).Wrap(err) return } @@ -47,15 +47,15 @@ func remoteClusterPing(c *Context, w http.ResponseWriter, r *http.Request) { return } - rc, err := c.App.GetRemoteCluster(frame.RemoteId) - if err != nil { + rc, appErr := c.App.GetRemoteCluster(frame.RemoteId) + if appErr != nil { c.SetInvalidRemoteIdError(frame.RemoteId) return } var ping model.RemoteClusterPing - if jsonErr := json.Unmarshal(frame.Msg.Payload, &ping); jsonErr != nil { - c.SetInvalidParam("msg.payload") + if err := json.Unmarshal(frame.Msg.Payload, &ping); err != nil { + c.SetInvalidParamWithErr("msg.payload", err) return } ping.RecvAt = model.GetMillis() @@ -64,8 +64,10 @@ func remoteClusterPing(c *Context, w http.ResponseWriter, r *http.Request) { metrics.IncrementRemoteClusterMsgReceivedCounter(rc.RemoteId) } - resp, _ := json.Marshal(&ping) - w.Write(resp) + err := json.NewEncoder(w).Encode(ping) + if err != nil { + c.Logger.Warn("Error writing response", mlog.Err(err)) + } } func remoteClusterAcceptMessage(c *Context, w http.ResponseWriter, r *http.Request) { @@ -77,12 +79,13 @@ func remoteClusterAcceptMessage(c *Context, w http.ResponseWriter, r *http.Reque } var frame model.RemoteClusterFrame - if jsonErr := json.NewDecoder(r.Body).Decode(&frame); jsonErr != nil { - c.Err = model.NewAppError("remoteClusterAcceptMessage", "api.unmarshal_error", nil, "", http.StatusBadRequest).Wrap(jsonErr) + if err := json.NewDecoder(r.Body).Decode(&frame); err != nil { + c.Err = model.NewAppError("remoteClusterAcceptMessage", "api.unmarshal_error", nil, "", http.StatusBadRequest).Wrap(err) return } - if appErr := frame.IsValid(); appErr != nil { + appErr = frame.IsValid() + if appErr != nil { c.Err = appErr return } @@ -97,8 +100,8 @@ func remoteClusterAcceptMessage(c *Context, w http.ResponseWriter, r *http.Reque return } - rc, err := c.App.GetRemoteCluster(frame.RemoteId) - if err != nil { + rc, appErr := c.App.GetRemoteCluster(frame.RemoteId) + if appErr != nil { c.SetInvalidRemoteIdError(frame.RemoteId) return } @@ -107,11 +110,12 @@ func remoteClusterAcceptMessage(c *Context, w http.ResponseWriter, r *http.Reque // pass message to Remote Cluster Service and write response resp := service.ReceiveIncomingMsg(rc, frame.Msg) - b, errMarshall := json.Marshal(resp) - if errMarshall != nil { - c.Err = model.NewAppError("remoteClusterAcceptMessage", "api.marshal_error", nil, errMarshall.Error(), http.StatusInternalServerError) + b, err := json.Marshal(resp) + if err != nil { + c.Err = model.NewAppError("remoteClusterAcceptMessage", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } + w.Write(b) } diff --git a/api4/role.go b/api4/role.go index f9ea2dda90..e404235ba1 100644 --- a/api4/role.go +++ b/api4/role.go @@ -32,15 +32,15 @@ func getAllRoles(c *Context, w http.ResponseWriter, r *http.Request) { return } - roles, err := c.App.GetAllRoles() - if err != nil { - c.Err = err + roles, appErr := c.App.GetAllRoles() + if appErr != nil { + c.Err = appErr return } - js, jsonErr := json.Marshal(roles) - if jsonErr != nil { - c.Err = model.NewAppError("getAllRoles", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(roles) + if err != nil { + c.Err = model.NewAppError("getAllRoles", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } @@ -95,17 +95,18 @@ func getRolesByNames(c *Context, w http.ResponseWriter, r *http.Request) { return } - roles, err := c.App.GetRolesByNames(cleanedRoleNames) - if err != nil { - c.Err = err + roles, appErr := c.App.GetRolesByNames(cleanedRoleNames) + if appErr != nil { + c.Err = appErr return } - js, jsonErr := json.Marshal(roles) - if jsonErr != nil { - c.Err = model.NewAppError("getRolesByNames", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(roles) + if err != nil { + c.Err = model.NewAppError("getRolesByNames", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } + w.Write(js) } @@ -116,8 +117,8 @@ func patchRole(c *Context, w http.ResponseWriter, r *http.Request) { } var patch model.RolePatch - if jsonErr := json.NewDecoder(r.Body).Decode(&patch); jsonErr != nil { - c.SetInvalidParamWithErr("role", jsonErr) + if err := json.NewDecoder(r.Body).Decode(&patch); err != nil { + c.SetInvalidParamWithErr("role", err) return } @@ -125,9 +126,9 @@ func patchRole(c *Context, w http.ResponseWriter, r *http.Request) { auditRec.AddEventParameter("role_patch", patch) defer c.LogAuditRec(auditRec) - oldRole, err := c.App.GetRole(c.Params.RoleId) - if err != nil { - c.Err = err + oldRole, appErr := c.App.GetRole(c.Params.RoleId) + if appErr != nil { + c.Err = appErr return } auditRec.AddEventPriorState(oldRole) @@ -203,9 +204,9 @@ func patchRole(c *Context, w http.ResponseWriter, r *http.Request) { } } - role, err := c.App.PatchRole(oldRole, &patch) - if err != nil { - c.Err = err + role, appErr := c.App.PatchRole(oldRole, &patch) + if appErr != nil { + c.Err = appErr return } diff --git a/api4/scheme.go b/api4/scheme.go index 200d8f554d..efb5f781b0 100644 --- a/api4/scheme.go +++ b/api4/scheme.go @@ -93,17 +93,18 @@ func getSchemes(c *Context, w http.ResponseWriter, r *http.Request) { return } - schemes, err := c.App.GetSchemesPage(c.Params.Scope, c.Params.Page, c.Params.PerPage) - if err != nil { - c.Err = err + schemes, appErr := c.App.GetSchemesPage(c.Params.Scope, c.Params.Page, c.Params.PerPage) + if appErr != nil { + c.Err = appErr return } - js, jsonErr := json.Marshal(schemes) - if jsonErr != nil { - c.Err = model.NewAppError("getSchemes", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(schemes) + if err != nil { + c.Err = model.NewAppError("getSchemes", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } + w.Write(js) } @@ -118,9 +119,9 @@ func getTeamsForScheme(c *Context, w http.ResponseWriter, r *http.Request) { return } - scheme, err := c.App.GetScheme(c.Params.SchemeId) - if err != nil { - c.Err = err + scheme, appErr := c.App.GetScheme(c.Params.SchemeId) + if appErr != nil { + c.Err = appErr return } @@ -129,17 +130,18 @@ func getTeamsForScheme(c *Context, w http.ResponseWriter, r *http.Request) { return } - teams, err := c.App.GetTeamsForSchemePage(scheme, c.Params.Page, c.Params.PerPage) - if err != nil { - c.Err = err + teams, appErr := c.App.GetTeamsForSchemePage(scheme, c.Params.Page, c.Params.PerPage) + if appErr != nil { + c.Err = appErr return } - js, jsonErr := json.Marshal(teams) - if jsonErr != nil { - c.Err = model.NewAppError("getTeamsForScheme", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(teams) + if err != nil { + c.Err = model.NewAppError("getTeamsForScheme", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } + w.Write(js) } diff --git a/api4/shared_channel.go b/api4/shared_channel.go index b2fc386bce..5e53ee5f33 100644 --- a/api4/shared_channel.go +++ b/api4/shared_channel.go @@ -50,9 +50,10 @@ func getSharedChannels(c *Context, w http.ResponseWriter, r *http.Request) { b, err := json.Marshal(channels) if err != nil { - c.SetJSONEncodingError() + c.SetJSONEncodingError(err) return } + w.Write(b) } @@ -80,7 +81,7 @@ func getRemoteClusterInfo(c *Context, w http.ResponseWriter, r *http.Request) { b, err := json.Marshal(remoteInfo) if err != nil { - c.SetJSONEncodingError() + c.SetJSONEncodingError(err) return } w.Write(b) diff --git a/api4/status.go b/api4/status.go index 5ecc754b9d..06311ee15b 100644 --- a/api4/status.go +++ b/api4/status.go @@ -64,17 +64,18 @@ func getUserStatusesByIds(c *Context, w http.ResponseWriter, r *http.Request) { } // No permission check required - statuses, err := c.App.GetUserStatusesByIds(userIds) - if err != nil { - c.Err = err + statuses, appErr := c.App.GetUserStatusesByIds(userIds) + if appErr != nil { + c.Err = appErr return } - js, jsonErr := json.Marshal(statuses) - if jsonErr != nil { - c.Err = model.NewAppError("getUserStatusesByIds", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(statuses) + if err != nil { + c.Err = model.NewAppError("getUserStatusesByIds", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } + w.Write(js) } diff --git a/api4/system.go b/api4/system.go index d35a2068c8..3d60335d63 100644 --- a/api4/system.go +++ b/api4/system.go @@ -195,7 +195,11 @@ func getSystemPing(c *Context, w http.ResponseWriter, r *http.Request) { } func testEmail(c *Context, w http.ResponseWriter, r *http.Request) { - cfg := model.ConfigFromJSON(r.Body) + var cfg *model.Config + err := json.NewDecoder(r.Body).Decode(&cfg) + if err != nil { + c.Logger.Warn("Error decoding the config", mlog.Err(err)) + } if cfg == nil { cfg = c.App.Config() } @@ -215,9 +219,9 @@ func testEmail(c *Context, w http.ResponseWriter, r *http.Request) { return } - err := c.App.TestEmail(c.AppContext.Session().UserId, cfg) - if err != nil { - c.Err = err + appErr := c.App.TestEmail(c.AppContext.Session().UserId, cfg) + if appErr != nil { + c.Err = appErr return } @@ -242,9 +246,9 @@ func testSiteURL(c *Context, w http.ResponseWriter, r *http.Request) { return } - err := c.App.TestSiteURL(siteURL) - if err != nil { - c.Err = err + appErr := c.App.TestSiteURL(siteURL) + if appErr != nil { + c.Err = appErr return } @@ -260,9 +264,9 @@ func getAudits(c *Context, w http.ResponseWriter, r *http.Request) { return } - audits, err := c.App.GetAuditsPage("", c.Params.Page, c.Params.PerPage) - if err != nil { - c.Err = err + audits, appErr := c.App.GetAuditsPage("", c.Params.Page, c.Params.PerPage) + if appErr != nil { + c.Err = appErr return } @@ -309,9 +313,9 @@ func invalidateCaches(c *Context, w http.ResponseWriter, r *http.Request) { return } - err := c.App.Srv().InvalidateAllCaches() - if err != nil { - c.Err = err + appErr := c.App.Srv().InvalidateAllCaches() + if appErr != nil { + c.Err = appErr return } @@ -335,9 +339,9 @@ func getLogs(c *Context, w http.ResponseWriter, r *http.Request) { return } - lines, err := c.App.GetLogs(c.Params.Page, c.Params.LogsPerPage) - if err != nil { - c.Err = err + lines, appErr := c.App.GetLogs(c.Params.Page, c.Params.LogsPerPage) + if appErr != nil { + c.Err = appErr return } @@ -361,7 +365,15 @@ func postLog(c *Context, w http.ResponseWriter, r *http.Request) { } } - m := model.MapFromJSON(r.Body) + var m map[string]string + err := json.NewDecoder(r.Body).Decode(&m) + if err != nil { + c.Logger.Warn("Error decoding request.", mlog.Err(err)) + } + if m == nil { + m = map[string]string{} + } + lvl := m["level"] msg := m["message"] @@ -382,7 +394,10 @@ func postLog(c *Context, w http.ResponseWriter, r *http.Request) { } m["message"] = msg - w.Write([]byte(model.MapToJSON(m))) + err = json.NewEncoder(w).Encode(m) + if err != nil { + c.Logger.Warn("Error while writing response.", mlog.Err(err)) + } } func getAnalytics(c *Context, w http.ResponseWriter, r *http.Request) { @@ -398,9 +413,9 @@ func getAnalytics(c *Context, w http.ResponseWriter, r *http.Request) { return } - rows, err := c.App.GetAnalytics(name, teamId) - if err != nil { - c.Err = err + rows, appErr := c.App.GetAnalytics(name, teamId) + if appErr != nil { + c.Err = appErr return } @@ -420,15 +435,15 @@ func getLatestVersion(c *Context, w http.ResponseWriter, r *http.Request) { return } - resp, err := c.App.GetLatestVersion("https://api.github.com/repos/mattermost/mattermost-server/releases/latest") - if err != nil { - c.Err = err + resp, appErr := c.App.GetLatestVersion("https://api.github.com/repos/mattermost/mattermost-server/releases/latest") + if appErr != nil { + c.Err = appErr return } - b, jsonErr := json.Marshal(resp) - if jsonErr != nil { - c.Logger.Warn("Unable to marshal JSON for latest version.", mlog.Err(jsonErr)) + b, err := json.Marshal(resp) + if err != nil { + c.Logger.Warn("Unable to marshal JSON for latest version.", mlog.Err(err)) w.WriteHeader(http.StatusInternalServerError) } @@ -451,7 +466,11 @@ func getSupportedTimezones(c *Context, w http.ResponseWriter, r *http.Request) { } func testS3(c *Context, w http.ResponseWriter, r *http.Request) { - cfg := model.ConfigFromJSON(r.Body) + var cfg *model.Config + err := json.NewDecoder(r.Body).Decode(&cfg) + if err != nil { + c.Logger.Warn("Error decoding the config", mlog.Err(err)) + } if cfg == nil { cfg = c.App.Config() } @@ -471,9 +490,9 @@ func testS3(c *Context, w http.ResponseWriter, r *http.Request) { return } - err := c.App.CheckMandatoryS3Fields(&cfg.FileSettings) - if err != nil { - c.Err = err + appErr := c.App.CheckMandatoryS3Fields(&cfg.FileSettings) + if appErr != nil { + c.Err = appErr return } @@ -481,7 +500,7 @@ func testS3(c *Context, w http.ResponseWriter, r *http.Request) { cfg.FileSettings.AmazonS3SecretAccessKey = c.App.Config().FileSettings.AmazonS3SecretAccessKey } - appErr := c.App.TestFileStoreConnectionWithConfig(&cfg.FileSettings) + appErr = c.App.TestFileStoreConnectionWithConfig(&cfg.FileSettings) if appErr != nil { c.Err = appErr return @@ -776,17 +795,18 @@ func getWarnMetricsStatus(c *Context, w http.ResponseWriter, r *http.Request) { return } - status, err := c.App.GetWarnMetricsStatus() - if err != nil { - c.Err = err + status, appErr := c.App.GetWarnMetricsStatus() + if appErr != nil { + c.Err = appErr return } - js, jsonErr := json.Marshal(status) - if jsonErr != nil { - c.Err = model.NewAppError("getWarnMetricsStatus", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(status) + if err != nil { + c.Err = model.NewAppError("getWarnMetricsStatus", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } + w.Write(js) } @@ -871,10 +891,9 @@ func getProductNotices(c *Context, w http.ResponseWriter, r *http.Request) { clientVersion := r.URL.Query().Get("clientVersion") locale := r.URL.Query().Get("locale") - notices, err := c.App.GetProductNotices(c.AppContext, c.AppContext.Session().UserId, c.Params.TeamId, client, clientVersion, locale) - - if err != nil { - c.Err = err + notices, appErr := c.App.GetProductNotices(c.AppContext, c.AppContext.Session().UserId, c.Params.TeamId, client, clientVersion, locale) + if appErr != nil { + c.Err = appErr return } result, _ := notices.Marshal() @@ -887,9 +906,9 @@ func updateViewedProductNotices(c *Context, w http.ResponseWriter, r *http.Reque c.LogAudit("attempt") ids := model.ArrayFromJSON(r.Body) - err := c.App.UpdateViewedProductNotices(c.AppContext.Session().UserId, ids) - if err != nil { - c.Err = err + appErr := c.App.UpdateViewedProductNotices(c.AppContext.Session().UserId, ids) + if appErr != nil { + c.Err = appErr return } @@ -910,7 +929,7 @@ func getOnboarding(c *Context, w http.ResponseWriter, r *http.Request) { firstAdminCompleteSetupObj, err := c.App.GetOnboarding() if err != nil { - c.Err = model.NewAppError("getOnboarding", "app.system.get_onboarding_request.app_error", nil, err.Error(), http.StatusInternalServerError) + c.Err = model.NewAppError("getOnboarding", "app.system.get_onboarding_request.app_error", nil, "", http.StatusInternalServerError).Wrap(err) return } @@ -931,7 +950,7 @@ func completeOnboarding(c *Context, w http.ResponseWriter, r *http.Request) { onboardingRequest, err := model.CompleteOnboardingRequestFromReader(r.Body) if err != nil { - c.Err = model.NewAppError("completeOnboarding", "app.system.complete_onboarding_request.app_error", nil, err.Error(), http.StatusBadRequest) + c.Err = model.NewAppError("completeOnboarding", "app.system.complete_onboarding_request.app_error", nil, "", http.StatusBadRequest).Wrap(err) return } auditRec.AddEventParameter("install_plugin", onboardingRequest.InstallPlugins) @@ -962,9 +981,9 @@ func getAppliedSchemaMigrations(c *Context, w http.ResponseWriter, r *http.Reque return } - js, jsonErr := json.Marshal(migrations) - if jsonErr != nil { - c.Err = model.NewAppError("getAppliedMigrations", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(migrations) + if err != nil { + c.Err = model.NewAppError("getAppliedMigrations", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } diff --git a/api4/system_local.go b/api4/system_local.go index 3b316f0f53..4559ab8d8c 100644 --- a/api4/system_local.go +++ b/api4/system_local.go @@ -33,7 +33,7 @@ func localCheckIntegrity(c *Context, w http.ResponseWriter, r *http.Request) { data, err := json.Marshal(results) if err != nil { - c.Err = model.NewAppError("Api4.localCheckIntegrity", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) + c.Err = model.NewAppError("Api4.localCheckIntegrity", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } diff --git a/api4/team.go b/api4/team.go index fac2d489c3..5ee8a0d3da 100644 --- a/api4/team.go +++ b/api4/team.go @@ -485,19 +485,20 @@ func getTeamsForUser(c *Context, w http.ResponseWriter, r *http.Request) { return } - teams, err := c.App.GetTeamsForUser(c.Params.UserId) - if err != nil { - c.Err = err + teams, appErr := c.App.GetTeamsForUser(c.Params.UserId) + if appErr != nil { + c.Err = appErr return } c.App.SanitizeTeams(*c.AppContext.Session(), teams) - js, jsonErr := json.Marshal(teams) - if jsonErr != nil { - c.Err = model.NewAppError("getTeamsForUser", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(teams) + if err != nil { + c.Err = model.NewAppError("getTeamsForUser", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } + w.Write(js) } @@ -516,15 +517,15 @@ func getTeamsUnreadForUser(c *Context, w http.ResponseWriter, r *http.Request) { teamId := r.URL.Query().Get("exclude_team") includeCollapsedThreads := r.URL.Query().Get("include_collapsed_threads") == "true" - unreadTeamsList, err := c.App.GetTeamsUnreadForUser(teamId, c.Params.UserId, includeCollapsedThreads) - if err != nil { - c.Err = err + unreadTeamsList, appErr := c.App.GetTeamsUnreadForUser(teamId, c.Params.UserId, includeCollapsedThreads) + if appErr != nil { + c.Err = appErr return } - js, jsonErr := json.Marshal(unreadTeamsList) - if jsonErr != nil { - c.Err = model.NewAppError("getTeamsUnreadForUser", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(unreadTeamsList) + if err != nil { + c.Err = model.NewAppError("getTeamsUnreadForUser", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } w.Write(js) @@ -541,9 +542,9 @@ func getTeamMember(c *Context, w http.ResponseWriter, r *http.Request) { return } - canSee, err := c.App.UserCanSeeOtherUser(c.AppContext.Session().UserId, c.Params.UserId) - if err != nil { - c.Err = err + canSee, appErr := c.App.UserCanSeeOtherUser(c.AppContext.Session().UserId, c.Params.UserId) + if appErr != nil { + c.Err = appErr return } @@ -552,9 +553,9 @@ func getTeamMember(c *Context, w http.ResponseWriter, r *http.Request) { return } - team, err := c.App.GetTeamMember(c.Params.TeamId, c.Params.UserId) - if err != nil { - c.Err = err + team, appErr := c.App.GetTeamMember(c.Params.TeamId, c.Params.UserId) + if appErr != nil { + c.Err = appErr return } @@ -578,9 +579,9 @@ func getTeamMembers(c *Context, w http.ResponseWriter, r *http.Request) { return } - restrictions, err := c.App.GetViewUsersRestrictions(c.AppContext.Session().UserId) - if err != nil { - c.Err = err + restrictions, appErr := c.App.GetViewUsersRestrictions(c.AppContext.Session().UserId) + if appErr != nil { + c.Err = appErr return } @@ -590,17 +591,18 @@ func getTeamMembers(c *Context, w http.ResponseWriter, r *http.Request) { ViewRestrictions: restrictions, } - members, err := c.App.GetTeamMembers(c.Params.TeamId, c.Params.Page*c.Params.PerPage, c.Params.PerPage, teamMembersGetOptions) - if err != nil { - c.Err = err + members, appErr := c.App.GetTeamMembers(c.Params.TeamId, c.Params.Page*c.Params.PerPage, c.Params.PerPage, teamMembersGetOptions) + if appErr != nil { + c.Err = appErr return } - js, jsonErr := json.Marshal(members) - if jsonErr != nil { - c.Err = model.NewAppError("getTeamMembers", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(members) + if err != nil { + c.Err = model.NewAppError("getTeamMembers", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } + w.Write(js) } @@ -615,9 +617,9 @@ func getTeamMembersForUser(c *Context, w http.ResponseWriter, r *http.Request) { return } - canSee, err := c.App.UserCanSeeOtherUser(c.AppContext.Session().UserId, c.Params.UserId) - if err != nil { - c.Err = err + canSee, appErr := c.App.UserCanSeeOtherUser(c.AppContext.Session().UserId, c.Params.UserId) + if appErr != nil { + c.Err = appErr return } @@ -626,17 +628,18 @@ func getTeamMembersForUser(c *Context, w http.ResponseWriter, r *http.Request) { return } - members, err := c.App.GetTeamMembersForUser(c.Params.UserId, "", true) - if err != nil { - c.Err = err + members, appErr := c.App.GetTeamMembersForUser(c.Params.UserId, "", true) + if appErr != nil { + c.Err = appErr return } - js, jsonErr := json.Marshal(members) - if jsonErr != nil { - c.Err = model.NewAppError("getTeamMembersForUser", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(members) + if err != nil { + c.Err = model.NewAppError("getTeamMembersForUser", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } + w.Write(js) } @@ -646,10 +649,10 @@ func getTeamMembersByIds(c *Context, w http.ResponseWriter, r *http.Request) { return } - userIds := model.ArrayFromJSON(r.Body) - - if len(userIds) == 0 { - c.SetInvalidParam("user_ids") + var userIDs []string + err := json.NewDecoder(r.Body).Decode(&userIDs) + if err != nil || len(userIDs) == 0 { + c.SetInvalidParamWithErr("user_ids", err) return } @@ -658,23 +661,24 @@ func getTeamMembersByIds(c *Context, w http.ResponseWriter, r *http.Request) { return } - restrictions, err := c.App.GetViewUsersRestrictions(c.AppContext.Session().UserId) - if err != nil { - c.Err = err + restrictions, appErr := c.App.GetViewUsersRestrictions(c.AppContext.Session().UserId) + if appErr != nil { + c.Err = appErr return } - members, err := c.App.GetTeamMembersByIds(c.Params.TeamId, userIds, restrictions) - if err != nil { - c.Err = err + members, appErr := c.App.GetTeamMembersByIds(c.Params.TeamId, userIDs, restrictions) + if appErr != nil { + c.Err = appErr return } - js, jsonErr := json.Marshal(members) - if jsonErr != nil { - c.Err = model.NewAppError("getTeamMembersByIds", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(members) + if err != nil { + c.Err = model.NewAppError("getTeamMembersByIds", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } + w.Write(js) } @@ -815,7 +819,7 @@ func addTeamMembers(c *Context, w http.ResponseWriter, r *http.Request) { return } - var err *model.AppError + var appErr *model.AppError var members []*model.TeamMember if jsonErr := json.NewDecoder(r.Body).Decode(&members); jsonErr != nil { c.SetInvalidParamWithErr("members", jsonErr) @@ -843,9 +847,9 @@ func addTeamMembers(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec.AddMeta("user_ids", memberIDs) - team, err := c.App.GetTeam(c.Params.TeamId) - if err != nil { - c.Err = err + team, appErr := c.App.GetTeam(c.Params.TeamId) + if appErr != nil { + c.Err = appErr return } auditRec.AddMeta("team", team) @@ -856,7 +860,7 @@ func addTeamMembers(c *Context, w http.ResponseWriter, r *http.Request) { if v, ok := err.(*model.AppError); ok { c.Err = v } else { - c.Err = model.NewAppError("addTeamMembers", "api.team.add_members.error", nil, err.Error(), http.StatusBadRequest) + c.Err = model.NewAppError("addTeamMembers", "api.team.add_members.error", nil, "", http.StatusBadRequest).Wrap(err) } return } @@ -866,7 +870,7 @@ func addTeamMembers(c *Context, w http.ResponseWriter, r *http.Request) { } } - var userIds []string + var userIDs []string for _, member := range members { if member.TeamId != c.Params.TeamId { c.SetInvalidParam("team_id for member with user_id=" + member.UserId) @@ -878,7 +882,7 @@ func addTeamMembers(c *Context, w http.ResponseWriter, r *http.Request) { return } - userIds = append(userIds, member.UserId) + userIDs = append(userIDs, member.UserId) } if !c.App.SessionHasPermissionToTeam(*c.AppContext.Session(), c.Params.TeamId, model.PermissionAddUserToTeam) { @@ -886,9 +890,9 @@ func addTeamMembers(c *Context, w http.ResponseWriter, r *http.Request) { return } - membersWithErrors, err := c.App.AddTeamMembers(c.AppContext, c.Params.TeamId, userIds, c.AppContext.Session().UserId, graceful) + membersWithErrors, appErr := c.App.AddTeamMembers(c.AppContext, c.Params.TeamId, userIDs, c.AppContext.Session().UserId, graceful) - if membersWithErrors != nil { + if len(membersWithErrors) != 0 { errList := make([]string, 0, len(membersWithErrors)) for _, m := range membersWithErrors { if m.Error != nil { @@ -897,21 +901,23 @@ func addTeamMembers(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec.AddMeta("errors", errList) } - if err != nil { - c.Err = err + if appErr != nil { + c.Err = appErr return } - var js []byte - var jsonErr error + var ( + js []byte + err error + ) if graceful { // in 'graceful' mode we allow a different return value, notifying the client which users were not added - js, jsonErr = json.Marshal(membersWithErrors) + js, err = json.Marshal(membersWithErrors) } else { - js, jsonErr = json.Marshal(model.TeamMembersWithErrorToTeamMembers(membersWithErrors)) + js, err = json.Marshal(model.TeamMembersWithErrorToTeamMembers(membersWithErrors)) } - if jsonErr != nil { - c.Err = model.NewAppError("addTeamMembers", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err != nil { + c.Err = model.NewAppError("addTeamMembers", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } @@ -1095,7 +1101,7 @@ func updateTeamMemberSchemeRoles(c *Context, w http.ResponseWriter, r *http.Requ func getAllTeams(c *Context, w http.ResponseWriter, r *http.Request) { teams := []*model.Team{} - var err *model.AppError + var appErr *model.AppError var teamsWithCount *model.TeamsWithCount opts := &model.TeamSearch{} @@ -1126,26 +1132,28 @@ func getAllTeams(c *Context, w http.ResponseWriter, r *http.Request) { } if c.Params.IncludeTotalCount { - teamsWithCount, err = c.App.GetAllTeamsPageWithCount(offset, limit, opts) + teamsWithCount, appErr = c.App.GetAllTeamsPageWithCount(offset, limit, opts) } else { - teams, err = c.App.GetAllTeamsPage(offset, limit, opts) + teams, appErr = c.App.GetAllTeamsPage(offset, limit, opts) } - if err != nil { - c.Err = err + if appErr != nil { + c.Err = appErr return } - var js []byte - var jsonErr error + var ( + js []byte + err error + ) if c.Params.IncludeTotalCount { c.App.SanitizeTeams(*c.AppContext.Session(), teamsWithCount.Teams) - js, jsonErr = json.Marshal(teamsWithCount) + js, err = json.Marshal(teamsWithCount) } else { c.App.SanitizeTeams(*c.AppContext.Session(), teams) - js, jsonErr = json.Marshal(teams) + js, err = json.Marshal(teams) } - if jsonErr != nil { - c.Err = model.NewAppError("getAllTeams", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err != nil { + c.Err = model.NewAppError("getAllTeams", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } @@ -1154,8 +1162,8 @@ func getAllTeams(c *Context, w http.ResponseWriter, r *http.Request) { func searchTeams(c *Context, w http.ResponseWriter, r *http.Request) { var props model.TeamSearch - if jsonErr := json.NewDecoder(r.Body).Decode(&props); jsonErr != nil { - c.SetInvalidParamWithErr("team_search", jsonErr) + if err := json.NewDecoder(r.Body).Decode(&props); err != nil { + c.SetInvalidParamWithErr("team_search", err) return } // Only system managers may use the ExcludePolicyConstrained field @@ -1169,30 +1177,32 @@ func searchTeams(c *Context, w http.ResponseWriter, r *http.Request) { props.IncludePolicyID = model.NewBool(true) } - var teams []*model.Team - var totalCount int64 - var err *model.AppError + var ( + teams []*model.Team + totalCount int64 + appErr *model.AppError + ) if c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionListPrivateTeams) && c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionListPublicTeams) { - teams, totalCount, err = c.App.SearchAllTeams(&props) + teams, totalCount, appErr = c.App.SearchAllTeams(&props) } else if c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionListPrivateTeams) { if props.Page != nil || props.PerPage != nil { c.Err = model.NewAppError("searchTeams", "api.team.search_teams.pagination_not_implemented.private_team_search", nil, "", http.StatusNotImplemented) return } - teams, err = c.App.SearchPrivateTeams(&props) + teams, appErr = c.App.SearchPrivateTeams(&props) } else if c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionListPublicTeams) { if props.Page != nil || props.PerPage != nil { c.Err = model.NewAppError("searchTeams", "api.team.search_teams.pagination_not_implemented.public_team_search", nil, "", http.StatusNotImplemented) return } - teams, err = c.App.SearchPublicTeams(&props) + teams, appErr = c.App.SearchPublicTeams(&props) } else { teams = []*model.Team{} } - if err != nil { - c.Err = err + if appErr != nil { + c.Err = appErr return } @@ -1203,9 +1213,9 @@ func searchTeams(c *Context, w http.ResponseWriter, r *http.Request) { twc := map[string]any{"teams": teams, "total_count": totalCount} payload = model.ToJSON(twc) } else { - js, jsonErr := json.Marshal(teams) - if jsonErr != nil { - c.Err = model.NewAppError("searchTeams", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(teams) + if err != nil { + c.Err = model.NewAppError("searchTeams", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } payload = js @@ -1357,26 +1367,26 @@ func inviteUsersToTeam(c *Context, w http.ResponseWriter, r *http.Request) { bf, err := io.ReadAll(r.Body) if err != nil { - c.Err = model.NewAppError("Api4.inviteUsersToTeams", "api.team.invite_members_to_team_and_channels.invalid_body.app_error", nil, err.Error(), http.StatusBadRequest) + c.Err = model.NewAppError("Api4.inviteUsersToTeams", "api.team.invite_members_to_team_and_channels.invalid_body.app_error", nil, "", http.StatusBadRequest).Wrap(err) return } memberInvite := &model.MemberInvite{} - if jsonErr := json.Unmarshal(bf, memberInvite); jsonErr != nil { - c.Err = model.NewAppError("Api4.inviteUsersToTeams", "api.team.invite_members_to_team_and_channels.invalid_body_parsing.app_error", nil, jsonErr.Error(), http.StatusBadRequest) + if err := json.Unmarshal(bf, memberInvite); err != nil { + c.Err = model.NewAppError("Api4.inviteUsersToTeams", "api.team.invite_members_to_team_and_channels.invalid_body_parsing.app_error", nil, "", http.StatusBadRequest).Wrap(err) return } emailList := memberInvite.Emails - for i := range emailList { - emailList[i] = strings.ToLower(emailList[i]) - } - if len(emailList) == 0 { c.SetInvalidParam("user_email") return } + for i := range emailList { + emailList[i] = strings.ToLower(emailList[i]) + } + auditRec := c.MakeAuditRecord("inviteUsersToTeam", audit.Fail) defer c.LogAuditRec(auditRec) auditRec.AddEventParameter("member_invite", memberInvite) @@ -1391,9 +1401,9 @@ func inviteUsersToTeam(c *Context, w http.ResponseWriter, r *http.Request) { if graceful { var invitesWithError []*model.EmailInviteWithError - var err *model.AppError + var appErr *model.AppError if emailList != nil { - invitesWithError, err = c.App.InviteNewUsersToTeamGracefully(memberInvite, c.Params.TeamId, c.AppContext.Session().UserId, "") + invitesWithError, appErr = c.App.InviteNewUsersToTeamGracefully(memberInvite, c.Params.TeamId, c.AppContext.Session().UserId, "") } if invitesWithError != nil { @@ -1405,8 +1415,8 @@ func inviteUsersToTeam(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec.AddMeta("errors", errList) } - if err != nil { - c.Err = err + if appErr != nil { + c.Err = appErr return } @@ -1424,23 +1434,24 @@ func inviteUsersToTeam(c *Context, w http.ResponseWriter, r *http.Request) { } // we then manually schedule the job to send another invite after 48 hours - _, e := c.App.Srv().Jobs.CreateJob(model.JobTypeResendInvitationEmail, jobData) - if e != nil { - c.Err = model.NewAppError("Api4.inviteUsersToTeam", e.Id, nil, e.Error(), e.StatusCode) + _, appErr = c.App.Srv().Jobs.CreateJob(model.JobTypeResendInvitationEmail, jobData) + if appErr != nil { + c.Err = model.NewAppError("Api4.inviteUsersToTeam", appErr.Id, nil, appErr.Error(), appErr.StatusCode) return } // in graceful mode we return both the successful ones and the failed ones - js, jsonErr := json.Marshal(invitesWithError) - if jsonErr != nil { - c.Err = model.NewAppError("inviteUsersToTeam", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(invitesWithError) + if err != nil { + c.Err = model.NewAppError("inviteUsersToTeam", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } + w.Write(js) } else { - err := c.App.InviteNewUsersToTeam(emailList, c.Params.TeamId, c.AppContext.Session().UserId) - if err != nil { - c.Err = err + appErr := c.App.InviteNewUsersToTeam(emailList, c.Params.TeamId, c.AppContext.Session().UserId) + if appErr != nil { + c.Err = appErr return } ReturnStatusOK(w) @@ -1475,8 +1486,8 @@ func inviteGuestsToChannels(c *Context, w http.ResponseWriter, r *http.Request) } var guestsInvite model.GuestsInvite - if jsonErr := json.NewDecoder(r.Body).Decode(&guestsInvite); jsonErr != nil { - c.Err = model.NewAppError("Api4.inviteGuestsToChannels", "api.team.invite_guests_to_channels.invalid_body.app_error", nil, "", http.StatusBadRequest).Wrap(jsonErr) + if err := json.NewDecoder(r.Body).Decode(&guestsInvite); err != nil { + c.Err = model.NewAppError("Api4.inviteGuestsToChannels", "api.team.invite_guests_to_channels.invalid_body.app_error", nil, "", http.StatusBadRequest).Wrap(err) return } auditRec.AddEventParameter("guests_invite", guestsInvite) @@ -1484,8 +1495,8 @@ func inviteGuestsToChannels(c *Context, w http.ResponseWriter, r *http.Request) for i, email := range guestsInvite.Emails { guestsInvite.Emails[i] = strings.ToLower(email) } - if err := guestsInvite.IsValid(); err != nil { - c.Err = err + if appErr := guestsInvite.IsValid(); appErr != nil { + c.Err = appErr return } auditRec.AddMeta("email_count", len(guestsInvite.Emails)) @@ -1495,32 +1506,33 @@ func inviteGuestsToChannels(c *Context, w http.ResponseWriter, r *http.Request) if graceful { var invitesWithError []*model.EmailInviteWithError - var err *model.AppError + var appErr *model.AppError if guestsInvite.Emails != nil { - invitesWithError, err = c.App.InviteGuestsToChannelsGracefully(c.Params.TeamId, &guestsInvite, c.AppContext.Session().UserId) + invitesWithError, appErr = c.App.InviteGuestsToChannelsGracefully(c.Params.TeamId, &guestsInvite, c.AppContext.Session().UserId) } - if err != nil { + if appErr != nil { errList := make([]string, 0, len(invitesWithError)) for _, inv := range invitesWithError { errList = append(errList, model.EmailInviteWithErrorToString(inv)) } auditRec.AddMeta("errors", errList) - c.Err = err + c.Err = appErr return } // in graceful mode we return both the successful ones and the failed ones - js, jsonErr := json.Marshal(invitesWithError) - if jsonErr != nil { - c.Err = model.NewAppError("inviteGuestsToChannel", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(invitesWithError) + if err != nil { + c.Err = model.NewAppError("inviteGuestsToChannel", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } + w.Write(js) } else { - err := c.App.InviteGuestsToChannels(c.Params.TeamId, &guestsInvite, c.AppContext.Session().UserId) - if err != nil { - c.Err = err + appErr := c.App.InviteGuestsToChannels(c.Params.TeamId, &guestsInvite, c.AppContext.Session().UserId) + if appErr != nil { + c.Err = appErr return } ReturnStatusOK(w) @@ -1534,9 +1546,9 @@ func getInviteInfo(c *Context, w http.ResponseWriter, r *http.Request) { return } - team, err := c.App.GetTeamByInviteId(c.Params.InviteId) - if err != nil { - c.Err = err + team, appErr := c.App.GetTeamByInviteId(c.Params.InviteId) + if appErr != nil { + c.Err = appErr return } @@ -1545,12 +1557,22 @@ func getInviteInfo(c *Context, w http.ResponseWriter, r *http.Request) { return } - result := map[string]string{} - result["display_name"] = team.DisplayName - result["description"] = team.Description - result["name"] = team.Name - result["id"] = team.Id - w.Write([]byte(model.MapToJSON(result))) + result := struct { + DisplayName string `json:"display_name"` + Description string `json:"description"` + Name string `json:"name"` + ID string `json:"id"` + }{ + DisplayName: team.DisplayName, + Description: team.Description, + Name: team.Name, + ID: team.Id, + } + + err := json.NewEncoder(w).Encode(result) + if err != nil { + c.Logger.Warn("Error writing response", mlog.Err(err)) + } } func invalidateAllEmailInvites(c *Context, w http.ResponseWriter, r *http.Request) { @@ -1781,23 +1803,23 @@ func teamMembersMinusGroupMembers(c *Context, w http.ResponseWriter, r *http.Req return } - users, totalCount, err := c.App.TeamMembersMinusGroupMembers( + users, totalCount, appErr := c.App.TeamMembersMinusGroupMembers( c.Params.TeamId, groupIDs, c.Params.Page, c.Params.PerPage, ) - if err != nil { - c.Err = err + if appErr != nil { + c.Err = appErr return } - b, marshalErr := json.Marshal(&model.UsersWithGroupsAndCount{ + b, err := json.Marshal(&model.UsersWithGroupsAndCount{ Users: users, Count: totalCount, }) - if marshalErr != nil { - c.Err = model.NewAppError("Api4.teamMembersMinusGroupMembers", "api.marshal_error", nil, marshalErr.Error(), http.StatusInternalServerError) + if err != nil { + c.Err = model.NewAppError("Api4.teamMembersMinusGroupMembers", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } diff --git a/api4/team_local.go b/api4/team_local.go index 29a93c6c0e..66b5bc96b9 100644 --- a/api4/team_local.go +++ b/api4/team_local.go @@ -81,12 +81,13 @@ func localInviteUsersToTeam(c *Context, w http.ResponseWriter, r *http.Request) bf, err := io.ReadAll(r.Body) if err != nil { - c.Err = model.NewAppError("Api4.inviteUsersToTeams", "api.team.invite_members_to_team_and_channels.invalid_body.app_error", nil, err.Error(), http.StatusBadRequest) + c.Err = model.NewAppError("Api4.inviteUsersToTeams", "api.team.invite_members_to_team_and_channels.invalid_body.app_error", nil, "", http.StatusBadRequest).Wrap(err) return } memberInvite := &model.MemberInvite{} - if jsonErr := json.Unmarshal(bf, memberInvite); jsonErr != nil { - c.Err = model.NewAppError("Api4.inviteUsersToTeams", "api.team.invite_members_to_team_and_channels.invalid_body_parsing.app_error", nil, jsonErr.Error(), http.StatusBadRequest) + err = json.Unmarshal(bf, memberInvite) + if err != nil { + c.Err = model.NewAppError("Api4.inviteUsersToTeams", "api.team.invite_members_to_team_and_channels.invalid_body_parsing.app_error", nil, "", http.StatusBadRequest).Wrap(err) return } @@ -117,14 +118,14 @@ func localInviteUsersToTeam(c *Context, w http.ResponseWriter, r *http.Request) auditRec.AddMeta("channels", memberInvite.ChannelIds) } - team, nErr := c.App.Srv().Store.Team().Get(c.Params.TeamId) - if nErr != nil { + team, err := c.App.Srv().Store.Team().Get(c.Params.TeamId) + if err != nil { var nfErr *store.ErrNotFound switch { - case errors.As(nErr, &nfErr): - c.Err = model.NewAppError("localInviteUsersToTeam", "app.team.get.find.app_error", nil, nfErr.Error(), http.StatusNotFound) + case errors.As(err, &nfErr): + c.Err = model.NewAppError("localInviteUsersToTeam", "app.team.get.find.app_error", nil, "", http.StatusNotFound).Wrap(err) default: - c.Err = model.NewAppError("localInviteUsersToTeam", "app.team.get.finding.app_error", nil, nErr.Error(), http.StatusInternalServerError) + c.Err = model.NewAppError("localInviteUsersToTeam", "app.team.get.finding.app_error", nil, "", http.StatusInternalServerError).Wrap(err) } return } @@ -135,7 +136,7 @@ func localInviteUsersToTeam(c *Context, w http.ResponseWriter, r *http.Request) if len(memberInvite.ChannelIds) > 0 { channels, err = c.App.Srv().Store.Channel().GetChannelsByIds(memberInvite.ChannelIds, false) if err != nil { - c.Err = model.NewAppError("prepareLocalInviteNewUsersToTeam", "app.channel.get_channels_by_ids.app_error", nil, err.Error(), http.StatusInternalServerError) + c.Err = model.NewAppError("prepareLocalInviteNewUsersToTeam", "app.channel.get_channels_by_ids.app_error", nil, "", http.StatusInternalServerError).Wrap(err) } } @@ -157,33 +158,34 @@ func localInviteUsersToTeam(c *Context, w http.ResponseWriter, r *http.Request) } auditRec.AddMeta("errors", errList) if len(goodEmails) > 0 { - var eErr error var invitesWithErrors2 []*model.EmailInviteWithError if len(channels) > 0 { - invitesWithErrors2, eErr = c.App.Srv().EmailService.SendInviteEmailsToTeamAndChannels(team, channels, "Administrator", "mmctl "+model.NewId(), nil, goodEmails, *c.App.Config().ServiceSettings.SiteURL, nil, memberInvite.Message, true) + invitesWithErrors2, err = c.App.Srv().EmailService.SendInviteEmailsToTeamAndChannels(team, channels, "Administrator", "mmctl "+model.NewId(), nil, goodEmails, *c.App.Config().ServiceSettings.SiteURL, nil, memberInvite.Message, true) invitesWithErrors = append(invitesWithErrors, invitesWithErrors2...) } else { - eErr = c.App.Srv().EmailService.SendInviteEmails(team, "Administrator", "mmctl "+model.NewId(), goodEmails, *c.App.Config().ServiceSettings.SiteURL, nil, false) + err = c.App.Srv().EmailService.SendInviteEmails(team, "Administrator", "mmctl "+model.NewId(), goodEmails, *c.App.Config().ServiceSettings.SiteURL, nil, false) } - if eErr != nil { + if err != nil { switch { case errors.Is(err, email.NoRateLimiterError): - c.Err = model.NewAppError("SendInviteEmails", "app.email.no_rate_limiter.app_error", nil, fmt.Sprintf("team_id=%s", team.Id), http.StatusInternalServerError) + c.Err = model.NewAppError("SendInviteEmails", "app.email.no_rate_limiter.app_error", nil, fmt.Sprintf("team_id=%s", team.Id), http.StatusInternalServerError).Wrap(err) case errors.Is(err, email.SetupRateLimiterError): - c.Err = model.NewAppError("SendInviteEmails", "app.email.setup_rate_limiter.app_error", nil, fmt.Sprintf("team_id=%s, error=%v", team.Id, err), http.StatusInternalServerError) + c.Err = model.NewAppError("SendInviteEmails", "app.email.setup_rate_limiter.app_error", nil, fmt.Sprintf("team_id=%s, error=%v", team.Id, err), http.StatusInternalServerError).Wrap(err) default: - c.Err = model.NewAppError("SendInviteEmails", "app.email.rate_limit_exceeded.app_error", nil, fmt.Sprintf("team_id=%s, error=%v", team.Id, err), http.StatusRequestEntityTooLarge) + c.Err = model.NewAppError("SendInviteEmails", "app.email.rate_limit_exceeded.app_error", nil, fmt.Sprintf("team_id=%s, error=%v", team.Id, err), http.StatusRequestEntityTooLarge).Wrap(err) } return } } + // in graceful mode we return both the successful ones and the failed ones - js, jsonErr := json.Marshal(invitesWithErrors) - if jsonErr != nil { - c.Err = model.NewAppError("localInviteUsersToTeam", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(invitesWithErrors) + if err != nil { + c.Err = model.NewAppError("localInviteUsersToTeam", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } + w.Write(js) } else { var invalidEmailList []string @@ -202,11 +204,11 @@ func localInviteUsersToTeam(c *Context, w http.ResponseWriter, r *http.Request) if err != nil { switch { case errors.Is(err, email.NoRateLimiterError): - c.Err = model.NewAppError("SendInviteEmails", "app.email.no_rate_limiter.app_error", nil, fmt.Sprintf("team_id=%s", team.Id), http.StatusInternalServerError) + c.Err = model.NewAppError("SendInviteEmails", "app.email.no_rate_limiter.app_error", nil, fmt.Sprintf("team_id=%s", team.Id), http.StatusInternalServerError).Wrap(err) case errors.Is(err, email.SetupRateLimiterError): - c.Err = model.NewAppError("SendInviteEmails", "app.email.setup_rate_limiter.app_error", nil, fmt.Sprintf("team_id=%s, error=%v", team.Id, err), http.StatusInternalServerError) + c.Err = model.NewAppError("SendInviteEmails", "app.email.setup_rate_limiter.app_error", nil, fmt.Sprintf("team_id=%s, error=%v", team.Id, err), http.StatusInternalServerError).Wrap(err) default: - c.Err = model.NewAppError("SendInviteEmails", "app.email.rate_limit_exceeded.app_error", nil, fmt.Sprintf("team_id=%s, error=%v", team.Id, err), http.StatusRequestEntityTooLarge) + c.Err = model.NewAppError("SendInviteEmails", "app.email.rate_limit_exceeded.app_error", nil, fmt.Sprintf("team_id=%s, error=%v", team.Id, err), http.StatusRequestEntityTooLarge).Wrap(err) } return } diff --git a/api4/usage.go b/api4/usage.go index 10581291c0..3822972ba4 100644 --- a/api4/usage.go +++ b/api4/usage.go @@ -25,13 +25,13 @@ func (api *API) InitUsage() { func getPostsUsage(c *Context, w http.ResponseWriter, r *http.Request) { count, appErr := c.App.GetPostsUsage() if appErr != nil { - c.Err = model.NewAppError("Api4.getPostsUsage", "app.post.analytics_posts_count.app_error", nil, appErr.Error(), http.StatusInternalServerError) + c.Err = model.NewAppError("Api4.getPostsUsage", "app.post.analytics_posts_count.app_error", nil, "", http.StatusInternalServerError).Wrap(appErr) return } json, err := json.Marshal(&model.PostsUsage{Count: count}) if err != nil { - c.Err = model.NewAppError("Api4.getPostsUsage", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) + c.Err = model.NewAppError("Api4.getPostsUsage", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } @@ -41,14 +41,14 @@ func getPostsUsage(c *Context, w http.ResponseWriter, r *http.Request) { func getStorageUsage(c *Context, w http.ResponseWriter, r *http.Request) { usage, appErr := c.App.GetStorageUsage() if appErr != nil { - c.Err = model.NewAppError("Api4.getStorageUsage", "app.usage.get_storage_usage.app_error", nil, appErr.Error(), http.StatusInternalServerError) + c.Err = model.NewAppError("Api4.getStorageUsage", "app.usage.get_storage_usage.app_error", nil, "", http.StatusInternalServerError).Wrap(appErr) return } usage = utils.RoundOffToZeroesResolution(float64(usage), 8) json, err := json.Marshal(&model.StorageUsage{Bytes: usage}) if err != nil { - c.Err = model.NewAppError("Api4.getStorageUsage", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) + c.Err = model.NewAppError("Api4.getStorageUsage", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } @@ -58,17 +58,17 @@ func getStorageUsage(c *Context, w http.ResponseWriter, r *http.Request) { func getTeamsUsage(c *Context, w http.ResponseWriter, r *http.Request) { teamsUsage, appErr := c.App.GetTeamsUsage() if appErr != nil { - c.Err = model.NewAppError("Api4.getTeamsUsage", "app.teams.analytics_teams_count.app_error", nil, appErr.Error(), http.StatusInternalServerError) + c.Err = model.NewAppError("Api4.getTeamsUsage", "app.teams.analytics_teams_count.app_error", nil, "", http.StatusInternalServerError).Wrap(appErr) return } if teamsUsage == nil { - c.Err = model.NewAppError("Api4.getTeamsUsage", "app.teams.analytics_teams_count.app_error", nil, appErr.Error(), http.StatusInternalServerError) + c.Err = model.NewAppError("Api4.getTeamsUsage", "app.teams.analytics_teams_count.app_error", nil, "", http.StatusInternalServerError).Wrap(appErr) } json, err := json.Marshal(teamsUsage) if err != nil { - c.Err = model.NewAppError("Api4.getTeamsUsage", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) + c.Err = model.NewAppError("Api4.getTeamsUsage", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } @@ -79,7 +79,7 @@ func getIntegrationsUsage(c *Context, w http.ResponseWriter, r *http.Request) { if !*c.App.Config().PluginSettings.Enable { json, err := json.Marshal(&model.IntegrationsUsage{}) if err != nil { - c.Err = model.NewAppError("Api4.getIntegrationsUsage", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) + c.Err = model.NewAppError("Api4.getIntegrationsUsage", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } @@ -95,7 +95,7 @@ func getIntegrationsUsage(c *Context, w http.ResponseWriter, r *http.Request) { json, err := json.Marshal(usage) if err != nil { - c.Err = model.NewAppError("Api4.getIntegrationsUsage", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) + c.Err = model.NewAppError("Api4.getIntegrationsUsage", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } diff --git a/api4/user.go b/api4/user.go index c1d682e560..8dd75f03ee 100644 --- a/api4/user.go +++ b/api4/user.go @@ -622,32 +622,37 @@ func getUsersByGroupChannelIds(c *Context, w http.ResponseWriter, r *http.Reques return } - usersByChannelId, err := c.App.GetUsersByGroupChannelIds(c.AppContext, channelIds, c.IsSystemAdmin()) - if err != nil { - c.Err = err + usersByChannelId, appErr := c.App.GetUsersByGroupChannelIds(c.AppContext, channelIds, c.IsSystemAdmin()) + if appErr != nil { + c.Err = appErr return } - b, _ := json.Marshal(usersByChannelId) - w.Write(b) + err := json.NewEncoder(w).Encode(usersByChannelId) + if err != nil { + c.Logger.Warn("Error writing response", mlog.Err(err)) + } } func getUsers(c *Context, w http.ResponseWriter, r *http.Request) { - inTeamId := r.URL.Query().Get("in_team") - notInTeamId := r.URL.Query().Get("not_in_team") - inChannelId := r.URL.Query().Get("in_channel") - inGroupId := r.URL.Query().Get("in_group") - notInGroupId := r.URL.Query().Get("not_in_group") - notInChannelId := r.URL.Query().Get("not_in_channel") - groupConstrained := r.URL.Query().Get("group_constrained") - withoutTeam := r.URL.Query().Get("without_team") - inactive := r.URL.Query().Get("inactive") - active := r.URL.Query().Get("active") - role := r.URL.Query().Get("role") - sort := r.URL.Query().Get("sort") - rolesString := r.URL.Query().Get("roles") - channelRolesString := r.URL.Query().Get("channel_roles") - teamRolesString := r.URL.Query().Get("team_roles") + var ( + query = r.URL.Query() + inTeamId = query.Get("in_team") + notInTeamId = query.Get("not_in_team") + inChannelId = query.Get("in_channel") + inGroupId = query.Get("in_group") + notInGroupId = query.Get("not_in_group") + notInChannelId = query.Get("not_in_channel") + groupConstrained = query.Get("group_constrained") + withoutTeam = query.Get("without_team") + inactive = query.Get("inactive") + active = query.Get("active") + role = query.Get("role") + sort = query.Get("sort") + rolesString = query.Get("roles") + channelRolesString = query.Get("channel_roles") + teamRolesString = query.Get("team_roles") + ) if notInChannelId != "" && inTeamId == "" { c.SetInvalidURLParam("team_id") @@ -674,10 +679,12 @@ func getUsers(c *Context, w http.ResponseWriter, r *http.Request) { return } - withoutTeamBool, _ := strconv.ParseBool(withoutTeam) - groupConstrainedBool, _ := strconv.ParseBool(groupConstrained) - inactiveBool, _ := strconv.ParseBool(inactive) - activeBool, _ := strconv.ParseBool(active) + var ( + withoutTeamBool, _ = strconv.ParseBool(withoutTeam) + groupConstrainedBool, _ = strconv.ParseBool(groupConstrained) + inactiveBool, _ = strconv.ParseBool(inactive) + activeBool, _ = strconv.ParseBool(active) + ) if inactiveBool && activeBool { c.SetInvalidURLParam("inactive") @@ -709,9 +716,9 @@ func getUsers(c *Context, w http.ResponseWriter, r *http.Request) { } } - restrictions, err := c.App.GetViewUsersRestrictions(c.AppContext.Session().UserId) - if err != nil { - c.Err = err + restrictions, appErr := c.App.GetViewUsersRestrictions(c.AppContext.Session().UserId) + if appErr != nil { + c.Err = appErr return } @@ -736,14 +743,16 @@ func getUsers(c *Context, w http.ResponseWriter, r *http.Request) { ViewRestrictions: restrictions, } - var profiles []*model.User - etag := "" + var ( + profiles []*model.User + etag string + ) if inChannelId != "" { if !*c.App.Config().TeamSettings.ExperimentalViewArchivedChannels { - channel, appErr := c.App.GetChannel(c.AppContext, inChannelId) - if appErr != nil { - c.Err = appErr + channel, cErr := c.App.GetChannel(c.AppContext, inChannelId) + if cErr != nil { + c.Err = cErr return } if channel.DeleteAt != 0 { @@ -760,14 +769,14 @@ func getUsers(c *Context, w http.ResponseWriter, r *http.Request) { return } - profiles, err = c.App.GetUsersWithoutTeamPage(userGetOptions, c.IsSystemAdmin()) + profiles, appErr = c.App.GetUsersWithoutTeamPage(userGetOptions, c.IsSystemAdmin()) } else if notInChannelId != "" { if !c.App.SessionHasPermissionToChannel(c.AppContext, *c.AppContext.Session(), notInChannelId, model.PermissionReadChannel) { c.SetPermissionError(model.PermissionReadChannel) return } - profiles, err = c.App.GetUsersNotInChannelPage(inTeamId, notInChannelId, groupConstrainedBool, c.Params.Page, c.Params.PerPage, c.IsSystemAdmin(), restrictions) + profiles, appErr = c.App.GetUsersNotInChannelPage(inTeamId, notInChannelId, groupConstrainedBool, c.Params.Page, c.Params.PerPage, c.IsSystemAdmin(), restrictions) } else if notInTeamId != "" { if !c.App.SessionHasPermissionToTeam(*c.AppContext.Session(), notInTeamId, model.PermissionViewTeam) { c.SetPermissionError(model.PermissionViewTeam) @@ -779,7 +788,7 @@ func getUsers(c *Context, w http.ResponseWriter, r *http.Request) { return } - profiles, err = c.App.GetUsersNotInTeamPage(notInTeamId, groupConstrainedBool, c.Params.Page, c.Params.PerPage, c.IsSystemAdmin(), restrictions) + profiles, appErr = c.App.GetUsersNotInTeamPage(notInTeamId, groupConstrainedBool, c.Params.Page, c.Params.PerPage, c.IsSystemAdmin(), restrictions) } else if inTeamId != "" { if !c.App.SessionHasPermissionToTeam(*c.AppContext.Session(), inTeamId, model.PermissionViewTeam) { c.SetPermissionError(model.PermissionViewTeam) @@ -787,15 +796,15 @@ func getUsers(c *Context, w http.ResponseWriter, r *http.Request) { } if sort == "last_activity_at" { - profiles, err = c.App.GetRecentlyActiveUsersForTeamPage(inTeamId, c.Params.Page, c.Params.PerPage, c.IsSystemAdmin(), restrictions) + profiles, appErr = c.App.GetRecentlyActiveUsersForTeamPage(inTeamId, c.Params.Page, c.Params.PerPage, c.IsSystemAdmin(), restrictions) } else if sort == "create_at" { - profiles, err = c.App.GetNewUsersForTeamPage(inTeamId, c.Params.Page, c.Params.PerPage, c.IsSystemAdmin(), restrictions) + profiles, appErr = c.App.GetNewUsersForTeamPage(inTeamId, c.Params.Page, c.Params.PerPage, c.IsSystemAdmin(), restrictions) } else { etag = c.App.GetUsersInTeamEtag(inTeamId, restrictions.Hash()) if c.HandleEtag(etag, "Get Users in Team", w, r) { return } - profiles, err = c.App.GetUsersInTeamPage(userGetOptions, c.IsSystemAdmin()) + profiles, appErr = c.App.GetUsersInTeamPage(userGetOptions, c.IsSystemAdmin()) } } else if inChannelId != "" { if !c.App.SessionHasPermissionToChannel(c.AppContext, *c.AppContext.Session(), inChannelId, model.PermissionReadChannel) { @@ -804,11 +813,11 @@ func getUsers(c *Context, w http.ResponseWriter, r *http.Request) { } if sort == "status" { - profiles, err = c.App.GetUsersInChannelPageByStatus(userGetOptions, c.IsSystemAdmin()) + profiles, appErr = c.App.GetUsersInChannelPageByStatus(userGetOptions, c.IsSystemAdmin()) } else if sort == "admin" { - profiles, err = c.App.GetUsersInChannelPageByAdmin(userGetOptions, c.IsSystemAdmin()) + profiles, appErr = c.App.GetUsersInChannelPageByAdmin(userGetOptions, c.IsSystemAdmin()) } else { - profiles, err = c.App.GetUsersInChannelPage(userGetOptions, c.IsSystemAdmin()) + profiles, appErr = c.App.GetUsersInChannelPage(userGetOptions, c.IsSystemAdmin()) } } else if inGroupId != "" { if gErr := requireGroupAccess(c, inGroupId); gErr != nil { @@ -817,34 +826,35 @@ func getUsers(c *Context, w http.ResponseWriter, r *http.Request) { return } - profiles, _, err = c.App.GetGroupMemberUsersPage(inGroupId, c.Params.Page, c.Params.PerPage) - if err != nil { - c.Err = err + profiles, _, appErr = c.App.GetGroupMemberUsersPage(inGroupId, c.Params.Page, c.Params.PerPage) + if appErr != nil { + c.Err = appErr return } } else if notInGroupId != "" { - if gErr := requireGroupAccess(c, notInGroupId); gErr != nil { - gErr.Where = "Api.getUsers" - c.Err = gErr + appErr = requireGroupAccess(c, notInGroupId) + if appErr != nil { + appErr.Where = "Api.getUsers" + c.Err = appErr return } - profiles, err = c.App.GetUsersNotInGroupPage(notInGroupId, c.Params.Page, c.Params.PerPage) - if err != nil { - c.Err = err + profiles, appErr = c.App.GetUsersNotInGroupPage(notInGroupId, c.Params.Page, c.Params.PerPage) + if appErr != nil { + c.Err = appErr return } } else { - userGetOptions, err = c.App.RestrictUsersGetByPermissions(c.AppContext.Session().UserId, userGetOptions) - if err != nil { - c.Err = err + userGetOptions, appErr = c.App.RestrictUsersGetByPermissions(c.AppContext.Session().UserId, userGetOptions) + if appErr != nil { + c.Err = appErr return } - profiles, err = c.App.GetUsersPage(userGetOptions, c.IsSystemAdmin()) + profiles, appErr = c.App.GetUsersPage(userGetOptions, c.IsSystemAdmin()) } - if err != nil { - c.Err = err + if appErr != nil { + c.Err = appErr return } @@ -853,9 +863,9 @@ func getUsers(c *Context, w http.ResponseWriter, r *http.Request) { } c.App.UpdateLastActivityAtIfNeeded(*c.AppContext.Session()) - js, jsonErr := json.Marshal(profiles) - if jsonErr != nil { - c.Err = model.NewAppError("getUsers", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(profiles) + if err != nil { + c.Err = model.NewAppError("getUsers", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } @@ -882,10 +892,10 @@ func requireGroupAccess(c *web.Context, groupID string) *model.AppError { } func getUsersByIds(c *Context, w http.ResponseWriter, r *http.Request) { - userIds := model.ArrayFromJSON(r.Body) - - if len(userIds) == 0 { - c.SetInvalidParam("user_ids") + var userIDs []string + err := json.NewDecoder(r.Body).Decode(&userIDs) + if err != nil || len(userIDs) == 0 { + c.SetInvalidParamWithErr("user_ids", err) return } @@ -896,30 +906,30 @@ func getUsersByIds(c *Context, w http.ResponseWriter, r *http.Request) { } if sinceString != "" { - since, parseError := strconv.ParseInt(sinceString, 10, 64) - if parseError != nil { - c.SetInvalidParam("since") + since, sErr := strconv.ParseInt(sinceString, 10, 64) + if sErr != nil { + c.SetInvalidParamWithErr("since", sErr) return } options.Since = since } - restrictions, err := c.App.GetViewUsersRestrictions(c.AppContext.Session().UserId) - if err != nil { - c.Err = err + restrictions, appErr := c.App.GetViewUsersRestrictions(c.AppContext.Session().UserId) + if appErr != nil { + c.Err = appErr return } options.ViewRestrictions = restrictions - users, err := c.App.GetUsersByIds(userIds, options) - if err != nil { - c.Err = err + users, appErr := c.App.GetUsersByIds(userIDs, options) + if appErr != nil { + c.Err = appErr return } - js, jsonErr := json.Marshal(users) - if jsonErr != nil { - c.Err = model.NewAppError("getUsersByIds", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(users) + if err != nil { + c.Err = model.NewAppError("getUsersByIds", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } @@ -927,28 +937,28 @@ func getUsersByIds(c *Context, w http.ResponseWriter, r *http.Request) { } func getUsersByNames(c *Context, w http.ResponseWriter, r *http.Request) { - usernames := model.ArrayFromJSON(r.Body) - - if len(usernames) == 0 { - c.SetInvalidParam("usernames") + var usernames []string + err := json.NewDecoder(r.Body).Decode(&usernames) + if err != nil || len(usernames) == 0 { + c.SetInvalidParamWithErr("usernames", err) return } - restrictions, err := c.App.GetViewUsersRestrictions(c.AppContext.Session().UserId) + restrictions, appErr := c.App.GetViewUsersRestrictions(c.AppContext.Session().UserId) + if appErr != nil { + c.Err = appErr + return + } + + users, appErr := c.App.GetUsersByUsernames(usernames, c.IsSystemAdmin(), restrictions) + if appErr != nil { + c.Err = appErr + return + } + + js, err := json.Marshal(users) if err != nil { - c.Err = err - return - } - - users, err := c.App.GetUsersByUsernames(usernames, c.IsSystemAdmin(), restrictions) - if err != nil { - c.Err = err - return - } - - js, jsonErr := json.Marshal(users) - if jsonErr != nil { - c.Err = model.NewAppError("getUsersByNames", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + c.Err = model.NewAppError("getUsersByNames", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } @@ -956,21 +966,22 @@ func getUsersByNames(c *Context, w http.ResponseWriter, r *http.Request) { } func getKnownUsers(c *Context, w http.ResponseWriter, r *http.Request) { - userIds, err := c.App.GetKnownUsers(c.AppContext.Session().UserId) - if err != nil { - c.Err = err + userIDs, appErr := c.App.GetKnownUsers(c.AppContext.Session().UserId) + if appErr != nil { + c.Err = appErr return } - data, _ := json.Marshal(userIds) - - w.Write(data) + err := json.NewEncoder(w).Encode(userIDs) + if err != nil { + c.Logger.Warn("Error writing response", mlog.Err(err)) + } } func searchUsers(c *Context, w http.ResponseWriter, r *http.Request) { var props model.UserSearch - if jsonErr := json.NewDecoder(r.Body).Decode(&props); jsonErr != nil { - c.SetInvalidParamWithErr("props", jsonErr) + if err := json.NewDecoder(r.Body).Decode(&props); err != nil { + c.SetInvalidParamWithErr("props", err) return } @@ -989,17 +1000,17 @@ func searchUsers(c *Context, w http.ResponseWriter, r *http.Request) { } if props.InGroupId != "" { - if gErr := requireGroupAccess(c, props.InGroupId); gErr != nil { - gErr.Where = "Api.searchUsers" - c.Err = gErr + if appErr := requireGroupAccess(c, props.InGroupId); appErr != nil { + appErr.Where = "Api.searchUsers" + c.Err = appErr return } } if props.NotInGroupId != "" { - if gErr := requireGroupAccess(c, props.NotInGroupId); gErr != nil { - gErr.Where = "Api.searchUsers" - c.Err = gErr + if appErr := requireGroupAccess(c, props.NotInGroupId); appErr != nil { + appErr.Where = "Api.searchUsers" + c.Err = appErr return } } @@ -1048,21 +1059,21 @@ func searchUsers(c *Context, w http.ResponseWriter, r *http.Request) { options.AllowFullNames = *c.App.Config().PrivacySettings.ShowFullName } - options, err := c.App.RestrictUsersSearchByPermissions(c.AppContext.Session().UserId, options) - if err != nil { - c.Err = err + options, appErr := c.App.RestrictUsersSearchByPermissions(c.AppContext.Session().UserId, options) + if appErr != nil { + c.Err = appErr return } - profiles, err := c.App.SearchUsers(&props, options) - if err != nil { - c.Err = err + profiles, appErr := c.App.SearchUsers(&props, options) + if appErr != nil { + c.Err = appErr return } - js, jsonErr := json.Marshal(profiles) - if jsonErr != nil { - c.Err = model.NewAppError("searchUsers", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(profiles) + if err != nil { + c.Err = model.NewAppError("searchUsers", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } @@ -1973,9 +1984,9 @@ func getSessions(c *Context, w http.ResponseWriter, r *http.Request) { return } - sessions, err := c.App.GetSessions(c.Params.UserId) - if err != nil { - c.Err = err + sessions, appErr := c.App.GetSessions(c.Params.UserId) + if appErr != nil { + c.Err = appErr return } @@ -1983,11 +1994,12 @@ func getSessions(c *Context, w http.ResponseWriter, r *http.Request) { session.Sanitize() } - js, jsonErr := json.Marshal(sessions) - if jsonErr != nil { - c.Err = model.NewAppError("getSessions", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(sessions) + if err != nil { + c.Err = model.NewAppError("getSessions", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } + w.Write(js) } @@ -2343,8 +2355,8 @@ func searchUserAccessTokens(c *Context, w http.ResponseWriter, r *http.Request) } var props model.UserAccessTokenSearch - if jsonErr := json.NewDecoder(r.Body).Decode(&props); jsonErr != nil { - c.SetInvalidParamWithErr("user_access_token_search", jsonErr) + if err := json.NewDecoder(r.Body).Decode(&props); err != nil { + c.SetInvalidParamWithErr("user_access_token_search", err) return } @@ -2353,15 +2365,15 @@ func searchUserAccessTokens(c *Context, w http.ResponseWriter, r *http.Request) return } - accessTokens, err := c.App.SearchUserAccessTokens(props.Term) - if err != nil { - c.Err = err + accessTokens, appErr := c.App.SearchUserAccessTokens(props.Term) + if appErr != nil { + c.Err = appErr return } - js, jsonErr := json.Marshal(accessTokens) - if jsonErr != nil { - c.Err = model.NewAppError("searchUserAccessTokens", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(accessTokens) + if err != nil { + c.Err = model.NewAppError("searchUserAccessTokens", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } @@ -2374,15 +2386,15 @@ func getUserAccessTokens(c *Context, w http.ResponseWriter, r *http.Request) { return } - accessTokens, err := c.App.GetUserAccessTokens(c.Params.Page, c.Params.PerPage) - if err != nil { - c.Err = err + accessTokens, appErr := c.App.GetUserAccessTokens(c.Params.Page, c.Params.PerPage) + if appErr != nil { + c.Err = appErr return } - js, jsonErr := json.Marshal(accessTokens) - if jsonErr != nil { - c.Err = model.NewAppError("searchUserAccessTokens", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(accessTokens) + if err != nil { + c.Err = model.NewAppError("searchUserAccessTokens", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } @@ -2405,15 +2417,15 @@ func getUserAccessTokensForUser(c *Context, w http.ResponseWriter, r *http.Reque return } - accessTokens, err := c.App.GetUserAccessTokensForUser(c.Params.UserId, c.Params.Page, c.Params.PerPage) - if err != nil { - c.Err = err + accessTokens, appErr := c.App.GetUserAccessTokensForUser(c.Params.UserId, c.Params.Page, c.Params.PerPage) + if appErr != nil { + c.Err = appErr return } - js, jsonErr := json.Marshal(accessTokens) - if jsonErr != nil { - c.Err = model.NewAppError("searchUserAccessTokens", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(accessTokens) + if err != nil { + c.Err = model.NewAppError("searchUserAccessTokens", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } @@ -2431,9 +2443,9 @@ func getUserAccessToken(c *Context, w http.ResponseWriter, r *http.Request) { return } - accessToken, err := c.App.GetUserAccessToken(c.Params.TokenId, true) - if err != nil { - c.Err = err + accessToken, appErr := c.App.GetUserAccessToken(c.Params.TokenId, true) + if appErr != nil { + c.Err = appErr return } @@ -2791,9 +2803,9 @@ func convertUserToBot(c *Context, w http.ResponseWriter, r *http.Request) { return } - user, err := c.App.GetUser(c.Params.UserId) - if err != nil { - c.Err = err + user, appErr := c.App.GetUser(c.Params.UserId) + if appErr != nil { + c.Err = appErr return } @@ -2807,9 +2819,9 @@ func convertUserToBot(c *Context, w http.ResponseWriter, r *http.Request) { return } - bot, err := c.App.ConvertUserToBot(user) - if err != nil { - c.Err = err + bot, appErr := c.App.ConvertUserToBot(user) + if appErr != nil { + c.Err = appErr return } @@ -2817,9 +2829,9 @@ func convertUserToBot(c *Context, w http.ResponseWriter, r *http.Request) { auditRec.AddEventResultState(bot) auditRec.AddEventObjectType("bot") - js, jsonErr := json.Marshal(bot) - if jsonErr != nil { - c.Err = model.NewAppError("convertUserToBot", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(bot) + if err != nil { + c.Err = model.NewAppError("convertUserToBot", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } @@ -2839,15 +2851,15 @@ func getUploadsForUser(c *Context, w http.ResponseWriter, r *http.Request) { return } - uss, err := c.App.GetUploadSessionsForUser(c.Params.UserId) - if err != nil { - c.Err = err + uss, appErr := c.App.GetUploadSessionsForUser(c.Params.UserId) + if appErr != nil { + c.Err = appErr return } - js, jsonErr := json.Marshal(uss) - if jsonErr != nil { - c.Err = model.NewAppError("getUploadsForUser", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(uss) + if err != nil { + c.Err = model.NewAppError("getUploadsForUser", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } w.Write(js) @@ -3252,14 +3264,16 @@ func getUsersWithInvalidEmails(c *Context, w http.ResponseWriter, r *http.Reques return } - users, err := c.App.GetUsersWithInvalidEmails(c.Params.Page, c.Params.PerPage) - if err != nil { - c.Err = err + users, appErr := c.App.GetUsersWithInvalidEmails(c.Params.Page, c.Params.PerPage) + if appErr != nil { + c.Err = appErr return } - b, _ := json.Marshal(users) - w.Write(b) + err := json.NewEncoder(w).Encode(users) + if err != nil { + c.Logger.Warn("Error writing response", mlog.Err(err)) + } } func getRecentSearches(c *Context, w http.ResponseWriter, r *http.Request) { diff --git a/api4/user_local.go b/api4/user_local.go index 1b9c4fdf33..50a451ea96 100644 --- a/api4/user_local.go +++ b/api4/user_local.go @@ -100,45 +100,47 @@ func localGetUsers(c *Context, w http.ResponseWriter, r *http.Request) { ViewRestrictions: nil, } - var err *model.AppError - var profiles []*model.User - etag := "" + var ( + appErr *model.AppError + profiles []*model.User + etag string + ) if withoutTeamBool, _ := strconv.ParseBool(withoutTeam); withoutTeamBool { - profiles, err = c.App.GetUsersWithoutTeamPage(userGetOptions, c.IsSystemAdmin()) + profiles, appErr = c.App.GetUsersWithoutTeamPage(userGetOptions, c.IsSystemAdmin()) } else if notInChannelId != "" { - profiles, err = c.App.GetUsersNotInChannelPage(inTeamId, notInChannelId, groupConstrainedBool, c.Params.Page, c.Params.PerPage, c.IsSystemAdmin(), nil) + profiles, appErr = c.App.GetUsersNotInChannelPage(inTeamId, notInChannelId, groupConstrainedBool, c.Params.Page, c.Params.PerPage, c.IsSystemAdmin(), nil) } else if notInTeamId != "" { etag = c.App.GetUsersNotInTeamEtag(inTeamId, "") if c.HandleEtag(etag, "Get Users Not in Team", w, r) { return } - profiles, err = c.App.GetUsersNotInTeamPage(notInTeamId, groupConstrainedBool, c.Params.Page, c.Params.PerPage, c.IsSystemAdmin(), nil) + profiles, appErr = c.App.GetUsersNotInTeamPage(notInTeamId, groupConstrainedBool, c.Params.Page, c.Params.PerPage, c.IsSystemAdmin(), nil) } else if inTeamId != "" { if sort == "last_activity_at" { - profiles, err = c.App.GetRecentlyActiveUsersForTeamPage(inTeamId, c.Params.Page, c.Params.PerPage, c.IsSystemAdmin(), nil) + profiles, appErr = c.App.GetRecentlyActiveUsersForTeamPage(inTeamId, c.Params.Page, c.Params.PerPage, c.IsSystemAdmin(), nil) } else if sort == "create_at" { - profiles, err = c.App.GetNewUsersForTeamPage(inTeamId, c.Params.Page, c.Params.PerPage, c.IsSystemAdmin(), nil) + profiles, appErr = c.App.GetNewUsersForTeamPage(inTeamId, c.Params.Page, c.Params.PerPage, c.IsSystemAdmin(), nil) } else { etag = c.App.GetUsersInTeamEtag(inTeamId, "") if c.HandleEtag(etag, "Get Users in Team", w, r) { return } - profiles, err = c.App.GetUsersInTeamPage(userGetOptions, c.IsSystemAdmin()) + profiles, appErr = c.App.GetUsersInTeamPage(userGetOptions, c.IsSystemAdmin()) } } else if inChannelId != "" { if sort == "status" { - profiles, err = c.App.GetUsersInChannelPageByStatus(userGetOptions, c.IsSystemAdmin()) + profiles, appErr = c.App.GetUsersInChannelPageByStatus(userGetOptions, c.IsSystemAdmin()) } else { - profiles, err = c.App.GetUsersInChannelPage(userGetOptions, c.IsSystemAdmin()) + profiles, appErr = c.App.GetUsersInChannelPage(userGetOptions, c.IsSystemAdmin()) } } else { - profiles, err = c.App.GetUsersPage(userGetOptions, c.IsSystemAdmin()) + profiles, appErr = c.App.GetUsersPage(userGetOptions, c.IsSystemAdmin()) } - if err != nil { - c.Err = err + if appErr != nil { + c.Err = appErr return } @@ -146,9 +148,9 @@ func localGetUsers(c *Context, w http.ResponseWriter, r *http.Request) { w.Header().Set(model.HeaderEtagServer, etag) } - js, jsonErr := json.Marshal(profiles) - if jsonErr != nil { - c.Err = model.NewAppError("localGetUsers", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(profiles) + if err != nil { + c.Err = model.NewAppError("localGetUsers", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } @@ -170,23 +172,23 @@ func localGetUsersByIds(c *Context, w http.ResponseWriter, r *http.Request) { } if sinceString != "" { - since, parseError := strconv.ParseInt(sinceString, 10, 64) - if parseError != nil { - c.SetInvalidParam("since") + since, err := strconv.ParseInt(sinceString, 10, 64) + if err != nil { + c.SetInvalidParamWithErr("since", err) return } options.Since = since } - users, err := c.App.GetUsersByIds(userIds, options) - if err != nil { - c.Err = err + users, appErr := c.App.GetUsersByIds(userIds, options) + if appErr != nil { + c.Err = appErr return } - js, jsonErr := json.Marshal(users) - if jsonErr != nil { - c.Err = model.NewAppError("localGetUsersByIds", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(users) + if err != nil { + c.Err = model.NewAppError("localGetUsersByIds", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } @@ -344,16 +346,17 @@ func localGetUserByEmail(c *Context, w http.ResponseWriter, r *http.Request) { } func localGetUploadsForUser(c *Context, w http.ResponseWriter, r *http.Request) { - uss, err := c.App.GetUploadSessionsForUser(c.Params.UserId) - if err != nil { - c.Err = err + uss, appErr := c.App.GetUploadSessionsForUser(c.Params.UserId) + if appErr != nil { + c.Err = appErr return } - js, jsonErr := json.Marshal(uss) - if jsonErr != nil { - c.Err = model.NewAppError("localGetUploadsForUser", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(uss) + if err != nil { + c.Err = model.NewAppError("localGetUploadsForUser", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } + w.Write(js) } diff --git a/api4/webhook.go b/api4/webhook.go index 744fc38263..3f871d9952 100644 --- a/api4/webhook.go +++ b/api4/webhook.go @@ -178,24 +178,26 @@ func updateIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) { } func getIncomingHooks(c *Context, w http.ResponseWriter, r *http.Request) { - teamId := r.URL.Query().Get("team_id") - userId := c.AppContext.Session().UserId + var ( + teamID = r.URL.Query().Get("team_id") + userID = c.AppContext.Session().UserId - var hooks []*model.IncomingWebhook - var err *model.AppError + hooks []*model.IncomingWebhook + appErr *model.AppError + ) - if teamId != "" { - if !c.App.SessionHasPermissionToTeam(*c.AppContext.Session(), teamId, model.PermissionManageIncomingWebhooks) { + if teamID != "" { + if !c.App.SessionHasPermissionToTeam(*c.AppContext.Session(), teamID, model.PermissionManageIncomingWebhooks) { c.SetPermissionError(model.PermissionManageIncomingWebhooks) return } // Remove userId as a filter if they have permission to manage others. - if c.App.SessionHasPermissionToTeam(*c.AppContext.Session(), teamId, model.PermissionManageOthersIncomingWebhooks) { - userId = "" + if c.App.SessionHasPermissionToTeam(*c.AppContext.Session(), teamID, model.PermissionManageOthersIncomingWebhooks) { + userID = "" } - hooks, err = c.App.GetIncomingWebhooksForTeamPageByUser(teamId, userId, c.Params.Page, c.Params.PerPage) + hooks, appErr = c.App.GetIncomingWebhooksForTeamPageByUser(teamID, userID, c.Params.Page, c.Params.PerPage) } else { if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionManageIncomingWebhooks) { c.SetPermissionError(model.PermissionManageIncomingWebhooks) @@ -204,22 +206,23 @@ func getIncomingHooks(c *Context, w http.ResponseWriter, r *http.Request) { // Remove userId as a filter if they have permission to manage others. if c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionManageOthersIncomingWebhooks) { - userId = "" + userID = "" } - hooks, err = c.App.GetIncomingWebhooksPageByUser(userId, c.Params.Page, c.Params.PerPage) + hooks, appErr = c.App.GetIncomingWebhooksPageByUser(userID, c.Params.Page, c.Params.PerPage) } + if appErr != nil { + c.Err = appErr + return + } + + js, err := json.Marshal(hooks) if err != nil { - c.Err = err + c.Err = model.NewAppError("getIncomingHooks", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } - js, jsonErr := json.Marshal(hooks) - if jsonErr != nil { - c.Err = model.NewAppError("getIncomingHooks", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) - return - } w.Write(js) } @@ -451,37 +454,40 @@ func createOutgoingHook(c *Context, w http.ResponseWriter, r *http.Request) { } func getOutgoingHooks(c *Context, w http.ResponseWriter, r *http.Request) { - channelId := r.URL.Query().Get("channel_id") - teamId := r.URL.Query().Get("team_id") - userId := c.AppContext.Session().UserId + var ( + query = r.URL.Query() + channelID = query.Get("channel_id") + teamID = query.Get("team_id") + userID = c.AppContext.Session().UserId - var hooks []*model.OutgoingWebhook - var err *model.AppError + hooks []*model.OutgoingWebhook + appErr *model.AppError + ) - if channelId != "" { - if !c.App.SessionHasPermissionToChannel(c.AppContext, *c.AppContext.Session(), channelId, model.PermissionManageOutgoingWebhooks) { + if channelID != "" { + if !c.App.SessionHasPermissionToChannel(c.AppContext, *c.AppContext.Session(), channelID, model.PermissionManageOutgoingWebhooks) { c.SetPermissionError(model.PermissionManageOutgoingWebhooks) return } // Remove userId as a filter if they have permission to manage others. - if c.App.SessionHasPermissionToChannel(c.AppContext, *c.AppContext.Session(), channelId, model.PermissionManageOthersOutgoingWebhooks) { - userId = "" + if c.App.SessionHasPermissionToChannel(c.AppContext, *c.AppContext.Session(), channelID, model.PermissionManageOthersOutgoingWebhooks) { + userID = "" } - hooks, err = c.App.GetOutgoingWebhooksForChannelPageByUser(channelId, userId, c.Params.Page, c.Params.PerPage) - } else if teamId != "" { - if !c.App.SessionHasPermissionToTeam(*c.AppContext.Session(), teamId, model.PermissionManageOutgoingWebhooks) { + hooks, appErr = c.App.GetOutgoingWebhooksForChannelPageByUser(channelID, userID, c.Params.Page, c.Params.PerPage) + } else if teamID != "" { + if !c.App.SessionHasPermissionToTeam(*c.AppContext.Session(), teamID, model.PermissionManageOutgoingWebhooks) { c.SetPermissionError(model.PermissionManageOutgoingWebhooks) return } // Remove userId as a filter if they have permission to manage others. - if c.App.SessionHasPermissionToTeam(*c.AppContext.Session(), teamId, model.PermissionManageOthersOutgoingWebhooks) { - userId = "" + if c.App.SessionHasPermissionToTeam(*c.AppContext.Session(), teamID, model.PermissionManageOthersOutgoingWebhooks) { + userID = "" } - hooks, err = c.App.GetOutgoingWebhooksForTeamPageByUser(teamId, userId, c.Params.Page, c.Params.PerPage) + hooks, appErr = c.App.GetOutgoingWebhooksForTeamPageByUser(teamID, userID, c.Params.Page, c.Params.PerPage) } else { if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionManageOutgoingWebhooks) { c.SetPermissionError(model.PermissionManageOutgoingWebhooks) @@ -490,22 +496,23 @@ func getOutgoingHooks(c *Context, w http.ResponseWriter, r *http.Request) { // Remove userId as a filter if they have permission to manage others. if c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionManageOthersOutgoingWebhooks) { - userId = "" + userID = "" } - hooks, err = c.App.GetOutgoingWebhooksPageByUser(userId, c.Params.Page, c.Params.PerPage) + hooks, appErr = c.App.GetOutgoingWebhooksPageByUser(userID, c.Params.Page, c.Params.PerPage) } + if appErr != nil { + c.Err = appErr + return + } + + js, err := json.Marshal(hooks) if err != nil { - c.Err = err + c.Err = model.NewAppError("getOutgoingHooks", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } - js, jsonErr := json.Marshal(hooks) - if jsonErr != nil { - c.Err = model.NewAppError("getOutgoingHooks", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) - return - } w.Write(js) } diff --git a/app/channel.go b/app/channel.go index e5f0c7aefc..74dd77938f 100644 --- a/app/channel.go +++ b/app/channel.go @@ -641,11 +641,11 @@ func (a *App) UpdateChannel(c request.CTX, channel *model.Channel) (*model.Chann var invErr *store.ErrInvalidInput switch { case errors.As(err, &invErr): - return nil, model.NewAppError("UpdateChannel", "app.channel.update.bad_id", nil, invErr.Error(), http.StatusBadRequest) + return nil, model.NewAppError("UpdateChannel", "app.channel.update.bad_id", nil, "", http.StatusBadRequest).Wrap(invErr) case errors.As(err, &appErr): return nil, appErr default: - return nil, model.NewAppError("UpdateChannel", "app.channel.update_channel.internal_error", nil, err.Error(), http.StatusInternalServerError) + return nil, model.NewAppError("UpdateChannel", "app.channel.update_channel.internal_error", nil, "", http.StatusInternalServerError).Wrap(err) } } @@ -1267,9 +1267,9 @@ func (a *App) UpdateChannelMemberNotifyProps(c request.CTX, data map[string]stri case errors.As(err, &appErr): return nil, appErr case errors.As(err, &nfErr): - return nil, model.NewAppError("updateMemberNotifyProps", MissingChannelMemberError, nil, nfErr.Error(), http.StatusNotFound) + return nil, model.NewAppError("updateMemberNotifyProps", MissingChannelMemberError, nil, "", http.StatusNotFound).Wrap(nfErr) default: - return nil, model.NewAppError("updateMemberNotifyProps", "app.channel.get_member.app_error", nil, err.Error(), http.StatusInternalServerError) + return nil, model.NewAppError("updateMemberNotifyProps", "app.channel.get_member.app_error", nil, "", http.StatusInternalServerError).Wrap(err) } } @@ -1289,17 +1289,17 @@ func (a *App) UpdateChannelMemberNotifyProps(c request.CTX, data map[string]stri } func (a *App) updateChannelMember(c request.CTX, member *model.ChannelMember) (*model.ChannelMember, *model.AppError) { - member, nErr := a.Srv().Store.Channel().UpdateMember(member) - if nErr != nil { + member, err := a.Srv().Store.Channel().UpdateMember(member) + if err != nil { var appErr *model.AppError var nfErr *store.ErrNotFound switch { - case errors.As(nErr, &appErr): + case errors.As(err, &appErr): return nil, appErr - case errors.As(nErr, &nfErr): - return nil, model.NewAppError("updateChannelMember", MissingChannelMemberError, nil, nfErr.Error(), http.StatusNotFound) + case errors.As(err, &nfErr): + return nil, model.NewAppError("updateChannelMember", MissingChannelMemberError, nil, "", http.StatusNotFound).Wrap(nfErr) default: - return nil, model.NewAppError("updateChannelMember", "app.channel.get_member.app_error", nil, nErr.Error(), http.StatusInternalServerError) + return nil, model.NewAppError("updateChannelMember", "app.channel.get_member.app_error", nil, "", http.StatusInternalServerError).Wrap(err) } } @@ -2604,14 +2604,14 @@ func (a *App) MarkChannelAsUnreadFromPost(c request.CTX, postID string, userID s } func (a *App) markChannelAsUnreadFromPostCRTUnsupported(c request.CTX, postID string, userID string) (*model.ChannelUnreadAt, *model.AppError) { - post, err := a.GetSinglePost(postID, false) - if err != nil { - return nil, err + post, appErr := a.GetSinglePost(postID, false) + if appErr != nil { + return nil, appErr } - user, err := a.GetUser(userID) - if err != nil { - return nil, err + user, appErr := a.GetUser(userID) + if appErr != nil { + return nil, appErr } threadId := post.RootId @@ -2619,18 +2619,18 @@ func (a *App) markChannelAsUnreadFromPostCRTUnsupported(c request.CTX, postID st threadId = post.Id } - unreadMentions, unreadMentionsRoot, err := a.countMentionsFromPost(c, user, post) - if err != nil { - return nil, err + unreadMentions, unreadMentionsRoot, appErr := a.countMentionsFromPost(c, user, post) + if appErr != nil { + return nil, appErr } // if root post, // In CRT Supported Client: badge on channel only sums mentions in root posts including and below the post that was marked. // In CRT Unsupported Client: badge on channel sums mentions in all posts (root & replies) including and below the post that was marked unread. if post.RootId == "" { - channelUnread, nErr := a.Srv().Store.Channel().UpdateLastViewedAtPost(post, userID, unreadMentions, unreadMentionsRoot, true) - if nErr != nil { - return channelUnread, model.NewAppError("MarkChannelAsUnreadFromPost", "app.channel.update_last_viewed_at_post.app_error", nil, nErr.Error(), http.StatusInternalServerError) + channelUnread, err := a.Srv().Store.Channel().UpdateLastViewedAtPost(post, userID, unreadMentions, unreadMentionsRoot, true) + if err != nil { + return channelUnread, model.NewAppError("MarkChannelAsUnreadFromPost", "app.channel.update_last_viewed_at_post.app_error", nil, "", http.StatusInternalServerError).Wrap(err) } a.sendWebSocketPostUnreadEvent(c, channelUnread, postID, true) @@ -2643,21 +2643,21 @@ func (a *App) markChannelAsUnreadFromPostCRTUnsupported(c request.CTX, postID st // If there are replies with mentions below the marked reply in the thread, then sum the mentions for the threads mention badge. // In CRT Unsupported Client: Channel is marked as unread and new messages line inserted above the marked post. // Badge on channel sums mentions in all posts (root & replies) including and below the post that was marked unread. - rootPost, err := a.GetSinglePost(post.RootId, false) - if err != nil { - return nil, err + rootPost, appErr := a.GetSinglePost(post.RootId, false) + if appErr != nil { + return nil, appErr } - channel, nErr := a.Srv().Store.Channel().Get(post.ChannelId, true) - if nErr != nil { - return nil, model.NewAppError("MarkChannelAsUnreadFromPost", "app.channel.update_last_viewed_at_post.app_error", nil, nErr.Error(), http.StatusInternalServerError) + channel, err := a.Srv().Store.Channel().Get(post.ChannelId, true) + if err != nil { + return nil, model.NewAppError("MarkChannelAsUnreadFromPost", "app.channel.update_last_viewed_at_post.app_error", nil, "", http.StatusInternalServerError).Wrap(err) } if *a.Config().ServiceSettings.ThreadAutoFollow { - threadMembership, sErr := a.Srv().Store.Thread().GetMembershipForUser(user.Id, threadId) + threadMembership, mErr := a.Srv().Store.Thread().GetMembershipForUser(user.Id, threadId) var errNotFound *store.ErrNotFound - if sErr != nil && !errors.As(sErr, &errNotFound) { - return nil, model.NewAppError("MarkChannelAsUnreadFromPost", "app.channel.update_last_viewed_at_post.app_error", nil, sErr.Error(), http.StatusInternalServerError) + if mErr != nil && !errors.As(mErr, &errNotFound) { + return nil, model.NewAppError("MarkChannelAsUnreadFromPost", "app.channel.update_last_viewed_at_post.app_error", nil, "", http.StatusInternalServerError).Wrap(mErr) } // Follow thread if we're not already following it if threadMembership == nil { @@ -2668,25 +2668,25 @@ func (a *App) markChannelAsUnreadFromPostCRTUnsupported(c request.CTX, postID st UpdateViewedTimestamp: false, UpdateParticipants: false, } - threadMembership, sErr = a.Srv().Store.Thread().MaintainMembership(user.Id, threadId, opts) - if sErr != nil { - return nil, model.NewAppError("MarkChannelAsUnreadFromPost", "app.channel.update_last_viewed_at_post.app_error", nil, sErr.Error(), http.StatusInternalServerError) + threadMembership, mErr = a.Srv().Store.Thread().MaintainMembership(user.Id, threadId, opts) + if mErr != nil { + return nil, model.NewAppError("MarkChannelAsUnreadFromPost", "app.channel.update_last_viewed_at_post.app_error", nil, "", http.StatusInternalServerError).Wrap(mErr) } } // If threadmembership already exists but user had previously unfollowed the thread, then follow the thread again. threadMembership.Following = true threadMembership.LastViewed = post.CreateAt - 1 - threadMembership.UnreadMentions, err = a.countThreadMentions(c, user, rootPost, channel.TeamId, post.CreateAt-1) - if err != nil { - return nil, err + threadMembership.UnreadMentions, appErr = a.countThreadMentions(c, user, rootPost, channel.TeamId, post.CreateAt-1) + if appErr != nil { + return nil, appErr } - threadMembership, sErr = a.Srv().Store.Thread().UpdateMembership(threadMembership) - if sErr != nil { - return nil, model.NewAppError("MarkChannelAsUnreadFromPost", "app.channel.update_last_viewed_at_post.app_error", nil, sErr.Error(), http.StatusInternalServerError) + threadMembership, mErr = a.Srv().Store.Thread().UpdateMembership(threadMembership) + if mErr != nil { + return nil, model.NewAppError("MarkChannelAsUnreadFromPost", "app.channel.update_last_viewed_at_post.app_error", nil, "", http.StatusInternalServerError).Wrap(mErr) } - thread, sErr := a.Srv().Store.Thread().GetThreadForUser(channel.TeamId, threadMembership, true) - if sErr != nil { - return nil, model.NewAppError("MarkChannelAsUnreadFromPost", "app.channel.update_last_viewed_at_post.app_error", nil, sErr.Error(), http.StatusInternalServerError) + thread, mErr := a.Srv().Store.Thread().GetThreadForUser(channel.TeamId, threadMembership, true) + if mErr != nil { + return nil, model.NewAppError("MarkChannelAsUnreadFromPost", "app.channel.update_last_viewed_at_post.app_error", nil, "", http.StatusInternalServerError).Wrap(mErr) } a.sanitizeProfiles(thread.Participants, false) thread.Post.SanitizeProps() @@ -2702,9 +2702,9 @@ func (a *App) markChannelAsUnreadFromPostCRTUnsupported(c request.CTX, postID st } } - channelUnread, nErr := a.Srv().Store.Channel().UpdateLastViewedAtPost(post, userID, unreadMentions, 0, false) - if nErr != nil { - return channelUnread, model.NewAppError("MarkChannelAsUnreadFromPost", "app.channel.update_last_viewed_at_post.app_error", nil, nErr.Error(), http.StatusInternalServerError) + channelUnread, err := a.Srv().Store.Channel().UpdateLastViewedAtPost(post, userID, unreadMentions, 0, false) + if err != nil { + return channelUnread, model.NewAppError("MarkChannelAsUnreadFromPost", "app.channel.update_last_viewed_at_post.app_error", nil, "", http.StatusInternalServerError).Wrap(err) } a.sendWebSocketPostUnreadEvent(c, channelUnread, postID, false) a.UpdateMobileAppBadge(userID) @@ -3213,14 +3213,14 @@ func (a *App) ToggleMuteChannel(c request.CTX, channelID, userID string) (*model } func (a *App) setChannelsMuted(c request.CTX, channelIDs []string, userID string, muted bool) ([]*model.ChannelMember, *model.AppError) { - members, nErr := a.Srv().Store.Channel().GetMembersByChannelIds(channelIDs, userID) - if nErr != nil { + members, err := a.Srv().Store.Channel().GetMembersByChannelIds(channelIDs, userID) + if err != nil { var appErr *model.AppError switch { - case errors.As(nErr, &appErr): + case errors.As(err, &appErr): return nil, appErr default: - return nil, model.NewAppError("setChannelsMuted", "app.channel.get_member.app_error", nil, nErr.Error(), http.StatusInternalServerError) + return nil, model.NewAppError("setChannelsMuted", "app.channel.get_member.app_error", nil, "", http.StatusInternalServerError).Wrap(err) } } @@ -3240,17 +3240,17 @@ func (a *App) setChannelsMuted(c request.CTX, channelIDs []string, userID string return nil, nil } - updated, nErr := a.Srv().Store.Channel().UpdateMultipleMembers(membersToUpdate) - if nErr != nil { + updated, err := a.Srv().Store.Channel().UpdateMultipleMembers(membersToUpdate) + if err != nil { var appErr *model.AppError var nfErr *store.ErrNotFound switch { - case errors.As(nErr, &appErr): + case errors.As(err, &appErr): return nil, appErr - case errors.As(nErr, &nfErr): - return nil, model.NewAppError("setChannelsMuted", MissingChannelMemberError, nil, nfErr.Error(), http.StatusNotFound) + case errors.As(err, &nfErr): + return nil, model.NewAppError("setChannelsMuted", MissingChannelMemberError, nil, "", http.StatusNotFound).Wrap(nfErr) default: - return nil, model.NewAppError("setChannelsMuted", "app.channel.get_member.app_error", nil, nErr.Error(), http.StatusInternalServerError) + return nil, model.NewAppError("setChannelsMuted", "app.channel.get_member.app_error", nil, "", http.StatusInternalServerError).Wrap(err) } } @@ -3375,7 +3375,7 @@ func (a *App) ClearChannelMembersCache(c request.CTX, channelID string) error { return nil } if err := a.forEachChannelMember(c, channelID, clearSessionCache); err != nil { - return fmt.Errorf("error clearing cache for channel members: channel_id: %s, error: %v", channelID, err) + return fmt.Errorf("error clearing cache for channel members: channel_id: %s, error: %w", channelID, err) } return nil } @@ -3383,7 +3383,7 @@ func (a *App) ClearChannelMembersCache(c request.CTX, channelID string) error { func (a *App) GetMemberCountsByGroup(ctx context.Context, channelID string, includeTimezones bool) ([]*model.ChannelMemberCountByGroup, *model.AppError) { channelMemberCounts, err := a.Srv().Store.Channel().GetMemberCountsByGroup(ctx, channelID, includeTimezones) if err != nil { - return nil, model.NewAppError("GetMemberCountsByGroup", "app.channel.get_member_count.app_error", nil, err.Error(), http.StatusInternalServerError) + return nil, model.NewAppError("GetMemberCountsByGroup", "app.channel.get_member_count.app_error", nil, "", http.StatusInternalServerError).Wrap(err) } return channelMemberCounts, nil diff --git a/app/channel_category.go b/app/channel_category.go index ff7ef067d8..972d80cc51 100644 --- a/app/channel_category.go +++ b/app/channel_category.go @@ -144,7 +144,7 @@ func (a *App) UpdateSidebarCategoryOrder(c request.CTX, userID, teamID string, c func (a *App) UpdateSidebarCategories(c request.CTX, userID, teamID string, categories []*model.SidebarCategoryWithChannels) ([]*model.SidebarCategoryWithChannels, *model.AppError) { updatedCategories, originalCategories, err := a.Srv().Store.Channel().UpdateSidebarCategories(userID, teamID, categories) if err != nil { - return nil, model.NewAppError("UpdateSidebarCategories", "app.channel.sidebar_categories.app_error", nil, err.Error(), http.StatusInternalServerError) + return nil, model.NewAppError("UpdateSidebarCategories", "app.channel.sidebar_categories.app_error", nil, "", http.StatusInternalServerError).Wrap(err) } message := model.NewWebSocketEvent(model.WebsocketEventSidebarCategoryUpdated, teamID, "", userID, nil) diff --git a/app/command_autocomplete.go b/app/command_autocomplete.go index 56fd45d6f5..43468ee498 100644 --- a/app/command_autocomplete.go +++ b/app/command_autocomplete.go @@ -280,7 +280,7 @@ func (a *App) getDynamicListArgument(c *request.Context, commandArgs *model.Comm var listItems []model.AutocompleteListItem if jsonErr := json.NewDecoder(resp.Body).Decode(&listItems); jsonErr != nil { - mlog.Warn("Failed to decode from JSON", mlog.Err(jsonErr)) + c.Logger().Warn("Failed to decode from JSON", mlog.Err(jsonErr)) } return parseListItems(listItems, parsed, toBeParsed) diff --git a/app/emoji.go b/app/emoji.go index 3de13ab795..5653ecacbc 100644 --- a/app/emoji.go +++ b/app/emoji.go @@ -52,8 +52,8 @@ func (a *App) CreateEmoji(sessionUserId string, emoji *model.Emoji, multiPartIma // do our best to validate the emoji before committing anything to the DB so that we don't have to clean up // orphaned files left over when validation fails later on emoji.PreSave() - if err := emoji.IsValid(); err != nil { - return nil, err + if appErr := emoji.IsValid(); appErr != nil { + return nil, appErr } if emoji.CreatorId != sessionUserId { @@ -61,22 +61,21 @@ func (a *App) CreateEmoji(sessionUserId string, emoji *model.Emoji, multiPartIma } if existingEmoji, err := a.Srv().Store.Emoji().GetByName(context.Background(), emoji.Name, true); err == nil && existingEmoji != nil { - return nil, model.NewAppError("createEmoji", "api.emoji.create.duplicate.app_error", nil, "", http.StatusBadRequest) + return nil, model.NewAppError("createEmoji", "api.emoji.create.duplicate.app_error", nil, "", http.StatusBadRequest).Wrap(err) } imageData := multiPartImageData.File["image"] if len(imageData) == 0 { - err := model.NewAppError("Context", "api.context.invalid_body_param.app_error", map[string]any{"Name": "createEmoji"}, "", http.StatusBadRequest) - return nil, err + return nil, model.NewAppError("Context", "api.context.invalid_body_param.app_error", map[string]any{"Name": "createEmoji"}, "", http.StatusBadRequest) } - if err := a.UploadEmojiImage(emoji.Id, imageData[0]); err != nil { - return nil, err + if appErr := a.UploadEmojiImage(emoji.Id, imageData[0]); appErr != nil { + return nil, appErr } emoji, err := a.Srv().Store.Emoji().Save(emoji) if err != nil { - return nil, model.NewAppError("CreateEmoji", "app.emoji.create.internal_error", nil, err.Error(), http.StatusInternalServerError) + return nil, model.NewAppError("CreateEmoji", "app.emoji.create.internal_error", nil, "", http.StatusInternalServerError).Wrap(err) } message := model.NewWebSocketEvent(model.WebsocketEventEmojiAdded, "", "", "", nil) diff --git a/app/export.go b/app/export.go index 7aad4a597d..553e1d41b7 100644 --- a/app/export.go +++ b/app/export.go @@ -141,14 +141,14 @@ func (a *App) BulkExport(ctx request.CTX, writer io.Writer, outPath string, opts return nil } -func (a *App) exportWriteLine(writer io.Writer, line *LineImportData) *model.AppError { +func (a *App) exportWriteLine(w io.Writer, line *LineImportData) *model.AppError { b, err := json.Marshal(line) if err != nil { - return model.NewAppError("BulkExport", "app.export.export_write_line.json_marshall.error", nil, "err="+err.Error(), http.StatusBadRequest) + return model.NewAppError("BulkExport", "app.export.export_write_line.json_marshall.error", nil, "", http.StatusBadRequest).Wrap(err) } - if _, err := writer.Write(append(b, '\n')); err != nil { - return model.NewAppError("BulkExport", "app.export.export_write_line.io_writer.error", nil, "err="+err.Error(), http.StatusBadRequest) + if _, err := w.Write(append(b, '\n')); err != nil { + return model.NewAppError("BulkExport", "app.export.export_write_line.io_writer.error", nil, "", http.StatusBadRequest).Wrap(err) } return nil diff --git a/app/group.go b/app/group.go index 686c2d6c0c..7f44487d5a 100644 --- a/app/group.go +++ b/app/group.go @@ -122,9 +122,9 @@ func (a *App) isUniqueToUsernames(val string) *model.AppError { } func (a *App) CreateGroupWithUserIds(group *model.GroupWithUserIds) (*model.Group, *model.AppError) { - if err := a.isUniqueToUsernames(group.GetName()); err != nil { - err.Where = "CreateGroupWithUserIds" - return nil, err + if appErr := a.isUniqueToUsernames(group.GetName()); appErr != nil { + appErr.Where = "CreateGroupWithUserIds" + return nil, appErr } newGroup, err := a.Srv().Store.Group().CreateWithUserIds(group) @@ -136,18 +136,18 @@ func (a *App) CreateGroupWithUserIds(group *model.GroupWithUserIds) (*model.Grou case errors.As(err, &appErr): return nil, appErr case errors.As(err, &invErr): - return nil, model.NewAppError("CreateGroupWithUserIds", "app.group.id.app_error", nil, invErr.Error(), http.StatusBadRequest) + return nil, model.NewAppError("CreateGroupWithUserIds", "app.group.id.app_error", nil, "", http.StatusBadRequest).Wrap(invErr) case errors.As(err, &dupKey): - return nil, model.NewAppError("CreateGroupWithUserIds", "app.custom_group.unique_name", nil, dupKey.Error(), http.StatusBadRequest) + return nil, model.NewAppError("CreateGroupWithUserIds", "app.custom_group.unique_name", nil, "", http.StatusBadRequest).Wrap(dupKey) default: - return nil, model.NewAppError("CreateGroupWithUserIds", "app.insert_error", nil, err.Error(), http.StatusInternalServerError) + return nil, model.NewAppError("CreateGroupWithUserIds", "app.insert_error", nil, "", http.StatusInternalServerError).Wrap(err) } } messageWs := model.NewWebSocketEvent(model.WebsocketEventReceivedGroup, "", "", "", nil) count, err := a.Srv().Store.Group().GetMemberCount(newGroup.Id) if err != nil { - return nil, model.NewAppError("CreateGroupWithUserIds", "app.group.id.app_error", nil, err.Error(), http.StatusBadRequest) + return nil, model.NewAppError("CreateGroupWithUserIds", "app.group.id.app_error", nil, "", http.StatusBadRequest).Wrap(err) } group.MemberCount = model.NewInt(int(count)) groupJSON, jsonErr := json.Marshal(newGroup) @@ -161,28 +161,12 @@ func (a *App) CreateGroupWithUserIds(group *model.GroupWithUserIds) (*model.Grou } func (a *App) UpdateGroup(group *model.Group) (*model.Group, *model.AppError) { - if err := a.isUniqueToUsernames(group.GetName()); err != nil { - err.Where = "UpdateGroup" - return nil, err + if appErr := a.isUniqueToUsernames(group.GetName()); appErr != nil { + appErr.Where = "UpdateGroup" + return nil, appErr } updatedGroup, err := a.Srv().Store.Group().Update(group) - - if err == nil { - count, countErr := a.Srv().Store.Group().GetMemberCount(updatedGroup.Id) - if countErr != nil { - return nil, model.NewAppError("UpdateGroup", "app.group.id.app_error", nil, countErr.Error(), http.StatusBadRequest) - } - updatedGroup.MemberCount = model.NewInt(int(count)) - messageWs := model.NewWebSocketEvent(model.WebsocketEventReceivedGroup, "", "", "", nil) - groupJSON, jsonErr := json.Marshal(updatedGroup) - if jsonErr != nil { - return nil, model.NewAppError("UpdateGroup", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(jsonErr) - } - messageWs.Add("group", string(groupJSON)) - a.Publish(messageWs) - } - if err != nil { var nfErr *store.ErrNotFound var appErr *model.AppError @@ -191,14 +175,29 @@ func (a *App) UpdateGroup(group *model.Group) (*model.Group, *model.AppError) { case errors.As(err, &appErr): return nil, appErr case errors.As(err, &nfErr): - return nil, model.NewAppError("UpdateGroup", "app.group.no_rows", nil, nfErr.Error(), http.StatusNotFound) + return nil, model.NewAppError("UpdateGroup", "app.group.no_rows", nil, "", http.StatusNotFound).Wrap(nfErr) case errors.As(err, &dupKey): - return nil, model.NewAppError("CreateGroup", "app.custom_group.unique_name", nil, dupKey.Error(), http.StatusBadRequest) + return nil, model.NewAppError("CreateGroup", "app.custom_group.unique_name", nil, "", http.StatusBadRequest).Wrap(dupKey) default: - return nil, model.NewAppError("UpdateGroup", "app.select_error", nil, err.Error(), http.StatusInternalServerError) + return nil, model.NewAppError("UpdateGroup", "app.select_error", nil, "", http.StatusInternalServerError).Wrap(err) } } + count, err := a.Srv().Store.Group().GetMemberCount(updatedGroup.Id) + if err != nil { + return nil, model.NewAppError("UpdateGroup", "app.group.id.app_error", nil, "", http.StatusBadRequest).Wrap(err) + } + + updatedGroup.MemberCount = model.NewInt(int(count)) + messageWs := model.NewWebSocketEvent(model.WebsocketEventReceivedGroup, "", "", "", nil) + + groupJSON, err := json.Marshal(updatedGroup) + if err != nil { + return nil, model.NewAppError("UpdateGroup", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) + } + messageWs.Add("group", string(groupJSON)) + a.Publish(messageWs) + return updatedGroup, nil } @@ -763,9 +762,9 @@ func (a *App) DeleteGroupMembers(groupID string, userIDs []string) ([]*model.Gro case errors.As(err, &appErr): return nil, appErr case errors.As(err, &invErr): - return nil, model.NewAppError("DeleteGroupMember", "app.group.uniqueness_error", nil, invErr.Error(), http.StatusBadRequest) + return nil, model.NewAppError("DeleteGroupMember", "app.group.uniqueness_error", nil, "", http.StatusBadRequest).Wrap(invErr) default: - return nil, model.NewAppError("DeleteGroupMember", "app.update_error", nil, err.Error(), http.StatusInternalServerError) + return nil, model.NewAppError("DeleteGroupMember", "app.update_error", nil, "", http.StatusInternalServerError).Wrap(err) } } diff --git a/app/import_validators.go b/app/import_validators.go index 3be6b8fabd..c2dc34b5d0 100644 --- a/app/import_validators.go +++ b/app/import_validators.go @@ -332,10 +332,10 @@ func validateUserTeamsImportData(data *[]UserTeamImportData) *model.AppError { } } - if tdata.Theme != nil && 0 < len(strings.Trim(*tdata.Theme, " \t\r")) { + if tdata.Theme != nil && strings.Trim(*tdata.Theme, " \t\r") != "" { var unused map[string]string if err := json.NewDecoder(strings.NewReader(*tdata.Theme)).Decode(&unused); err != nil { - return model.NewAppError("BulkImport", "app.import.validate_user_teams_import_data.invalid_team_theme.error", nil, err.Error(), http.StatusBadRequest) + return model.NewAppError("BulkImport", "app.import.validate_user_teams_import_data.invalid_team_theme.error", nil, "", http.StatusBadRequest).Wrap(err) } } } diff --git a/app/integration_action.go b/app/integration_action.go index dfc85cfbdc..35b93a956f 100644 --- a/app/integration_action.go +++ b/app/integration_action.go @@ -98,9 +98,9 @@ func (a *App) DoPostActionWithCookie(c *request.Context, postID, actionId, userI var nfErr *store.ErrNotFound switch { case errors.As(result.NErr, &nfErr): - return "", model.NewAppError("DoPostActionWithCookie", "app.post.get.app_error", nil, nfErr.Error(), http.StatusNotFound) + return "", model.NewAppError("DoPostActionWithCookie", "app.post.get.app_error", nil, "", http.StatusNotFound).Wrap(nfErr) default: - return "", model.NewAppError("DoPostActionWithCookie", "app.post.get.app_error", nil, result.NErr.Error(), http.StatusInternalServerError) + return "", model.NewAppError("DoPostActionWithCookie", "app.post.get.app_error", nil, "", http.StatusInternalServerError).Wrap(result.NErr) } } if cookie.Integration == nil { @@ -116,9 +116,9 @@ func (a *App) DoPostActionWithCookie(c *request.Context, postID, actionId, userI var nfErr *store.ErrNotFound switch { case errors.As(err, &nfErr): - return "", model.NewAppError("DoPostActionWithCookie", "app.channel.get.existing.app_error", nil, nfErr.Error(), http.StatusNotFound) + return "", model.NewAppError("DoPostActionWithCookie", "app.channel.get.existing.app_error", nil, "", http.StatusNotFound).Wrap(nfErr) default: - return "", model.NewAppError("DoPostActionWithCookie", "app.channel.get.find.app_error", nil, err.Error(), http.StatusInternalServerError) + return "", model.NewAppError("DoPostActionWithCookie", "app.channel.get.find.app_error", nil, "", http.StatusInternalServerError).Wrap(err) } } @@ -137,7 +137,7 @@ func (a *App) DoPostActionWithCookie(c *request.Context, postID, actionId, userI post := result.Data.(*model.Post) result = <-cchan if result.NErr != nil { - return "", model.NewAppError("DoPostActionWithCookie", "app.channel.get_for_post.app_error", nil, result.NErr.Error(), http.StatusInternalServerError) + return "", model.NewAppError("DoPostActionWithCookie", "app.channel.get_for_post.app_error", nil, "", http.StatusInternalServerError).Wrap(result.NErr) } channel := result.Data.(*model.Channel) @@ -195,9 +195,9 @@ func (a *App) DoPostActionWithCookie(c *request.Context, postID, actionId, userI var nfErr *store.ErrNotFound switch { case errors.As(ur.NErr, &nfErr): - return "", model.NewAppError("DoPostActionWithCookie", MissingAccountError, nil, nfErr.Error(), http.StatusNotFound) + return "", model.NewAppError("DoPostActionWithCookie", MissingAccountError, nil, "", http.StatusNotFound).Wrap(nfErr) default: - return "", model.NewAppError("DoPostActionWithCookie", "app.user.get.app_error", nil, ur.NErr.Error(), http.StatusInternalServerError) + return "", model.NewAppError("DoPostActionWithCookie", "app.user.get.app_error", nil, "", http.StatusInternalServerError).Wrap(ur.NErr) } } user := ur.Data.(*model.User) @@ -209,9 +209,9 @@ func (a *App) DoPostActionWithCookie(c *request.Context, postID, actionId, userI var nfErr *store.ErrNotFound switch { case errors.As(tr.NErr, &nfErr): - return "", model.NewAppError("DoPostActionWithCookie", "app.team.get.find.app_error", nil, nfErr.Error(), http.StatusNotFound) + return "", model.NewAppError("DoPostActionWithCookie", "app.team.get.find.app_error", nil, "", http.StatusNotFound).Wrap(nfErr) default: - return "", model.NewAppError("DoPostActionWithCookie", "app.team.get.finding.app_error", nil, tr.NErr.Error(), http.StatusInternalServerError) + return "", model.NewAppError("DoPostActionWithCookie", "app.team.get.finding.app_error", nil, "", http.StatusInternalServerError).Wrap(tr.NErr) } } @@ -234,7 +234,6 @@ func (a *App) DoPostActionWithCookie(c *request.Context, postID, actionId, userI return "", appErr } - var resp *http.Response if strings.HasPrefix(upstreamURL, "/warn_metrics/") { appErr = a.doLocalWarnMetricsRequest(c, upstreamURL, upstreamRequest) if appErr != nil { @@ -242,11 +241,12 @@ func (a *App) DoPostActionWithCookie(c *request.Context, postID, actionId, userI } return "", nil } - requestJSON, jsonErr := json.Marshal(upstreamRequest) - if jsonErr != nil { - return "", model.NewAppError("DoPostActionWithCookie", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + + requestJSON, err := json.Marshal(upstreamRequest) + if err != nil { + return "", model.NewAppError("DoPostActionWithCookie", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) } - resp, appErr = a.DoActionRequest(c, upstreamURL, requestJSON) + resp, appErr := a.DoActionRequest(c, upstreamURL, requestJSON) if appErr != nil { return "", appErr } @@ -255,12 +255,12 @@ func (a *App) DoPostActionWithCookie(c *request.Context, postID, actionId, userI var response model.PostActionIntegrationResponse respBytes, err := io.ReadAll(resp.Body) if err != nil { - return "", model.NewAppError("DoPostActionWithCookie", "api.post.do_action.action_integration.app_error", nil, "err="+err.Error(), http.StatusBadRequest) + return "", model.NewAppError("DoPostActionWithCookie", "api.post.do_action.action_integration.app_error", nil, "", http.StatusBadRequest).Wrap(err) } if len(respBytes) > 0 { if err = json.Unmarshal(respBytes, &response); err != nil { - return "", model.NewAppError("DoPostActionWithCookie", "api.post.do_action.action_integration.app_error", nil, "err="+err.Error(), http.StatusBadRequest) + return "", model.NewAppError("DoPostActionWithCookie", "api.post.do_action.action_integration.app_error", nil, "", http.StatusBadRequest).Wrap(err) } } @@ -585,14 +585,17 @@ func (a *App) DoLocalRequest(c *request.Context, rawURL string, body []byte) (*h } func (a *App) OpenInteractiveDialog(request model.OpenDialogRequest) *model.AppError { - clientTriggerId, userID, err := request.DecodeAndVerifyTriggerId(a.AsymmetricSigningKey()) - if err != nil { - return err + clientTriggerId, userID, appErr := request.DecodeAndVerifyTriggerId(a.AsymmetricSigningKey()) + if appErr != nil { + return appErr } request.TriggerId = clientTriggerId - jsonRequest, _ := json.Marshal(request) + jsonRequest, err := json.Marshal(request) + if err != nil { + a.ch.srv.GetLogger().Warn("Error encoding request", mlog.Err(err)) + } message := model.NewWebSocketEvent(model.WebsocketEventOpenDialog, "", "", userID, nil) message.Add("dialog", string(jsonRequest)) @@ -606,23 +609,19 @@ func (a *App) SubmitInteractiveDialog(c *request.Context, request model.SubmitDi request.URL = "" request.Type = "dialog_submission" - b, jsonErr := json.Marshal(request) - if jsonErr != nil { - return nil, model.NewAppError("SubmitInteractiveDialog", "app.submit_interactive_dialog.json_error", nil, jsonErr.Error(), http.StatusBadRequest) - } - - resp, err := a.DoActionRequest(c, url, b) + b, err := json.Marshal(request) if err != nil { - return nil, err + return nil, model.NewAppError("SubmitInteractiveDialog", "app.submit_interactive_dialog.json_error", nil, "", http.StatusBadRequest).Wrap(err) } + resp, appErr := a.DoActionRequest(c, url, b) + if appErr != nil { + return nil, appErr + } defer resp.Body.Close() var response model.SubmitDialogResponse - if err := json.NewDecoder(resp.Body).Decode(&response); err != nil { - // Don't fail, an empty response is acceptable - return &response, nil - } + json.NewDecoder(resp.Body).Decode(&response) // Don't fail, an empty response is acceptable return &response, nil } diff --git a/app/license.go b/app/license.go index ff6b2dff9a..bf359752cf 100644 --- a/app/license.go +++ b/app/license.go @@ -342,14 +342,14 @@ func (s *Server) GetSanitizedClientLicense() map[string]string { // RequestTrialLicense request a trial license from the mattermost official license server func (s *Server) RequestTrialLicense(trialRequest *model.TrialLicenseRequest) *model.AppError { - trialRequestJSON, jsonErr := json.Marshal(trialRequest) - if jsonErr != nil { - return model.NewAppError("RequestTrialLicense", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + trialRequestJSON, err := json.Marshal(trialRequest) + if err != nil { + return model.NewAppError("RequestTrialLicense", "api.unmarshal_error", nil, "", http.StatusInternalServerError).Wrap(err) } resp, err := http.Post(RequestTrialURL, "application/json", bytes.NewBuffer(trialRequestJSON)) if err != nil { - return model.NewAppError("RequestTrialLicense", "api.license.request_trial_license.app_error", nil, err.Error(), http.StatusBadRequest) + return model.NewAppError("RequestTrialLicense", "api.license.request_trial_license.app_error", nil, "", http.StatusBadRequest).Wrap(err) } defer resp.Body.Close() @@ -363,7 +363,11 @@ func (s *Server) RequestTrialLicense(trialRequest *model.TrialLicenseRequest) *m fmt.Sprintf("Unexpected HTTP status code %q returned by server", resp.Status), http.StatusInternalServerError) } - licenseResponse := model.MapFromJSON(resp.Body) + var licenseResponse map[string]string + err = json.NewDecoder(resp.Body).Decode(&licenseResponse) + if err != nil { + s.GetLogger().Warn("Error decoding license response", mlog.Err(err)) + } if _, ok := licenseResponse["license"]; !ok { return model.NewAppError("RequestTrialLicense", "api.license.request_trial_license.app_error", nil, licenseResponse["message"], http.StatusBadRequest) diff --git a/app/notification_push.go b/app/notification_push.go index b0643754a5..1065dbf1fe 100644 --- a/app/notification_push.go +++ b/app/notification_push.go @@ -6,14 +6,14 @@ package app import ( "bytes" "encoding/json" + "errors" + "fmt" "io" "net/http" "runtime" "strings" "sync" - "github.com/pkg/errors" - "github.com/mattermost/mattermost-server/v6/app/request" "github.com/mattermost/mattermost-server/v6/model" "github.com/mattermost/mattermost-server/v6/shared/i18n" @@ -382,9 +382,9 @@ func (s *Server) StopPushNotificationsHubWorkers() { } func (a *App) rawSendToPushProxy(msg *model.PushNotification) (model.PushResponse, error) { - msgJSON, jsonErr := json.Marshal(msg) - if jsonErr != nil { - return nil, errors.Wrap(jsonErr, "failed to encode to JSON") + msgJSON, err := json.Marshal(msg) + if err != nil { + return nil, fmt.Errorf("failed to encode to JSON: %w", err) } url := strings.TrimRight(*a.Config().EmailSettings.PushNotificationServer, "/") + model.APIURLSuffixV1 + "/send_push" @@ -400,8 +400,8 @@ func (a *App) rawSendToPushProxy(msg *model.PushNotification) (model.PushRespons defer resp.Body.Close() var pushResponse model.PushResponse - if jsonErr := json.NewDecoder(resp.Body).Decode(&pushResponse); jsonErr != nil { - return nil, errors.Wrap(jsonErr, "failed to decode from JSON") + if err := json.NewDecoder(resp.Body).Decode(&pushResponse); err != nil { + return nil, fmt.Errorf("failed to decode from JSON: %w", err) } return pushResponse, nil @@ -427,7 +427,7 @@ func (a *App) sendToPushProxy(msg *model.PushNotification, session *model.Sessio case model.PushStatusRemove: a.AttachDeviceId(session.Id, "", session.ExpiresAt) a.ClearSessionCacheForUser(session.UserId) - return errors.New("Device was reported as removed") + return errors.New("device was reported as removed") case model.PushStatusFail: return errors.New(pushResponse[model.PushStatusErrorMsg]) } @@ -447,9 +447,9 @@ func (a *App) SendAckToPushProxy(ack *model.PushNotificationAck) error { mlog.String("status", model.PushReceived), ) - ackJSON, jsonErr := json.Marshal(ack) - if jsonErr != nil { - return errors.Wrap(jsonErr, "failed to encode to JSON") + ackJSON, err := json.Marshal(ack) + if err != nil { + return fmt.Errorf("failed to encode to JSON: %w", err) } request, err := http.NewRequest( @@ -457,7 +457,6 @@ func (a *App) SendAckToPushProxy(ack *model.PushNotificationAck) error { strings.TrimRight(*a.Config().EmailSettings.PushNotificationServer, "/")+model.APIURLSuffixV1+"/ack", bytes.NewReader(ackJSON), ) - if err != nil { return err } @@ -467,19 +466,16 @@ func (a *App) SendAckToPushProxy(ack *model.PushNotificationAck) error { return err } defer resp.Body.Close() + // Reading the body to completion. _, err = io.Copy(io.Discard, resp.Body) - if err != nil { - return err - } - - return nil + return err } func (a *App) getMobileAppSessions(userID string) ([]*model.Session, *model.AppError) { sessions, err := a.Srv().Store.Session().GetSessionsWithActiveDeviceIds(userID) if err != nil { - return nil, model.NewAppError("getMobileAppSessions", "app.session.get_sessions.app_error", nil, err.Error(), http.StatusInternalServerError) + return nil, model.NewAppError("getMobileAppSessions", "app.session.get_sessions.app_error", nil, "", http.StatusInternalServerError).Wrap(err) } return sessions, nil @@ -572,7 +568,7 @@ func (a *App) BuildPushNotificationMessage(c request.CTX, contentsConfig string, unreadCount, err := a.Srv().Store.User().GetUnreadCount(user.Id) if err != nil { - return nil, model.NewAppError("BuildPushNotificationMessage", "app.user.get_unread_count.app_error", nil, err.Error(), http.StatusInternalServerError) + return nil, model.NewAppError("BuildPushNotificationMessage", "app.user.get_unread_count.app_error", nil, "", http.StatusInternalServerError).Wrap(err) } msg.Badge = int(unreadCount) diff --git a/app/oauth.go b/app/oauth.go index 8dd67ffdcb..e205641522 100644 --- a/app/oauth.go +++ b/app/oauth.go @@ -852,7 +852,7 @@ func (a *App) AuthorizeOAuthUser(w http.ResponseWriter, r *http.Request, service var ar *model.AccessResponse err = json.NewDecoder(tee).Decode(&ar) if err != nil || resp.StatusCode != http.StatusOK { - return nil, "", stateProps, nil, model.NewAppError("AuthorizeOAuthUser", "api.user.authorize_oauth_user.bad_response.app_error", nil, fmt.Sprintf("response_body=%s, status_code=%d, error=%v", buf.String(), resp.StatusCode, err), http.StatusInternalServerError) + return nil, "", stateProps, nil, model.NewAppError("AuthorizeOAuthUser", "api.user.authorize_oauth_user.bad_response.app_error", nil, fmt.Sprintf("response_body=%s, status_code=%d, error=%v", buf.String(), resp.StatusCode, err), http.StatusInternalServerError).Wrap(err) } if strings.ToLower(ar.TokenType) != model.AccessTokenType { diff --git a/app/post.go b/app/post.go index b537e43417..3abd81a0a8 100644 --- a/app/post.go +++ b/app/post.go @@ -251,7 +251,7 @@ func (a *App) CreatePost(c request.CTX, post *model.Post, channel *model.Channel post.AddProp("attachments", attachmentsInterface) } if err != nil { - mlog.Warn("Could not convert post attachments to map interface.", mlog.Err(err)) + c.Logger().Warn("Could not convert post attachments to map interface.", mlog.Err(err)) } } @@ -329,7 +329,7 @@ func (a *App) CreatePost(c request.CTX, post *model.Post, channel *model.Channel if len(post.FileIds) > 0 { if err = a.attachFilesToPost(post); err != nil { - mlog.Warn("Encountered error attaching files to post", mlog.String("post_id", post.Id), mlog.Any("file_ids", post.FileIds), mlog.Err(err)) + c.Logger().Warn("Encountered error attaching files to post", mlog.String("post_id", post.Id), mlog.Any("file_ids", post.FileIds), mlog.Err(err)) } if a.Metrics() != nil { @@ -348,12 +348,12 @@ func (a *App) CreatePost(c request.CTX, post *model.Post, channel *model.Channel UpdateFollowing: true, }) if err != nil { - mlog.Warn("Failed to update thread membership", mlog.Err(err)) + c.Logger().Warn("Failed to update thread membership", mlog.Err(err)) } } if err := a.handlePostEvents(c, rpost, user, channel, triggerWebhooks, parentPostList, setOnline); err != nil { - mlog.Warn("Failed to handle post events", mlog.Err(err)) + c.Logger().Warn("Failed to handle post events", mlog.Err(err)) } // Send any ephemeral posts after the post is created to ensure it shows up after the latest post created @@ -1224,34 +1224,35 @@ func (a *App) GetPostsForChannelAroundLastUnread(c request.CTX, channelID, userI } func (a *App) DeletePost(c request.CTX, postID, deleteByID string) (*model.Post, *model.AppError) { - post, nErr := a.Srv().Store.Post().GetSingle(postID, false) - if nErr != nil { - return nil, model.NewAppError("DeletePost", "app.post.get.app_error", nil, nErr.Error(), http.StatusBadRequest) + post, err := a.Srv().Store.Post().GetSingle(postID, false) + if err != nil { + return nil, model.NewAppError("DeletePost", "app.post.get.app_error", nil, err.Error(), http.StatusBadRequest) } - channel, err := a.GetChannel(c, post.ChannelId) - if err != nil { - return nil, err + channel, appErr := a.GetChannel(c, post.ChannelId) + if appErr != nil { + return nil, appErr } if channel.DeleteAt != 0 { - err := model.NewAppError("DeletePost", "api.post.delete_post.can_not_delete_post_in_deleted.error", nil, "", http.StatusBadRequest) - return nil, err + appErr := model.NewAppError("DeletePost", "api.post.delete_post.can_not_delete_post_in_deleted.error", nil, "", http.StatusBadRequest) + return nil, appErr } - if err := a.Srv().Store.Post().Delete(postID, model.GetMillis(), deleteByID); err != nil { + err = a.Srv().Store.Post().Delete(postID, model.GetMillis(), deleteByID) + if err != nil { var nfErr *store.ErrNotFound switch { case errors.As(err, &nfErr): - return nil, model.NewAppError("DeletePost", "app.post.delete.app_error", nil, nfErr.Error(), http.StatusNotFound) + return nil, model.NewAppError("DeletePost", "app.post.delete.app_error", nil, "", http.StatusNotFound).Wrap(nfErr) default: - return nil, model.NewAppError("DeletePost", "app.post.delete.app_error", nil, err.Error(), http.StatusInternalServerError) + return nil, model.NewAppError("DeletePost", "app.post.delete.app_error", nil, "", http.StatusInternalServerError).Wrap(err) } } - postJSON, jsonErr := json.Marshal(post) - if jsonErr != nil { - return nil, model.NewAppError("DeletePost", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(jsonErr) + postJSON, err := json.Marshal(post) + if err != nil { + return nil, model.NewAppError("DeletePost", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) } userMessage := model.NewWebSocketEvent(model.WebsocketEventPostDeleted, "", post.ChannelId, "", nil) @@ -1283,14 +1284,14 @@ func (a *App) DeletePost(c request.CTX, postID, deleteByID string) (*model.Post, func (a *App) deleteFlaggedPosts(postID string) { if err := a.Srv().Store.Preference().DeleteCategoryAndName(model.PreferenceCategoryFlaggedPost, postID); err != nil { - mlog.Warn("Unable to delete flagged post preference when deleting post.", mlog.Err(err)) + a.Log().Warn("Unable to delete flagged post preference when deleting post.", mlog.Err(err)) return } } func (a *App) deletePostFiles(postID string) { if _, err := a.Srv().Store.FileInfo().DeleteForPost(postID); err != nil { - mlog.Warn("Encountered error when deleting files for post", mlog.String("post_id", postID), mlog.Err(err)) + a.Log().Warn("Encountered error when deleting files for post", mlog.String("post_id", postID), mlog.Err(err)) } } @@ -1358,7 +1359,7 @@ func (a *App) searchPostsInTeam(teamID string, userID string, paramsList []*mode for result := range pchan { if result.NErr != nil { - return nil, model.NewAppError("searchPostsInTeam", "app.post.search.app_error", nil, result.NErr.Error(), http.StatusInternalServerError) + return nil, model.NewAppError("searchPostsInTeam", "app.post.search.app_error", nil, "", http.StatusInternalServerError).Wrap(result.NErr) } data := result.Data.(*model.PostList) posts.Extend(data) @@ -1375,7 +1376,7 @@ func (a *App) convertChannelNamesToChannelIds(c *request.Context, channels []str for idx, channelName := range channels { channel, err := a.parseAndFetchChannelIdByNameFromInFilter(c, channelName, userID, teamID, includeDeletedChannels) if err != nil { - mlog.Warn("error getting channel id by name from in filter", mlog.Err(err)) + a.Log().Warn("error getting channel id by name from in filter", mlog.Err(err)) continue } channels[idx] = channel.Id @@ -1387,7 +1388,7 @@ func (a *App) convertUserNameToUserIds(usernames []string) []string { for idx, username := range usernames { user, err := a.GetUserByUsername(username) if err != nil { - mlog.Warn("error getting user by username", mlog.String("user_name", username), mlog.Err(err)) + a.Log().Warn("error getting user by username", mlog.String("user_name", username), mlog.Err(err)) continue } usernames[idx] = user.Id @@ -1410,13 +1411,13 @@ func (a *App) GetLastAccessiblePostTime() (int64, *model.AppError) { // All posts are accessible return 0, nil default: - return 0, model.NewAppError("GetLastAccessiblePostTime", "app.system.get_by_name.app_error", nil, err.Error(), http.StatusInternalServerError) + return 0, model.NewAppError("GetLastAccessiblePostTime", "app.system.get_by_name.app_error", nil, "", http.StatusInternalServerError).Wrap(err) } } lastAccessiblePostTime, err := strconv.ParseInt(system.Value, 10, 64) if err != nil { - return 0, model.NewAppError("GetLastAccessiblePostTime", "common.parse_error_int64", map[string]interface{}{"Value": system.Value}, err.Error(), http.StatusInternalServerError) + return 0, model.NewAppError("GetLastAccessiblePostTime", "common.parse_error_int64", map[string]interface{}{"Value": system.Value}, "", http.StatusInternalServerError).Wrap(err) } return lastAccessiblePostTime, nil @@ -1434,7 +1435,7 @@ func (a *App) ComputeLastAccessiblePostTime() error { if err != nil { var nfErr *store.ErrNotFound if !errors.As(err, &nfErr) { - return model.NewAppError("ComputeLastAccessiblePostTime", "app.last_accessible_post.app_error", nil, err.Error(), http.StatusInternalServerError) + return model.NewAppError("ComputeLastAccessiblePostTime", "app.last_accessible_post.app_error", nil, "", http.StatusInternalServerError).Wrap(err) } } @@ -1444,7 +1445,7 @@ func (a *App) ComputeLastAccessiblePostTime() error { Value: strconv.FormatInt(createdAt, 10), }) if err != nil { - return model.NewAppError("ComputeLastAccessiblePostTime", "app.system.save.app_error", nil, err.Error(), http.StatusInternalServerError) + return model.NewAppError("ComputeLastAccessiblePostTime", "app.system.save.app_error", nil, "", http.StatusInternalServerError).Wrap(err) } return nil @@ -1458,7 +1459,7 @@ func (a *App) getCloudMessagesHistoryLimit() (int64, *model.AppError) { limits, err := a.Cloud().GetCloudLimits("") if err != nil { - return 0, model.NewAppError("getCloudMessagesHistoryLimit", "api.cloud.app_error", nil, err.Error(), http.StatusInternalServerError) + return 0, model.NewAppError("getCloudMessagesHistoryLimit", "api.cloud.app_error", nil, "", http.StatusInternalServerError).Wrap(err) } if limits == nil || limits.Messages == nil || limits.Messages.History == nil { @@ -1516,14 +1517,14 @@ func (a *App) SearchPostsForUser(c *request.Context, terms string, userID string return model.MakePostSearchResults(model.NewPostList(), nil), nil } - postSearchResults, nErr := a.Srv().Store.Post().SearchPostsForUser(finalParamsList, userID, teamID, page, perPage) - if nErr != nil { + postSearchResults, err := a.Srv().Store.Post().SearchPostsForUser(finalParamsList, userID, teamID, page, perPage) + if err != nil { var appErr *model.AppError switch { - case errors.As(nErr, &appErr): + case errors.As(err, &appErr): return nil, appErr default: - return nil, model.NewAppError("SearchPostsForUser", "app.post.search.app_error", nil, nErr.Error(), http.StatusInternalServerError) + return nil, model.NewAppError("SearchPostsForUser", "app.post.search.app_error", nil, "", http.StatusInternalServerError).Wrap(err) } } @@ -1535,9 +1536,9 @@ func (a *App) SearchPostsForUser(c *request.Context, terms string, userID string } func (a *App) GetRecentSearchesForUser(userID string) ([]*model.SearchParams, *model.AppError) { - searchParams, nErr := a.Srv().Store.Post().GetRecentSearchesForUser(userID) - if nErr != nil { - return nil, model.NewAppError("GetRecentSearchesForUser", "app.recent_searches.app_error", nil, nErr.Error(), http.StatusInternalServerError) + searchParams, err := a.Srv().Store.Post().GetRecentSearchesForUser(userID) + if err != nil { + return nil, model.NewAppError("GetRecentSearchesForUser", "app.recent_searches.app_error", nil, "", http.StatusInternalServerError).Wrap(err) } return searchParams, nil diff --git a/app/preference.go b/app/preference.go index 843976d122..4f470dd108 100644 --- a/app/preference.go +++ b/app/preference.go @@ -53,12 +53,12 @@ func (a *App) UpdatePreferences(userID string, preferences model.Preferences) *m case errors.As(err, &appErr): return appErr default: - return model.NewAppError("UpdatePreferences", "app.preference.save.updating.app_error", nil, err.Error(), http.StatusBadRequest) + return model.NewAppError("UpdatePreferences", "app.preference.save.updating.app_error", nil, "", http.StatusBadRequest).Wrap(err) } } if err := a.Srv().Store.Channel().UpdateSidebarChannelsByPreferences(preferences); err != nil { - return model.NewAppError("UpdatePreferences", "api.preference.update_preferences.update_sidebar.app_error", nil, err.Error(), http.StatusInternalServerError) + return model.NewAppError("UpdatePreferences", "api.preference.update_preferences.update_sidebar.app_error", nil, "", http.StatusInternalServerError).Wrap(err) } message := model.NewWebSocketEvent(model.WebsocketEventSidebarCategoryUpdated, "", "", userID, nil) @@ -87,12 +87,12 @@ func (a *App) DeletePreferences(userID string, preferences model.Preferences) *m for _, preference := range preferences { if err := a.Srv().Store.Preference().Delete(userID, preference.Category, preference.Name); err != nil { - return model.NewAppError("DeletePreferences", "app.preference.delete.app_error", nil, err.Error(), http.StatusBadRequest) + return model.NewAppError("DeletePreferences", "app.preference.delete.app_error", nil, "", http.StatusBadRequest).Wrap(err) } } if err := a.Srv().Store.Channel().DeleteSidebarChannelsByPreferences(preferences); err != nil { - return model.NewAppError("DeletePreferences", "api.preference.delete_preferences.update_sidebar.app_error", nil, err.Error(), http.StatusInternalServerError) + return model.NewAppError("DeletePreferences", "api.preference.delete_preferences.update_sidebar.app_error", nil, "", http.StatusInternalServerError).Wrap(err) } message := model.NewWebSocketEvent(model.WebsocketEventSidebarCategoryUpdated, "", "", userID, nil) diff --git a/app/reaction.go b/app/reaction.go index 26aa7d8414..7451677f2c 100644 --- a/app/reaction.go +++ b/app/reaction.go @@ -162,9 +162,9 @@ func (a *App) DeleteReactionForPost(c *request.Context, reaction *model.Reaction func (a *App) sendReactionEvent(event string, reaction *model.Reaction, post *model.Post) { // send out that a reaction has been added/removed message := model.NewWebSocketEvent(event, "", post.ChannelId, "", nil) - reactionJSON, jsonErr := json.Marshal(reaction) - if jsonErr != nil { - mlog.Warn("Failed to encode reaction to JSON") + reactionJSON, err := json.Marshal(reaction) + if err != nil { + a.Log().Warn("Failed to encode reaction to JSON", mlog.Err(err)) } message.Add("reaction", string(reactionJSON)) a.Publish(message) diff --git a/app/security_update_check.go b/app/security_update_check.go index cf8d9cc2c5..258ef03f0e 100644 --- a/app/security_update_check.go +++ b/app/security_update_check.go @@ -91,7 +91,7 @@ func (s *Server) DoSecurityUpdateCheck() { var bulletins model.SecurityBulletins if jsonErr := json.NewDecoder(res.Body).Decode(&bulletins); jsonErr != nil { - mlog.Error("Failed to decode JSON", mlog.Err(jsonErr)) + s.Log.Error("Failed to decode JSON", mlog.Err(jsonErr)) return } diff --git a/app/slashcommands/command_expand_collapse.go b/app/slashcommands/command_expand_collapse.go index e9c6414d95..7c8ab6583f 100644 --- a/app/slashcommands/command_expand_collapse.go +++ b/app/slashcommands/command_expand_collapse.go @@ -77,9 +77,9 @@ func setCollapsePreference(a *app.App, args *model.CommandArgs, isCollapse bool) socketMessage := model.NewWebSocketEvent(model.WebsocketEventPreferenceChanged, "", "", args.UserId, nil) - prefJSON, jsonErr := json.Marshal(pref) - if jsonErr != nil { - return &model.CommandResponse{Text: args.T("api.marshal_error") + jsonErr.Error(), ResponseType: model.CommandResponseTypeEphemeral} + prefJSON, err := json.Marshal(pref) + if err != nil { + return &model.CommandResponse{Text: args.T("api.marshal_error") + err.Error(), ResponseType: model.CommandResponseTypeEphemeral} } socketMessage.Add("preference", string(prefJSON)) a.Publish(socketMessage) diff --git a/app/slashcommands/command_loadtest.go b/app/slashcommands/command_loadtest.go index d953ddd9fb..4ca6718446 100644 --- a/app/slashcommands/command_loadtest.go +++ b/app/slashcommands/command_loadtest.go @@ -570,7 +570,7 @@ func (*LoadTestProvider) JsonCommand(a *app.App, c request.CTX, args *model.Comm var post model.Post if jsonErr := json.NewDecoder(r.Body).Decode(&post); jsonErr != nil { - return &model.CommandResponse{Text: "Unable to decode post", ResponseType: model.CommandResponseTypeEphemeral}, errors.Errorf("could not decode post from json") + return &model.CommandResponse{Text: "Unable to decode post", ResponseType: model.CommandResponseTypeEphemeral}, errors.Wrapf(jsonErr, "could not decode post from json") } post.ChannelId = args.ChannelId post.UserId = args.UserId diff --git a/app/status.go b/app/status.go index 374e3477de..377261eeb9 100644 --- a/app/status.go +++ b/app/status.go @@ -22,9 +22,9 @@ func (a *App) AddStatusCache(status *model.Status) { a.AddStatusCacheSkipClusterSend(status) if a.Cluster() != nil { - statusJSON, jsonErr := json.Marshal(status) - if jsonErr != nil { - mlog.Warn("Failed to encode status to JSON") + statusJSON, err := json.Marshal(status) + if err != nil { + a.Log().Warn("Failed to encode status to JSON", mlog.Err(err)) } msg := &model.ClusterMessage{ Event: model.ClusterEventUpdateStatus, @@ -456,20 +456,20 @@ func (a *App) GetCustomStatus(userID string) (*model.CustomStatus, *model.AppErr func (a *App) addRecentCustomStatus(userID string, status *model.CustomStatus) *model.AppError { var newRCS model.RecentCustomStatuses - pref, err := a.GetPreferenceByCategoryAndNameForUser(userID, model.PreferenceCategoryCustomStatus, model.PreferenceNameRecentCustomStatuses) - if err != nil || pref.Value == "" { + pref, appErr := a.GetPreferenceByCategoryAndNameForUser(userID, model.PreferenceCategoryCustomStatus, model.PreferenceNameRecentCustomStatuses) + if appErr != nil || pref.Value == "" { newRCS = model.RecentCustomStatuses{*status} } else { var existingRCS model.RecentCustomStatuses - if jsonErr := json.Unmarshal([]byte(pref.Value), &existingRCS); jsonErr != nil { - return model.NewAppError("addRecentCustomStatus", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusBadRequest) + if err := json.Unmarshal([]byte(pref.Value), &existingRCS); err != nil { + return model.NewAppError("addRecentCustomStatus", "api.unmarshal_error", nil, "", http.StatusBadRequest).Wrap(err) } newRCS = existingRCS.Add(status) } - newRCSJSON, jsonErr := json.Marshal(newRCS) - if jsonErr != nil { - return model.NewAppError("addRecentCustomStatus", "api.marshal_error", nil, jsonErr.Error(), http.StatusBadRequest) + newRCSJSON, err := json.Marshal(newRCS) + if err != nil { + return model.NewAppError("addRecentCustomStatus", "api.marshal_error", nil, "", http.StatusBadRequest).Wrap(err) } pref = &model.Preference{ UserId: userID, @@ -477,17 +477,17 @@ func (a *App) addRecentCustomStatus(userID string, status *model.CustomStatus) * Name: model.PreferenceNameRecentCustomStatuses, Value: string(newRCSJSON), } - if err := a.UpdatePreferences(userID, model.Preferences{*pref}); err != nil { - return err + if appErr := a.UpdatePreferences(userID, model.Preferences{*pref}); appErr != nil { + return appErr } return nil } func (a *App) RemoveRecentCustomStatus(userID string, status *model.CustomStatus) *model.AppError { - pref, err := a.GetPreferenceByCategoryAndNameForUser(userID, model.PreferenceCategoryCustomStatus, model.PreferenceNameRecentCustomStatuses) - if err != nil { - return err + pref, appErr := a.GetPreferenceByCategoryAndNameForUser(userID, model.PreferenceCategoryCustomStatus, model.PreferenceNameRecentCustomStatuses) + if appErr != nil { + return appErr } if pref.Value == "" { @@ -495,26 +495,26 @@ func (a *App) RemoveRecentCustomStatus(userID string, status *model.CustomStatus } var existingRCS model.RecentCustomStatuses - if jsonErr := json.Unmarshal([]byte(pref.Value), &existingRCS); jsonErr != nil { - return model.NewAppError("RemoveRecentCustomStatus", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusBadRequest) + if err := json.Unmarshal([]byte(pref.Value), &existingRCS); err != nil { + return model.NewAppError("RemoveRecentCustomStatus", "api.unmarshal_error", nil, "", http.StatusBadRequest).Wrap(err) } if ok, err := existingRCS.Contains(status); !ok || err != nil { return model.NewAppError("RemoveRecentCustomStatus", "api.custom_status.recent_custom_statuses.delete.app_error", nil, "", http.StatusBadRequest) } - newRCS, removeErr := existingRCS.Remove(status) - if removeErr != nil { - return model.NewAppError("RemoveRecentCustomStatus", "api.custom_status.recent_custom_statuses.delete.app_error", nil, removeErr.Error(), http.StatusBadRequest) + newRCS, err := existingRCS.Remove(status) + if err != nil { + return model.NewAppError("RemoveRecentCustomStatus", "api.custom_status.recent_custom_statuses.delete.app_error", nil, "", http.StatusBadRequest).Wrap(err) } - newRCSJSON, jsonErr := json.Marshal(newRCS) - if jsonErr != nil { - return model.NewAppError("RemoveRecentCustomStatus", "api.marshal_error", nil, jsonErr.Error(), http.StatusBadRequest) + newRCSJSON, err := json.Marshal(newRCS) + if err != nil { + return model.NewAppError("RemoveRecentCustomStatus", "api.marshal_error", nil, "", http.StatusBadRequest).Wrap(err) } pref.Value = string(newRCSJSON) - if err := a.UpdatePreferences(userID, model.Preferences{*pref}); err != nil { - return err + if appErr := a.UpdatePreferences(userID, model.Preferences{*pref}); appErr != nil { + return appErr } return nil diff --git a/app/user.go b/app/user.go index 9d2a2eb3ac..ec4d24063d 100644 --- a/app/user.go +++ b/app/user.go @@ -1241,7 +1241,7 @@ func (a *App) updateUserNotifyProps(userID string, props map[string]string) *mod case errors.As(err, &appErr): return appErr default: - return model.NewAppError("UpdateUser", "app.user.update.finding.app_error", nil, err.Error(), http.StatusInternalServerError) + return model.NewAppError("UpdateUser", "app.user.update.finding.app_error", nil, "", http.StatusInternalServerError).Wrap(err) } } @@ -1417,7 +1417,7 @@ func (a *App) CreatePasswordRecoveryToken(userID, email string) (*model.Token, * } jsonData, err := json.Marshal(tokenExtra) if err != nil { - return nil, model.NewAppError("CreatePasswordRecoveryToken", "api.user.create_password_token.error", nil, "", http.StatusInternalServerError) + return nil, model.NewAppError("CreatePasswordRecoveryToken", "api.user.create_password_token.error", nil, "", http.StatusInternalServerError).Wrap(err) } token := model.NewToken(TokenTypePasswordRecovery, string(jsonData)) @@ -2184,9 +2184,9 @@ func (a *App) PromoteGuestToUser(c *request.Context, user *model.User, requestor for _, member := range teamMembers { a.sendUpdatedMemberRoleEvent(user.Id, member) - channelMembers, err := a.GetChannelMembersForUser(c, member.TeamId, user.Id) - if err != nil { - c.Logger().Warn("Failed to get channel members for user on promote guest to user", mlog.Err(err)) + channelMembers, appErr := a.GetChannelMembersForUser(c, member.TeamId, user.Id) + if appErr != nil { + c.Logger().Warn("Failed to get channel members for user on promote guest to user", mlog.Err(appErr)) } for _, member := range channelMembers { @@ -2228,9 +2228,9 @@ func (a *App) DemoteUserToGuest(c request.CTX, user *model.User) *model.AppError for _, member := range teamMembers { a.sendUpdatedMemberRoleEvent(user.Id, member) - channelMembers, err := a.GetChannelMembersForUser(c, member.TeamId, user.Id) - if err != nil { - c.Logger().Warn("Failed to get channel members for users on demote user to guest", mlog.Err(err)) + channelMembers, appErr := a.GetChannelMembersForUser(c, member.TeamId, user.Id) + if appErr != nil { + c.Logger().Warn("Failed to get channel members for users on demote user to guest", mlog.Err(appErr)) continue } diff --git a/app/webhook.go b/app/webhook.go index 37e68fd544..e8b201f056 100644 --- a/app/webhook.go +++ b/app/webhook.go @@ -98,9 +98,9 @@ func (a *App) TriggerWebhook(c request.CTX, payload *model.OutgoingWebhookPayloa var body io.Reader var contentType string if hook.ContentType == "application/json" { - js, jsonErr := json.Marshal(payload) - if jsonErr != nil { - mlog.Warn("Failed to encode to JSON", mlog.Err(jsonErr)) + js, err := json.Marshal(payload) + if err != nil { + c.Logger().Warn("Failed to encode to JSON", mlog.Err(err)) } body = bytes.NewReader(js) contentType = "application/json" @@ -116,7 +116,7 @@ func (a *App) TriggerWebhook(c request.CTX, payload *model.OutgoingWebhookPayloa a.Srv().Go(func() { webhookResp, err := a.doOutgoingWebhookRequest(url, body, contentType) if err != nil { - mlog.Error("Event POST failed.", mlog.Err(err)) + c.Logger().Error("Event POST failed.", mlog.Err(err)) return } @@ -147,7 +147,7 @@ func (a *App) TriggerWebhook(c request.CTX, payload *model.OutgoingWebhookPayloa webhookResp.IconURL = hook.IconURL } if _, err := a.CreateWebhookPost(c, hook.CreatorId, channel, text, webhookResp.Username, webhookResp.IconURL, "", webhookResp.Props, webhookResp.Type, postRootId); err != nil { - mlog.Error("Failed to create response post.", mlog.Err(err)) + c.Logger().Error("Failed to create response post.", mlog.Err(err)) } } }) @@ -175,7 +175,7 @@ func (a *App) doOutgoingWebhookRequest(url string, body io.Reader, contentType s if jsonErr == io.EOF { return nil, nil } - return nil, model.NewAppError("doOutgoingWebhookRequest", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + return nil, model.NewAppError("doOutgoingWebhookRequest", "api.unmarshal_error", nil, "", http.StatusInternalServerError).Wrap(jsonErr) } return &hookResp, nil diff --git a/jobs/migrations/advanced_permissions_phase_2.go b/jobs/migrations/advanced_permissions_phase_2.go index 4dbf0b233b..e0c517f0ea 100644 --- a/jobs/migrations/advanced_permissions_phase_2.go +++ b/jobs/migrations/advanced_permissions_phase_2.go @@ -10,6 +10,7 @@ import ( "strings" "github.com/mattermost/mattermost-server/v6/model" + "github.com/mattermost/mattermost-server/v6/shared/mlog" ) type AdvancedPermissionsPhase2Progress struct { @@ -26,7 +27,10 @@ func (p *AdvancedPermissionsPhase2Progress) ToJSON() string { func AdvancedPermissionsPhase2ProgressFromJSON(data io.Reader) *AdvancedPermissionsPhase2Progress { var o *AdvancedPermissionsPhase2Progress - json.NewDecoder(data).Decode(&o) + err := json.NewDecoder(data).Decode(&o) + if err != nil { + mlog.Warn("Error decoding advanced permissions phase 2 progress", mlog.Err(err)) + } return o } @@ -57,13 +61,17 @@ func (worker *Worker) runAdvancedPermissionsPhase2Migration(lastDone string) (bo var progress *AdvancedPermissionsPhase2Progress if lastDone == "" { // Haven't started the migration yet. - progress = new(AdvancedPermissionsPhase2Progress) - progress.CurrentTable = "TeamMembers" - progress.LastChannelId = strings.Repeat("0", 26) - progress.LastTeamId = strings.Repeat("0", 26) - progress.LastUserId = strings.Repeat("0", 26) + progress = &AdvancedPermissionsPhase2Progress{ + CurrentTable: "TeamMembers", + LastChannelId: strings.Repeat("0", 26), + LastTeamId: strings.Repeat("0", 26), + LastUserId: strings.Repeat("0", 26), + } } else { - progress = AdvancedPermissionsPhase2ProgressFromJSON(strings.NewReader(lastDone)) + err := json.NewDecoder(strings.NewReader(lastDone)).Decode(&progress) + if err != nil { + return false, "", model.NewAppError("MigrationsWorker.runAdvancedPermissionsPhase2Migration", "migrations.worker.run_advanced_permissions_phase_2_migration.invalid_progress", map[string]any{"lastDone": lastDone}, "", http.StatusInternalServerError).Wrap(err) + } if !progress.IsValid() { return false, "", model.NewAppError("MigrationsWorker.runAdvancedPermissionsPhase2Migration", "migrations.worker.run_advanced_permissions_phase_2_migration.invalid_progress", map[string]any{"progress": progress.ToJSON()}, "", http.StatusInternalServerError) } diff --git a/model/channel.go b/model/channel.go index cdf40140a5..e66c30faef 100644 --- a/model/channel.go +++ b/model/channel.go @@ -156,7 +156,6 @@ type ChannelModeratedRolesPatch struct { // Paginate whether to paginate the results. // Page page requested, if results are paginated. // PerPage number of results per page, if paginated. -// type ChannelSearchOpts struct { NotAssociatedToGroup string ExcludeDefaultChannels bool diff --git a/model/client4.go b/model/client4.go index 7225c94a1c..b00694fee4 100644 --- a/model/client4.go +++ b/model/client4.go @@ -662,8 +662,8 @@ func (c *Client4) doUploadFile(url string, body io.Reader, contentType string, c } var res FileUploadResponse - if jsonErr := json.NewDecoder(rp.Body).Decode(&res); jsonErr != nil { - return nil, nil, NewAppError("doUploadFile", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(rp.Body).Decode(&res); err != nil { + return nil, nil, NewAppError("doUploadFile", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &res, BuildResponse(rp), nil } @@ -690,8 +690,8 @@ func (c *Client4) DoEmojiUploadFile(url string, data []byte, contentType string) } var e Emoji - if jsonErr := json.NewDecoder(rp.Body).Decode(&e); jsonErr != nil { - return nil, nil, NewAppError("DoEmojiUploadFile", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(rp.Body).Decode(&e); err != nil { + return nil, nil, NewAppError("DoEmojiUploadFile", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &e, BuildResponse(rp), nil } @@ -778,8 +778,8 @@ func (c *Client4) login(m map[string]string) (*User, *Response, error) { c.AuthType = HeaderBearer var user User - if jsonErr := json.NewDecoder(r.Body).Decode(&user); jsonErr != nil { - return nil, nil, NewAppError("login", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&user); err != nil { + return nil, nil, NewAppError("login", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &user, BuildResponse(r), nil } @@ -800,7 +800,7 @@ func (c *Client4) Logout() (*Response, error) { func (c *Client4) SwitchAccountType(switchRequest *SwitchRequest) (string, *Response, error) { buf, err := json.Marshal(switchRequest) if err != nil { - return "", BuildResponse(nil), NewAppError("SwitchAccountType", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) + return "", BuildResponse(nil), NewAppError("SwitchAccountType", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) } r, err := c.DoAPIPostBytes(c.usersRoute()+"/login/switch", buf) if err != nil { @@ -814,9 +814,9 @@ func (c *Client4) SwitchAccountType(switchRequest *SwitchRequest) (string, *Resp // CreateUser creates a user in the system based on the provided user struct. func (c *Client4) CreateUser(user *User) (*User, *Response, error) { - userJSON, jsonErr := json.Marshal(user) - if jsonErr != nil { - return nil, nil, NewAppError("CreateUser", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + userJSON, err := json.Marshal(user) + if err != nil { + return nil, nil, NewAppError("CreateUser", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) } r, err := c.DoAPIPost(c.usersRoute(), string(userJSON)) @@ -825,8 +825,8 @@ func (c *Client4) CreateUser(user *User) (*User, *Response, error) { } defer closeBody(r) var u User - if jsonErr := json.NewDecoder(r.Body).Decode(&u); jsonErr != nil { - return nil, nil, NewAppError("CreateUser", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&u); err != nil { + return nil, nil, NewAppError("CreateUser", "api.unmarshal_error", nil, "", http.StatusInternalServerError).Wrap(err) } return &u, BuildResponse(r), nil } @@ -837,10 +837,10 @@ func (c *Client4) CreateUserWithToken(user *User, tokenId string) (*User, *Respo return nil, nil, NewAppError("MissingHashOrData", "api.user.create_user.missing_token.app_error", nil, "", http.StatusBadRequest) } - query := fmt.Sprintf("?t=%v", tokenId) + query := "?t=" + tokenId buf, err := json.Marshal(user) if err != nil { - return nil, nil, NewAppError("CreateUserWithToken", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) + return nil, nil, NewAppError("CreateUserWithToken", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) } r, err := c.DoAPIPostBytes(c.usersRoute()+query, buf) if err != nil { @@ -849,8 +849,8 @@ func (c *Client4) CreateUserWithToken(user *User, tokenId string) (*User, *Respo defer closeBody(r) var u User - if jsonErr := json.NewDecoder(r.Body).Decode(&u); jsonErr != nil { - return nil, nil, NewAppError("CreateUserWithToken", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&u); err != nil { + return nil, nil, NewAppError("CreateUserWithToken", "api.unmarshal_error", nil, "", http.StatusInternalServerError).Wrap(err) } return &u, BuildResponse(r), nil } @@ -861,10 +861,10 @@ func (c *Client4) CreateUserWithInviteId(user *User, inviteId string) (*User, *R return nil, nil, NewAppError("MissingInviteId", "api.user.create_user.missing_invite_id.app_error", nil, "", http.StatusBadRequest) } - query := fmt.Sprintf("?iid=%v", url.QueryEscape(inviteId)) + query := "?iid=" + url.QueryEscape(inviteId) buf, err := json.Marshal(user) if err != nil { - return nil, nil, NewAppError("CreateUserWithInviteId", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) + return nil, nil, NewAppError("CreateUserWithInviteId", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) } r, err := c.DoAPIPostBytes(c.usersRoute()+query, buf) if err != nil { @@ -873,8 +873,8 @@ func (c *Client4) CreateUserWithInviteId(user *User, inviteId string) (*User, *R defer closeBody(r) var u User - if jsonErr := json.NewDecoder(r.Body).Decode(&u); jsonErr != nil { - return nil, nil, NewAppError("CreateUserWithInviteId", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&u); err != nil { + return nil, nil, NewAppError("CreateUserWithInviteId", "api.unmarshal_error", nil, "", http.StatusInternalServerError).Wrap(err) } return &u, BuildResponse(r), nil } @@ -890,8 +890,8 @@ func (c *Client4) GetMe(etag string) (*User, *Response, error) { if r.StatusCode == http.StatusNotModified { return &u, BuildResponse(r), nil } - if jsonErr := json.NewDecoder(r.Body).Decode(&u); jsonErr != nil { - return nil, nil, NewAppError("GetMe", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&u); err != nil { + return nil, nil, NewAppError("GetMe", "api.unmarshal_error", nil, "", http.StatusInternalServerError).Wrap(err) } return &u, BuildResponse(r), nil } @@ -907,8 +907,8 @@ func (c *Client4) GetUser(userId, etag string) (*User, *Response, error) { if r.StatusCode == http.StatusNotModified { return &u, BuildResponse(r), nil } - if jsonErr := json.NewDecoder(r.Body).Decode(&u); jsonErr != nil { - return nil, nil, NewAppError("GetUser", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&u); err != nil { + return nil, nil, NewAppError("GetUser", "api.unmarshal_error", nil, "", http.StatusInternalServerError).Wrap(err) } return &u, BuildResponse(r), nil } @@ -924,8 +924,8 @@ func (c *Client4) GetUserByUsername(userName, etag string) (*User, *Response, er if r.StatusCode == http.StatusNotModified { return &u, BuildResponse(r), nil } - if jsonErr := json.NewDecoder(r.Body).Decode(&u); jsonErr != nil { - return nil, nil, NewAppError("GetUserByUsername", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&u); err != nil { + return nil, nil, NewAppError("GetUserByUsername", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &u, BuildResponse(r), nil } @@ -941,8 +941,8 @@ func (c *Client4) GetUserByEmail(email, etag string) (*User, *Response, error) { if r.StatusCode == http.StatusNotModified { return &u, BuildResponse(r), nil } - if jsonErr := json.NewDecoder(r.Body).Decode(&u); jsonErr != nil { - return nil, nil, NewAppError("GetUserByEmail", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&u); err != nil { + return nil, nil, NewAppError("GetUserByEmail", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &u, BuildResponse(r), nil } @@ -959,8 +959,8 @@ func (c *Client4) AutocompleteUsersInTeam(teamId string, username string, limit if r.StatusCode == http.StatusNotModified { return &u, BuildResponse(r), nil } - if jsonErr := json.NewDecoder(r.Body).Decode(&u); jsonErr != nil { - return nil, nil, NewAppError("AutocompleteUsersInTeam", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&u); err != nil { + return nil, nil, NewAppError("AutocompleteUsersInTeam", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &u, BuildResponse(r), nil } @@ -977,8 +977,8 @@ func (c *Client4) AutocompleteUsersInChannel(teamId string, channelId string, us if r.StatusCode == http.StatusNotModified { return &u, BuildResponse(r), nil } - if jsonErr := json.NewDecoder(r.Body).Decode(&u); jsonErr != nil { - return nil, nil, NewAppError("AutocompleteUsersInChannel", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&u); err != nil { + return nil, nil, NewAppError("AutocompleteUsersInChannel", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &u, BuildResponse(r), nil } @@ -995,8 +995,8 @@ func (c *Client4) AutocompleteUsers(username string, limit int, etag string) (*U if r.StatusCode == http.StatusNotModified { return &u, BuildResponse(r), nil } - if jsonErr := json.NewDecoder(r.Body).Decode(&u); jsonErr != nil { - return nil, nil, NewAppError("AutocompleteUsers", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&u); err != nil { + return nil, nil, NewAppError("AutocompleteUsers", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &u, BuildResponse(r), nil } @@ -1044,8 +1044,8 @@ func (c *Client4) GetUsers(page int, perPage int, etag string) ([]*User, *Respon if r.StatusCode == http.StatusNotModified { return list, BuildResponse(r), nil } - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetUsers", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetUsers", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return list, BuildResponse(r), nil } @@ -1062,8 +1062,8 @@ func (c *Client4) GetUsersInTeam(teamId string, page int, perPage int, etag stri if r.StatusCode == http.StatusNotModified { return list, BuildResponse(r), nil } - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetUsersInTeam", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetUsersInTeam", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return list, BuildResponse(r), nil } @@ -1080,8 +1080,8 @@ func (c *Client4) GetNewUsersInTeam(teamId string, page int, perPage int, etag s if r.StatusCode == http.StatusNotModified { return list, BuildResponse(r), nil } - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetNewUsersInTeam", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetNewUsersInTeam", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return list, BuildResponse(r), nil } @@ -1098,8 +1098,8 @@ func (c *Client4) GetRecentlyActiveUsersInTeam(teamId string, page int, perPage if r.StatusCode == http.StatusNotModified { return list, BuildResponse(r), nil } - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetRecentlyActiveUsersInTeam", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetRecentlyActiveUsersInTeam", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return list, BuildResponse(r), nil } @@ -1116,8 +1116,8 @@ func (c *Client4) GetActiveUsersInTeam(teamId string, page int, perPage int, eta if r.StatusCode == http.StatusNotModified { return list, BuildResponse(r), nil } - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetActiveUsersInTeam", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetActiveUsersInTeam", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return list, BuildResponse(r), nil } @@ -1134,8 +1134,8 @@ func (c *Client4) GetUsersNotInTeam(teamId string, page int, perPage int, etag s if r.StatusCode == http.StatusNotModified { return list, BuildResponse(r), nil } - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetUsersNotInTeam", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetUsersNotInTeam", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return list, BuildResponse(r), nil } @@ -1152,8 +1152,8 @@ func (c *Client4) GetUsersInChannel(channelId string, page int, perPage int, eta if r.StatusCode == http.StatusNotModified { return list, BuildResponse(r), nil } - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetUsersInChannel", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetUsersInChannel", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return list, BuildResponse(r), nil } @@ -1170,8 +1170,8 @@ func (c *Client4) GetUsersInChannelByStatus(channelId string, page int, perPage if r.StatusCode == http.StatusNotModified { return list, BuildResponse(r), nil } - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetUsersInChannelByStatus", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetUsersInChannelByStatus", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return list, BuildResponse(r), nil } @@ -1188,8 +1188,8 @@ func (c *Client4) GetUsersNotInChannel(teamId, channelId string, page int, perPa if r.StatusCode == http.StatusNotModified { return list, BuildResponse(r), nil } - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetUsersNotInChannel", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetUsersNotInChannel", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return list, BuildResponse(r), nil } @@ -1206,8 +1206,8 @@ func (c *Client4) GetUsersWithoutTeam(page int, perPage int, etag string) ([]*Us if r.StatusCode == http.StatusNotModified { return list, BuildResponse(r), nil } - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetUsersWithoutTeam", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetUsersWithoutTeam", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return list, BuildResponse(r), nil } @@ -1224,8 +1224,8 @@ func (c *Client4) GetUsersInGroup(groupID string, page int, perPage int, etag st if r.StatusCode == http.StatusNotModified { return list, BuildResponse(r), nil } - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetUsersInGroup", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetUsersInGroup", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return list, BuildResponse(r), nil } @@ -1238,8 +1238,8 @@ func (c *Client4) GetUsersByIds(userIds []string) ([]*User, *Response, error) { } defer closeBody(r) var list []*User - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetUsersByIds", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetUsersByIds", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return list, BuildResponse(r), nil } @@ -1262,8 +1262,8 @@ func (c *Client4) GetUsersByIdsWithOptions(userIds []string, options *UserGetByI } defer closeBody(r) var list []*User - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetUsersByIdsWithOptions", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetUsersByIdsWithOptions", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return list, BuildResponse(r), nil } @@ -1276,8 +1276,8 @@ func (c *Client4) GetUsersByUsernames(usernames []string) ([]*User, *Response, e } defer closeBody(r) var list []*User - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetUsersByUsernames", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetUsersByUsernames", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return list, BuildResponse(r), nil } @@ -1300,7 +1300,7 @@ func (c *Client4) GetUsersByGroupChannelIds(groupChannelIds []string) (map[strin func (c *Client4) SearchUsers(search *UserSearch) ([]*User, *Response, error) { buf, err := json.Marshal(search) if err != nil { - return nil, nil, NewAppError("SearchUsers", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) + return nil, nil, NewAppError("SearchUsers", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) } r, err := c.DoAPIPostBytes(c.usersRoute()+"/search", buf) if err != nil { @@ -1308,8 +1308,8 @@ func (c *Client4) SearchUsers(search *UserSearch) ([]*User, *Response, error) { } defer closeBody(r) var list []*User - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("SearchUsers", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("SearchUsers", "api.unmarshal_error", nil, "", http.StatusInternalServerError).Wrap(err) } return list, BuildResponse(r), nil } @@ -1318,7 +1318,7 @@ func (c *Client4) SearchUsers(search *UserSearch) ([]*User, *Response, error) { func (c *Client4) UpdateUser(user *User) (*User, *Response, error) { buf, err := json.Marshal(user) if err != nil { - return nil, nil, NewAppError("UpdateUser", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) + return nil, nil, NewAppError("UpdateUser", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) } r, err := c.DoAPIPutBytes(c.userRoute(user.Id), buf) if err != nil { @@ -1326,8 +1326,8 @@ func (c *Client4) UpdateUser(user *User) (*User, *Response, error) { } defer closeBody(r) var u User - if jsonErr := json.NewDecoder(r.Body).Decode(&u); jsonErr != nil { - return nil, nil, NewAppError("UpdateUser", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&u); err != nil { + return nil, nil, NewAppError("UpdateUser", "api.unmarshal_error", nil, "", http.StatusInternalServerError).Wrap(err) } return &u, BuildResponse(r), nil } @@ -1336,7 +1336,7 @@ func (c *Client4) UpdateUser(user *User) (*User, *Response, error) { func (c *Client4) PatchUser(userId string, patch *UserPatch) (*User, *Response, error) { buf, err := json.Marshal(patch) if err != nil { - return nil, nil, NewAppError("PatchUser", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) + return nil, nil, NewAppError("PatchUser", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) } r, err := c.DoAPIPutBytes(c.userRoute(userId)+"/patch", buf) if err != nil { @@ -1344,8 +1344,8 @@ func (c *Client4) PatchUser(userId string, patch *UserPatch) (*User, *Response, } defer closeBody(r) var u User - if jsonErr := json.NewDecoder(r.Body).Decode(&u); jsonErr != nil { - return nil, nil, NewAppError("PatchUser", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&u); err != nil { + return nil, nil, NewAppError("PatchUser", "api.unmarshal_error", nil, "", http.StatusInternalServerError).Wrap(err) } return &u, BuildResponse(r), nil } @@ -1354,7 +1354,7 @@ func (c *Client4) PatchUser(userId string, patch *UserPatch) (*User, *Response, func (c *Client4) UpdateUserAuth(userId string, userAuth *UserAuth) (*UserAuth, *Response, error) { buf, err := json.Marshal(userAuth) if err != nil { - return nil, nil, NewAppError("UpdateUserAuth", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) + return nil, nil, NewAppError("UpdateUserAuth", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) } r, err := c.DoAPIPutBytes(c.userRoute(userId)+"/auth", buf) if err != nil { @@ -1362,8 +1362,8 @@ func (c *Client4) UpdateUserAuth(userId string, userAuth *UserAuth) (*UserAuth, } defer closeBody(r) var ua UserAuth - if jsonErr := json.NewDecoder(r.Body).Decode(&ua); jsonErr != nil { - return nil, nil, NewAppError("UpdateUserAuth", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&ua); err != nil { + return nil, nil, NewAppError("UpdateUserAuth", "api.unmarshal_error", nil, "", http.StatusInternalServerError).Wrap(err) } return &ua, BuildResponse(r), nil } @@ -1393,8 +1393,8 @@ func (c *Client4) GenerateMfaSecret(userId string) (*MfaSecret, *Response, error } defer closeBody(r) var secret MfaSecret - if jsonErr := json.NewDecoder(r.Body).Decode(&secret); jsonErr != nil { - return nil, nil, NewAppError("GenerateMfaSecret", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&secret); err != nil { + return nil, nil, NewAppError("GenerateMfaSecret", "api.unmarshal_error", nil, "", http.StatusInternalServerError).Wrap(err) } return &secret, BuildResponse(r), nil } @@ -1495,7 +1495,7 @@ func (c *Client4) ConvertUserToBot(userId string) (*Bot, *Response, error) { var bot *Bot err = json.NewDecoder(r.Body).Decode(&bot) if err != nil { - return nil, BuildResponse(r), NewAppError("ConvertUserToBot", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) + return nil, BuildResponse(r), NewAppError("ConvertUserToBot", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) } return bot, BuildResponse(r), nil } @@ -1508,7 +1508,7 @@ func (c *Client4) ConvertBotToUser(userId string, userPatch *UserPatch, setSyste } buf, err := json.Marshal(userPatch) if err != nil { - return nil, nil, NewAppError("ConvertBotToUser", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) + return nil, nil, NewAppError("ConvertBotToUser", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) } r, err := c.DoAPIPostBytes(c.botRoute(userId)+"/convert_to_user"+query, buf) if err != nil { @@ -1516,8 +1516,8 @@ func (c *Client4) ConvertBotToUser(userId string, userPatch *UserPatch, setSyste } defer closeBody(r) var u User - if jsonErr := json.NewDecoder(r.Body).Decode(&u); jsonErr != nil { - return nil, nil, NewAppError("ConvertBotToUser", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&u); err != nil { + return nil, nil, NewAppError("ConvertBotToUser", "api.unmarshal_error", nil, "", http.StatusInternalServerError).Wrap(err) } return &u, BuildResponse(r), nil } @@ -1563,8 +1563,8 @@ func (c *Client4) GetSessions(userId, etag string) ([]*Session, *Response, error } defer closeBody(r) var list []*Session - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetSessions", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetSessions", "api.unmarshal_error", nil, "", http.StatusInternalServerError).Wrap(err) } return list, BuildResponse(r), nil } @@ -1633,8 +1633,8 @@ func (c *Client4) GetTeamsUnreadForUser(userId, teamIdToExclude string, includeC defer closeBody(r) var list []*TeamUnread - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetTeamsUnreadForUser", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetTeamsUnreadForUser", "api.unmarshal_error", nil, "", http.StatusInternalServerError).Wrap(err) } return list, BuildResponse(r), nil } @@ -1651,7 +1651,7 @@ func (c *Client4) GetUserAudits(userId string, page int, perPage int, etag strin var audits Audits err = json.NewDecoder(r.Body).Decode(&audits) if err != nil { - return nil, BuildResponse(r), NewAppError("GetUserAudits", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) + return nil, BuildResponse(r), NewAppError("GetUserAudits", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) } return audits, BuildResponse(r), nil } @@ -1675,8 +1675,8 @@ func (c *Client4) VerifyUserEmailWithoutToken(userId string) (*User, *Response, } defer closeBody(r) var u User - if jsonErr := json.NewDecoder(r.Body).Decode(&u); jsonErr != nil { - return nil, nil, NewAppError("VerifyUserEmailWithoutToken", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&u); err != nil { + return nil, nil, NewAppError("VerifyUserEmailWithoutToken", "api.unmarshal_error", nil, "", http.StatusInternalServerError).Wrap(err) } return &u, BuildResponse(r), nil } @@ -1710,15 +1710,15 @@ func (c *Client4) SetProfileImage(userId string, data []byte) (*Response, error) part, err := writer.CreateFormFile("image", "profile.png") if err != nil { - return nil, NewAppError("SetProfileImage", "model.client.set_profile_user.no_file.app_error", nil, err.Error(), http.StatusBadRequest) + return nil, NewAppError("SetProfileImage", "model.client.set_profile_user.no_file.app_error", nil, "", http.StatusBadRequest).Wrap(err) } if _, err = io.Copy(part, bytes.NewBuffer(data)); err != nil { - return nil, NewAppError("SetProfileImage", "model.client.set_profile_user.no_file.app_error", nil, err.Error(), http.StatusBadRequest) + return nil, NewAppError("SetProfileImage", "model.client.set_profile_user.no_file.app_error", nil, "", http.StatusBadRequest).Wrap(err) } if err = writer.Close(); err != nil { - return nil, NewAppError("SetProfileImage", "model.client.set_profile_user.writer.app_error", nil, err.Error(), http.StatusBadRequest) + return nil, NewAppError("SetProfileImage", "model.client.set_profile_user.writer.app_error", nil, "", http.StatusBadRequest).Wrap(err) } rq, err := http.NewRequest("POST", c.APIURL+c.userRoute(userId)+"/image", bytes.NewReader(body.Bytes())) @@ -1756,8 +1756,8 @@ func (c *Client4) CreateUserAccessToken(userId, description string) (*UserAccess } defer closeBody(r) var uat UserAccessToken - if jsonErr := json.NewDecoder(r.Body).Decode(&uat); jsonErr != nil { - return nil, nil, NewAppError("CreateUserAccessToken", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&uat); err != nil { + return nil, nil, NewAppError("CreateUserAccessToken", "api.unmarshal_error", nil, "", http.StatusInternalServerError).Wrap(err) } return &uat, BuildResponse(r), nil } @@ -1773,8 +1773,8 @@ func (c *Client4) GetUserAccessTokens(page int, perPage int) ([]*UserAccessToken } defer closeBody(r) var list []*UserAccessToken - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetUserAccessTokens", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetUserAccessTokens", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return list, BuildResponse(r), nil } @@ -1790,8 +1790,8 @@ func (c *Client4) GetUserAccessToken(tokenId string) (*UserAccessToken, *Respons } defer closeBody(r) var uat UserAccessToken - if jsonErr := json.NewDecoder(r.Body).Decode(&uat); jsonErr != nil { - return nil, nil, NewAppError("GetUserAccessToken", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&uat); err != nil { + return nil, nil, NewAppError("GetUserAccessToken", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &uat, BuildResponse(r), nil } @@ -1808,8 +1808,8 @@ func (c *Client4) GetUserAccessTokensForUser(userId string, page, perPage int) ( } defer closeBody(r) var list []*UserAccessToken - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetUserAccessTokensForUser", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetUserAccessTokensForUser", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return list, BuildResponse(r), nil } @@ -1839,8 +1839,8 @@ func (c *Client4) SearchUserAccessTokens(search *UserAccessTokenSearch) ([]*User } defer closeBody(r) var list []*UserAccessToken - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("SearchUserAccessTokens", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("SearchUserAccessTokens", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return list, BuildResponse(r), nil } @@ -2065,8 +2065,8 @@ func (c *Client4) CreateTeam(team *Team) (*Team, *Response, error) { } defer closeBody(r) var t Team - if jsonErr := json.NewDecoder(r.Body).Decode(&t); jsonErr != nil { - return nil, nil, NewAppError("CreateTeam", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&t); err != nil { + return nil, nil, NewAppError("CreateTeam", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &t, BuildResponse(r), nil } @@ -2079,8 +2079,8 @@ func (c *Client4) GetTeam(teamId, etag string) (*Team, *Response, error) { } defer closeBody(r) var t Team - if jsonErr := json.NewDecoder(r.Body).Decode(&t); jsonErr != nil { - return nil, nil, NewAppError("GetTeam", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&t); err != nil { + return nil, nil, NewAppError("GetTeam", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &t, BuildResponse(r), nil } @@ -2094,8 +2094,8 @@ func (c *Client4) GetAllTeams(etag string, page int, perPage int) ([]*Team, *Res } defer closeBody(r) var list []*Team - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetAllTeams", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetAllTeams", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return list, BuildResponse(r), nil } @@ -2109,8 +2109,8 @@ func (c *Client4) GetAllTeamsWithTotalCount(etag string, page int, perPage int) } defer closeBody(r) var listWithCount TeamsWithCount - if jsonErr := json.NewDecoder(r.Body).Decode(&listWithCount); jsonErr != nil { - return nil, 0, nil, NewAppError("GetAllTeamsWithTotalCount", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&listWithCount); err != nil { + return nil, 0, nil, NewAppError("GetAllTeamsWithTotalCount", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return listWithCount.Teams, listWithCount.TotalCount, BuildResponse(r), nil } @@ -2125,8 +2125,8 @@ func (c *Client4) GetAllTeamsExcludePolicyConstrained(etag string, page int, per } defer closeBody(r) var list []*Team - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetAllTeamsExcludePolicyConstrained", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetAllTeamsExcludePolicyConstrained", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return list, BuildResponse(r), nil } @@ -2139,8 +2139,8 @@ func (c *Client4) GetTeamByName(name, etag string) (*Team, *Response, error) { } defer closeBody(r) var t Team - if jsonErr := json.NewDecoder(r.Body).Decode(&t); jsonErr != nil { - return nil, nil, NewAppError("GetTeamByName", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&t); err != nil { + return nil, nil, NewAppError("GetTeamByName", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &t, BuildResponse(r), nil } @@ -2157,8 +2157,8 @@ func (c *Client4) SearchTeams(search *TeamSearch) ([]*Team, *Response, error) { } defer closeBody(r) var list []*Team - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("SearchTeams", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("SearchTeams", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return list, BuildResponse(r), nil } @@ -2181,8 +2181,8 @@ func (c *Client4) SearchTeamsPaged(search *TeamSearch) ([]*Team, int64, *Respons } defer closeBody(r) var listWithCount TeamsWithCount - if jsonErr := json.NewDecoder(r.Body).Decode(&listWithCount); jsonErr != nil { - return nil, 0, nil, NewAppError("GetAllTeamsWithTotalCount", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&listWithCount); err != nil { + return nil, 0, nil, NewAppError("GetAllTeamsWithTotalCount", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return listWithCount.Teams, listWithCount.TotalCount, BuildResponse(r), nil } @@ -2206,8 +2206,8 @@ func (c *Client4) GetTeamsForUser(userId, etag string) ([]*Team, *Response, erro } defer closeBody(r) var list []*Team - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetTeamsForUser", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetTeamsForUser", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return list, BuildResponse(r), nil } @@ -2223,8 +2223,8 @@ func (c *Client4) GetTeamMember(teamId, userId, etag string) (*TeamMember, *Resp if r.StatusCode == http.StatusNotModified { return &tm, BuildResponse(r), nil } - if jsonErr := json.NewDecoder(r.Body).Decode(&tm); jsonErr != nil { - return nil, nil, NewAppError("GetTeamMember", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&tm); err != nil { + return nil, nil, NewAppError("GetTeamMember", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &tm, BuildResponse(r), nil } @@ -2266,8 +2266,8 @@ func (c *Client4) UpdateTeam(team *Team) (*Team, *Response, error) { } defer closeBody(r) var t Team - if jsonErr := json.NewDecoder(r.Body).Decode(&t); jsonErr != nil { - return nil, nil, NewAppError("UpdateTeam", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&t); err != nil { + return nil, nil, NewAppError("UpdateTeam", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &t, BuildResponse(r), nil } @@ -2284,8 +2284,8 @@ func (c *Client4) PatchTeam(teamId string, patch *TeamPatch) (*Team, *Response, } defer closeBody(r) var t Team - if jsonErr := json.NewDecoder(r.Body).Decode(&t); jsonErr != nil { - return nil, nil, NewAppError("PatchTeam", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&t); err != nil { + return nil, nil, NewAppError("PatchTeam", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &t, BuildResponse(r), nil } @@ -2298,8 +2298,8 @@ func (c *Client4) RestoreTeam(teamId string) (*Team, *Response, error) { } defer closeBody(r) var t Team - if jsonErr := json.NewDecoder(r.Body).Decode(&t); jsonErr != nil { - return nil, nil, NewAppError("RestoreTeam", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&t); err != nil { + return nil, nil, NewAppError("RestoreTeam", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &t, BuildResponse(r), nil } @@ -2312,8 +2312,8 @@ func (c *Client4) RegenerateTeamInviteId(teamId string) (*Team, *Response, error } defer closeBody(r) var t Team - if jsonErr := json.NewDecoder(r.Body).Decode(&t); jsonErr != nil { - return nil, nil, NewAppError("RegenerateTeamInviteId", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&t); err != nil { + return nil, nil, NewAppError("RegenerateTeamInviteId", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &t, BuildResponse(r), nil } @@ -2349,8 +2349,8 @@ func (c *Client4) UpdateTeamPrivacy(teamId string, privacy string) (*Team, *Resp } defer closeBody(r) var t Team - if jsonErr := json.NewDecoder(r.Body).Decode(&t); jsonErr != nil { - return nil, nil, NewAppError("UpdateTeamPrivacy", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&t); err != nil { + return nil, nil, NewAppError("UpdateTeamPrivacy", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &t, BuildResponse(r), nil } @@ -2367,8 +2367,8 @@ func (c *Client4) GetTeamMembers(teamId string, page int, perPage int, etag stri if r.StatusCode == http.StatusNotModified { return tms, BuildResponse(r), nil } - if jsonErr := json.NewDecoder(r.Body).Decode(&tms); jsonErr != nil { - return nil, nil, NewAppError("GetTeamMembers", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&tms); err != nil { + return nil, nil, NewAppError("GetTeamMembers", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return tms, BuildResponse(r), nil } @@ -2386,8 +2386,8 @@ func (c *Client4) GetTeamMembersSortAndWithoutDeletedUsers(teamId string, page i if r.StatusCode == http.StatusNotModified { return tms, BuildResponse(r), nil } - if jsonErr := json.NewDecoder(r.Body).Decode(&tms); jsonErr != nil { - return nil, nil, NewAppError("GetTeamMembersSortAndWithoutDeletedUsers", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&tms); err != nil { + return nil, nil, NewAppError("GetTeamMembersSortAndWithoutDeletedUsers", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return tms, BuildResponse(r), nil } @@ -2403,8 +2403,8 @@ func (c *Client4) GetTeamMembersForUser(userId string, etag string) ([]*TeamMemb if r.StatusCode == http.StatusNotModified { return tms, BuildResponse(r), nil } - if jsonErr := json.NewDecoder(r.Body).Decode(&tms); jsonErr != nil { - return nil, nil, NewAppError("GetTeamMembersForUser", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&tms); err != nil { + return nil, nil, NewAppError("GetTeamMembersForUser", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return tms, BuildResponse(r), nil } @@ -2418,8 +2418,8 @@ func (c *Client4) GetTeamMembersByIds(teamId string, userIds []string) ([]*TeamM } defer closeBody(r) var tms []*TeamMember - if jsonErr := json.NewDecoder(r.Body).Decode(&tms); jsonErr != nil { - return nil, nil, NewAppError("GetTeamMembersByIds", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&tms); err != nil { + return nil, nil, NewAppError("GetTeamMembersByIds", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return tms, BuildResponse(r), nil } @@ -2437,8 +2437,8 @@ func (c *Client4) AddTeamMember(teamId, userId string) (*TeamMember, *Response, } defer closeBody(r) var tm TeamMember - if jsonErr := json.NewDecoder(r.Body).Decode(&tm); jsonErr != nil { - return nil, nil, NewAppError("AddTeamMember", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&tm); err != nil { + return nil, nil, NewAppError("AddTeamMember", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &tm, BuildResponse(r), nil } @@ -2462,8 +2462,8 @@ func (c *Client4) AddTeamMemberFromInvite(token, inviteId string) (*TeamMember, } defer closeBody(r) var tm TeamMember - if jsonErr := json.NewDecoder(r.Body).Decode(&tm); jsonErr != nil { - return nil, nil, NewAppError("AddTeamMemberFromInvite", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&tm); err != nil { + return nil, nil, NewAppError("AddTeamMemberFromInvite", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &tm, BuildResponse(r), nil } @@ -2475,9 +2475,9 @@ func (c *Client4) AddTeamMembers(teamId string, userIds []string) ([]*TeamMember member := &TeamMember{TeamId: teamId, UserId: userId} members = append(members, member) } - js, jsonErr := json.Marshal(members) - if jsonErr != nil { - return nil, nil, NewAppError("AddTeamMembers", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(members) + if err != nil { + return nil, nil, NewAppError("AddTeamMembers", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) } r, err := c.DoAPIPost(c.teamMembersRoute(teamId)+"/batch", string(js)) if err != nil { @@ -2485,8 +2485,8 @@ func (c *Client4) AddTeamMembers(teamId string, userIds []string) ([]*TeamMember } defer closeBody(r) var tms []*TeamMember - if jsonErr := json.NewDecoder(r.Body).Decode(&tms); jsonErr != nil { - return nil, nil, NewAppError("AddTeamMembers", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&tms); err != nil { + return nil, nil, NewAppError("AddTeamMembers", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return tms, BuildResponse(r), nil } @@ -2498,9 +2498,9 @@ func (c *Client4) AddTeamMembersGracefully(teamId string, userIds []string) ([]* member := &TeamMember{TeamId: teamId, UserId: userId} members = append(members, member) } - js, jsonErr := json.Marshal(members) - if jsonErr != nil { - return nil, nil, NewAppError("AddTeamMembersGracefully", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(members) + if err != nil { + return nil, nil, NewAppError("AddTeamMembersGracefully", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) } r, err := c.DoAPIPost(c.teamMembersRoute(teamId)+"/batch?graceful="+c.boolString(true), string(js)) @@ -2509,8 +2509,8 @@ func (c *Client4) AddTeamMembersGracefully(teamId string, userIds []string) ([]* } defer closeBody(r) var tms []*TeamMemberWithError - if jsonErr := json.NewDecoder(r.Body).Decode(&tms); jsonErr != nil { - return nil, nil, NewAppError("AddTeamMembersGracefully", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&tms); err != nil { + return nil, nil, NewAppError("AddTeamMembersGracefully", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return tms, BuildResponse(r), nil } @@ -2534,8 +2534,8 @@ func (c *Client4) GetTeamStats(teamId, etag string) (*TeamStats, *Response, erro } defer closeBody(r) var ts TeamStats - if jsonErr := json.NewDecoder(r.Body).Decode(&ts); jsonErr != nil { - return nil, nil, NewAppError("GetTeamStats", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&ts); err != nil { + return nil, nil, NewAppError("GetTeamStats", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &ts, BuildResponse(r), nil } @@ -2549,8 +2549,8 @@ func (c *Client4) GetTotalUsersStats(etag string) (*UsersStats, *Response, error } defer closeBody(r) var stats UsersStats - if jsonErr := json.NewDecoder(r.Body).Decode(&stats); jsonErr != nil { - return nil, nil, NewAppError("GetTotalUsersStats", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&stats); err != nil { + return nil, nil, NewAppError("GetTotalUsersStats", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &stats, BuildResponse(r), nil } @@ -2565,8 +2565,8 @@ func (c *Client4) GetTeamUnread(teamId, userId string) (*TeamUnread, *Response, } defer closeBody(r) var tu TeamUnread - if jsonErr := json.NewDecoder(r.Body).Decode(&tu); jsonErr != nil { - return nil, nil, NewAppError("GetTeamUnread", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&tu); err != nil { + return nil, nil, NewAppError("GetTeamUnread", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &tu, BuildResponse(r), nil } @@ -2648,8 +2648,8 @@ func (c *Client4) InviteUsersToTeamGracefully(teamId string, userEmails []string } defer closeBody(r) var list []*EmailInviteWithError - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("InviteUsersToTeamGracefully", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("InviteUsersToTeamGracefully", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return list, BuildResponse(r), nil } @@ -2671,8 +2671,8 @@ func (c *Client4) InviteUsersToTeamAndChannelsGracefully(teamId string, userEmai } defer closeBody(r) var list []*EmailInviteWithError - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("InviteUsersToTeamGracefully", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("InviteUsersToTeamGracefully", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return list, BuildResponse(r), nil } @@ -2694,8 +2694,8 @@ func (c *Client4) InviteGuestsToTeamGracefully(teamId string, userEmails []strin } defer closeBody(r) var list []*EmailInviteWithError - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("InviteGuestsToTeamGracefully", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("InviteGuestsToTeamGracefully", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return list, BuildResponse(r), nil } @@ -2718,8 +2718,8 @@ func (c *Client4) GetTeamInviteInfo(inviteId string) (*Team, *Response, error) { } defer closeBody(r) var t Team - if jsonErr := json.NewDecoder(r.Body).Decode(&t); jsonErr != nil { - return nil, nil, NewAppError("GetTeamInviteInfo", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&t); err != nil { + return nil, nil, NewAppError("GetTeamInviteInfo", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &t, BuildResponse(r), nil } @@ -2844,9 +2844,9 @@ func (c *Client4) GetAllChannelsWithCount(page int, perPage int, etag string) (C // CreateChannel creates a channel based on the provided channel struct. func (c *Client4) CreateChannel(channel *Channel) (*Channel, *Response, error) { - channelJSON, jsonErr := json.Marshal(channel) - if jsonErr != nil { - return nil, nil, NewAppError("CreateChannel", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + channelJSON, err := json.Marshal(channel) + if err != nil { + return nil, nil, NewAppError("CreateChannel", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) } r, err := c.DoAPIPost(c.channelsRoute(), string(channelJSON)) if err != nil { @@ -2864,9 +2864,9 @@ func (c *Client4) CreateChannel(channel *Channel) (*Channel, *Response, error) { // UpdateChannel updates a channel based on the provided channel struct. func (c *Client4) UpdateChannel(channel *Channel) (*Channel, *Response, error) { - channelJSON, jsonErr := json.Marshal(channel) - if jsonErr != nil { - return nil, nil, NewAppError("UpdateChannel", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + channelJSON, err := json.Marshal(channel) + if err != nil { + return nil, nil, NewAppError("UpdateChannel", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) } r, err := c.DoAPIPut(c.channelRoute(channel.Id), string(channelJSON)) if err != nil { @@ -2993,8 +2993,8 @@ func (c *Client4) GetChannelStats(channelId string, etag string) (*ChannelStats, } defer closeBody(r) var stats ChannelStats - if jsonErr := json.NewDecoder(r.Body).Decode(&stats); jsonErr != nil { - return nil, nil, NewAppError("GetChannelStats", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&stats); err != nil { + return nil, nil, NewAppError("GetChannelStats", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &stats, BuildResponse(r), nil } @@ -3022,8 +3022,8 @@ func (c *Client4) GetPinnedPosts(channelId string, etag string) (*PostList, *Res return &list, BuildResponse(r), nil } - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetPinnedPosts", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetPinnedPosts", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &list, BuildResponse(r), nil } @@ -3149,9 +3149,9 @@ func (c *Client4) GetChannelsForUserWithLastDeleteAt(userID string, lastDeleteAt // SearchChannels returns the channels on a team matching the provided search term. func (c *Client4) SearchChannels(teamId string, search *ChannelSearch) ([]*Channel, *Response, error) { - searchJSON, jsonErr := json.Marshal(search) - if jsonErr != nil { - return nil, nil, NewAppError("SearchChannels", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + searchJSON, err := json.Marshal(search) + if err != nil { + return nil, nil, NewAppError("SearchChannels", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) } r, err := c.DoAPIPost(c.channelsForTeamRoute(teamId)+"/search", string(searchJSON)) if err != nil { @@ -3169,9 +3169,9 @@ func (c *Client4) SearchChannels(teamId string, search *ChannelSearch) ([]*Chann // SearchArchivedChannels returns the archived channels on a team matching the provided search term. func (c *Client4) SearchArchivedChannels(teamId string, search *ChannelSearch) ([]*Channel, *Response, error) { - searchJSON, jsonErr := json.Marshal(search) - if jsonErr != nil { - return nil, nil, NewAppError("SearchArchivedChannels", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + searchJSON, err := json.Marshal(search) + if err != nil { + return nil, nil, NewAppError("SearchArchivedChannels", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) } r, err := c.DoAPIPost(c.channelsForTeamRoute(teamId)+"/search_archived", string(searchJSON)) if err != nil { @@ -3189,9 +3189,9 @@ func (c *Client4) SearchArchivedChannels(teamId string, search *ChannelSearch) ( // SearchAllChannels search in all the channels. Must be a system administrator. func (c *Client4) SearchAllChannels(search *ChannelSearch) (ChannelListWithTeamData, *Response, error) { - searchJSON, jsonErr := json.Marshal(search) - if jsonErr != nil { - return nil, nil, NewAppError("SearchAllChannels", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + searchJSON, err := json.Marshal(search) + if err != nil { + return nil, nil, NewAppError("SearchAllChannels", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) } r, err := c.DoAPIPost(c.channelsRoute()+"/search", string(searchJSON)) if err != nil { @@ -3212,9 +3212,9 @@ func (c *Client4) SearchAllChannelsForUser(term string) (ChannelListWithTeamData search := &ChannelSearch{ Term: term, } - searchJSON, jsonErr := json.Marshal(search) - if jsonErr != nil { - return nil, nil, NewAppError("SearchAllChannelsForUser", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + searchJSON, err := json.Marshal(search) + if err != nil { + return nil, nil, NewAppError("SearchAllChannelsForUser", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) } r, err := c.DoAPIPost(c.channelsRoute()+"/search?system_console=false", string(searchJSON)) if err != nil { @@ -3232,9 +3232,9 @@ func (c *Client4) SearchAllChannelsForUser(term string) (ChannelListWithTeamData // SearchAllChannelsPaged searches all the channels and returns the results paged with the total count. func (c *Client4) SearchAllChannelsPaged(search *ChannelSearch) (*ChannelsWithCount, *Response, error) { - searchJSON, jsonErr := json.Marshal(search) - if jsonErr != nil { - return nil, nil, NewAppError("SearchAllChannelsPaged", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + searchJSON, err := json.Marshal(search) + if err != nil { + return nil, nil, NewAppError("SearchAllChannelsPaged", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) } r, err := c.DoAPIPost(c.channelsRoute()+"/search", string(searchJSON)) if err != nil { @@ -3252,9 +3252,9 @@ func (c *Client4) SearchAllChannelsPaged(search *ChannelSearch) (*ChannelsWithCo // SearchGroupChannels returns the group channels of the user whose members' usernames match the search term. func (c *Client4) SearchGroupChannels(search *ChannelSearch) ([]*Channel, *Response, error) { - searchJSON, jsonErr := json.Marshal(search) - if jsonErr != nil { - return nil, nil, NewAppError("SearchGroupChannels", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + searchJSON, err := json.Marshal(search) + if err != nil { + return nil, nil, NewAppError("SearchGroupChannels", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) } r, err := c.DoAPIPost(c.channelsRoute()+"/group/search", string(searchJSON)) if err != nil { @@ -3616,8 +3616,8 @@ func (c *Client4) GetTopChannelsForTeamSince(teamId string, timeRange string, pa } defer closeBody(r) var topChannels *TopChannelList - if jsonErr := json.NewDecoder(r.Body).Decode(&topChannels); jsonErr != nil { - return nil, nil, NewAppError("GetTopChannelsForTeamSince", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&topChannels); err != nil { + return nil, nil, NewAppError("GetTopChannelsForTeamSince", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return topChannels, BuildResponse(r), nil } @@ -3636,8 +3636,8 @@ func (c *Client4) GetTopChannelsForUserSince(teamId string, timeRange string, pa } defer closeBody(r) var topChannels *TopChannelList - if jsonErr := json.NewDecoder(r.Body).Decode(&topChannels); jsonErr != nil { - return nil, nil, NewAppError("GetTopChannelsForUserSince", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&topChannels); err != nil { + return nil, nil, NewAppError("GetTopChannelsForUserSince", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return topChannels, BuildResponse(r), nil } @@ -3646,9 +3646,9 @@ func (c *Client4) GetTopChannelsForUserSince(teamId string, timeRange string, pa // CreatePost creates a post based on the provided post struct. func (c *Client4) CreatePost(post *Post) (*Post, *Response, error) { - postJSON, jsonErr := json.Marshal(post) - if jsonErr != nil { - return nil, nil, NewAppError("CreatePost", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + postJSON, err := json.Marshal(post) + if err != nil { + return nil, nil, NewAppError("CreatePost", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) } r, err := c.DoAPIPost(c.postsRoute(), string(postJSON)) if err != nil { @@ -3659,17 +3659,17 @@ func (c *Client4) CreatePost(post *Post) (*Post, *Response, error) { if r.StatusCode == http.StatusNotModified { return &p, BuildResponse(r), nil } - if jsonErr := json.NewDecoder(r.Body).Decode(&p); jsonErr != nil { - return nil, nil, NewAppError("CreatePost", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&p); err != nil { + return nil, nil, NewAppError("CreatePost", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &p, BuildResponse(r), nil } // CreatePostEphemeral creates a ephemeral post based on the provided post struct which is send to the given user id. func (c *Client4) CreatePostEphemeral(post *PostEphemeral) (*Post, *Response, error) { - postJSON, jsonErr := json.Marshal(post) - if jsonErr != nil { - return nil, nil, NewAppError("CreatePostEphemeral", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + postJSON, err := json.Marshal(post) + if err != nil { + return nil, nil, NewAppError("CreatePostEphemeral", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) } r, err := c.DoAPIPost(c.postsEphemeralRoute(), string(postJSON)) if err != nil { @@ -3680,17 +3680,17 @@ func (c *Client4) CreatePostEphemeral(post *PostEphemeral) (*Post, *Response, er if r.StatusCode == http.StatusNotModified { return &p, BuildResponse(r), nil } - if jsonErr := json.NewDecoder(r.Body).Decode(&p); jsonErr != nil { - return nil, nil, NewAppError("CreatePostEphemeral", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&p); err != nil { + return nil, nil, NewAppError("CreatePostEphemeral", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &p, BuildResponse(r), nil } // UpdatePost updates a post based on the provided post struct. func (c *Client4) UpdatePost(postId string, post *Post) (*Post, *Response, error) { - postJSON, jsonErr := json.Marshal(post) - if jsonErr != nil { - return nil, nil, NewAppError("UpdatePost", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + postJSON, err := json.Marshal(post) + if err != nil { + return nil, nil, NewAppError("UpdatePost", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) } r, err := c.DoAPIPut(c.postRoute(postId), string(postJSON)) if err != nil { @@ -3701,8 +3701,8 @@ func (c *Client4) UpdatePost(postId string, post *Post) (*Post, *Response, error if r.StatusCode == http.StatusNotModified { return &p, BuildResponse(r), nil } - if jsonErr := json.NewDecoder(r.Body).Decode(&p); jsonErr != nil { - return nil, nil, NewAppError("UpdatePost", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&p); err != nil { + return nil, nil, NewAppError("UpdatePost", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &p, BuildResponse(r), nil } @@ -3722,8 +3722,8 @@ func (c *Client4) PatchPost(postId string, patch *PostPatch) (*Post, *Response, if r.StatusCode == http.StatusNotModified { return &p, BuildResponse(r), nil } - if jsonErr := json.NewDecoder(r.Body).Decode(&p); jsonErr != nil { - return nil, nil, NewAppError("PatchPost", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&p); err != nil { + return nil, nil, NewAppError("PatchPost", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &p, BuildResponse(r), nil } @@ -3791,8 +3791,8 @@ func (c *Client4) GetPost(postId string, etag string) (*Post, *Response, error) if r.StatusCode == http.StatusNotModified { return &post, BuildResponse(r), nil } - if jsonErr := json.NewDecoder(r.Body).Decode(&post); jsonErr != nil { - return nil, nil, NewAppError("GetPost", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&post); err != nil { + return nil, nil, NewAppError("GetPost", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &post, BuildResponse(r), nil } @@ -3809,8 +3809,8 @@ func (c *Client4) GetPostIncludeDeleted(postId string, etag string) (*Post, *Res if r.StatusCode == http.StatusNotModified { return &post, BuildResponse(r), nil } - if jsonErr := json.NewDecoder(r.Body).Decode(&post); jsonErr != nil { - return nil, nil, NewAppError("GetPostIncludeDeleted", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&post); err != nil { + return nil, nil, NewAppError("GetPostIncludeDeleted", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &post, BuildResponse(r), nil } @@ -3840,8 +3840,8 @@ func (c *Client4) GetPostThread(postId string, etag string, collapsedThreads boo if r.StatusCode == http.StatusNotModified { return &list, BuildResponse(r), nil } - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetPostThread", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetPostThread", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &list, BuildResponse(r), nil } @@ -3883,8 +3883,8 @@ func (c *Client4) GetPostThreadWithOpts(postID string, etag string, opts GetPost if r.StatusCode == http.StatusNotModified { return &list, BuildResponse(r), nil } - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetPostThread", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetPostThread", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &list, BuildResponse(r), nil } @@ -3904,17 +3904,17 @@ func (c *Client4) GetPostsForChannel(channelId string, page, perPage int, etag s if r.StatusCode == http.StatusNotModified { return &list, BuildResponse(r), nil } - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetPostsForChannel", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetPostsForChannel", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &list, BuildResponse(r), nil } // GetPostsByIds gets a list of posts by taking an array of post ids func (c *Client4) GetPostsByIds(postIds []string) ([]*Post, *Response, error) { - js, jsonErr := json.Marshal(postIds) - if jsonErr != nil { - return nil, nil, NewAppError("SearchFilesWithParams", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(postIds) + if err != nil { + return nil, nil, NewAppError("SearchFilesWithParams", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) } r, err := c.DoAPIPost(c.postsRoute()+"/ids", string(js)) if err != nil { @@ -3925,8 +3925,8 @@ func (c *Client4) GetPostsByIds(postIds []string) ([]*Post, *Response, error) { if r.StatusCode == http.StatusNotModified { return list, BuildResponse(r), nil } - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetPostsByIds", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetPostsByIds", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return list, BuildResponse(r), nil } @@ -3943,8 +3943,8 @@ func (c *Client4) GetFlaggedPostsForUser(userId string, page int, perPage int) ( if r.StatusCode == http.StatusNotModified { return &list, BuildResponse(r), nil } - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetFlaggedPostsForUser", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetFlaggedPostsForUser", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &list, BuildResponse(r), nil } @@ -3965,8 +3965,8 @@ func (c *Client4) GetFlaggedPostsForUserInTeam(userId string, teamId string, pag if r.StatusCode == http.StatusNotModified { return &list, BuildResponse(r), nil } - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetFlaggedPostsForUserInTeam", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetFlaggedPostsForUserInTeam", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &list, BuildResponse(r), nil } @@ -3987,8 +3987,8 @@ func (c *Client4) GetFlaggedPostsForUserInChannel(userId string, channelId strin if r.StatusCode == http.StatusNotModified { return &list, BuildResponse(r), nil } - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetFlaggedPostsForUserInChannel", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetFlaggedPostsForUserInChannel", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &list, BuildResponse(r), nil } @@ -4008,8 +4008,8 @@ func (c *Client4) GetPostsSince(channelId string, time int64, collapsedThreads b if r.StatusCode == http.StatusNotModified { return &list, BuildResponse(r), nil } - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetPostsSince", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetPostsSince", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &list, BuildResponse(r), nil } @@ -4029,8 +4029,8 @@ func (c *Client4) GetPostsAfter(channelId, postId string, page, perPage int, eta if r.StatusCode == http.StatusNotModified { return &list, BuildResponse(r), nil } - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetPostsAfter", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetPostsAfter", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &list, BuildResponse(r), nil } @@ -4050,8 +4050,8 @@ func (c *Client4) GetPostsBefore(channelId, postId string, page, perPage int, et if r.StatusCode == http.StatusNotModified { return &list, BuildResponse(r), nil } - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetPostsBefore", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetPostsBefore", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &list, BuildResponse(r), nil } @@ -4071,8 +4071,8 @@ func (c *Client4) GetPostsAroundLastUnread(userId, channelId string, limitBefore if r.StatusCode == http.StatusNotModified { return &list, BuildResponse(r), nil } - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetPostsAroundLastUnread", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetPostsAroundLastUnread", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &list, BuildResponse(r), nil } @@ -4088,9 +4088,9 @@ func (c *Client4) SearchFiles(teamId string, terms string, isOrSearch bool) (*Fi // SearchFilesWithParams returns any posts with matching terms string. func (c *Client4) SearchFilesWithParams(teamId string, params *SearchParameter) (*FileInfoList, *Response, error) { - js, jsonErr := json.Marshal(params) - if jsonErr != nil { - return nil, nil, NewAppError("SearchFilesWithParams", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(params) + if err != nil { + return nil, nil, NewAppError("SearchFilesWithParams", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) } r, err := c.DoAPIPost(c.teamRoute(teamId)+"/files/search", string(js)) if err != nil { @@ -4099,8 +4099,8 @@ func (c *Client4) SearchFilesWithParams(teamId string, params *SearchParameter) defer closeBody(r) var list FileInfoList - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("SearchFilesWithParams", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("SearchFilesWithParams", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &list, BuildResponse(r), nil } @@ -4116,9 +4116,9 @@ func (c *Client4) SearchPosts(teamId string, terms string, isOrSearch bool) (*Po // SearchPostsWithParams returns any posts with matching terms string. func (c *Client4) SearchPostsWithParams(teamId string, params *SearchParameter) (*PostList, *Response, error) { - js, jsonErr := json.Marshal(params) - if jsonErr != nil { - return nil, nil, NewAppError("SearchFilesWithParams", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + js, err := json.Marshal(params) + if err != nil { + return nil, nil, NewAppError("SearchFilesWithParams", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) } var route string if teamId == "" { @@ -4135,8 +4135,8 @@ func (c *Client4) SearchPostsWithParams(teamId string, params *SearchParameter) if r.StatusCode == http.StatusNotModified { return &list, BuildResponse(r), nil } - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("SearchFilesWithParams", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("SearchFilesWithParams", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &list, BuildResponse(r), nil } @@ -4156,8 +4156,8 @@ func (c *Client4) SearchPostsWithMatches(teamId string, terms string, isOrSearch } defer closeBody(r) var psr PostSearchResults - if jsonErr := json.NewDecoder(r.Body).Decode(&psr); jsonErr != nil { - return nil, nil, NewAppError("SearchPostsWithMatches", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&psr); err != nil { + return nil, nil, NewAppError("SearchPostsWithMatches", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &psr, BuildResponse(r), nil } @@ -4176,13 +4176,13 @@ func (c *Client4) DoPostAction(postId, actionId string) (*Response, error) { func (c *Client4) DoPostActionWithCookie(postId, actionId, selected, cookieStr string) (*Response, error) { var body []byte if selected != "" || cookieStr != "" { - var jsonErr error - body, jsonErr = json.Marshal(DoPostActionRequest{ + var err error + body, err = json.Marshal(DoPostActionRequest{ SelectedOption: selected, Cookie: cookieStr, }) - if jsonErr != nil { - return nil, NewAppError("DoPostActionWithCookie", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err != nil { + return nil, NewAppError("DoPostActionWithCookie", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) } } r, err := c.DoAPIPost(c.postRoute(postId)+"/actions/"+actionId, string(body)) @@ -4202,8 +4202,8 @@ func (c *Client4) GetTopThreadsForTeamSince(teamId string, timeRange string, pag } defer closeBody(r) var topThreads *TopThreadList - if jsonErr := json.NewDecoder(r.Body).Decode(&topThreads); jsonErr != nil { - return nil, nil, NewAppError("GetTopThreadsForTeamSince", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&topThreads); err != nil { + return nil, nil, NewAppError("GetTopThreadsForTeamSince", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return topThreads, BuildResponse(r), nil } @@ -4222,8 +4222,8 @@ func (c *Client4) GetTopThreadsForUserSince(teamId string, timeRange string, pag } defer closeBody(r) var topThreads *TopThreadList - if jsonErr := json.NewDecoder(r.Body).Decode(&topThreads); jsonErr != nil { - return nil, nil, NewAppError("GetTopThreadsForUserSince", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&topThreads); err != nil { + return nil, nil, NewAppError("GetTopThreadsForUserSince", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return topThreads, BuildResponse(r), nil } @@ -4233,9 +4233,9 @@ func (c *Client4) GetTopThreadsForUserSince(teamId string, timeRange string, pag // provided data. Used with interactive message buttons, menus and // slash commands. func (c *Client4) OpenInteractiveDialog(request OpenDialogRequest) (*Response, error) { - b, jsonErr := json.Marshal(request) - if jsonErr != nil { - return nil, NewAppError("OpenInteractiveDialog", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + b, err := json.Marshal(request) + if err != nil { + return nil, NewAppError("OpenInteractiveDialog", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) } r, err := c.DoAPIPost("/actions/dialogs/open", string(b)) if err != nil { @@ -4248,9 +4248,9 @@ func (c *Client4) OpenInteractiveDialog(request OpenDialogRequest) (*Response, e // SubmitInteractiveDialog will submit the provided dialog data to the integration // configured by the URL. Used with the interactive dialogs integration feature. func (c *Client4) SubmitInteractiveDialog(request SubmitDialogRequest) (*SubmitDialogResponse, *Response, error) { - b, jsonErr := json.Marshal(request) - if jsonErr != nil { - return nil, nil, NewAppError("SubmitInteractiveDialog", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + b, err := json.Marshal(request) + if err != nil { + return nil, nil, NewAppError("SubmitInteractiveDialog", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) } r, err := c.DoAPIPost("/actions/dialogs/submit", string(b)) if err != nil { @@ -4411,8 +4411,8 @@ func (c *Client4) GetFileInfo(fileId string) (*FileInfo, *Response, error) { defer closeBody(r) var fi FileInfo - if jsonErr := json.NewDecoder(r.Body).Decode(&fi); jsonErr != nil { - return nil, nil, NewAppError("GetFileInfo", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&fi); err != nil { + return nil, nil, NewAppError("GetFileInfo", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &fi, BuildResponse(r), nil } @@ -4429,8 +4429,8 @@ func (c *Client4) GetFileInfosForPost(postId string, etag string) ([]*FileInfo, if r.StatusCode == http.StatusNotModified { return list, BuildResponse(r), nil } - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetFileInfosForPost", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetFileInfosForPost", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return list, BuildResponse(r), nil } @@ -4447,8 +4447,8 @@ func (c *Client4) GetFileInfosForPostIncludeDeleted(postId string, etag string) if r.StatusCode == http.StatusNotModified { return list, BuildResponse(r), nil } - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetFileInfosForPostIncludeDeleted", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetFileInfosForPostIncludeDeleted", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return list, BuildResponse(r), nil } @@ -4561,7 +4561,10 @@ func (c *Client4) GetConfig() (*Config, *Response, error) { return nil, BuildResponse(r), err } defer closeBody(r) - return ConfigFromJSON(r.Body), BuildResponse(r), nil + + var cfg *Config + d := json.NewDecoder(r.Body) + return cfg, BuildResponse(r), d.Decode(&cfg) } // ReloadConfig will reload the server configuration. @@ -4639,7 +4642,10 @@ func (c *Client4) UpdateConfig(config *Config) (*Config, *Response, error) { return nil, BuildResponse(r), err } defer closeBody(r) - return ConfigFromJSON(r.Body), BuildResponse(r), nil + + var cfg *Config + d := json.NewDecoder(r.Body) + return cfg, BuildResponse(r), d.Decode(&cfg) } // MigrateConfig will migrate existing config to the new one. @@ -4745,8 +4751,8 @@ func (c *Client4) CreateIncomingWebhook(hook *IncomingWebhook) (*IncomingWebhook defer closeBody(r) var iw IncomingWebhook - if jsonErr := json.NewDecoder(r.Body).Decode(&iw); jsonErr != nil { - return nil, nil, NewAppError("CreateIncomingWebhook", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&iw); err != nil { + return nil, nil, NewAppError("CreateIncomingWebhook", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &iw, BuildResponse(r), nil } @@ -4764,8 +4770,8 @@ func (c *Client4) UpdateIncomingWebhook(hook *IncomingWebhook) (*IncomingWebhook defer closeBody(r) var iw IncomingWebhook - if jsonErr := json.NewDecoder(r.Body).Decode(&iw); jsonErr != nil { - return nil, nil, NewAppError("UpdateIncomingWebhook", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&iw); err != nil { + return nil, nil, NewAppError("UpdateIncomingWebhook", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &iw, BuildResponse(r), nil } @@ -4782,8 +4788,8 @@ func (c *Client4) GetIncomingWebhooks(page int, perPage int, etag string) ([]*In if r.StatusCode == http.StatusNotModified { return iwl, BuildResponse(r), nil } - if jsonErr := json.NewDecoder(r.Body).Decode(&iwl); jsonErr != nil { - return nil, nil, NewAppError("GetIncomingWebhooks", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&iwl); err != nil { + return nil, nil, NewAppError("GetIncomingWebhooks", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return iwl, BuildResponse(r), nil } @@ -4800,8 +4806,8 @@ func (c *Client4) GetIncomingWebhooksForTeam(teamId string, page int, perPage in if r.StatusCode == http.StatusNotModified { return iwl, BuildResponse(r), nil } - if jsonErr := json.NewDecoder(r.Body).Decode(&iwl); jsonErr != nil { - return nil, nil, NewAppError("GetIncomingWebhooksForTeam", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&iwl); err != nil { + return nil, nil, NewAppError("GetIncomingWebhooksForTeam", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return iwl, BuildResponse(r), nil } @@ -4817,8 +4823,8 @@ func (c *Client4) GetIncomingWebhook(hookID string, etag string) (*IncomingWebho if r.StatusCode == http.StatusNotModified { return &iw, BuildResponse(r), nil } - if jsonErr := json.NewDecoder(r.Body).Decode(&iw); jsonErr != nil { - return nil, nil, NewAppError("GetIncomingWebhook", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&iw); err != nil { + return nil, nil, NewAppError("GetIncomingWebhook", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &iw, BuildResponse(r), nil } @@ -4845,8 +4851,8 @@ func (c *Client4) CreateOutgoingWebhook(hook *OutgoingWebhook) (*OutgoingWebhook } defer closeBody(r) var ow OutgoingWebhook - if jsonErr := json.NewDecoder(r.Body).Decode(&ow); jsonErr != nil { - return nil, nil, NewAppError("CreateOutgoingWebhook", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&ow); err != nil { + return nil, nil, NewAppError("CreateOutgoingWebhook", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &ow, BuildResponse(r), nil } @@ -4863,8 +4869,8 @@ func (c *Client4) UpdateOutgoingWebhook(hook *OutgoingWebhook) (*OutgoingWebhook } defer closeBody(r) var ow OutgoingWebhook - if jsonErr := json.NewDecoder(r.Body).Decode(&ow); jsonErr != nil { - return nil, nil, NewAppError("UpdateOutgoingWebhook", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&ow); err != nil { + return nil, nil, NewAppError("UpdateOutgoingWebhook", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &ow, BuildResponse(r), nil } @@ -4881,8 +4887,8 @@ func (c *Client4) GetOutgoingWebhooks(page int, perPage int, etag string) ([]*Ou if r.StatusCode == http.StatusNotModified { return owl, BuildResponse(r), nil } - if jsonErr := json.NewDecoder(r.Body).Decode(&owl); jsonErr != nil { - return nil, nil, NewAppError("GetOutgoingWebhooks", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&owl); err != nil { + return nil, nil, NewAppError("GetOutgoingWebhooks", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return owl, BuildResponse(r), nil } @@ -4895,8 +4901,8 @@ func (c *Client4) GetOutgoingWebhook(hookId string) (*OutgoingWebhook, *Response } defer closeBody(r) var ow OutgoingWebhook - if jsonErr := json.NewDecoder(r.Body).Decode(&ow); jsonErr != nil { - return nil, nil, NewAppError("GetOutgoingWebhook", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&ow); err != nil { + return nil, nil, NewAppError("GetOutgoingWebhook", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &ow, BuildResponse(r), nil } @@ -4913,8 +4919,8 @@ func (c *Client4) GetOutgoingWebhooksForChannel(channelId string, page int, perP if r.StatusCode == http.StatusNotModified { return owl, BuildResponse(r), nil } - if jsonErr := json.NewDecoder(r.Body).Decode(&owl); jsonErr != nil { - return nil, nil, NewAppError("GetOutgoingWebhooksForChannel", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&owl); err != nil { + return nil, nil, NewAppError("GetOutgoingWebhooksForChannel", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return owl, BuildResponse(r), nil } @@ -4931,8 +4937,8 @@ func (c *Client4) GetOutgoingWebhooksForTeam(teamId string, page int, perPage in if r.StatusCode == http.StatusNotModified { return owl, BuildResponse(r), nil } - if jsonErr := json.NewDecoder(r.Body).Decode(&owl); jsonErr != nil { - return nil, nil, NewAppError("GetOutgoingWebhooksForTeam", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&owl); err != nil { + return nil, nil, NewAppError("GetOutgoingWebhooksForTeam", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return owl, BuildResponse(r), nil } @@ -4945,8 +4951,8 @@ func (c *Client4) RegenOutgoingHookToken(hookId string) (*OutgoingWebhook, *Resp } defer closeBody(r) var ow OutgoingWebhook - if jsonErr := json.NewDecoder(r.Body).Decode(&ow); jsonErr != nil { - return nil, nil, NewAppError("RegenOutgoingHookToken", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&ow); err != nil { + return nil, nil, NewAppError("RegenOutgoingHookToken", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &ow, BuildResponse(r), nil } @@ -4972,8 +4978,8 @@ func (c *Client4) GetPreferences(userId string) (Preferences, *Response, error) defer closeBody(r) var prefs Preferences - if jsonErr := json.NewDecoder(r.Body).Decode(&prefs); jsonErr != nil { - return nil, nil, NewAppError("GetPreferences", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&prefs); err != nil { + return nil, nil, NewAppError("GetPreferences", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return prefs, BuildResponse(r), nil } @@ -5015,8 +5021,8 @@ func (c *Client4) GetPreferencesByCategory(userId string, category string) (Pref } defer closeBody(r) var prefs Preferences - if jsonErr := json.NewDecoder(r.Body).Decode(&prefs); jsonErr != nil { - return nil, nil, NewAppError("GetPreferencesByCategory", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&prefs); err != nil { + return nil, nil, NewAppError("GetPreferencesByCategory", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return prefs, BuildResponse(r), nil } @@ -5031,8 +5037,8 @@ func (c *Client4) GetPreferenceByCategoryAndName(userId string, category string, defer closeBody(r) var pref Preference - if jsonErr := json.NewDecoder(r.Body).Decode(&pref); jsonErr != nil { - return nil, nil, NewAppError("GetPreferenceByCategoryAndName", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&pref); err != nil { + return nil, nil, NewAppError("GetPreferenceByCategoryAndName", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &pref, BuildResponse(r), nil } @@ -5151,8 +5157,8 @@ func (c *Client4) GetSamlCertificateStatus() (*SamlCertificateStatus, *Response, defer closeBody(r) var status SamlCertificateStatus - if jsonErr := json.NewDecoder(r.Body).Decode(&status); jsonErr != nil { - return nil, nil, NewAppError("GetSamlCertificateStatus", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&status); err != nil { + return nil, nil, NewAppError("GetSamlCertificateStatus", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &status, BuildResponse(r), nil } @@ -5167,8 +5173,8 @@ func (c *Client4) GetSamlMetadataFromIdp(samlMetadataURL string) (*SamlMetadataR defer closeBody(r) var resp SamlMetadataResponse - if jsonErr := json.NewDecoder(r.Body).Decode(&resp); jsonErr != nil { - return nil, nil, NewAppError("GetSamlMetadataFromIdp", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&resp); err != nil { + return nil, nil, NewAppError("GetSamlMetadataFromIdp", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &resp, BuildResponse(r), nil } @@ -5180,9 +5186,9 @@ func (c *Client4) ResetSamlAuthDataToEmail(includeDeleted bool, dryRun bool, use "dry_run": dryRun, "user_ids": userIDs, } - b, jsonErr := json.Marshal(params) - if jsonErr != nil { - return 0, nil, NewAppError("ResetSamlAuthDataToEmail", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + b, err := json.Marshal(params) + if err != nil { + return 0, nil, NewAppError("ResetSamlAuthDataToEmail", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) } r, err := c.DoAPIPostBytes(c.samlRoute()+"/reset_auth_data", b) if err != nil { @@ -5211,8 +5217,8 @@ func (c *Client4) CreateComplianceReport(report *Compliance) (*Compliance, *Resp } defer closeBody(r) var comp Compliance - if jsonErr := json.NewDecoder(r.Body).Decode(&comp); jsonErr != nil { - return nil, nil, NewAppError("CreateComplianceReport", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&comp); err != nil { + return nil, nil, NewAppError("CreateComplianceReport", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &comp, BuildResponse(r), nil } @@ -5226,8 +5232,8 @@ func (c *Client4) GetComplianceReports(page, perPage int) (Compliances, *Respons } defer closeBody(r) var comp Compliances - if jsonErr := json.NewDecoder(r.Body).Decode(&comp); jsonErr != nil { - return nil, nil, NewAppError("GetComplianceReports", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&comp); err != nil { + return nil, nil, NewAppError("GetComplianceReports", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return comp, BuildResponse(r), nil } @@ -5240,8 +5246,8 @@ func (c *Client4) GetComplianceReport(reportId string) (*Compliance, *Response, } defer closeBody(r) var comp Compliance - if jsonErr := json.NewDecoder(r.Body).Decode(&comp); jsonErr != nil { - return nil, nil, NewAppError("GetComplianceReport", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&comp); err != nil { + return nil, nil, NewAppError("GetComplianceReport", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &comp, BuildResponse(r), nil } @@ -5285,8 +5291,8 @@ func (c *Client4) GetClusterStatus() ([]*ClusterInfo, *Response, error) { } defer closeBody(r) var list []*ClusterInfo - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetClusterStatus", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetClusterStatus", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return list, BuildResponse(r), nil } @@ -5297,11 +5303,11 @@ func (c *Client4) GetClusterStatus() ([]*ClusterInfo, *Response, error) { // If includeRemovedMembers is true, then group members who left or were removed from a // synced team/channel will be re-joined; otherwise, they will be excluded. func (c *Client4) SyncLdap(includeRemovedMembers bool) (*Response, error) { - reqBody, jsonErr := json.Marshal(map[string]any{ + reqBody, err := json.Marshal(map[string]any{ "include_removed_members": includeRemovedMembers, }) - if jsonErr != nil { - return nil, NewAppError("SyncLdap", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err != nil { + return nil, NewAppError("SyncLdap", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) } r, err := c.DoAPIPostBytes(c.ldapRoute()+"/sync", reqBody) if err != nil { @@ -5357,8 +5363,8 @@ func (c *Client4) LinkLdapGroup(dn string) (*Group, *Response, error) { defer closeBody(r) var g Group - if jsonErr := json.NewDecoder(r.Body).Decode(&g); jsonErr != nil { - return nil, nil, NewAppError("LinkLdapGroup", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&g); err != nil { + return nil, nil, NewAppError("LinkLdapGroup", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &g, BuildResponse(r), nil } @@ -5374,8 +5380,8 @@ func (c *Client4) UnlinkLdapGroup(dn string) (*Group, *Response, error) { defer closeBody(r) var g Group - if jsonErr := json.NewDecoder(r.Body).Decode(&g); jsonErr != nil { - return nil, nil, NewAppError("UnlinkLdapGroup", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&g); err != nil { + return nil, nil, NewAppError("UnlinkLdapGroup", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &g, BuildResponse(r), nil } @@ -5486,8 +5492,8 @@ func (c *Client4) GetGroups(opts GroupSearchOpts) ([]*Group, *Response, error) { defer closeBody(r) var list []*Group - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetGroups", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetGroups", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return list, BuildResponse(r), nil } @@ -5506,8 +5512,8 @@ func (c *Client4) GetGroupsByUserId(userId string) ([]*Group, *Response, error) } defer closeBody(r) var list []*Group - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetGroupsByUserId", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetGroupsByUserId", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return list, BuildResponse(r), nil } @@ -5711,8 +5717,8 @@ func (c *Client4) CreateOAuthApp(app *OAuthApp) (*OAuthApp, *Response, error) { defer closeBody(r) var oapp OAuthApp - if jsonErr := json.NewDecoder(r.Body).Decode(&oapp); jsonErr != nil { - return nil, nil, NewAppError("CreateOAuthApp", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&oapp); err != nil { + return nil, nil, NewAppError("CreateOAuthApp", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &oapp, BuildResponse(r), nil } @@ -5729,8 +5735,8 @@ func (c *Client4) UpdateOAuthApp(app *OAuthApp) (*OAuthApp, *Response, error) { } defer closeBody(r) var oapp OAuthApp - if jsonErr := json.NewDecoder(r.Body).Decode(&oapp); jsonErr != nil { - return nil, nil, NewAppError("UpdateOAuthApp", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&oapp); err != nil { + return nil, nil, NewAppError("UpdateOAuthApp", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &oapp, BuildResponse(r), nil } @@ -5744,8 +5750,8 @@ func (c *Client4) GetOAuthApps(page, perPage int) ([]*OAuthApp, *Response, error } defer closeBody(r) var list []*OAuthApp - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetOAuthApps", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetOAuthApps", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return list, BuildResponse(r), nil } @@ -5758,8 +5764,8 @@ func (c *Client4) GetOAuthApp(appId string) (*OAuthApp, *Response, error) { } defer closeBody(r) var oapp OAuthApp - if jsonErr := json.NewDecoder(r.Body).Decode(&oapp); jsonErr != nil { - return nil, nil, NewAppError("GetOAuthApp", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&oapp); err != nil { + return nil, nil, NewAppError("GetOAuthApp", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &oapp, BuildResponse(r), nil } @@ -5772,8 +5778,8 @@ func (c *Client4) GetOAuthAppInfo(appId string) (*OAuthApp, *Response, error) { } defer closeBody(r) var oapp OAuthApp - if jsonErr := json.NewDecoder(r.Body).Decode(&oapp); jsonErr != nil { - return nil, nil, NewAppError("GetOAuthAppInfo", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&oapp); err != nil { + return nil, nil, NewAppError("GetOAuthAppInfo", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &oapp, BuildResponse(r), nil } @@ -5796,8 +5802,8 @@ func (c *Client4) RegenerateOAuthAppSecret(appId string) (*OAuthApp, *Response, } defer closeBody(r) var oapp OAuthApp - if jsonErr := json.NewDecoder(r.Body).Decode(&oapp); jsonErr != nil { - return nil, nil, NewAppError("RegenerateOAuthAppSecret", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&oapp); err != nil { + return nil, nil, NewAppError("RegenerateOAuthAppSecret", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &oapp, BuildResponse(r), nil } @@ -5811,8 +5817,8 @@ func (c *Client4) GetAuthorizedOAuthAppsForUser(userId string, page, perPage int } defer closeBody(r) var list []*OAuthApp - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetAuthorizedOAuthAppsForUser", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetAuthorizedOAuthAppsForUser", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return list, BuildResponse(r), nil } @@ -5919,8 +5925,8 @@ func (c *Client4) GetDataRetentionPolicy() (*GlobalRetentionPolicy, *Response, e } defer closeBody(r) var p GlobalRetentionPolicy - if jsonErr := json.NewDecoder(r.Body).Decode(&p); jsonErr != nil { - return nil, nil, NewAppError("GetDataRetentionPolicy", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&p); err != nil { + return nil, nil, NewAppError("GetDataRetentionPolicy", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &p, BuildResponse(r), nil } @@ -5934,8 +5940,8 @@ func (c *Client4) GetDataRetentionPolicyByID(policyID string) (*RetentionPolicyW defer closeBody(r) var p RetentionPolicyWithTeamAndChannelCounts - if jsonErr := json.NewDecoder(r.Body).Decode(&p); jsonErr != nil { - return nil, nil, NewAppError("GetDataRetentionPolicyByID", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&p); err != nil { + return nil, nil, NewAppError("GetDataRetentionPolicyByID", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &p, BuildResponse(r), nil } @@ -5967,8 +5973,8 @@ func (c *Client4) GetDataRetentionPolicies(page, perPage int) (*RetentionPolicyW defer closeBody(r) var p RetentionPolicyWithTeamAndChannelCountsList - if jsonErr := json.NewDecoder(r.Body).Decode(&p); jsonErr != nil { - return nil, nil, NewAppError("GetDataRetentionPolicies", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&p); err != nil { + return nil, nil, NewAppError("GetDataRetentionPolicies", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &p, BuildResponse(r), nil } @@ -5976,9 +5982,9 @@ func (c *Client4) GetDataRetentionPolicies(page, perPage int) (*RetentionPolicyW // CreateDataRetentionPolicy will create a new granular data retention policy which will be applied to // the specified teams and channels. The Id field of `policy` must be empty. func (c *Client4) CreateDataRetentionPolicy(policy *RetentionPolicyWithTeamAndChannelIDs) (*RetentionPolicyWithTeamAndChannelCounts, *Response, error) { - policyJSON, jsonErr := json.Marshal(policy) - if jsonErr != nil { - return nil, nil, NewAppError("CreateDataRetentionPolicy", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + policyJSON, err := json.Marshal(policy) + if err != nil { + return nil, nil, NewAppError("CreateDataRetentionPolicy", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) } r, err := c.DoAPIPostBytes(c.dataRetentionRoute()+"/policies", policyJSON) if err != nil { @@ -5986,8 +5992,8 @@ func (c *Client4) CreateDataRetentionPolicy(policy *RetentionPolicyWithTeamAndCh } defer closeBody(r) var p RetentionPolicyWithTeamAndChannelCounts - if jsonErr := json.NewDecoder(r.Body).Decode(&p); jsonErr != nil { - return nil, nil, NewAppError("CreateDataRetentionPolicy", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&p); err != nil { + return nil, nil, NewAppError("CreateDataRetentionPolicy", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &p, BuildResponse(r), nil } @@ -6005,9 +6011,9 @@ func (c *Client4) DeleteDataRetentionPolicy(policyID string) (*Response, error) // PatchDataRetentionPolicy will patch the granular data retention policy with the specified ID. // The Id field of `patch` must be non-empty. func (c *Client4) PatchDataRetentionPolicy(patch *RetentionPolicyWithTeamAndChannelIDs) (*RetentionPolicyWithTeamAndChannelCounts, *Response, error) { - patchJSON, jsonErr := json.Marshal(patch) - if jsonErr != nil { - return nil, nil, NewAppError("PatchDataRetentionPolicy", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + patchJSON, err := json.Marshal(patch) + if err != nil { + return nil, nil, NewAppError("PatchDataRetentionPolicy", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) } r, err := c.DoAPIPatchBytes(c.dataRetentionPolicyRoute(patch.ID), patchJSON) if err != nil { @@ -6015,8 +6021,8 @@ func (c *Client4) PatchDataRetentionPolicy(patch *RetentionPolicyWithTeamAndChan } defer closeBody(r) var p RetentionPolicyWithTeamAndChannelCounts - if jsonErr := json.NewDecoder(r.Body).Decode(&p); jsonErr != nil { - return nil, nil, NewAppError("PatchDataRetentionPolicy", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&p); err != nil { + return nil, nil, NewAppError("PatchDataRetentionPolicy", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &p, BuildResponse(r), nil } @@ -6038,9 +6044,9 @@ func (c *Client4) GetTeamsForRetentionPolicy(policyID string, page, perPage int) // SearchTeamsForRetentionPolicy will search the teams to which the specified policy is currently applied. func (c *Client4) SearchTeamsForRetentionPolicy(policyID string, term string) ([]*Team, *Response, error) { - body, jsonErr := json.Marshal(map[string]any{"term": term}) - if jsonErr != nil { - return nil, nil, NewAppError("SearchTeamsForRetentionPolicy", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + body, err := json.Marshal(map[string]any{"term": term}) + if err != nil { + return nil, nil, NewAppError("SearchTeamsForRetentionPolicy", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) } r, err := c.DoAPIPostBytes(c.dataRetentionPolicyRoute(policyID)+"/teams/search", body) if err != nil { @@ -6057,9 +6063,9 @@ func (c *Client4) SearchTeamsForRetentionPolicy(policyID string, term string) ([ // AddTeamsToRetentionPolicy will add the specified teams to the granular data retention policy // with the specified ID. func (c *Client4) AddTeamsToRetentionPolicy(policyID string, teamIDs []string) (*Response, error) { - body, jsonErr := json.Marshal(teamIDs) - if jsonErr != nil { - return nil, NewAppError("AddTeamsToRetentionPolicy", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + body, err := json.Marshal(teamIDs) + if err != nil { + return nil, NewAppError("AddTeamsToRetentionPolicy", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) } r, err := c.DoAPIPostBytes(c.dataRetentionPolicyRoute(policyID)+"/teams", body) if err != nil { @@ -6072,9 +6078,9 @@ func (c *Client4) AddTeamsToRetentionPolicy(policyID string, teamIDs []string) ( // RemoveTeamsFromRetentionPolicy will remove the specified teams from the granular data retention policy // with the specified ID. func (c *Client4) RemoveTeamsFromRetentionPolicy(policyID string, teamIDs []string) (*Response, error) { - body, jsonErr := json.Marshal(teamIDs) - if jsonErr != nil { - return nil, NewAppError("RemoveTeamsFromRetentionPolicy", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + body, err := json.Marshal(teamIDs) + if err != nil { + return nil, NewAppError("RemoveTeamsFromRetentionPolicy", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) } r, err := c.DoAPIDeleteBytes(c.dataRetentionPolicyRoute(policyID)+"/teams", body) if err != nil { @@ -6101,9 +6107,9 @@ func (c *Client4) GetChannelsForRetentionPolicy(policyID string, page, perPage i // SearchChannelsForRetentionPolicy will search the channels to which the specified policy is currently applied. func (c *Client4) SearchChannelsForRetentionPolicy(policyID string, term string) (ChannelListWithTeamData, *Response, error) { - body, jsonErr := json.Marshal(map[string]any{"term": term}) - if jsonErr != nil { - return nil, nil, NewAppError("SearchChannelsForRetentionPolicy", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + body, err := json.Marshal(map[string]any{"term": term}) + if err != nil { + return nil, nil, NewAppError("SearchChannelsForRetentionPolicy", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) } r, err := c.DoAPIPostBytes(c.dataRetentionPolicyRoute(policyID)+"/channels/search", body) if err != nil { @@ -6120,9 +6126,9 @@ func (c *Client4) SearchChannelsForRetentionPolicy(policyID string, term string) // AddChannelsToRetentionPolicy will add the specified channels to the granular data retention policy // with the specified ID. func (c *Client4) AddChannelsToRetentionPolicy(policyID string, channelIDs []string) (*Response, error) { - body, jsonErr := json.Marshal(channelIDs) - if jsonErr != nil { - return nil, NewAppError("AddChannelsToRetentionPolicy", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + body, err := json.Marshal(channelIDs) + if err != nil { + return nil, NewAppError("AddChannelsToRetentionPolicy", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) } r, err := c.DoAPIPostBytes(c.dataRetentionPolicyRoute(policyID)+"/channels", body) if err != nil { @@ -6135,9 +6141,9 @@ func (c *Client4) AddChannelsToRetentionPolicy(policyID string, channelIDs []str // RemoveChannelsFromRetentionPolicy will remove the specified channels from the granular data retention policy // with the specified ID. func (c *Client4) RemoveChannelsFromRetentionPolicy(policyID string, channelIDs []string) (*Response, error) { - body, jsonErr := json.Marshal(channelIDs) - if jsonErr != nil { - return nil, NewAppError("RemoveChannelsFromRetentionPolicy", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + body, err := json.Marshal(channelIDs) + if err != nil { + return nil, NewAppError("RemoveChannelsFromRetentionPolicy", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) } r, err := c.DoAPIDeleteBytes(c.dataRetentionPolicyRoute(policyID)+"/channels", body) if err != nil { @@ -6190,8 +6196,8 @@ func (c *Client4) CreateCommand(cmd *Command) (*Command, *Response, error) { defer closeBody(r) var command Command - if jsonErr := json.NewDecoder(r.Body).Decode(&command); jsonErr != nil { - return nil, nil, NewAppError("CreateCommand", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&command); err != nil { + return nil, nil, NewAppError("CreateCommand", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &command, BuildResponse(r), nil } @@ -6208,8 +6214,8 @@ func (c *Client4) UpdateCommand(cmd *Command) (*Command, *Response, error) { } defer closeBody(r) var command Command - if jsonErr := json.NewDecoder(r.Body).Decode(&command); jsonErr != nil { - return nil, nil, NewAppError("UpdateCommand", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&command); err != nil { + return nil, nil, NewAppError("UpdateCommand", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &command, BuildResponse(r), nil } @@ -6249,8 +6255,8 @@ func (c *Client4) ListCommands(teamId string, customOnly bool) ([]*Command, *Res defer closeBody(r) var list []*Command - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("ListCommands", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("ListCommands", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return list, BuildResponse(r), nil } @@ -6264,8 +6270,8 @@ func (c *Client4) ListCommandAutocompleteSuggestions(userInput, teamId string) ( } defer closeBody(r) var list []AutocompleteSuggestion - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("ListCommandAutocompleteSuggestions", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("ListCommandAutocompleteSuggestions", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return list, BuildResponse(r), nil } @@ -6279,8 +6285,8 @@ func (c *Client4) GetCommandById(cmdId string) (*Command, *Response, error) { } defer closeBody(r) var command Command - if jsonErr := json.NewDecoder(r.Body).Decode(&command); jsonErr != nil { - return nil, nil, NewAppError("GetCommandById", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&command); err != nil { + return nil, nil, NewAppError("GetCommandById", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &command, BuildResponse(r), nil } @@ -6341,8 +6347,8 @@ func (c *Client4) ListAutocompleteCommands(teamId string) ([]*Command, *Response } defer closeBody(r) var list []*Command - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("ListAutocompleteCommands", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("ListAutocompleteCommands", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return list, BuildResponse(r), nil } @@ -6370,8 +6376,8 @@ func (c *Client4) GetUserStatus(userId, etag string) (*Status, *Response, error) if r.StatusCode == http.StatusNotModified { return &s, BuildResponse(r), nil } - if jsonErr := json.NewDecoder(r.Body).Decode(&s); jsonErr != nil { - return nil, nil, NewAppError("GetUserStatus", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&s); err != nil { + return nil, nil, NewAppError("GetUserStatus", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &s, BuildResponse(r), nil } @@ -6384,8 +6390,8 @@ func (c *Client4) GetUsersStatusesByIds(userIds []string) ([]*Status, *Response, } defer closeBody(r) var list []*Status - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetUsersStatusesByIds", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetUsersStatusesByIds", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return list, BuildResponse(r), nil } @@ -6402,8 +6408,8 @@ func (c *Client4) UpdateUserStatus(userId string, userStatus *Status) (*Status, } defer closeBody(r) var s Status - if jsonErr := json.NewDecoder(r.Body).Decode(&s); jsonErr != nil { - return nil, nil, NewAppError("UpdateUserStatus", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&s); err != nil { + return nil, nil, NewAppError("UpdateUserStatus", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &s, BuildResponse(r), nil } @@ -6461,13 +6467,14 @@ func (c *Client4) CreateEmoji(emoji *Emoji, image []byte, filename string) (*Emo return nil, nil, err } - if _, err := io.Copy(part, bytes.NewBuffer(image)); err != nil { + _, err = io.Copy(part, bytes.NewBuffer(image)) + if err != nil { return nil, nil, err } - emojiJSON, jsonErr := json.Marshal(emoji) - if jsonErr != nil { - return nil, nil, NewAppError("CreateEmoji", "api.marshal_error", nil, jsonErr.Error(), 0) + emojiJSON, err := json.Marshal(emoji) + if err != nil { + return nil, nil, NewAppError("CreateEmoji", "api.marshal_error", nil, err.Error(), 0) } if err := writer.WriteField("emoji", string(emojiJSON)); err != nil { @@ -6491,8 +6498,8 @@ func (c *Client4) GetEmojiList(page, perPage int) ([]*Emoji, *Response, error) { defer closeBody(r) var list []*Emoji - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetEmojiList", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetEmojiList", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return list, BuildResponse(r), nil } @@ -6507,8 +6514,8 @@ func (c *Client4) GetSortedEmojiList(page, perPage int, sort string) ([]*Emoji, } defer closeBody(r) var list []*Emoji - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetSortedEmojiList", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetSortedEmojiList", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return list, BuildResponse(r), nil } @@ -6531,8 +6538,8 @@ func (c *Client4) GetEmoji(emojiId string) (*Emoji, *Response, error) { } defer closeBody(r) var e Emoji - if jsonErr := json.NewDecoder(r.Body).Decode(&e); jsonErr != nil { - return nil, nil, NewAppError("GetEmoji", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&e); err != nil { + return nil, nil, NewAppError("GetEmoji", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &e, BuildResponse(r), nil } @@ -6545,8 +6552,8 @@ func (c *Client4) GetEmojiByName(name string) (*Emoji, *Response, error) { } defer closeBody(r) var e Emoji - if jsonErr := json.NewDecoder(r.Body).Decode(&e); jsonErr != nil { - return nil, nil, NewAppError("GetEmojiByName", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&e); err != nil { + return nil, nil, NewAppError("GetEmojiByName", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &e, BuildResponse(r), nil } @@ -6579,8 +6586,8 @@ func (c *Client4) SearchEmoji(search *EmojiSearch) ([]*Emoji, *Response, error) } defer closeBody(r) var list []*Emoji - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("SearchEmoji", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("SearchEmoji", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return list, BuildResponse(r), nil } @@ -6594,8 +6601,8 @@ func (c *Client4) AutocompleteEmoji(name string, etag string) ([]*Emoji, *Respon } defer closeBody(r) var list []*Emoji - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("AutocompleteEmoji", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("AutocompleteEmoji", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return list, BuildResponse(r), nil } @@ -6614,8 +6621,8 @@ func (c *Client4) SaveReaction(reaction *Reaction) (*Reaction, *Response, error) } defer closeBody(r) var re Reaction - if jsonErr := json.NewDecoder(r.Body).Decode(&re); jsonErr != nil { - return nil, nil, NewAppError("SaveReaction", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&re); err != nil { + return nil, nil, NewAppError("SaveReaction", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &re, BuildResponse(r), nil } @@ -6628,8 +6635,8 @@ func (c *Client4) GetReactions(postId string) ([]*Reaction, *Response, error) { } defer closeBody(r) var list []*Reaction - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetReactions", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetReactions", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return list, BuildResponse(r), nil } @@ -6652,8 +6659,8 @@ func (c *Client4) GetBulkReactions(postIds []string) (map[string][]*Reaction, *R } defer closeBody(r) reactions := map[string][]*Reaction{} - if jsonErr := json.NewDecoder(r.Body).Decode(&reactions); jsonErr != nil { - return nil, nil, NewAppError("GetBulkReactions", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&reactions); err != nil { + return nil, nil, NewAppError("GetBulkReactions", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return reactions, BuildResponse(r), nil } @@ -6666,8 +6673,8 @@ func (c *Client4) GetTopReactionsForTeamSince(teamId string, timeRange string, p } defer closeBody(r) var topReactions *TopReactionList - if jsonErr := json.NewDecoder(r.Body).Decode(&topReactions); jsonErr != nil { - return nil, nil, NewAppError("GetTopReactionsForTeamSince", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&topReactions); err != nil { + return nil, nil, NewAppError("GetTopReactionsForTeamSince", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return topReactions, BuildResponse(r), nil } @@ -6685,8 +6692,8 @@ func (c *Client4) GetTopReactionsForUserSince(teamId string, timeRange string, p } defer closeBody(r) var topReactions *TopReactionList - if jsonErr := json.NewDecoder(r.Body).Decode(&topReactions); jsonErr != nil { - return nil, nil, NewAppError("GetTopReactionsForUserSince", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&topReactions); err != nil { + return nil, nil, NewAppError("GetTopReactionsForUserSince", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return topReactions, BuildResponse(r), nil } @@ -6730,8 +6737,8 @@ func (c *Client4) GetJob(id string) (*Job, *Response, error) { } defer closeBody(r) var j Job - if jsonErr := json.NewDecoder(r.Body).Decode(&j); jsonErr != nil { - return nil, nil, NewAppError("GetJob", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&j); err != nil { + return nil, nil, NewAppError("GetJob", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &j, BuildResponse(r), nil } @@ -6744,8 +6751,8 @@ func (c *Client4) GetJobs(page int, perPage int) ([]*Job, *Response, error) { } defer closeBody(r) var list []*Job - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetJobs", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetJobs", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return list, BuildResponse(r), nil } @@ -6758,8 +6765,8 @@ func (c *Client4) GetJobsByType(jobType string, page int, perPage int) ([]*Job, } defer closeBody(r) var list []*Job - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetJobsByType", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetJobsByType", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return list, BuildResponse(r), nil } @@ -6776,8 +6783,8 @@ func (c *Client4) CreateJob(job *Job) (*Job, *Response, error) { } defer closeBody(r) var j Job - if jsonErr := json.NewDecoder(r.Body).Decode(&j); jsonErr != nil { - return nil, nil, NewAppError("CreateJob", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&j); err != nil { + return nil, nil, NewAppError("CreateJob", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &j, BuildResponse(r), nil } @@ -6817,8 +6824,8 @@ func (c *Client4) GetAllRoles() ([]*Role, *Response, error) { } defer closeBody(r) var list []*Role - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetAllRoles", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetAllRoles", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return list, BuildResponse(r), nil } @@ -6831,8 +6838,8 @@ func (c *Client4) GetRole(id string) (*Role, *Response, error) { } defer closeBody(r) var role Role - if jsonErr := json.NewDecoder(r.Body).Decode(&role); jsonErr != nil { - return nil, nil, NewAppError("GetRole", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&role); err != nil { + return nil, nil, NewAppError("GetRole", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &role, BuildResponse(r), nil } @@ -6845,8 +6852,8 @@ func (c *Client4) GetRoleByName(name string) (*Role, *Response, error) { } defer closeBody(r) var role Role - if jsonErr := json.NewDecoder(r.Body).Decode(&role); jsonErr != nil { - return nil, nil, NewAppError("GetRoleByName", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&role); err != nil { + return nil, nil, NewAppError("GetRoleByName", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &role, BuildResponse(r), nil } @@ -6859,8 +6866,8 @@ func (c *Client4) GetRolesByNames(roleNames []string) ([]*Role, *Response, error } defer closeBody(r) var list []*Role - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetRolesByNames", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetRolesByNames", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return list, BuildResponse(r), nil } @@ -6877,8 +6884,8 @@ func (c *Client4) PatchRole(roleId string, patch *RolePatch) (*Role, *Response, } defer closeBody(r) var role Role - if jsonErr := json.NewDecoder(r.Body).Decode(&role); jsonErr != nil { - return nil, nil, NewAppError("PatchRole", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&role); err != nil { + return nil, nil, NewAppError("PatchRole", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &role, BuildResponse(r), nil } @@ -6897,8 +6904,8 @@ func (c *Client4) CreateScheme(scheme *Scheme) (*Scheme, *Response, error) { } defer closeBody(r) var s Scheme - if jsonErr := json.NewDecoder(r.Body).Decode(&s); jsonErr != nil { - return nil, nil, NewAppError("CreateScheme", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&s); err != nil { + return nil, nil, NewAppError("CreateScheme", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &s, BuildResponse(r), nil } @@ -6911,8 +6918,8 @@ func (c *Client4) GetScheme(id string) (*Scheme, *Response, error) { } defer closeBody(r) var s Scheme - if jsonErr := json.NewDecoder(r.Body).Decode(&s); jsonErr != nil { - return nil, nil, NewAppError("GetScheme", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&s); err != nil { + return nil, nil, NewAppError("GetScheme", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &s, BuildResponse(r), nil } @@ -6925,8 +6932,8 @@ func (c *Client4) GetSchemes(scope string, page int, perPage int) ([]*Scheme, *R } defer closeBody(r) var list []*Scheme - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetSchemes", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetSchemes", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return list, BuildResponse(r), nil } @@ -6953,8 +6960,8 @@ func (c *Client4) PatchScheme(id string, patch *SchemePatch) (*Scheme, *Response } defer closeBody(r) var s Scheme - if jsonErr := json.NewDecoder(r.Body).Decode(&s); jsonErr != nil { - return nil, nil, NewAppError("PatchScheme", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&s); err != nil { + return nil, nil, NewAppError("PatchScheme", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &s, BuildResponse(r), nil } @@ -6967,8 +6974,8 @@ func (c *Client4) GetTeamsForScheme(schemeId string, page int, perPage int) ([]* } defer closeBody(r) var list []*Team - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetTeamsForScheme", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetTeamsForScheme", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return list, BuildResponse(r), nil } @@ -7045,8 +7052,8 @@ func (c *Client4) uploadPlugin(file io.Reader, force bool) (*Manifest, *Response } var m Manifest - if jsonErr := json.NewDecoder(rp.Body).Decode(&m); jsonErr != nil { - return nil, nil, NewAppError("uploadPlugin", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(rp.Body).Decode(&m); err != nil { + return nil, nil, NewAppError("uploadPlugin", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &m, BuildResponse(rp), nil } @@ -7062,8 +7069,8 @@ func (c *Client4) InstallPluginFromURL(downloadURL string, force bool) (*Manifes defer closeBody(r) var m Manifest - if jsonErr := json.NewDecoder(r.Body).Decode(&m); jsonErr != nil { - return nil, nil, NewAppError("InstallPluginFromUrl", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&m); err != nil { + return nil, nil, NewAppError("InstallPluginFromUrl", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &m, BuildResponse(r), nil } @@ -7081,8 +7088,8 @@ func (c *Client4) InstallMarketplacePlugin(request *InstallMarketplacePluginRequ defer closeBody(r) var m Manifest - if jsonErr := json.NewDecoder(r.Body).Decode(&m); jsonErr != nil { - return nil, nil, NewAppError("InstallMarketplacePlugin", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&m); err != nil { + return nil, nil, NewAppError("InstallMarketplacePlugin", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &m, BuildResponse(r), nil } @@ -7096,8 +7103,8 @@ func (c *Client4) GetPlugins() (*PluginsResponse, *Response, error) { defer closeBody(r) var resp PluginsResponse - if jsonErr := json.NewDecoder(r.Body).Decode(&resp); jsonErr != nil { - return nil, nil, NewAppError("GetPlugins", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&resp); err != nil { + return nil, nil, NewAppError("GetPlugins", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &resp, BuildResponse(r), nil } @@ -7111,8 +7118,8 @@ func (c *Client4) GetPluginStatuses() (PluginStatuses, *Response, error) { } defer closeBody(r) var list PluginStatuses - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetPluginStatuses", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetPluginStatuses", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return list, BuildResponse(r), nil } @@ -7136,8 +7143,8 @@ func (c *Client4) GetWebappPlugins() ([]*Manifest, *Response, error) { defer closeBody(r) var list []*Manifest - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetWebappPlugins", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetWebappPlugins", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return list, BuildResponse(r), nil } @@ -7258,8 +7265,8 @@ func (c *Client4) GetServerBusy() (*ServerBusyState, *Response, error) { defer closeBody(r) var sbs ServerBusyState - if jsonErr := json.NewDecoder(r.Body).Decode(&sbs); jsonErr != nil { - return nil, nil, NewAppError("GetServerBusy", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&sbs); err != nil { + return nil, nil, NewAppError("GetServerBusy", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &sbs, BuildResponse(r), nil } @@ -7285,8 +7292,8 @@ func (c *Client4) GetTermsOfService(etag string) (*TermsOfService, *Response, er } defer closeBody(r) var tos TermsOfService - if jsonErr := json.NewDecoder(r.Body).Decode(&tos); jsonErr != nil { - return nil, nil, NewAppError("GetTermsOfService", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&tos); err != nil { + return nil, nil, NewAppError("GetTermsOfService", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &tos, BuildResponse(r), nil } @@ -7300,8 +7307,8 @@ func (c *Client4) GetUserTermsOfService(userId, etag string) (*UserTermsOfServic } defer closeBody(r) var u UserTermsOfService - if jsonErr := json.NewDecoder(r.Body).Decode(&u); jsonErr != nil { - return nil, nil, NewAppError("GetUserTermsOfService", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&u); err != nil { + return nil, nil, NewAppError("GetUserTermsOfService", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &u, BuildResponse(r), nil } @@ -7316,8 +7323,8 @@ func (c *Client4) CreateTermsOfService(text, userId string) (*TermsOfService, *R } defer closeBody(r) var tos TermsOfService - if jsonErr := json.NewDecoder(r.Body).Decode(&tos); jsonErr != nil { - return nil, nil, NewAppError("CreateTermsOfService", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&tos); err != nil { + return nil, nil, NewAppError("CreateTermsOfService", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &tos, BuildResponse(r), nil } @@ -7329,16 +7336,16 @@ func (c *Client4) GetGroup(groupID, etag string) (*Group, *Response, error) { } defer closeBody(r) var g Group - if jsonErr := json.NewDecoder(r.Body).Decode(&g); jsonErr != nil { - return nil, nil, NewAppError("GetGroup", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&g); err != nil { + return nil, nil, NewAppError("GetGroup", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &g, BuildResponse(r), nil } func (c *Client4) CreateGroup(group *Group) (*Group, *Response, error) { - groupJSON, jsonErr := json.Marshal(group) - if jsonErr != nil { - return nil, nil, NewAppError("CreateGroup", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + groupJSON, err := json.Marshal(group) + if err != nil { + return nil, nil, NewAppError("CreateGroup", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) } r, err := c.DoAPIPostBytes("/groups", groupJSON) if err != nil { @@ -7346,8 +7353,8 @@ func (c *Client4) CreateGroup(group *Group) (*Group, *Response, error) { } defer closeBody(r) var p Group - if jsonErr := json.NewDecoder(r.Body).Decode(&p); jsonErr != nil { - return nil, nil, NewAppError("CreateGroup", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&p); err != nil { + return nil, nil, NewAppError("CreateGroup", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &p, BuildResponse(r), nil } @@ -7359,16 +7366,16 @@ func (c *Client4) DeleteGroup(groupID string) (*Group, *Response, error) { } defer closeBody(r) var p Group - if jsonErr := json.NewDecoder(r.Body).Decode(&p); jsonErr != nil { - return nil, nil, NewAppError("DeleteGroup", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&p); err != nil { + return nil, nil, NewAppError("DeleteGroup", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &p, BuildResponse(r), nil } func (c *Client4) PatchGroup(groupID string, patch *GroupPatch) (*Group, *Response, error) { - payload, jsonErr := json.Marshal(patch) - if jsonErr != nil { - return nil, nil, NewAppError("PatchGroup", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + payload, err := json.Marshal(patch) + if err != nil { + return nil, nil, NewAppError("PatchGroup", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) } r, err := c.DoAPIPut(c.groupRoute(groupID)+"/patch", string(payload)) if err != nil { @@ -7376,16 +7383,16 @@ func (c *Client4) PatchGroup(groupID string, patch *GroupPatch) (*Group, *Respon } defer closeBody(r) var g Group - if jsonErr := json.NewDecoder(r.Body).Decode(&g); jsonErr != nil { - return nil, nil, NewAppError("PatchGroup", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&g); err != nil { + return nil, nil, NewAppError("PatchGroup", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &g, BuildResponse(r), nil } func (c *Client4) UpsertGroupMembers(groupID string, userIds *GroupModifyMembers) ([]*GroupMember, *Response, error) { - payload, jsonErr := json.Marshal(userIds) - if jsonErr != nil { - return nil, nil, NewAppError("UpsertGroupMembers", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + payload, err := json.Marshal(userIds) + if err != nil { + return nil, nil, NewAppError("UpsertGroupMembers", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) } r, err := c.DoAPIPostBytes(c.groupRoute(groupID)+"/members", payload) if err != nil { @@ -7393,16 +7400,16 @@ func (c *Client4) UpsertGroupMembers(groupID string, userIds *GroupModifyMembers } defer closeBody(r) var g []*GroupMember - if jsonErr := json.NewDecoder(r.Body).Decode(&g); jsonErr != nil { - return nil, nil, NewAppError("UpsertGroupMembers", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&g); err != nil { + return nil, nil, NewAppError("UpsertGroupMembers", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return g, BuildResponse(r), nil } func (c *Client4) DeleteGroupMembers(groupID string, userIds *GroupModifyMembers) ([]*GroupMember, *Response, error) { - payload, jsonErr := json.Marshal(userIds) - if jsonErr != nil { - return nil, nil, NewAppError("DeleteGroupMembers", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + payload, err := json.Marshal(userIds) + if err != nil { + return nil, nil, NewAppError("DeleteGroupMembers", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) } r, err := c.DoAPIDeleteBytes(c.groupRoute(groupID)+"/members", payload) if err != nil { @@ -7410,16 +7417,16 @@ func (c *Client4) DeleteGroupMembers(groupID string, userIds *GroupModifyMembers } defer closeBody(r) var g []*GroupMember - if jsonErr := json.NewDecoder(r.Body).Decode(&g); jsonErr != nil { - return nil, nil, NewAppError("DeleteGroupMembers", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&g); err != nil { + return nil, nil, NewAppError("DeleteGroupMembers", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return g, BuildResponse(r), nil } func (c *Client4) LinkGroupSyncable(groupID, syncableID string, syncableType GroupSyncableType, patch *GroupSyncablePatch) (*GroupSyncable, *Response, error) { - payload, jsonErr := json.Marshal(patch) - if jsonErr != nil { - return nil, nil, NewAppError("LinkGroupSyncable", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + payload, err := json.Marshal(patch) + if err != nil { + return nil, nil, NewAppError("LinkGroupSyncable", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) } url := fmt.Sprintf("%s/link", c.groupSyncableRoute(groupID, syncableID, syncableType)) r, err := c.DoAPIPost(url, string(payload)) @@ -7428,8 +7435,8 @@ func (c *Client4) LinkGroupSyncable(groupID, syncableID string, syncableType Gro } defer closeBody(r) var gs GroupSyncable - if jsonErr := json.NewDecoder(r.Body).Decode(&gs); jsonErr != nil { - return nil, nil, NewAppError("LinkGroupSyncable", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&gs); err != nil { + return nil, nil, NewAppError("LinkGroupSyncable", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &gs, BuildResponse(r), nil } @@ -7451,8 +7458,8 @@ func (c *Client4) GetGroupSyncable(groupID, syncableID string, syncableType Grou } defer closeBody(r) var gs GroupSyncable - if jsonErr := json.NewDecoder(r.Body).Decode(&gs); jsonErr != nil { - return nil, nil, NewAppError("GetGroupSyncable", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&gs); err != nil { + return nil, nil, NewAppError("GetGroupSyncable", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &gs, BuildResponse(r), nil } @@ -7464,16 +7471,16 @@ func (c *Client4) GetGroupSyncables(groupID string, syncableType GroupSyncableTy } defer closeBody(r) var list []*GroupSyncable - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetGroupSyncables", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetGroupSyncables", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return list, BuildResponse(r), nil } func (c *Client4) PatchGroupSyncable(groupID, syncableID string, syncableType GroupSyncableType, patch *GroupSyncablePatch) (*GroupSyncable, *Response, error) { - payload, jsonErr := json.Marshal(patch) - if jsonErr != nil { - return nil, nil, NewAppError("PatchGroupSyncable", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + payload, err := json.Marshal(patch) + if err != nil { + return nil, nil, NewAppError("PatchGroupSyncable", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) } r, err := c.DoAPIPut(c.groupSyncableRoute(groupID, syncableID, syncableType)+"/patch", string(payload)) if err != nil { @@ -7481,8 +7488,8 @@ func (c *Client4) PatchGroupSyncable(groupID, syncableID string, syncableType Gr } defer closeBody(r) var gs GroupSyncable - if jsonErr := json.NewDecoder(r.Body).Decode(&gs); jsonErr != nil { - return nil, nil, NewAppError("PatchGroupSyncable", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&gs); err != nil { + return nil, nil, NewAppError("PatchGroupSyncable", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &gs, BuildResponse(r), nil } @@ -7497,8 +7504,8 @@ func (c *Client4) TeamMembersMinusGroupMembers(teamID string, groupIDs []string, defer closeBody(r) var ugc UsersWithGroupsAndCount - if jsonErr := json.NewDecoder(r.Body).Decode(&ugc); jsonErr != nil { - return nil, 0, nil, NewAppError("TeamMembersMinusGroupMembers", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&ugc); err != nil { + return nil, 0, nil, NewAppError("TeamMembersMinusGroupMembers", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return ugc.Users, ugc.Count, BuildResponse(r), nil } @@ -7512,8 +7519,8 @@ func (c *Client4) ChannelMembersMinusGroupMembers(channelID string, groupIDs []s } defer closeBody(r) var ugc UsersWithGroupsAndCount - if jsonErr := json.NewDecoder(r.Body).Decode(&ugc); jsonErr != nil { - return nil, 0, nil, NewAppError("ChannelMembersMinusGroupMembers", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&ugc); err != nil { + return nil, 0, nil, NewAppError("ChannelMembersMinusGroupMembers", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return ugc.Users, ugc.Count, BuildResponse(r), nil } @@ -7528,7 +7535,10 @@ func (c *Client4) PatchConfig(config *Config) (*Config, *Response, error) { return nil, BuildResponse(r), err } defer closeBody(r) - return ConfigFromJSON(r.Body), BuildResponse(r), nil + + var cfg *Config + d := json.NewDecoder(r.Body) + return cfg, BuildResponse(r), d.Decode(&cfg) } func (c *Client4) GetChannelModerations(channelID string, etag string) ([]*ChannelModeration, *Response, error) { @@ -7608,9 +7618,9 @@ func (c *Client4) GetChannelMemberCountsByGroup(channelID string, includeTimezon // RequestTrialLicense will request a trial license and install it in the server func (c *Client4) RequestTrialLicense(users int) (*Response, error) { - b, jsonErr := json.Marshal(map[string]any{"users": users, "terms_accepted": true}) - if jsonErr != nil { - return nil, NewAppError("RequestTrialLicense", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + b, err := json.Marshal(map[string]any{"users": users, "terms_accepted": true}) + if err != nil { + return nil, NewAppError("RequestTrialLicense", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) } r, err := c.DoAPIPost("/trial-license", string(b)) if err != nil { @@ -7628,8 +7638,8 @@ func (c *Client4) GetGroupStats(groupID string) (*GroupStats, *Response, error) } defer closeBody(r) var gs GroupStats - if jsonErr := json.NewDecoder(r.Body).Decode(&gs); jsonErr != nil { - return nil, nil, NewAppError("GetGroupStats", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&gs); err != nil { + return nil, nil, NewAppError("GetGroupStats", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &gs, BuildResponse(r), nil } @@ -7650,9 +7660,9 @@ func (c *Client4) GetSidebarCategoriesForTeamForUser(userID, teamID, etag string } func (c *Client4) CreateSidebarCategoryForTeamForUser(userID, teamID string, category *SidebarCategoryWithChannels) (*SidebarCategoryWithChannels, *Response, error) { - payload, jsonErr := json.Marshal(category) - if jsonErr != nil { - return nil, nil, NewAppError("CreateSidebarCategoryForTeamForUser", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + payload, err := json.Marshal(category) + if err != nil { + return nil, nil, NewAppError("CreateSidebarCategoryForTeamForUser", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) } route := c.userCategoryRoute(userID, teamID) r, err := c.DoAPIPostBytes(route, payload) @@ -7669,9 +7679,9 @@ func (c *Client4) CreateSidebarCategoryForTeamForUser(userID, teamID string, cat } func (c *Client4) UpdateSidebarCategoriesForTeamForUser(userID, teamID string, categories []*SidebarCategoryWithChannels) ([]*SidebarCategoryWithChannels, *Response, error) { - payload, jsonErr := json.Marshal(categories) - if jsonErr != nil { - return nil, nil, NewAppError("UpdateSidebarCategoriesForTeamForUser", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + payload, err := json.Marshal(categories) + if err != nil { + return nil, nil, NewAppError("UpdateSidebarCategoriesForTeamForUser", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) } route := c.userCategoryRoute(userID, teamID) @@ -7701,9 +7711,9 @@ func (c *Client4) GetSidebarCategoryOrderForTeamForUser(userID, teamID, etag str } func (c *Client4) UpdateSidebarCategoryOrderForTeamForUser(userID, teamID string, order []string) ([]string, *Response, error) { - payload, jsonErr := json.Marshal(order) - if jsonErr != nil { - return nil, nil, NewAppError("UpdateSidebarCategoryOrderForTeamForUser", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + payload, err := json.Marshal(order) + if err != nil { + return nil, nil, NewAppError("UpdateSidebarCategoryOrderForTeamForUser", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) } route := c.userCategoryRoute(userID, teamID) + "/order" r, err := c.DoAPIPutBytes(route, payload) @@ -7731,9 +7741,9 @@ func (c *Client4) GetSidebarCategoryForTeamForUser(userID, teamID, categoryID, e } func (c *Client4) UpdateSidebarCategoryForTeamForUser(userID, teamID, categoryID string, category *SidebarCategoryWithChannels) (*SidebarCategoryWithChannels, *Response, error) { - payload, jsonErr := json.Marshal(category) - if jsonErr != nil { - return nil, nil, NewAppError("UpdateSidebarCategoryForTeamForUser", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + payload, err := json.Marshal(category) + if err != nil { + return nil, nil, NewAppError("UpdateSidebarCategoryForTeamForUser", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) } route := c.userCategoryRoute(userID, teamID) + "/" + categoryID r, err := c.DoAPIPutBytes(route, payload) @@ -7814,8 +7824,8 @@ func (c *Client4) CreateUpload(us *UploadSession) (*UploadSession, *Response, er defer closeBody(r) var s UploadSession - if jsonErr := json.NewDecoder(r.Body).Decode(&s); jsonErr != nil { - return nil, nil, NewAppError("CreateUpload", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&s); err != nil { + return nil, nil, NewAppError("CreateUpload", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &s, BuildResponse(r), nil } @@ -7828,8 +7838,8 @@ func (c *Client4) GetUpload(uploadId string) (*UploadSession, *Response, error) } defer closeBody(r) var s UploadSession - if jsonErr := json.NewDecoder(r.Body).Decode(&s); jsonErr != nil { - return nil, nil, NewAppError("GetUpload", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&s); err != nil { + return nil, nil, NewAppError("GetUpload", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &s, BuildResponse(r), nil } @@ -7843,8 +7853,8 @@ func (c *Client4) GetUploadsForUser(userId string) ([]*UploadSession, *Response, } defer closeBody(r) var list []*UploadSession - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetUploadsForUser", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetUploadsForUser", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return list, BuildResponse(r), nil } @@ -7862,8 +7872,8 @@ func (c *Client4) UploadData(uploadId string, data io.Reader) (*FileInfo, *Respo if r.StatusCode == http.StatusNoContent { return nil, BuildResponse(r), nil } - if jsonErr := json.NewDecoder(r.Body).Decode(&fi); jsonErr != nil { - return nil, nil, NewAppError("UploadData", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&fi); err != nil { + return nil, nil, NewAppError("UploadData", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return &fi, BuildResponse(r), nil } @@ -7920,9 +7930,9 @@ func (c *Client4) CreateCustomerPayment() (*StripeSetupIntent, *Response, error) } func (c *Client4) ConfirmCustomerPayment(confirmRequest *ConfirmPaymentMethodRequest) (*Response, error) { - json, jsonErr := json.Marshal(confirmRequest) - if jsonErr != nil { - return nil, NewAppError("ConfirmCustomerPayment", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + json, err := json.Marshal(confirmRequest) + if err != nil { + return nil, NewAppError("ConfirmCustomerPayment", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) } r, err := c.DoAPIPostBytes(c.cloudRoute()+"/payment/confirm", json) if err != nil { @@ -7934,9 +7944,9 @@ func (c *Client4) ConfirmCustomerPayment(confirmRequest *ConfirmPaymentMethodReq } func (c *Client4) RequestCloudTrial(email *StartCloudTrialRequest) (*Subscription, *Response, error) { - payload, jsonErr := json.Marshal(email) - if jsonErr != nil { - return nil, nil, NewAppError("RequestCloudTrial", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + payload, err := json.Marshal(email) + if err != nil { + return nil, nil, NewAppError("RequestCloudTrial", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) } r, err := c.DoAPIPutBytes(c.cloudRoute()+"/request-trial", payload) if err != nil { @@ -7961,8 +7971,8 @@ func (c *Client4) ValidateWorkspaceBusinessEmail() (*Response, error) { } func (c *Client4) NotifyAdmin(nr *NotifyAdminToUpgradeRequest) int { - nrJSON, jsonErr := json.Marshal(nr) - if jsonErr != nil { + nrJSON, err := json.Marshal(nr) + if err != nil { return 0 } @@ -8027,9 +8037,9 @@ func (c *Client4) GetInvoicesForSubscription() ([]*Invoice, *Response, error) { } func (c *Client4) UpdateCloudCustomer(customerInfo *CloudCustomerInfo) (*CloudCustomer, *Response, error) { - customerBytes, jsonErr := json.Marshal(customerInfo) - if jsonErr != nil { - return nil, nil, NewAppError("UpdateCloudCustomer", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + customerBytes, err := json.Marshal(customerInfo) + if err != nil { + return nil, nil, NewAppError("UpdateCloudCustomer", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) } r, err := c.DoAPIPutBytes(c.cloudRoute()+"/customer", customerBytes) if err != nil { @@ -8044,9 +8054,9 @@ func (c *Client4) UpdateCloudCustomer(customerInfo *CloudCustomerInfo) (*CloudCu } func (c *Client4) UpdateCloudCustomerAddress(address *Address) (*CloudCustomer, *Response, error) { - addressBytes, jsonErr := json.Marshal(address) - if jsonErr != nil { - return nil, nil, NewAppError("UpdateCloudCustomerAddress", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + addressBytes, err := json.Marshal(address) + if err != nil { + return nil, nil, NewAppError("UpdateCloudCustomerAddress", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) } r, err := c.DoAPIPutBytes(c.cloudRoute()+"/customer/address", addressBytes) if err != nil { @@ -8271,8 +8281,8 @@ func (c *Client4) GetUsersWithInvalidEmails(page, perPage int) ([]*User, *Respon if r.StatusCode == http.StatusNotModified { return list, BuildResponse(r), nil } - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetUsers", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetUsers", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return list, BuildResponse(r), nil } @@ -8284,8 +8294,8 @@ func (c *Client4) GetAppliedSchemaMigrations() ([]AppliedMigration, *Response, e } defer closeBody(r) var list []AppliedMigration - if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil { - return nil, nil, NewAppError("GetUsers", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + if err := json.NewDecoder(r.Body).Decode(&list); err != nil { + return nil, nil, NewAppError("GetUsers", "api.unmarshal_error", nil, err.Error(), http.StatusInternalServerError) } return list, BuildResponse(r), nil } diff --git a/model/preference.go b/model/preference.go index 6ce93be67a..98e0a08c5a 100644 --- a/model/preference.go +++ b/model/preference.go @@ -91,23 +91,21 @@ func (o *Preference) IsValid() *AppError { if o.Category == PreferenceCategoryTheme { var unused map[string]string if err := json.NewDecoder(strings.NewReader(o.Value)).Decode(&unused); err != nil { - return NewAppError("Preference.IsValid", "model.preference.is_valid.theme.app_error", nil, "value="+o.Value, http.StatusBadRequest) + return NewAppError("Preference.IsValid", "model.preference.is_valid.theme.app_error", nil, "value="+o.Value, http.StatusBadRequest).Wrap(err) } } return nil } +var preUpdateColorPattern = regexp.MustCompile(`^#[0-9a-fA-F]{3}([0-9a-fA-F]{3})?$`) + func (o *Preference) PreUpdate() { if o.Category == PreferenceCategoryTheme { // decode the value of theme (a map of strings to string) and eliminate any invalid values var props map[string]string - if err := json.NewDecoder(strings.NewReader(o.Value)).Decode(&props); err != nil { - // just continue, the invalid preference value should get caught by IsValid before saving - return - } - - colorPattern := regexp.MustCompile(`^#[0-9a-fA-F]{3}([0-9a-fA-F]{3})?$`) + // just continue, the invalid preference value should get caught by IsValid before saving + json.NewDecoder(strings.NewReader(o.Value)).Decode(&props) // blank out any invalid theme values for name, value := range props { @@ -115,7 +113,7 @@ func (o *Preference) PreUpdate() { continue } - if !colorPattern.MatchString(value) { + if !preUpdateColorPattern.MatchString(value) { props[name] = "#ffffff" } } diff --git a/model/utils.go b/model/utils.go index 8d93015c57..86ec1536f2 100644 --- a/model/utils.go +++ b/model/utils.go @@ -293,7 +293,7 @@ func AppErrorFromJSON(data io.Reader) *AppError { var er AppError err := decoder.Decode(&er) if err != nil { - return NewAppError("AppErrorFromJSON", "model.utils.decode_json.app_error", nil, "body: "+str, http.StatusInternalServerError) + return NewAppError("AppErrorFromJSON", "model.utils.decode_json.app_error", nil, "body: "+str, http.StatusInternalServerError).Wrap(err) } return &er } @@ -401,23 +401,25 @@ func MapBoolToJSON(objmap map[string]bool) string { // MapFromJSON will decode the key/value pair map func MapFromJSON(data io.Reader) map[string]string { - decoder := json.NewDecoder(data) - var objmap map[string]string - if err := decoder.Decode(&objmap); err != nil { + + json.NewDecoder(data).Decode(&objmap) + if objmap == nil { return make(map[string]string) } + return objmap } // MapFromJSON will decode the key/value pair map func MapBoolFromJSON(data io.Reader) map[string]bool { - decoder := json.NewDecoder(data) - var objmap map[string]bool - if err := decoder.Decode(&objmap); err != nil { + + json.NewDecoder(data).Decode(&objmap) + if objmap == nil { return make(map[string]bool) } + return objmap } @@ -427,12 +429,13 @@ func ArrayToJSON(objmap []string) string { } func ArrayFromJSON(data io.Reader) []string { - decoder := json.NewDecoder(data) - var objmap []string - if err := decoder.Decode(&objmap); err != nil { + + json.NewDecoder(data).Decode(&objmap) + if objmap == nil { return make([]string, 0) } + return objmap } @@ -459,12 +462,13 @@ func StringInterfaceToJSON(objmap map[string]any) string { } func StringInterfaceFromJSON(data io.Reader) map[string]any { - decoder := json.NewDecoder(data) - var objmap map[string]any - if err := decoder.Decode(&objmap); err != nil { + + json.NewDecoder(data).Decode(&objmap) + if objmap == nil { return make(map[string]any) } + return objmap } diff --git a/services/slackimport/parsers.go b/services/slackimport/parsers.go index f3eab0ab1a..fcd50f3de9 100644 --- a/services/slackimport/parsers.go +++ b/services/slackimport/parsers.go @@ -16,7 +16,7 @@ func slackParseChannels(data io.Reader, channelType model.ChannelType) ([]slackC var channels []slackChannel if err := decoder.Decode(&channels); err != nil { - mlog.Warn("Slack Import: Error occurred when parsing some Slack channels. Import may work anyway.") + mlog.Warn("Slack Import: Error occurred when parsing some Slack channels. Import may work anyway.", mlog.Err(err)) return channels, err } @@ -43,7 +43,7 @@ func slackParsePosts(data io.Reader) ([]slackPost, error) { var posts []slackPost if err := decoder.Decode(&posts); err != nil { - mlog.Warn("Slack Import: Error occurred when parsing some Slack posts. Import may work anyway.") + mlog.Warn("Slack Import: Error occurred when parsing some Slack posts. Import may work anyway.", mlog.Err(err)) return posts, err } return posts, nil diff --git a/shared/filestore/filesstore_test.go b/shared/filestore/filesstore_test.go index ea8dae2435..dae092e8a7 100644 --- a/shared/filestore/filesstore_test.go +++ b/shared/filestore/filesstore_test.go @@ -500,15 +500,16 @@ func (s *FileBackendTestSuite) TestFileModTime() { func BenchmarkS3WriteFile(b *testing.B) { settings := FileBackendSettings{ - DriverName: driverS3, - AmazonS3AccessKeyId: "minioaccesskey", - AmazonS3SecretAccessKey: "miniosecretkey", - AmazonS3Bucket: "mattermost-test", - AmazonS3Region: "", - AmazonS3Endpoint: "localhost:9000", - AmazonS3PathPrefix: "", - AmazonS3SSL: false, - AmazonS3SSE: false, + DriverName: driverS3, + AmazonS3AccessKeyId: "minioaccesskey", + AmazonS3SecretAccessKey: "miniosecretkey", + AmazonS3Bucket: "mattermost-test", + AmazonS3Region: "", + AmazonS3Endpoint: "localhost:9000", + AmazonS3PathPrefix: "", + AmazonS3SSL: false, + AmazonS3SSE: false, + AmazonS3RequestTimeoutMilliseconds: 20000, } backend, err := NewFileBackend(settings) diff --git a/shared/mail/mail.go b/shared/mail/mail.go index b3c2ef10d0..03dbddc62a 100644 --- a/shared/mail/mail.go +++ b/shared/mail/mail.go @@ -58,7 +58,6 @@ type mailData struct { } // smtpClient is implemented by an smtp.Client. See https://golang.org/pkg/net/smtp/#Client. -// type smtpClient interface { Mail(string) error Rcpt(string) error diff --git a/web/context.go b/web/context.go index de02d18c03..fb9dd48169 100644 --- a/web/context.go +++ b/web/context.go @@ -241,8 +241,8 @@ func (c *Context) SetInvalidRemoteClusterTokenError() { c.Err = NewInvalidRemoteClusterTokenError() } -func (c *Context) SetJSONEncodingError() { - c.Err = NewJSONEncodingError() +func (c *Context) SetJSONEncodingError(err error) { + c.Err = NewJSONEncodingError(err) } func (c *Context) SetCommandNotFoundError() { @@ -294,9 +294,9 @@ func NewInvalidRemoteClusterTokenError() *model.AppError { return err } -func NewJSONEncodingError() *model.AppError { - err := model.NewAppError("Context", "api.context.json_encoding.app_error", nil, "", http.StatusInternalServerError) - return err +func NewJSONEncodingError(err error) *model.AppError { + appErr := model.NewAppError("Context", "api.context.json_encoding.app_error", nil, "", http.StatusInternalServerError).Wrap(err) + return appErr } func (c *Context) SetPermissionError(permissions ...*model.Permission) { diff --git a/web/oauth.go b/web/oauth.go index bee17266b0..2ed3a86f3c 100644 --- a/web/oauth.go +++ b/web/oauth.go @@ -48,7 +48,7 @@ func authorizeOAuthApp(c *Context, w http.ResponseWriter, r *http.Request) { var authRequest *model.AuthorizeRequest err := json.NewDecoder(r.Body).Decode(&authRequest) if err != nil || authRequest == nil { - c.SetInvalidParam("authorize_request") + c.SetInvalidParamWithErr("authorize_request", err) return } @@ -241,7 +241,7 @@ func getAccessToken(c *Context, w http.ResponseWriter, r *http.Request) { c.LogAudit("success") if err := json.NewEncoder(w).Encode(accessRsp); err != nil { - mlog.Warn("Error writing response", mlog.Err(err)) + c.Logger.Warn("Error writing response", mlog.Err(err)) } } diff --git a/web/webhook.go b/web/webhook.go index 858a551b5d..a54e72e301 100644 --- a/web/webhook.go +++ b/web/webhook.go @@ -50,8 +50,15 @@ func incomingWebhook(c *Context, w http.ResponseWriter, r *http.Request) { defer func() { if *c.App.Config().LogSettings.EnableWebhookDebugging { if c.Err != nil { - payload, _ := json.Marshal(incomingWebhookPayload) - mlog.Debug("Incoming webhook received", mlog.String("webhook_id", id), mlog.String("request_id", c.AppContext.RequestId()), mlog.String("payload", string(payload))) + fields := []mlog.Field{mlog.String("webhook_id", id), mlog.String("request_id", c.AppContext.RequestId())} + payload, err := json.Marshal(incomingWebhookPayload) + if err != nil { + fields = append(fields, mlog.NamedErr("encoding_err", err)) + } else { + fields = append(fields, mlog.String("payload", string(payload))) + } + + mlog.Debug("Incoming webhook received", fields...) } } }()